www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Finding UDAs with Templates

reply Paul O'Neil <redballoon36 gmail.com> writes:
I'm trying to write some code that finds all the members of a class that 
have a particular user defined attribute.  My current attempt is at 
https://github.com/todayman/d_template_experiments/tree/8fccd27d7d5557ec6e2f0614374cf5f79fe80b4c

I would like to have a static method that returns an array of strings of 
the names of the members with the " Sync" attribute.  I use the 
allMembers trait to get the list of strings, then try to filter out the 
ones I want.  There are problems when I convert from the string to a 
symbol / something to get the attributes.  Right now, I'm getting errors 
like:


 metadata.d(158): Error: template instance doesFieldSync_imp!(_hash) cannot use
local '_hash' as parameter to non-global template doesFieldSync_imp(alias
field)()
which I understand is related to http://d.puremagic.com/issues/show_bug.cgi?id=5710 and
 metadata.d(160): Error: first argument is not a symbol
from _traits(getAttributes, mxin("FileData."~key)) What's a good way to work around these? I'm also open to entirely different ways of doing this. Thanks, Paul
Jul 22 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-07-23 06:27, Paul O'Neil wrote:
 I'm trying to write some code that finds all the members of a class that
 have a particular user defined attribute.  My current attempt is at
 https://github.com/todayman/d_template_experiments/tree/8fccd27d7d5557ec6e2f0614374cf5f79fe80b4c


 I would like to have a static method that returns an array of strings of
 the names of the members with the " Sync" attribute.  I use the
 allMembers trait to get the list of strings, then try to filter out the
 ones I want.  There are problems when I convert from the string to a
 symbol / something to get the attributes.  Right now, I'm getting errors
 like:
I tried your code and this should be enough: import std.typetuple; static bool doesFieldSync (string field) () { alias attrs = TypeTuple!(__traits(getAttributes, mixin("FileData." ~ field))); return staticIndexOf!(Sync, attrs) != -1; } The important things here are that __traits(getAttributes) returns a tuple. You cannot assign a tuple to a variable. But you can alias it. When you alias it you do need to use this wrapper TypeTuple, I don't remember why but that's how it works. // This is the method I'm trying to write static string[] syncableFields() { auto result = new string[0]; foreach( key ; __traits(derivedMembers, FileData) ) { if( doesFieldSync!key() ) { result ~= key; } } return result; } Here I used derivedMembers instead of allMembers, this is want you want, most times. But I see that there are some problems with some members. These members are mixed in "mixin Signal". So if you try to filter out these members. I would just hard code them. -- /Jacob Carlborg
Jul 22 2013
parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 07/23/13 08:38, Jacob Carlborg wrote:
 static bool doesFieldSync (string field) ()
 {
     alias attrs = TypeTuple!(__traits(getAttributes, mixin("FileData." ~
field)));
     return staticIndexOf!(Sync, attrs) != -1;
 }
 
 The important things here are that __traits(getAttributes) returns a tuple.
You cannot assign a tuple to a variable. 
We can. :) enum attrs = __traits... // `auto` would work too. Just be careful and remember the `typeof(attrs)` part if/when using staticIndexOf with types - it might otherwise return bogus results (instead of failing). staticIndexOf!(Sync, typeof(attrs)) artur
Jul 23 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-07-23 12:59, Artur Skawina wrote:

 We can. :)

     enum attrs = __traits... // `auto` would work too.
I can't remember that working for me, but perhaps it does.
 Just be careful and remember the `typeof(attrs)` part if/when
 using staticIndexOf with types - it might otherwise return bogus
 results (instead of failing).

     staticIndexOf!(Sync, typeof(attrs))
Yeah, I think I encountered something like that. -- /Jacob Carlborg
Jul 23 2013
prev sibling parent Paul O'Neil <redballoon36 gmail.com> writes:
I basically ended up doing what Jacob suggested.

To deal with the extra members from "mixin Signal" by using the compiles 
trait to avoid the normal case for them.

Thanks for the help.
Paul
Jul 23 2013