User defined attributes use

ilya-stromberg ilya-stromberg-2009 at yandex.ru
Thu Sep 19 23:59:36 PDT 2013


On Monday, 16 September 2013 at 07:36:13 UTC, simendsjo wrote:
> I don't have a full example without adding a lot of code, but 
> this partial
> example might give you the gist of it.
>
>
> // This is the type that validates
> struct matches(string mustMatch)
> {
>     alias re = ctRegex!(mustMatch);
>
>     static string[] validate(T)(const ref T t)
>     {
>         static if(!isSomeString!T)
>             static assert(0, "matches only works on strings, 
> not "~T.stringof);
>         return match(t, re).empty ? ["no match"] : null;
>     }
> }
>
> // and this is the code that runs all validators for a variable
> void validate(alias T)(ref Appender!(string[]) app)
> {
>     static if(isTupleWrapper!T)
>     {
>         validate!(T.Head)(app);
>         validate!(T.Tail)(app);
>     }
>     else
>     {
>         foreach(memberAttr; getValidaterAttrs!T)
>         {
>             foreach(attr; memberAttr.Tail)
>             {
>                 foreach(msg; attr.validate(T))
>                     if(msg.length)
>                         app.put(msg);
>             }
>         }
>     }
> }
>
> // .. And here is some of the plumbing
>
> string[] validate(Vars...)()
> {
>     auto app = appender!(string[])();
>     validate!Vars(app);
>     return app.data();
> }
>
>
> // The getMembersAndAttributesWhere are templates in my little 
> library that isn't released. Uses quite some custom __traits 
> stuff, but it's basically __traits(getAttributes
> template getValidaterAttrs(alias T)
> {
>     alias getValidaterAttrs = 
> TypeTuple!(getMembersAndAttributesWhere!(T, 
> isValidationAttr).Elements,
>                                          
> getMembersAndAttributesWhere!(TypeOf!T, 
> isValidationAttr).Elements);
> }
>
> // Well.. Incomplete
> template isValidationAttr(alias T)
> {
>     enum isValidationAttr = hasMember!(TypeOf!T, "validate");
> }

Can I explicitly specify when I can use attribute? Something like
this:

@attribute("field")
struct matches(string mustMatch)
{
}

string wrongAttribute
{
}

class Foo
{
     @matches("[0-9]+")
     string someNumber; //OK, it's a field
}

@matches("[0-9]+") //Error, it's a class, not a field
class Bar
{
}

@wrongAttribute //Error, this attribute doesn't exist
class C
{
}


More information about the Digitalmars-d-learn mailing list