On 03/05/2014 03:10 PM, Frustrated wrote:

>>     assert(s.Do(1, 2.5) == 3.5);

> And this is exactly what I don't what!

Sorry, I've completely misunderstood. :)

> Do, in my case, is a ctfe used
> only at compile time to make it easy to generate code. It's not needed
> at runtime and does not belong anywhere.

So, you want to mixin what D() generates. The following example mixes in a static member function and two variables to S:

// Makes a make() function that returns a T
string makeMakeFunc(T)()
{
    import std.string;

    return format("static %s make() { %s result; return result; }",
                  T.stringof, T.stringof);
}

unittest
{
    assert(makeMakeFunc!int() ==
           "static int make() { int result; return result; }",
           makeMakeFunc!int());
}

// Declares a make() function that returns T[0] and two variables of types
// T[1], T[2], etc.
string DoImpl(T...)()
{
    import std.conv;

    string result;
    size_t i = 0;

    foreach (Type; T[1 .. $]) {
        result ~= Type.stringof ~ " var" ~ i.to!string ~ ";\n";
        ++i;
    }

    result ~= makeMakeFunc!(T[0])();

    return result;
}

unittest
{
    assert(DoImpl!(int, double, long) ==
"double var0;
long var1;
static int make() { int result; return result; }");
}

// Declares a make() function that returns typeof(this) and two variables of
// types T[0], T[1], etc.
template Do(T...)
{
    mixin(DoImpl!(typeof(this), T)());
}

struct S
{
    mixin Do!(int, double);
}

void main()
{
    // S has a static member function that makes an S:
    auto s = S.make();
    static assert(is (typeof(s) == S));

    // S has gained two member variables:
    static assert(is (typeof(s.var0) == int));
    static assert(is (typeof(s.var1) == double));
}

Ali

Reply via email to