www.digitalmars.com         C & C++   DMDScript  

c++.beta - Functional C++, FC++

reply Richard Grant <fractal clark.net> writes:
Moved this from C++ since I worked on it with the latest beta..

c++/2170

I don't think any compiler works out of the box with this lib. At least not
without some encouragement from the authors. So we are like 80% functional with
minor adjustments to get to 90%, with hard work we can get to 98% - need
explicit function template specialization for 100%, but I'll need to actually
try and use it to see if any mainstream features are missing.

Here goes:

Change the name of the directories to something else like FCPP14, FCPPClients14
instead of FC++.1.4, FC++-Clients.1.4. Linker will look at the dash and think
its an option, and projects with + in them are a no no.

Add the equivalent of the following macro guard to your project or compile parms
to get around some special sections that seem to be for gcc, but dm compiles the
regular implementation, and can't compile the workaround:

#define FCPP_TEMPLATE_ENUM

You need to fixup the code in list.h a little.. following the babble are the
diffs as reported by "fc /L /N /W c:\orig\list.h c:\fcpp14\list.h". Where orig
is the distribution lib, and fcpp14 is the adjusted lib. Sorry no GNU patch..
not much time..

Most of the problems are in List.h, and like boost::tuple, the trouble starts
with the data representation of linked lists of arbitrary types. In this case,
the implementation uses similiar concepts, but an lvalue representation - as in
not rvalue like tuple.

Anyway, definitions.cc can't compile "Length length;" because of some ambiguity
- probably a namespace bug, but kind of a tongue twister so I don't know yet.
The other 50 odd checks in definitions.cc compile fine so that may be considered
successful.

Always get "Warning 18" on some functions that throw with no final return.
Problem is with compiler but Walter said he was fixing it..

Compose and more than 10 other tests do not compile becuase of problems with
something like:

template <class T> struct A {
protected:
T i;
T j;
};

template <class T> struct B : A<T> {
protected:
using A<T>::i;
// Error: using-declaration cannot name template-id 'A'
using A<T>::j;
// Error: using-declaration cannot name template-id 'A' 
};

int main() {
B<int> b;
}

Curry tests doen't work becuase of some class access problem, but everything
seems accessable, so probably a class template with friends workaround.

Not sure what is up with the client ecoop2b.cc, it just makes the compiler go
away silently. When try in IDE, everything closes with no protection fault,
notice or anything else - kind of wish it closed that fast by itself, but for
that need a better computer ;)

Not sure what's up with odd_list.cc, but looks like the same type of workaround
they used for gcc - that gets turned off with FCPP_TEMPLATE_ENUM, is implemented
here, but with no macro guard.

mem_fun.cc test fails because no support for function template specialization
yet: c++.beta/99

Not sure what is up with Monad[x].cc, but none of those compile.

Several more fail to compile with nested template references. Boost
compressed_pair has similiar problems, so looking at that anyway. The format of
these failures resemble:

template <class T> struct E : F<T, typename D<T>::R> { };

ord_test.cc compiles ok, but generates an access violation when run. Looks
pretty simple program - mmmm.

rctest.cc does not compile becuase of an ambigious reference caused by friend
declaration in conflict with namespace scope declaration.. this was the source
of several problems in list.h, so I won't fix this and get a test case case so
Walter can stamp it out.

tw_hamming.cc fails to compile, but with a misleading error message. Its a
parenthesis operator with a static class object initialized via operator =.
Error is: dynamically initialized global variable 'h' should be static. Wierd
since the var are declared as static.

So total is 31 of 57 tests. I think 12 will be fixed with minor adjustments
indicated above.. around 10 more will need researching, and the rest won't
compile without explicit function template specialization.

Ok, now comes the diff. Careful with line breaks.

Richard

=============

Comparing files C:\ORIG\list.h and C:\FCPP14\LIST.H
***** C:\ORIG\list.h
53:  template <class T, class F, class R> struct ListHelp;
54:  template <class T> Cache<T>* xempty_helper();
56:  struct ListRaw {};
***** C:\FCPP14\LIST.H
53:  template <class T, class F, class R> struct ListHelp;
54:  template <class U> Cache<U>* xempty_helper(const U&);
56:  struct ListRaw {};
*****

***** C:\ORIG\list.h
104:     : rep( new Cache<T>( ListItHelp<T,It>(begin,end) ) ) {}
106:     List( const OddList<T>& e )
***** C:\FCPP14\LIST.H
104:     : rep( new Cache<T>( ListItHelp<T,It>(begin,end) ) ) {}
106:  #if defined (__DMC__)
107:     List( const OddList<T>& e )
*****

***** C:\ORIG\list.h
107:     : rep( (e.second.rep != Cache<T>::XNIL()) ?
108:            new Cache<T>(e) : Cache<T>::XEMPTY() ) {}
110:  #ifdef FCPP_SAFE_LIST
***** C:\FCPP14\LIST.H
108:     : rep( (e.second.rep != Cache<T>::XNIL()) ?
109:            IRef<Cache<T>>(new Cache<T>(e)) : Cache<T>::XEMPTY() ) {}
110:  #else
111:     List( const OddList<T>& e )
112:     : rep( (e.second.rep != Cache<T>::XNIL()) ?
113:            new Cache<T>(e) : Cache<T>::XEMPTY() ) {}
114:  #endif
116:  #ifdef FCPP_SAFE_LIST
*****

