Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
October 05, 2013 UDA usage | ||||
---|---|---|---|---|
| ||||
Attachments:
| So, I was away from active D development for a while, and I'm having trouble finding info about how to use UDAs. I can see the basics, like how to apply a UDA to a symbol, but now how to do specific things, like: * Check to see if a specific attribute exists * Check to see if an attribute of a specific type exists, something like: @Foo('a') int x; enum hasAnyFoo = __traits(hasAttributeOfType, Foo, x); * Create a function that can only be called if the first argument has a UDA of a specific type Are any of these doable? Thank you, -Matt Soucy |
October 05, 2013 Re: UDA usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matt Soucy | On Saturday, 5 October 2013 at 02:51:21 UTC, Matt Soucy wrote: > * Check to see if a specific attribute exists > * Check to see if an attribute of a specific type exists, something like: The helper functions from my web.d might help: // checks to see if it has one of a type // static if(hasAnnotation!(func, Foo)) { has @Foo } // use if Foo is a simple enum. 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; } /// checks to see if it has an annotation with a value e.g. @Something(10) 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; } /// gets the thing you checked for above. so getAnnotation!(Func, Something) returns Something(10) (if Something is as struct) 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; } > * Create a function that can only be called if the first argument has a > UDA of a specific type Since the UDA is only available at compile time, you can't do that without some kind of template. |
October 05, 2013 Re: UDA usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe Attachments:
| On 10/04/2013 11:04 PM, Adam D. Ruppe wrote: > On Saturday, 5 October 2013 at 02:51:21 UTC, Matt Soucy wrote: >> * Check to see if a specific attribute exists >> * Check to see if an attribute of a specific type exists, something like: > > The helper functions from my web.d might help: > > // checks to see if it has one of a type > // static if(hasAnnotation!(func, Foo)) { has @Foo } > // use if Foo is a simple enum. > 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; > } > > /// checks to see if it has an annotation with a value e.g. @Something(10) > 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; > } > > /// gets the thing you checked for above. so getAnnotation!(Func, > Something) returns Something(10) (if Something is as struct) > 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; > } > > Nice, thank you. These are really helpful! >> * Create a function that can only be called if the first argument has a UDA of a specific type > > Since the UDA is only available at compile time, you can't do that without some kind of template. Using the above tools I got what I wanted, so I'm satisfied for now. Thank you, though! -Matt Soucy |
October 08, 2013 Re: UDA usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matt Soucy Attachments:
| On 10/04/2013 11:50 PM, Matt Soucy wrote: > On 10/04/2013 11:04 PM, Adam D. Ruppe wrote: >> On Saturday, 5 October 2013 at 02:51:21 UTC, Matt Soucy wrote: >>> * Check to see if a specific attribute exists >>> * Check to see if an attribute of a specific type exists, something like: >> >> The helper functions from my web.d might help: >> >> // checks to see if it has one of a type >> // static if(hasAnnotation!(func, Foo)) { has @Foo } >> // use if Foo is a simple enum. >> 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; >> } >> >> /// checks to see if it has an annotation with a value e.g. @Something(10) >> 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; >> } >> >> /// gets the thing you checked for above. so getAnnotation!(Func, >> Something) returns Something(10) (if Something is as struct) >> 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; >> } >> >> > > Nice, thank you. These are really helpful! > >>> * Create a function that can only be called if the first argument has a UDA of a specific type >> >> Since the UDA is only available at compile time, you can't do that without some kind of template. > > Using the above tools I got what I wanted, so I'm satisfied for now. > Thank you, though! > -Matt Soucy > > Update on this - unfortunately, I discovered that this doesn't seem to work for any members, due to requiring a specific "this". I can't quite figure out why though... -- Matt Soucy http://msoucy.me/ |
October 08, 2013 Re: UDA usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matt Soucy | On Tuesday, 8 October 2013 at 20:59:04 UTC, Matt Soucy wrote:
> Update on this - unfortunately, I discovered that this doesn't seem to work for any members, due to requiring a specific "this". I can't quite figure out why though...
Try adding static to the helper functions in the templates. I just did that and this worked:
struct Whoa {
int a;
}
class Foo {
@lol void argh() {}
@Whoa(12) int keanu;
}
void main() {
pragma(msg, hasAnnotation!(Foo.argh, lol));
pragma(msg, getAnnotation!(Foo.keanu, Whoa));
}
~$ dmd test34
true
Whoa(12)
The change to get it to compile was just this:
template hasValueAnnotation(alias f, Attr) {
static bool helper() { // added static
and so on for all three of the helper functions, just make them all static.
|
Copyright © 1999-2021 by the D Language Foundation