MemberDefaults trait

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Oct 10 16:50:29 PDT 2016


Could you please review the following template to see whether it makes 
sense. It produces an AliasSeq type consisting of the default values of 
the members of a struct. It should and does support members that are 
initialized with '= void'. I could not achieve this with std.traits or 
__traits.

However, I'm not that happy with the use of __traits(compiles) below. 
Can this be improved?

Thank you,
Ali


import std.meta;

/** Get as an expression tuple the default values of members of a struct. */
template MemberDefaults(T) {
     static if (!is(T == struct)) {
         static assert(T.stringof ~ " is not a struct type");
     }

     import std.traits : FieldNameTuple;
     enum t = T.init;
     alias fields = FieldNameTuple!T;

     template get(size_t i) {
         static if (__traits(compiles, { enum _ = t.tupleof[i]; })) {
             enum get = t.tupleof[i];
         }
         else {
             alias get = void;
         }
     }

     template Impl(size_t i = 0) {
         import std.meta : AliasSeq;
         static if (i == fields.length) {
             alias Impl = AliasSeq!();
         } else {
             alias Impl = AliasSeq!(get!i, Impl!(i+1));
         }
     }

     alias MemberDefaults = Impl!();
}

unittest {
     struct S {
         int i = 42;
         string s = "hello";
         char c = 'c';
     }

     static assert(MemberDefaults!S == AliasSeq!(42, "hello", 'c'));
}

unittest {
     struct S {
         int i = 42;
         int j = void;
     }

     static assert(MemberDefaults!S[0] == 42);
     static assert(is(MemberDefaults!S[1] == void));
}

void main() {
}


More information about the Digitalmars-d-learn mailing list