On Thursday, 8 November 2012 at 07:35:30 UTC, Jacob Carlborg wrote:
On 2012-11-07 23:20, Walter Bright wrote:

module bar;

@attribute struct foo
{
    string name;
}

@foo int a;

alias Tuple!(__traits(getAttributes, foo)) TP;

enum bool yes = hasAttribute!(bar.foo);

static if (yes)
    enum foo attr = getAttribute!(bar.foo);

The last two could actually be library functions.

Could you explain why it is impossible without complicating the current state of things? I gave it a quick try and it seems to work reasonably well (a proper implementation will be more involved due to compiler bugs and language issues irrelevant to this discussion):

// library that defines attribute accessors
module library;
import std.typetuple;

template TypeOf(alias symbol)
{
    alias typeof(symbol) TypeOf;
}

template indexOfAttribute(alias symbol, alias attrType)
{
alias staticMap!(TypeOf, __traits(getAttributes, symbol)) attrTypes;
    enum indexOfAttribute = staticIndexOf!(attrTypes, attrType);
}

template hasAttribute(alias symbol, alias attrType)
{
    enum hasAttribute = indexOfAttribute!(symbol, attrType) != -1;
}

template getAttribute(alias symbol, alias attrType)
{
    alias TypeTuple!(__traits(getAttributes, symbol)) attrs;
enum getAttribute = attrs[indexOfAttribute!(symbol, attrType)];
}

// module that defines a foo attribute
module a;

struct foo
{
    string name;
}

[foo("a's foo")] int a;

// an unrelated module that defines its own foo
module b;

import library;
import a;

struct foo
{
    string name;
}

[foo("b's foo")] int b;

static if (hasAttribute!(b, foo))
{
    alias getAttribute!(b, foo) t;
    static assert(getAttribute!(b, foo).name == "b's foo");
}

static if (hasAttribute!(a.a, a.foo))
    static assert(getAttribute!(a.a, a.foo).name == "a's foo");

void main()
{
}







Reply via email to