Here's how I do it:

enum Dump; // just a type, no value here

template Dumper(T) {
   void dump() {
     foreach (mem; __traits(allMembers, T)) {
// loop over the attrs instead of try to store them in a var foreach(attr; __traits(getAttributes, __traits(getMember, T, mem)))
           // identify them by type rather than value
           static if ( is(attr == Dump)) {
                  writeln(mem);
           }
        }
    }
}




Or some helper functions might be good. Here's the ones I did:

template hasAnnotation(alias f, Attr) {
        bool helper() {
                foreach(attr; __traits(getAttributes, f))
                        static if(is(attr == Attr) || is(typeof(attr) == Attr))
                                return true;
                return false;

        }
        enum bool hasAnnotation = helper;
}

template hasValueAnnotation(alias f, Attr) {
        bool helper() {
                foreach(attr; __traits(getAttributes, f))
                        static if(is(typeof(attr) == Attr))
                                return true;
                return false;

        }
        enum bool hasValueAnnotation = helper;
}



template getAnnotation(alias f, Attr) if(hasValueAnnotation!(f, Attr)) {
        auto helper() {
                foreach(attr; __traits(getAttributes, f))
                        static if(is(typeof(attr) == Attr))
                                return attr;
                assert(0);
        }

        enum getAnnotation = helper;
}





hasAnnotation!(something, Dump) tells you if it is just there

hasValueAnnotation tells you if the annoation has a value (enum Dump; won't, but struct Dump { int option; } would).

getAnnotation fetches the value.



The "something" argument there is a symbol, e.g. __traits(getMember, T, mem). The second argument is the type you're interested in.

Reply via email to