digitalmars.D.learn - proper way to find if attribute present?
- Daniel Davidson (23/23) Oct 24 2013 enum Bar = "Bar";
- Jonathan M Davis (8/18) Oct 24 2013 You should probably use std.traits.functionAttributes:
- Adam D. Ruppe (3/4) Oct 24 2013 it doesn't list UDAs though.
- Dicebot (33/33) Oct 24 2013 I use this small helper in vibe.d:
- Adam D. Ruppe (33/34) Oct 24 2013 This function looks for annotations as identified by type.
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
Oct 24 2013
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:
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
Oct 24 2013
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.
Oct 24 2013
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)
Oct 24 2013
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.
Oct 24 2013









"Adam D. Ruppe" <destructionator gmail.com> 