www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Get TypeNames of Variadic Templates

reply =?ISO-8859-1?Q?Christian_K=F6stlin?= <christian.koestlin gmail.com> writes:
Hi,

i am trying to generate members for all types in a variadic class 
template like this:

import std.stdio;

class Component(Children...) {
   /// results eg. in public Component1 fComponent1;
   static string createMembers() {
     string res = "";
     foreach (child; Children) {
       res ~= "public " ~ child.stringof ~ " f" ~ child.stringof ~ ";\n";
     }
     return res;
   }
   mixin(createMembers());
}

class Component1 : Component!() {
}

class Component2 : Component!(Component1) {
}
int main(string[] args) {
   writeln([ __traits(allMembers, Component2) ]);
   return 0;
}

as you can see, Component2 now has a member called fComponent1.
My question is, is it possible to generate this with some mapping 
algorithm, instead of writing this loop by hand?

regards

christian koestlin
Feb 01 2013
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
Hi Christian,

 My question is, is it possible to generate this with some mapping algorithm,
 instead of writing this loop by hand?
You can create a tuple: class Component(Children...) { Children components; // <- Here this() {} static if (Children.length > 0) this(Children args) { components = args; } } void main() { auto c = new Component!(int, double, Component!(string)); writeln(c.components); c.components[0] = 1; c.components[1] = 3.14159; c.components[2] = new Component!(string)("abc"); writeln(c.components); writeln(c.components[2].components); }
Feb 01 2013
parent reply =?UTF-8?B?Q2hyaXN0aWFuIEvDtnN0bGlu?= <christian.koestlin gmail.com> writes:
Hi Philippe,

wonderful solution. I also added
T get(T)() {
   return components[staticIndexOf!(T, Children)];
}
to the class to get the Children out by type (works as long as there is 
only one child of each type in the tuple).

thanks a lot!!!

christian


On 2/1/13 16:04 , Philippe Sigaud wrote:
 Hi Christian,

 My question is, is it possible to generate this with some mapping algorithm,
 instead of writing this loop by hand?
You can create a tuple: class Component(Children...) { Children components; //<- Here this() {} static if (Children.length> 0) this(Children args) { components = args; } } void main() { auto c = new Component!(int, double, Component!(string)); writeln(c.components); c.components[0] = 1; c.components[1] = 3.14159; c.components[2] = new Component!(string)("abc"); writeln(c.components); writeln(c.components[2].components); }
Feb 01 2013
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Fri, Feb 1, 2013 at 11:04 PM, Christian K=C3=B6stlin
<christian.koestlin gmail.com> wrote:
 Hi Philippe,

 wonderful solution. I also added
 T get(T)() {
   return components[staticIndexOf!(T, Children)];
 }
 to the class to get the Children out by type (works as long as there is o=
nly
 one child of each type in the tuple).
Indeed, that's easier for the user this way. In that case, you might want to either return a tuple of one or more type (when there is more than one of a given type) or put a restriction on Components so it's only a set of types. Maybe with: ... if(NoDuplicates!(Children).length =3D=3D Children.length) See http://dlang.org/phobos/std_typetuple.html#.NoDuplicates Then, when you're feeling masochistic, the next step is to allow assignments from other Components with a permutation of children, because Component!(int,double) is not much different from Components!(double, int) :)
Feb 02 2013
parent =?UTF-8?B?Q2hyaXN0aWFuIEvDtnN0bGlu?= <christian.koestlin gmail.com> writes:
Yes! very good idea!
I also added something like static assert(staticIndexOf!(T, Children) != 
-1); to get a compile time error when someone wants to get something 
which is not there.

thanks

christian


On 2/2/13 14:13 , Philippe Sigaud wrote:
 On Fri, Feb 1, 2013 at 11:04 PM, Christian Köstlin
 <christian.koestlin gmail.com>  wrote:
 Hi Philippe,

 wonderful solution. I also added
 T get(T)() {
    return components[staticIndexOf!(T, Children)];
 }
 to the class to get the Children out by type (works as long as there is only
 one child of each type in the tuple).
Indeed, that's easier for the user this way. In that case, you might want to either return a tuple of one or more type (when there is more than one of a given type) or put a restriction on Components so it's only a set of types. Maybe with: ... if(NoDuplicates!(Children).length == Children.length) See http://dlang.org/phobos/std_typetuple.html#.NoDuplicates Then, when you're feeling masochistic, the next step is to allow assignments from other Components with a permutation of children, because Component!(int,double) is not much different from Components!(double, int) :)
Feb 02 2013