import std.string;
static struct X(Args...)
{
void func( Args args )
{
static if( Args.length == 1 && is( Args[0] == string ) )
assert( args[0] == "hello" );
else static if( Args.length == 2 && is( Args[0] == float ) && is( Args[1] == int ) )
{
import std.math;
assert( abs(args[0] - 3.14) < float.epsilon );
assert( args[1] == 12 );
}
else static assert(0,"undefined for this unittest");
}
}
static class ZZ
{
mixin DefineTemplateVars!( X, TemplateVarDef!("ok",string),
TemplateVarDef!("da",float,int),
);
}
auto zz = new ZZ;
static assert( is( typeof(zz.ok) == X!string ) );
static assert( is( typeof(zz.da) == X!(float,int) ) );
zz.ok.func( "hello" );
zz.da.func( 3.14, 12 );
enum mark;
static class A
{
void s1() @mark {}
void f2() {}
@mark
{
void s3( int, string ) {}
void s4( float x ) {}
}
}
template isVoidMarked(T)
{
alias isVoidMarked = isVoidMarkedFunc;
template isVoidMarkedFunc(string n)
{
static if( __traits(compiles,impl!(__traits(getMember,T,n))) )
enum isVoidMarkedFunc = impl!(__traits(getMember,T,n));
else enum isVoidMarkedFunc = false;
template impl(alias f)
{
enum impl = isCallable!f &&
is( ReturnType!f == void ) &&
hasAttrib!(mark,f);
}
}
}
template TemplateVarDefFromMethod(T)
{
template TemplateVarDefFromMethod(string name)
{
alias TemplateVarDefFromMethod = TemplateVarDef!(name,ParameterTypeTuple!(__traits(getMember,T,name)));
}
}
alias tvd = staticMap!( TemplateVarDefFromMethod!A, staticFilter!(isVoidMarked!A,__traits(allMembers,A)) );
static assert( tvd.length == 3 );
alias exp = TypeTuple!( TemplateVarDef!("s1"), TemplateVarDef!("s3",int,string), TemplateVarDef!("s4",float) );
static assert( is(tvd[0] == exp[0]) );
static assert( is(tvd[1] == exp[1]) );
static assert( is(tvd[2] == exp[2]) );