UDA syntax
Ali Çehreli
acehreli at yahoo.com
Wed Jan 16 20:38:14 PST 2013
On 01/16/2013 05:59 PM, Joseph Cassman wrote:
> I was wondering what the syntax is for user defined attributes (i.e. bug
> 9222) implemented in release 2.061. I was still unclear after reading
> the thread forum.dlang.org/thread/k7afq6$2832$1 at digitalmars.com.
>
> Thanks for the help
>
> Joseph
The following is the code that I had used for experimenting with UDAs:
import std.stdio;
/* Here we define a type which we will later use to add attributes
* to. Although this type can have member variables as well, its name
will be
* sufficient in this case.
*/
struct SafeToDoFooWith
{}
/* This type has that attribute. This attribute can be obtained at compile
* time by the __traits(getAttributes) syntax.
*/
@SafeToDoFooWith
struct Struct
{}
/* This type does not have that attribute.
*/
struct AnotherStruct
{}
/* This template is not directly related. (I expect it to be in Phobos;
maybe
* it's already there. (?))
*/
template hasAttribute(T, AttributeInQuestion)
{
bool does_have()
{
/* UDAs can be obtained by __traits(getAttributes). This loop is a
* linear search.
*/
foreach (t; __traits(getAttributes, T)) {
if (typeid(t) is typeid(AttributeInQuestion)) {
return true;
}
}
return false;
}
enum hasAttribute = does_have();
}
/* This is a function that demonstrates how UDAs can affect code. */
void foo(T)(T parameter)
{
/* UDA are a fully compile-time feature. */
static if (hasAttribute!(T, SafeToDoFooWith)) {
writefln("'%s' can safely be copied. Copying...", T.stringof);
T theCopy = parameter;
/* ... the rest of the algorithm ... */
} else {
writefln("It is not safe to copy '%s'. Must use a different
algorithm.",
T.stringof);
/* ... another algorithm ... */
}
}
void main()
{
auto y = Struct();
foo(y);
auto by = AnotherStruct();
foo(by);
}
The following program demonstrates how to have multiple attributes as
well as how to test for the presence of a particular attribute value.
import std.stdio;
/* Whether one of the attributes matches the specified type and value. */
bool hasAttributeValue(T, D)(D value)
{
foreach (t; __traits(getAttributes, T)) {
static if (is (typeof(t) == D)) {
if (t == value) {
return true;
}
}
}
return false;
}
/* The attributes of this type are two fundamental values. */
@(42, "hello")
struct Struct
{}
void foo(T)(T obj)
{
static if (hasAttributeValue!T(42) &&
hasAttributeValue!T("hello")) {
writeln("Has both attribute values");
} else {
writeln("Nope...");
}
}
void main()
{
Struct a = Struct();
foo(a);
}
Ali
More information about the Digitalmars-d-learn
mailing list