***** C:\ORIG\list.h
223:     OddList( const T& x, const List<T>& y ) : second(y) { init(x); }
224:     OddList( const T& x, AUniqueTypeForNil )
***** C:\FCPP14\LIST.H
229:     OddList( const T& x, const List<T>& y ) : second(y) { init(x); }
230:     OddList( const T& x, AUniqueTypeForNil )
*****

***** C:\ORIG\list.h
289:  }
291:  template <class T>
292:  Cache<T>* xempty_helper() {
293:  #ifdef FCPP_1_3_LIST_IMPL
294:     (void) Cache<T>::xnil;   // Make sure xnil exists before moving forward
295:  #endif
296:     return new Cache<T>( CacheEmpty() );
297:  }
***** C:\FCPP14\LIST.H
295:  }
297:  template <class U>
298:  Cache<U>* xempty_helper(const U& = 0) {
299:  #ifdef FCPP_1_3_LIST_IMPL
300:     (void) Cache<U>::xnil;   // Make sure xnil exists before moving forward
301:  #endif
302:     return new Cache<U>( CacheEmpty() );
303:  }
*****

***** C:\ORIG\list.h
392:     template <class U, class F, class R> friend struct ListHelp;
393:     template <class U> friend Cache<U>* xempty_helper();
395:     Cache( CacheEmpty ) : refC(0), fxn(blackhole()), val() {}
***** C:\FCPP14\LIST.H
398:     template <class U, class F, class R> friend struct ListHelp;
399:     template <class U> friend Cache<U>* xempty_helper(const U&);
401:     Cache( CacheEmpty ) : refC(0), fxn(blackhole()), val() {}
*****
Apr 24 2003
next sibling parent reply Mark Evans <Mark_member pathlink.com> writes:
I don't think any compiler works out of the box with this lib.

You are doing nice work. I may have posted this link before. http://www.cc.gatech.edu/~yannis/fc++/New/compilers.html
Apr 24 2003
parent Richard Grant <fractal clark.net> writes:
In article <b89sc7$2g0a$1 digitaldaemon.com>, Mark Evans says...

I don't think any compiler works out of the box with this lib.

You are doing nice work. I may have posted this link before.

Thanks! The following snippit fails to compile, and has been a nuisance in boost compressed_pair. This in turn causes problems in iterator_adaptors, the new filesystem library and others. It is also a problem with the FC++ lib. If you uncomment the definition of "aa", it compiles fine. Fixing this one will probably have a healthy amount of mileage. template <class T1, class T2, int N> class A; template <class T1, class T2> class A<T1,T2,2> { }; struct B { }; struct C { }; int main() { //A<B,C,2> aa; const int i = 2; A<B,C,i> ab; // Error: size of ?$A UB UC $01 is not known } Richard
Apr 26 2003
prev sibling next sibling parent Richard Grant <fractal clark.net> writes:
rctest.cc does not compile becuase of an ambigious reference caused by friend
declaration in conflict with namespace scope declaration.. this was the source
of several problems in list.h, so I won't fix this and get a test case case so
Walter can stamp it out.

template<class T> class A; template <class T> int fn( const A<T>& r ); template<class T> class A { template <class U> friend int fn( const A<U>& r ); }; template <class T> int fn( const A<T>& r ) { return 0; } int main() { A<int> a; int i = fn<int>(a); // Error: ambiguous reference to symbol // Had: fn(const A<T>&) // and: fn(const A<U>&) } Richard
Apr 26 2003
prev sibling parent Richard Grant <fractal clark.net> writes:
Anyway, definitions.cc can't compile "Length length;" because of some ambiguity
- probably a namespace bug, but kind of a tongue twister so I don't know yet.

Here is the test case. I don't think this is a bug, but the behavior might be worth looking into briefly. The error message is valid since "length" is defined twice - first in an unamed namespace, and again in the enclosing namespace. However, there is no obvious dereference of "length", and it looks like the template class static member function "length" in A is being confused with the function template parenthesis operator in the Length struct. I think that makes it worth a look. Also, if you move the second definition of "length" from the second ns2 block into the first ns2 block, and remove the second ns2 block, the test case compiles. namespace ns1 { template <class T> struct A { }; template <> struct A<int> { static unsigned length(const char* s) { return 10; } }; template <class T1> struct B { B() { int i = A<T1>::length(0); } // Error: ambiguous reference to symbol // Had: ns2::unique::length // and: ns2::length }; }//ns1 namespace ns2 { ns1::B<int> b; struct Length { template <class L> unsigned operator()( const L& ll ) const { return 9; } }; namespace { Length length; }//unique }//ns2 namespace ns2 { Length length; }//ns2 int main() { } Richard
May 02 2003