Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
October 24, 2013 proper way to find if attribute present? | ||||
---|---|---|---|---|
| ||||
enum Bar = "Bar"; @("Foo") @Bar int x; pragma(msg, __traits(getAttributes, x)); This prints: tuple("Foo", "Bar") How do you run code only if "Bar" is associated with a symbol like x? I was hoping something like this: pragma(msg, hasAnnotation!(x, Bar)); Where getAnnotation from (http://forum.dlang.org/thread/jxbdiwyyxwnmmybiqvyq@forum.dlang.org) was written as: 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; } I am missing how this can be used. Thanks Dan |
October 24, 2013 Re: proper way to find if attribute present? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | On Thursday, October 24, 2013 18:22:43 Daniel Davidson wrote: > enum Bar = "Bar"; > @("Foo") @Bar int x; > pragma(msg, __traits(getAttributes, x)); > > This prints: tuple("Foo", "Bar") > > How do you run code only if "Bar" is associated with a symbol > like x? > I was hoping something like this: > pragma(msg, hasAnnotation!(x, Bar)); You should probably use std.traits.functionAttributes: http://dlang.org/phobos/std_traits.html#.FunctionAttribute And in general, you should favor using std.traits over __traits. Ideally, no code outside of the standard library would need to use __traits. That's not currently the case unfortunately, but it is the case that std.traits has much of what you need for anything involving static introspection. - Jonathan M Davis |
October 24, 2013 Re: proper way to find if attribute present? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 24 October 2013 at 17:36:42 UTC, Jonathan M Davis wrote:
> You should probably use std.traits.functionAttributes:
it doesn't list UDAs though.
|
October 24, 2013 Re: proper way to find if attribute present? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | I use this small helper in vibe.d: ======================= template extractUda(UDA, alias Symbol) { import std.typetuple : TypeTuple; private alias TypeTuple!(__traits(getAttributes, Symbol)) udaTuple; private template extract(list...) { static if (!list.length) enum extract = null; else { static assert (!is(list[0] == UDA), "extractUda is designed to look up values, not types"); static if (is(typeof(list[0]) == UDA)) enum extract = list[0]; else enum extract = extract!(list[1..$]); } } enum extractUda = extract!udaTuple; } ======================= Used like this: ======================= @Bar("value") void foo(); enum uda = extractUda!(Bar, foo); static if (is(typeof(uda) != typeof(null))) static assert (uda == Bar("value")); ======================= It is far from perfection but can serve as a starting point for more complete implementation (though I have kept certain limitations intentionally) |
October 24, 2013 Re: proper way to find if attribute present? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | On Thursday, 24 October 2013 at 16:22:44 UTC, Daniel Davidson wrote:
> template hasAnnotation(alias f, Attr) {
This function looks for annotations as identified by type. Instead of using a plain string, you should make them some kind of struct:
struct MyAnnotation {
string value;
}
Then you attach it like this:
@MyAnnotation("some value") void foo() {}
Then you'll be able to get it with the other two functions in there:
static if(hasValueAnnotation!(foo, MyAnnotation)) {
pragma(msg, getAnnotation!(foo, MyAnnotation)); // prints MyAnnotation("some value")
// or you can fetch it into a variable:
MyAnnotation a = getAnnotation!(foo, MyAnnotation);
assert(a.value == "some value");
}
It is possible to use plain string in place of the MyAnnotation struct:
@("some value") void foo() {}
static if(hasValueAnnotation!(foo, string)) {
pragma(msg, getAnnotation!(foo, string)); // prints MyAnnotation("some value")
// or you can fetch it into a variable:
string a = getAnnotation!(foo, string);
assert(a == "some value");
}
But that isn't as reliable across modules because strings might be reused by anyone. A struct would always have a unique identifier - the struct name, which can be disambiguated by module.
|
Copyright © 1999-2021 by the D Language Foundation