www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Suggestion : improve compile-time type manipulation facilities

reply Alex B. <Alex_member pathlink.com> writes:
It seems pattern matching in specialization facilities of D aren't powerful
enough to implement concept of type-lists. Well it simply can't match smthing
like 'template <class T, class U> struct Length< Typelist<T, U> >' and it is
essential feature of C++ template engine.

I tried a simpler way to implement them and discovered a serious clash between
'properties' concept and type aliasing.

Here is the code:

class NullType
{
}

template TypeList(U,V)
{
class TypeList
{
alias U Head;
alias V Tail;
}
}


template TL_Length(Arg : NullType)
{
enum
{
Result = 0
}	
}


template TL_Length(Arg)
{
enum
{
Result = 1 + TL_Length!(Arg.Tail).Result
}
}

void main()
{
// no property 'Tail' for type 'TypeList'
printf("%d\n",TL_Length!(TypeList!(int,TypeList!(float,NullType))).Result);
// ok 
typeid(TypeList!(int,TypeList!(float,NullType)).Tail).print();
// no property 'Tail' for type 'TypeList'  
typeid(TypeList!(int,TypeList!(float,NullType)).Tail.Tail).print();
// .property not implemented for typeof
typeid(typeof(TypeList!(int,TypeList!(float,NullType)).Tail).Tail).print();
}

Are there any work-arounds? Is it possible to make a proper implementation of
specialization?
Jun 29 2004
next sibling parent reply Andy Friesen <andy ikagames.com> writes:
Alex B. wrote:
 It seems pattern matching in specialization facilities of D aren't powerful
 enough to implement concept of type-lists. Well it simply can't match smthing
 like 'template <class T, class U> struct Length< Typelist<T, U> >' and it is
 essential feature of C++ template engine.
 
 I tried a simpler way to implement them and discovered a serious clash between
 'properties' concept and type aliasing.
 
 Here is the code:
 
 class NullType
 {
 }
 
 template TypeList(U,V)
 {
 class TypeList
 {
 alias U Head;
 alias V Tail;
 }
 }
 
 
 template TL_Length(Arg : NullType)
 {
 enum
 {
 Result = 0
 }	
 }
 
 
 template TL_Length(Arg)
 {
 enum
 {
 Result = 1 + TL_Length!(Arg.Tail).Result
 }
 }
 
 void main()
 {
 // no property 'Tail' for type 'TypeList'
 printf("%d\n",TL_Length!(TypeList!(int,TypeList!(float,NullType))).Result);
 // ok 
 typeid(TypeList!(int,TypeList!(float,NullType)).Tail).print();
 // no property 'Tail' for type 'TypeList'  
 typeid(TypeList!(int,TypeList!(float,NullType)).Tail.Tail).print();
 // .property not implemented for typeof
 typeid(typeof(TypeList!(int,TypeList!(float,NullType)).Tail).Tail).print();
 }
 
 Are there any work-arounds? Is it possible to make a proper implementation of
 specialization?

I believe this is a bug. One workaround is to do: struct Empty{} template TypeList(_Head, _Tail) { struct TypeList { alias _Head HeadType; alias _Tail TailType; HeadType head; TailType tail; } } template Length(_TL) { // _Tl.HeadType or TailType won't work. But this will: const int Length = 1 + .Length!(typeof(_TL.tail)); } template Length(_TL : Empty) { const int Length = 0; } -- andy
Jun 29 2004
parent reply Alex B. <Alex_member pathlink.com> writes:
I believe this is a bug.  One workaround is to do:

Thanks! Excellent code. D's ability to directly return value of template instaniation is totally cool. Too bad it doesn't support specialization well enough. :(
Jun 29 2004
parent Andy Friesen <andy ikagames.com> writes:
Alex B. wrote:

I believe this is a bug.  One workaround is to do:

Thanks! Excellent code. D's ability to directly return value of template instaniation is totally cool. Too bad it doesn't support specialization well enough. :(

The problem is that, somehow, aliases aren't quite first class citizens of the namespace. Like I said, I believe this to be a bug, not a deficiency. :) I really would like to see some more clever deduction, though, a la: template LastTwo(_Head, _Dummy : TypeList!(_TailHead, _TailTail : Empty)) { alias _TailHead Last; alias _Head SecondLast; } -- andy
Jun 29 2004
prev sibling parent Sean Kelly <sean f4.ca> writes:
Attempting to compile this example in version 0.93 actually crashes the
compiler.  And it produces different errors as well.  So I would report this as
a bug in 0.93 and see how things work once it's been fixed.


Sean
Jun 29 2004