User Defined Attributes

Max Samukha maxsamukha at gmail.com
Thu Nov 8 01:08:22 PST 2012


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()
{
}









More information about the Digitalmars-d-announce mailing list