mixin templates with name parameter

Ali Çehreli acehreli at yahoo.com
Thu Nov 29 20:04:09 PST 2012


On 11/29/2012 05:08 PM, js.mdnq wrote:
> mixin templates seems like they could benefit from an extra parameter
> that one can pass a name. The name, a string literal, sort of acts like
> a preprocessor token:
>
> mixin template InjectX!(T)
> {
> private T x;
> T get#name#( ) { return x; }
> void set#name#(T y)
> {
> // Checks
> x = y;
> }
> }
>
> Then something like "mixin InjectX!int Mylnt;" will create the following
> function
>
> getMylnt and setMylnt.
>
> The scope names are a nice solution and sometimes what one wants. But
> sometimes one would like to avoid an extra referencing step.
>
> In fact, it would be nice if one could inject code into the template
> code. One, could example, even supply an object or another mixin with
> the mixin to compose the code. If, say, I wanted slightly different set
> functions above I would have to write a template for each one, but if I
> code compose mixins then I could avoid that.
>
> In any case, it can get rather complicated and notation is the key
> issue(how to describe it all elegantly). I think the idea and the way D
> does it is pretty elegant though and probably good enough for most
> cases. I just imagine cases where a very complex mixin might need slight
> changes from one use to the next but unfortunately would require some
> inelegant methods to use it.
>
> Possibly one could compose mixins in a way that all common function
> overlap are serialized.
>
> "alias mixin InjectX!int with InjectY!int Mylntalias;"
> "mixin MyIntalias!int MyInt;"
>
> will produce a mixin s.t., the set functions of Y are serialized with
> those of X. (the new set function will first call the set of InjectY
> then that of InjectX)
>
> This way, we can "extend" a mixin relatively easy by simply "appending"
> code to it's functions.
>
>
> Just some food for thought.
>

There are also string mixins, which provide some help:

string getFunction(string name)()
{
     return "T get" ~ name ~ "( ) { return x; }";
}

string setFunction(string name)()
{
     return "void set" ~ name ~ "(T y)" ~ q{
         {
             // Checks
             x = y;
         }
     };
}

string varDeclaration(string name)()
{
     return "private T " ~ name ~ ";";
}

template InjectX(T, string name)
{
     mixin (varDeclaration!name);
     mixin (getFunction!name);
     mixin (setFunction!name);
}

class C
{
     mixin InjectX!(int, "x");
}

void main()
{
     auto c = new C;
     c.getx();
     c.setx(42);
}

There is a warning though: The current compiler is very slow when there 
are too many little string mixins. I heard that one large function that 
generates all three string above would be way faster than the three that 
I have used.

Ali


More information about the Digitalmars-d mailing list