digitalmars.D - Getting a tuple of all members of a struct or a class
- Philippe Sigaud (78/78) Jul 11 2010 Damn, sorry for the botched post. One tab too many.
Damn, sorry for the botched post. One tab too many. So, I'm trying to get a feel for __traits(allMembers, T). I'm using it to get a tuple consisting of the types and names of a type. Let say I have struct S { int i; double delegate(double) d; int foo(int j) { return i*j;} } I want Members!S to be: TypeTuple!(int, "i", double delegate(double), "d", int function(int), "foo") I'm almost there, but I have some troubles: - first, if foo is defined many times inside S, I get it only once. Is there any way to get overloaded function inside a struct? (for a class, I'll have a look at __traits(getOverloads, T)). - second, classes have a Monitor member that's wreaking havoc with my code. Any help on this would be welcome. Maybe I'll just jump over it. - third, DMD is a bit incoherent when it comes to tuples and strings thereof (hi, retard!). For example, all my types are wrapped in parenthesis like this: ((int), "i", (double delegate(double)), "d", ...) - also, methods are treated differently than member functions. In the above example, foo gives me 'int function(int j)' as a type and not 'int function(int)'. It's cumbersome. Annex: the code: /** 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 of 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