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?
Also is there a way to see my code after mixins, templates and
CTFE gets executed? Like some kind of compiler switch or
something?