How to create mixin template and pass name of a variable?

Bosak bosak at gmail.com
Fri Aug 2 05:02:39 PDT 2013


On Friday, 2 August 2013 at 11:48:32 UTC, Andrej Mitrovic wrote:
> On Friday, 2 August 2013 at 11:37:27 UTC, Bosak wrote:
>> I want to create a mixin template such that:
>>
>> mixin template ArgNull(alias arg, string name)
>> {
>>    if(arg is null)
>>        throw new Exception(name~" cannot be null.");
>> }
>>
>> But is there a way to do that with only one template argument. 
>> And then use it like:
>>
>> string text = null;
>> mixin ArgNull!(text);
>>
>> And the above mixin to make:
>>
>> if(text is null)
>>    throw new Exception("text cannot be null.");
>
> Note that template mixins cannot inject arbitrary code, they 
> can only inject declarations. You can use '__traits(identifier, 
> symbol)' on an alias parameter to retrieve the symbol name, for 
> example:
>
> -----
> mixin template ArgNull(alias arg)
> {
>     void test()
>     {
>         if (arg is null)
>             throw new Exception(__traits(identifier, arg) ~ " 
> cannot be null.");
>     }
> }
>
> string text = null;
> mixin ArgNull!text;
>
> void main()
> {
>     test();
> }
> -----

I ended up with the following code:

string ArgNull(string arg)() {
     return "if("~arg~" is null)throw new Exception(\""~arg~" 
cannot be null.\");";
}

unittest {
     import std.exception;

     void foo(Object obj, string str)
     {
         mixin(ArgNull!"obj");
         mixin(ArgNull!"str");
     }

     assertThrown(foo(null, ""));
     assertThrown(foo(new Object, null));
     assertNotThrown(foo(new Object, ""));
}

It does what I wanted it to. Is there a better way to do it? Or 
do you have any suggestions on my code? I am kind of new to D and 
all this template and mixin stuff.


More information about the Digitalmars-d-learn mailing list