March 12, 2014 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
 | ||||
Copyright © 1999-2021 by the D Language Foundation
 
Permalink
Reply