www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - anyMemberSatisfies

Hi all,

First time I'm posting here, so if this isn't the right place to 
ask such questions, feel free to redirect me.

I wish to know (in compile time, of course) if any member of a 
struct has a certain UDA. If any member has it, it implies 
"propagates" to the struct as a whole. I wrote this code, which 
works:

template hasAttributeByName(ATTR, STRUCT) {
     template byName(string NAME) {
         enum byName = staticIndexOf!(ATTR, 
__traits(getAttributes, __traits(getMember, STRUCT, NAME))) != -1;
     }
}
template anyMemberHasAttribute(ATTR, STRUCT) {
     alias pred = hasAttributeByName!(ATTR, STRUCT);
     enum anyMemberHasAttribute = anySatisfy!(pred.byName, 
__traits(allMembers, STRUCT));
}

enum MyUDA;
struct MyStruct {
     int a;
      MyUDA int b;
}
pragma(msg, anyMemberHasAttribute!(MyUDA, MyStruct));


This works and prints `true`. I then tried to make this code a 
little more generic, but for some reason I can't get it working:


template anyMemberSatisfies(alias PRED, STRUCT) {
     template byName(string NAME) {
         enum byName = PRED!(__traits(getMember, STRUCT, NAME));
     }

     enum anyMemberSatisfies = anySatisfy!(byName, 
__traits(allMembers, STRUCT));
}
template hasAttribute(alias ATTR) {
     template pred(alias VAR) {
         enum pred = staticIndexOf!(ATTR, __traits(getAttributes, 
VAR)) != -1;
     }
}

alias hasMyUDA = hasAttribute!MyUDA;

// fails to compile
pragma(msg, anyMemberSatisfies!(hasMyUDA.pred, MyStruct));


The error I'm getting is

(219): Error: template instance PRED!(a) cannot use local 'a' as 
parameter to non-global template pred(alias VAR)
typetuple.d(632): Error: template instance 
serialization.anyMemberSatisfies!(pred, MyStruct).F!"a" error 
instantiating
(222):        instantiated from here: anySatisfy!(byName, "a")
(238):        instantiated from here: anyMemberSatisfies!(pred, 
MyStruct)
(222): Error: template instance std.typetuple.anySatisfy!(byName, 
"a") error instantiating
(238):        instantiated from here: anyMemberSatisfies!(pred, 
MyStruct)
(238): Error: template instance 
serialization.anyMemberSatisfies!(pred, MyStruct) error 
instantiating
(238):        while evaluating pragma(msg, 
anyMemberSatisfies!(pred, MyStruct))


I get such an error for each member of the struct.
By the way, I tried using ``mixin(STRUCT.stringof ~ ".init." ~ 
NAME)`` instead of ``__traits(getMember, STRUCT, NAME)`` but to 
no avail.

What am I doing wrong?

Thanks in advance,
-Tomer
Mar 12 2014