populateFromUdas

This populates a struct from a list of values (or other expressions, but it only looks at the values) based on types of the members, with one exception: bool members.. maybe.

It is intended for collecting a record of relevant UDAs off a symbol in a single call like this:

struct Name {
	string n;
}

struct Validator {
	string regex;
}

struct FormInfo {
	Name name;
	Validator validator;
}

@Name("foo") @Validator(".*")
void foo() {}

auto info = populateFromUdas!(FormInfo, __traits(getAttributes, foo));
assert(info.name == Name("foo"));
assert(info.validator == Validator(".*"));

Note that instead of UDAs, you can also pass a variadic argument list and get the same result, but the function is populateFromArgs and you pass them as the runtime list to bypass "args cannot be evaluated at compile time" errors:

void foo(T...)(T t) {
	auto info = populateFromArgs!(FormInfo)(t);
	// assuming the call below
	assert(info.name == Name("foo"));
	assert(info.validator == Validator(".*"));
}

foo(Name("foo"), Validator(".*"));

The benefit of this over constructing the struct directly is that the arguments can be reordered or missing. Its value is diminished with named arguments in the language.

template populateFromUdas (
Struct
UDAs...
) {
enum Struct populateFromUdas;
}

Examples

enum a;
enum b;
struct Name { string name; }
struct Info {
	Name n;
	PresenceOf!a athere;
	PresenceOf!b bthere;
	int c;
}

void test() @a @Name("test") {}

auto info = populateFromUdas!(Info, __traits(getAttributes, test));
assert(info.n == Name("test")); // but present ones are in there
assert(info.athere == true); // non-values can be tested with PresenceOf!it, which works like a bool
assert(info.bthere == false);
assert(info.c == 0); // absent thing will keep the default value

Meta