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...@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

Reply via email to