Daniel Keep wrote:
Lars T. Kyllingstad wrote:
...
Knocked this up in about two minutes. Might be handy.
template TestInstantiateImpl(alias Tmpl, Ts...)
{
static if( Ts.length > 0 )
{
alias Tmpl!(Ts[0]) test;
alias TestInstantiateImpl!(Tmpl, Ts[1..$]).next next;
}
else
{
enum next = true;
}
}
template TestInstantiate(alias Tmpl, Ts...)
{
alias TestInstantiateImpl!(Tmpl, Ts).next TestInstantiate;
}
template Blah(T)
{
pragma(msg, "Blah!("~T.stringof~")");
alias T Blah;
}
T nanFor(T)()
{
pragma(msg, "nanFor!("~T.stringof~")");
return T.nan;
}
unittest
{
static assert( TestInstantiate!(Blah, float, double, real) );
static assert( TestInstantiate!(nanFor, float, double, real) );
static assert( TestInstantiate!(Blah, int) );
static assert( TestInstantiate!(nanFor, int) );
}
void main()
{
}
$ dmd -unittest irc
Blah!(float)
Blah!(double)
Blah!(real)
nanFor!(float)
nanFor!(double)
nanFor!(real)
Blah!(int)
nanFor!(int)
irc.d(34): Error: no property 'nan' for type 'int'
irc.d(43): Error: template instance irc.TestInstantiate!(nanFor,int)
error instantiating
Good idea. :) Without having tested it, I think your template also works
with multi-parameter templates:
template Foo(T, U, V) { ... }
unittest
{
static assert (TestInstantiate!(Foo, Tuple!(int, real, real),
Tuple!(uint, double, cdouble)));
}
If something like this was to go into a library, I'd remove the
pragma(msg)s, though. They'd get pretty annoying after a while. ;)
-Lars