Thread overview
Can I parametrize template mixin's identifiers?
Feb 19, 2011
Nick
Feb 19, 2011
Lutger Blijdestijn
Feb 21, 2011
Nick
February 19, 2011
I know I can parametrize template mixin types, but how about mixin identifiers? This is the code:

----------------------------------------------------------------

mixin template Box(T) {
  T val;
}

class Set(A, B) {
  mixin Box!A a;
  mixin Box!B b;
}

alias Set!(int, int) IntSet;

int main(string[] argv) {
  scope auto s = new IntSet();
  s.a.val = 3;
}

----------------------------------------------------------------

As you can see, the A and B types can be changed and with them the boxed values. But they need disambiguation, since they have identically named members. I know only to hard-code that disambiguation.

I need this because I intend to change (A, B) with a type list eventually and I need to make operations on the boxed types independent on the template mixin  identifiers (a, b).

This pattern comes from C++ code, where Box(T) would be classes, Set (A, B, ...) would recursively apply multiple inheritance on the type list. Then each Box members could be addressed by casting to the correct Box(T).

Any idea if this is possible in D?

Thanks!
February 19, 2011
Nick wrote:

> I know I can parametrize template mixin types, but how about mixin identifiers? This is the code:
> 
> ----------------------------------------------------------------
> 
> mixin template Box(T) {
>    T val;
> }
> 
> class Set(A, B) {
>    mixin Box!A a;
>    mixin Box!B b;
> }
> 
> alias Set!(int, int) IntSet;
> 
> int main(string[] argv) {
>    scope auto s = new IntSet();
>    s.a.val = 3;
> }
> 
> ----------------------------------------------------------------
> 
> As you can see, the A and B types can be changed and with them the boxed values. But they need disambiguation, since they have identically named members. I know only to hard-code that disambiguation.
> 
> I need this because I intend to change (A, B) with a type list
> eventually and I need to make operations on the boxed types independent
> on the template mixin  identifiers (a, b).
> 
> This pattern comes from C++ code, where Box(T) would be classes, Set (A,
> B, ...) would recursively apply multiple inheritance on the type list.
> Then each Box members could be addressed by casting to the correct Box(T).
> 
> Any idea if this is possible in D?
> 
> Thanks!

Possible yes, but probably not so pretty. There must be some places in phobos where something like this is done (better), perhaps in the code for tuples in std.typecons. Here is my unpolished attempt:

mixin template Box(T)
{
    T val;
}

mixin template MixinFields(P...)
{
    /* P[0] is the template to use as mixin
     * P[1] is the type to be use as parameter for P[0]
     * P[2] is the symbol name the mixin will be aliased to
     */
    mixin("mixin " ~ __traits(identifier, P[0]) ~ "!(" ~ P[1].stringof ~ ")
          " ~ P[2] ~ ";");
    static if(P.length > 3)
        mixin MixinFields!(P[0], P[3..$]);
}


class Set(T...)
{
    mixin MixinFields!(Box, T);
}

alias Set!(int, "a", int, "b") IntSet;

void main()
{
    scope auto s = new IntSet();
    s.a.val = 3;
}
February 21, 2011
On 2/19/2011 10:46 PM, Lutger Blijdestijn wrote:
> Nick wrote:
>
>> I know I can parametrize template mixin types, but how about mixin
>> identifiers? This is the code:
>>
>> ----------------------------------------------------------------
>>
>> mixin template Box(T) {
>>     T val;
>> }
>>
>> class Set(A, B) {
>>     mixin Box!A a;
>>     mixin Box!B b;
>> }
>>
>> alias Set!(int, int) IntSet;
>>
>> int main(string[] argv) {
>>     scope auto s = new IntSet();
>>     s.a.val = 3;
>> }
>>
>> ----------------------------------------------------------------
>>
>> As you can see, the A and B types can be changed and with them the boxed
>> values. But they need disambiguation, since they have identically named
>> members. I know only to hard-code that disambiguation.
>>
>> I need this because I intend to change (A, B) with a type list
>> eventually and I need to make operations on the boxed types independent
>> on the template mixin  identifiers (a, b).
>>
>> This pattern comes from C++ code, where Box(T) would be classes, Set (A,
>> B, ...) would recursively apply multiple inheritance on the type list.
>> Then each Box members could be addressed by casting to the correct Box(T).
>>
>> Any idea if this is possible in D?
>>
>> Thanks!
>
> Possible yes, but probably not so pretty. There must be some places in
> phobos where something like this is done (better), perhaps in the code for
> tuples in std.typecons. Here is my unpolished attempt:
>
> mixin template Box(T)
> {
>      T val;
> }
>
> mixin template MixinFields(P...)
> {
>      /* P[0] is the template to use as mixin
>       * P[1] is the type to be use as parameter for P[0]
>       * P[2] is the symbol name the mixin will be aliased to
>       */
>      mixin("mixin " ~ __traits(identifier, P[0]) ~ "!(" ~ P[1].stringof ~ ")
>            " ~ P[2] ~ ";");
>      static if(P.length>  3)
>          mixin MixinFields!(P[0], P[3..$]);
> }
>
>
> class Set(T...)
> {
>      mixin MixinFields!(Box, T);
> }
>
> alias Set!(int, "a", int, "b") IntSet;
>
> void main()
> {
>      scope auto s = new IntSet();
>      s.a.val = 3;
> }

Thanks!

I was staying away from string mixins as they seem (although powerful) rather difficult to grok. But if I must, I must...