Various stuff for working with templates.
Instantiate a template Template using arguments A.
import std.traits: PointerTarget; static assert(is(Inst!(PointerTarget, int*) == int));
Create template from a string Pred. If Pred isn't a string, alises itself to Pred.
If argumentsCount is -1 created template will accept any number
of arguments, otherwise it will expect argumentsCount arguments.
If EnumType is void created template may be an alias or
an enum, otherwise it will be an enum of type EnumType.
Created template can access its aruments as a generic tuple with Args.
If argumentsCount is 1 or 2 created template can access
its first argument with a if it is an value, with T if it is a type
and with A otherwise.
If argumentsCount is 2 created template can access
its second argument with b if it is an value, with U if it is a type
and with B otherwise.
UnaryTemplate is a convinient way to create a template with one argument (argumentsCount is 1).
BinaryTemplate is a convinient way to create a template with two arguments (argumentsCount is 2).
static assert(Inst!(UnaryTemplate!`__traits(isUnsigned, T)`, uint)); static assert(is(Inst!(UnaryTemplate!`T[]`, int) == int[])); static assert(Inst!(UnaryTemplate!`a == 5`, 5)); static assert(Inst!(BinaryTemplate!`a == 1 && b == 2`, 1, 2)); static assert(Inst!(BinaryTemplate!`a + U.sizeof`, 1, int) == 5); static assert(PackedGenericTuple!(Inst!(Template!(`Args`, -1), "x", int)).equals!("x", int));
Using unaryPred or binaryPred is a convinient way to create a template with one or two arguments respectively which is an enum of type bool.
It is equal to instantiating Template with corresponding argumentsCount and bool as EnumType.
static assert(Inst!(unaryPred!`__traits(isUnsigned, T)`, uint)); static assert(Inst!(binaryPred!`a == U.sizeof`, 4, int));
Create predicate template returning !template_.
import std.traits: isPointer; alias notPointer = notTemplate!isPointer; static assert( notPointer! int ); static assert(!notPointer!(int*)); alias toBoolTemplate = notTemplate!notTemplate; static assert(Inst!(toBoolTemplate!isPointer, int*)); template get5() { enum get5 = 5; } static assert(Inst!(toBoolTemplate!get5) == true);
Create predicate template returning true iff there are no templates or all templates return non-zero.
import std.traits: isIntegral, isSigned; alias isSignedIntegral = andTemplates!(isIntegral, isSigned); static assert( allTuple!(isSignedIntegral, int, short, long)); static assert(!anyTuple!(isSignedIntegral, uint, ushort, ulong)); alias isShort = andTemplates!(isSignedIntegral, unaryPred!`is(T == short)`); static assert( isShort!short); static assert(!anyTuple!(isShort, int, long, uint, ushort, ulong));
Create predicate template returning true iff any template of templates return non-zero (i.e. returning false if there are no templates).
import std.traits: isIntegral, isFloatingPoint; alias isIntegralOrFloating = orTemplates!(isIntegral, isFloatingPoint); static assert( allTuple!(isIntegralOrFloating, int, short, long, float, double)); static assert(!anyTuple!(isIntegralOrFloating, bool, char)); alias isIntegralOrFloatingOrChar = orTemplates!(isIntegralOrFloating, unaryPred!`is(T == char)`); static assert( allTuple!(isIntegralOrFloatingOrChar, int, short, long, float, double, char)); static assert(!isIntegralOrFloatingOrChar!bool);
Binds template arguments.
import unstd.traits; static assert(is(Inst!(BindTemplate!(CommonType, long, allArgs), int) == long)); static assert(!Inst!(BindTemplate!(isImplicitlyConvertible, args[0], int), long)); static assert( Inst!(BindTemplate!(isImplicitlyConvertible, int , arg!0), long)); alias UnqualAll = BindTemplate!(MapTuple, Unqual, allArgs); static assert(is(UnqualAll!(const(int), immutable(bool[])) == TypeTuple!(int, immutable(bool)[])));
Binds template arguments using format string.
import unstd.traits; mixin Bind!q{ CommonTypeToLong = CommonType!(long, %*) }; static assert(is(CommonTypeToLong!int == long)); mixin Bind!q{ isImplicitlyConvertibleToInt = isImplicitlyConvertible!(%0, int) }; static assert(!isImplicitlyConvertibleToInt!long); mixin Bind!q{ isImplicitlyConvertibleFromInt = isImplicitlyConvertible!(int, %0) }; static assert( isImplicitlyConvertibleFromInt!long); mixin Bind!q{ UnqualAll = MapTuple!(Unqual, %*) }; static assert(is(UnqualAll!(const(int), immutable(bool[])) == TypeTuple!(int, immutable(bool)[])));