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() {
}