www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting a tuple of all members

I'm trying to get a feel for __traits(allMembers, T).
I'm using it to also extract the members types and return a tuple like this:

given:

struct Test
{
    int i;
    double delegate(double) d;


/**
Double-decker template to get the type of T.member. It's a 2 stage template to
be used by staticMap
*/
template GetMember(T)
{
    template GetMember(string member)
    {
        mixin(getMember!T(member));
    }
}

/**
Helper CT string generator function.
*/
string getMember(T)(string member)
{
    return
       "static if (is( typeof(&(T." ~ member ~ ") ) ) )
            alias typeof(&T." ~ member ~ ") GetMember;
        else
            alias typeof(T." ~ member ~ ") GetMember;";
}

/**
Given a type T, returns a typetuple all members of a class or a struct,
alternating
with their names: TypeTuple!(int, "a", double function(string), "fun").
*/
template Members(T) if (is (T == class) || is (T == struct))
{
    alias Interleave!(staticMap!(GetMember!T, __traits(allMembers, T)),
__traits(allMembers, T)) Members;
}

/**
Helper template. Given T0, T1, T2, ..., Tn, Tn+1, ... T2n, will returns
the interleaving of the first part with the second part: T0, Tn+1, T1, Tn+2,
... Tn, T2n
It's fragile: no test, etc. A better way to do this would be as a two-steps
template: Interleave!(T...).With!(U...)
*/
template Interleave(T...)
{
    static if (T.length > 1)
        alias TypeTuple!(T[0], T[$/2], Interleave!(T[1..$/2], T[$/2+1 .. $]))
Interleave;
    else
        alias T Interleave;
}

void main() {

    alias object.AssociativeArray!(int,double) T;
//    alias Test T;

    alias Members!T M;
    writeln(M.stringof);
Jul 11 2010