On Aug 9, 11 05:05, Andrej Mitrovic wrote:
Done deal:

import std.traits;

string FieldInit(T, int len, string fun)()
{
     string result;
     auto fields = [__traits(allMembers, T)];

     result ~= "this(";

     foreach (y, x; (RepresentationTypeTuple!T)[0..len])
     {
         result ~= x.stringof ~ " " ~ fields[y] ~ ", ";
     }

     result = result[0.. $-2] ~ ") { ";

     foreach (x; 0 .. len)
     {
         result ~= "this." ~ fields[x] ~ " = " ~ fields[x] ~ "; ";
     }

     result ~= fun ~ "();";
     result ~= "}";

     return result;
}

struct Foo
{
     int a;
     int b;
     int c;
     int d;

     mixin( FieldInit!(typeof(this), 4, "_this") );

     int sum;
     int average;

     void _this()
     {
         sum = a + b + c + d;
         average = (a + b + c + d) / 4;
     }
}

void main()
{
     auto foo = Foo(1, 2, 3, 4);

     assert(foo.sum == 10);
     assert(foo.average == 2);
}

Mostly.. Of course it doesn't work too good if the fields are placed
below some functions.

Template-mixin is often shorter and less error-prone.


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

mixin template FieldInit(size_t count, alias fun)
{
    this(RepresentationTypeTuple!(typeof(this))[0..count] params)
    {
        foreach (y, x; __traits(allMembers, typeof(this))[0..count])
            __traits(getMember, this, x) = params[y];
        fun();
    }
}

struct Foo
{
    int a;
    int b;
    int c;
    int d;

    int sum;
    int average;

    void _this()
    {
        sum = a + b + c + d;
        average = (a + b + c + d) / 4;
    }

    mixin FieldInit!(4, _this);
}

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

Reply via email to