How to create mixin template and pass name of a variable?
Nicolas Sicard
dransic at gmail.com
Fri Aug 2 06:47:05 PDT 2013
On Friday, 2 August 2013 at 12:10:00 UTC, Bosak wrote:
> On Friday, 2 August 2013 at 11:52:32 UTC, monarch_dodra 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.");
>>
>> A mixin template can't inject arbitrary code (AFAIK), but only
>> members/functions/structs etc.
>>
>> A simple string mixin would solve what you need better anyways:
>>
>> import std.stdio, std.typetuple, std.string;
>>
>> //----
>> template ArgNull(alias name)
>> {
>> enum ArgNull = format(q{
>> if(%1$s is null)
>> throw new Exception("%1$s cannot be null.");
>> }, name.stringof);
>> }
>>
>> void main()
>> {
>> string s1 = "hello";
>> string s2;
>>
>> mixin(ArgNull!s1);
>> mixin(ArgNull!s2);
>> }
>> //----
>>
>> FYI, "q{}" is called a "token string", and is formidably
>> useful to write a string that contains code. Also, I'm
>> exploiting the alias arg to extract the name out of the
>> variable. This makes it impossible to accidentally call the
>> mixin with an invalid string (the error will be *at* the mixin
>> call, not *in* the mixin call).
>
> Oh I like your solution. It is just what I needed, thanks! Also
> I didn't knew you could make enums that contain string values.
> So in D enums are like constants in C#, right? I see that enums
> are used a lot with templates. And why is the name of the enum
> the same with the name of the template? Does it allways have to
> be like that?
String mixins are fun, but you could also use a more classic
template:
---
void checkNonNull(alias var)() {
if (var is null)
throw new Exception(var.stringof ~ " cannot be null.");
}
void main() {
string s;
checkNonNull!s;
}
---
Or with file and line:
---
void checkNonNull(alias var)(string file = __FILE__, size_t line
= __LINE__) {
if (var is null)
throw new Exception(var.stringof ~ " cannot be null.", file,
line);
}
---
More information about the Digitalmars-d-learn
mailing list