Thread overview
Get TypeNames of Variadic Templates
Feb 01, 2013
Christian Köstlin
Feb 01, 2013
Philippe Sigaud
Feb 01, 2013
Christian Köstlin
Feb 02, 2013
Philippe Sigaud
Feb 02, 2013
Christian Köstlin
February 01, 2013
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
February 01, 2013
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);
}
February 01, 2013
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);
> }

February 02, 2013
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)

:)
February 02, 2013
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)
>
> :)