www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problem with a convoluted templated struct

reply Kiith-Sa <42 theanswer.com> writes:
Hello.

I am trying to implement a templated struct containing a
data member created by std.variant.Algebraic instantiated
with the struct's template parameters. 

The problem is, I want to template the struct with e.g. 
arrays (lists, etc.) of its own type. I don't know
any way to do this without ugly string mixin code.

I'm not sure if I can explain this clearly, so here's some code:



import std.variant;

struct Node(Types ...)
{
    Algebraic!(Types) value;
    
    //other members, etc...
}

unittest
{
    //this works
    Node!(string, int) node1;

    //this is what I want, but I can't do it, since
    //Node must be templated
    Node!(Node[], string, int) node1;
}


//Now, I can get around this with a string mixin:
//(just one argument in this example, but it
// could be variadic with more complex code)


struct Node2(string t)
{
    mixin("private alias " ~ t ~ " Type;");
    Algebraic!(Type) value;
}

unittest
{
    //works, but ugly
    Node2!("Node2[]") node;
}



Is there any way to do this without string mixins?
(in case this is proposed: I specifically need structs, not classes.
I know I could do this with templated derived classes storing
an array/list/whatever with parent class type.


Thanks for any help.
Jun 28 2011
parent Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> writes:
On Wed, 29 Jun 2011 04:06:02 +0200, Kiith-Sa wrote:

 Hello.
 
 I am trying to implement a templated struct containing a data member
 created by std.variant.Algebraic instantiated with the struct's template
 parameters.
 
 The problem is, I want to template the struct with e.g. arrays (lists,
 etc.) of its own type. I don't know any way to do this without ugly
 string mixin code.
 
 I'm not sure if I can explain this clearly, so here's some code:
 
 
 
 import std.variant;
 
 struct Node(Types ...)
 {
     Algebraic!(Types) value;
     
     //other members, etc...
 }
 
 unittest
 {
     //this works
     Node!(string, int) node1;
 
     //this is what I want, but I can't do it, since //Node must be
     templated
     Node!(Node[], string, int) node1;
 }
 
 
 //Now, I can get around this with a string mixin: //(just one argument
 in this example, but it // could be variadic with more complex code)
 
 
 struct Node2(string t)
 {
     mixin("private alias " ~ t ~ " Type;"); Algebraic!(Type) value;
 }
 
 unittest
 {
     //works, but ugly
     Node2!("Node2[]") node;

That works because the name Node2 represents the complete type of the templated struct in the struct definition.
 }
 
 
 
 Is there any way to do this without string mixins? (in case this is
 proposed: I specifically need structs, not classes. I know I could do
 this with templated derived classes storing an array/list/whatever with
 parent class type.
 
 
 Thanks for any help.

Providing the container type as an alias template parameter seems to work: import std.container; import std.variant; struct MyAlgebraic(Types ...) {} struct MyList(T) {} struct Node(alias ContainerType, Types ...) { ContainerType!Node container; MyAlgebraic!(Types) value; } unittest { Node!(Array, string, int) node1; Node!(MyList, double, char) node2; } void main() {} But I hit other compilation problems in Algebraic, which I believe to be const-correctness issues. Also consider looking at Phobos ranges. Instead of templatizing on the container type, templatizing on the range type may be better. Ali
Jun 28 2011