Some operations on alias sequences are built into the language, such as
S[i], which accesses the element at index
i in the sequence.
S[low .. high] returns a new alias sequence that is a slice of the old one.
For more information, see
Compile-time Sequences.
Note: Several templates in this module use or operate on eponymous templates that take a single argument and evaluate to a boolean constant. Such templates are referred to as
template predicates.
template
AliasSeq(TList...)
Creates a sequence of zero or more aliases. This is most commonly used as template parameters or arguments.
In previous versions of Phobos, this was known asTypeTuple.
Examples:import std.meta;alias TL =AliasSeq!(int,double);int foo(TL td)// same as int foo(int, double);{return td[0] +cast(int) td[1];} Examples:alias TL =AliasSeq!(int,double);alias Types =AliasSeq!(TL,char);staticassert(is(Types ==AliasSeq!(int,double,char)));
Examples:// Creates a compile-time sequence of function call expressions// that each call `func` with the next variadic template argumenttemplate Map(alias func, args...){autoref lazyItem() {return func(args[0]);}staticif (args.length == 1) {alias Map = lazyItem; }else {// recursealias Map =AliasSeq!(lazyItem, Map!(func, args[1 .. $])); }}staticvoid test(int a,int b){ writeln(a);// 4 writeln(b);// 16}staticint a = 2;staticint b = 4;test(Map!(i => i ^^ 2, a, b));writeln(a);// 2writeln(b);// 4test(Map!((ref i) => i *= i, a, b));writeln(a);// 4writeln(b);// 16staticvoid testRef(refint a,refint b){ writeln(a++);// 16 writeln(b++);// 256}testRef(Map!(functionref(ref i) => i *= i, a, b));writeln(a);// 17writeln(b);// 257 template
Alias(alias a)
template
Alias(T)
Allowsaliasing of any single symbol, type or compile-time expression.
Not everything can be directly aliased. An alias cannot be declared of - for example - a literal:
alias a = 4;//Error
With this template any single entity can be aliased:
alias b =Alias!4;//OK
See Also:To alias more than one thing at once, use
AliasSeq.
Examples:// Without Alias this would fail if Args[0] was e.g. a value and// some logic would be needed to detect when to use enum insteadalias Head(Args...) =Alias!(Args[0]);alias Tail(Args...) = Args[1 .. $];alias Blah = AliasSeq!(3,int,"hello");staticassert(Head!Blah == 3);staticassert(is(Head!(Tail!Blah) ==int));staticassert((Tail!Blah)[1] =="hello");
Examples:alias a =Alias!(123);staticassert(a == 123);enum abc = 1;alias b =Alias!(abc);staticassert(b == 1);alias c =Alias!(3 + 4);staticassert(c == 7);alias concat = (s0, s1) => s0 ~ s1;alias d =Alias!(concat("Hello"," World!"));staticassert(d =="Hello World!");alias e =Alias!(int);staticassert(is(e ==int));alias f =Alias!(AliasSeq!(int));staticassert(!is(typeof(f[0])));//not an AliasSeqstaticassert(is(f ==int));auto g = 6;alias h =Alias!g;++h;writeln(g);// 7 template
staticIndexOf(args...) if (args.length >= 1)
Returns the index of the first occurrence ofargs[0] in the sequenceargs[1 .. $].args may be types or compile-time values. If not found,-1 is returned.
Examples:import std.stdio;void foo(){ writefln("The index of long is %s",staticIndexOf!(long, AliasSeq!(int,long,double)));// prints: The index of long is 1} template
Erase(args...) if (args.length >= 1)
Returns anAliasSeq created fromargs[1 .. $] with the first occurrence, if any, ofargs[0] removed.
Examples:alias Types = AliasSeq!(int,long,double,char);alias TL =Erase!(long, Types);staticassert(is(TL == AliasSeq!(int,double,char)));
template
EraseAll(args...) if (args.length >= 1)
Returns anAliasSeq created fromargs[1 .. $] with all occurrences, if any, ofargs[0] removed.
Examples:alias Types = AliasSeq!(int,long,long,int);staticassert(is(EraseAll!(long, Types) == AliasSeq!(int,int)));
template
NoDuplicates(args...)
Returns anAliasSeq created fromargs with all duplicate types removed.
Examples:alias Types = AliasSeq!(int,long,long,int,float);alias TL =NoDuplicates!(Types);staticassert(is(TL == AliasSeq!(int,long,float)));
template
Replace(T, U, TList...)
template
Replace(alias T, U, TList...)
template
Replace(T, alias U, TList...)
template
Replace(alias T, alias U, TList...)
Returns anAliasSeq created from TList with the first occurrence of T, if found, replaced with U.
Examples:alias Types = AliasSeq!(int,long,long,int,float);alias TL =Replace!(long,char, Types);staticassert(is(TL == AliasSeq!(int,char,long,int,float)));
template
ReplaceAll(args...)
Returns anAliasSeq created fromargs[2 .. $] with all occurrences ofargs[0], if any, replaced withargs[1].
Examples:alias Types = AliasSeq!(int,long,long,int,float);alias TL =ReplaceAll!(long,char, Types);staticassert(is(TL == AliasSeq!(int,char,char,int,float)));
Returns anAliasSeq created fromargs with the order reversed.
Examples:alias Types = AliasSeq!(int,long,long,int,float,byte,ubyte,short,ushort,uint);alias TL =Reverse!(Types);staticassert(is(TL == AliasSeq!(uint,ushort,short,ubyte,byte,float,int,long,long,int)));
template
MostDerived(T, TList...)
Returns the type fromTList that is the most derived from typeT. If no such type is found,T is returned.
Examples:class A { }class B : A { }class C : B { }alias Types = AliasSeq!(A, C, B);MostDerived!(Object, Types) x;// x is declared as type Cstaticassert(is(typeof(x) == C)); template
DerivedToFront(TList...)
Returns anAliasSeq with the elements of TList sorted so that the most derived types come first.
Examples:class A { }class B : A { }class C : B { }alias Types = AliasSeq!(A, C, B);alias TL =DerivedToFront!(Types);staticassert(is(TL == AliasSeq!(C, B, A)));alias TL2 =DerivedToFront!(A, A, A, B, B, B, C, C, C);staticassert(is(TL2 == AliasSeq!(C, C, C, B, B, B, A, A, A))); template
staticMap(alias fun, args...)
Evaluates toAliasSeq!(fun!(args[0]), fun!(args[1]), ..., fun!(args[$ - 1])).
Examples:import std.traits : Unqual;alias TL =staticMap!(Unqual,int,constint,immutableint,uint,ubyte,byte,short,ushort);staticassert(is(TL == AliasSeq!(int,int,int,uint,ubyte,byte,short,ushort)));
template
allSatisfy(alias F, T...)
Tests whether all given items satisfy a template predicate, i.e. evaluates toF!(T[0]) && F!(T[1]) && ... && F!(T[$ - 1]).
Evaluation isnot short-circuited if a false result is encountered; the template predicate must be instantiable with all the given items.
template
anySatisfy(alias F, T...)
Tests whether any given items satisfy a template predicate, i.e. evaluates toF!(T[0]) || F!(T[1]) || ... || F!(T[$ - 1]).
Evaluation is short-circuited if a true result is encountered; the template predicate must be instantiable with one of the given items.
template
Filter(alias pred, args...)
Filters anAliasSeq using a template predicate. Returns anAliasSeq of the elements which satisfy the predicate.
Examples:import std.traits : isNarrowString, isUnsigned;alias Types1 = AliasSeq!(string, wstring,dchar[],char[], dstring,int);alias TL1 =Filter!(isNarrowString, Types1);staticassert(is(TL1 == AliasSeq!(string, wstring,char[])));alias Types2 = AliasSeq!(int,byte,ubyte, dstring,dchar,uint,ulong);alias TL2 =Filter!(isUnsigned, Types2);staticassert(is(TL2 == AliasSeq!(ubyte,uint,ulong)));
template
templateNot(alias pred)
Negates the passed template predicate.
Examples:import std.traits : isPointer;alias isNoPointer =templateNot!isPointer;staticassert(!isNoPointer!(int*));staticassert(allSatisfy!(isNoPointer, string,char,float));
template
templateAnd(Preds...)
Combines several template predicates using logical AND, i.e. constructs a new predicate which evaluates to true for a given input T if and only if all of the passed predicates are true for T.
The predicates are evaluated from left to right, aborting evaluation in a short-cut manner if a false result is encountered, in which case the latter instantiations do not need to compile.
Examples:import std.traits : isNumeric, isUnsigned;alias storesNegativeNumbers =templateAnd!(isNumeric, templateNot!isUnsigned);staticassert(storesNegativeNumbers!int);staticassert(!storesNegativeNumbers!string && !storesNegativeNumbers!uint);// An empty sequence of predicates always yields true.alias alwaysTrue =templateAnd!();staticassert(alwaysTrue!int);
template
templateOr(Preds...)
Combines several template predicates using logical OR, i.e. constructs a new predicate which evaluates to true for a given input T if and only at least one of the passed predicates is true for T.
The predicates are evaluated from left to right, aborting evaluation in a short-cut manner if a true result is encountered, in which case the latter instantiations do not need to compile.
Examples:import std.traits : isPointer, isUnsigned;alias isPtrOrUnsigned =templateOr!(isPointer, isUnsigned);staticassert( isPtrOrUnsigned!uint && isPtrOrUnsigned!(short*));staticassert(!isPtrOrUnsigned!int && !isPtrOrUnsigned!(string));// An empty sequence of predicates never yields true.alias alwaysFalse =templateOr!();staticassert(!alwaysFalse!int);
template
aliasSeqOf(alias iter) if (isIterable!(typeof(iter)) && !isInfinite!(typeof(iter)))
Converts any foreach-iterable entity (e.g. an input range) to an alias sequence.
Parameters:| iter | the entity to convert into anAliasSeq. It must be able to be able to be iterated over using aforeach-statement. |
Returns:AnAliasSeq containing the values produced by iterating overiter.
Examples:import std.algorithm.iteration : map;import std.algorithm.sorting : sort;import std.string : capitalize;struct S{int a;int c;int b;}alias capMembers =aliasSeqOf!([__traits(allMembers, S)].sort().map!capitalize());staticassert(capMembers[0] =="A");staticassert(capMembers[1] =="B");staticassert(capMembers[2] =="C"); Examples:staticimmutable REF = [0, 1, 2, 3];foreach (I, V;aliasSeqOf!([0, 1, 2, 3])){staticassert(V == I);staticassert(V == REF[I]);} template
ApplyLeft(alias Template, args...)
template
ApplyRight(alias Template, args...)
Partially appliesTemplate by binding its first (left) or last (right) arguments to
args.
Behaves like the identity function whenargs is empty.
Parameters:| Template | template to partially apply |
| args | arguments to bind |
Returns:Template with arity smaller than or equal toTemplate
Examples:// enum bool isImplicitlyConvertible(From, To)import std.traits : isImplicitlyConvertible;staticassert(allSatisfy!(ApplyLeft!(isImplicitlyConvertible,ubyte),short,ushort,int,uint,long,ulong));staticassert(is(Filter!(ApplyRight!(isImplicitlyConvertible,short),ubyte, string,short,float,int) == AliasSeq!(ubyte,short)));
Examples:import std.traits : hasMember, ifTestable;struct T1{bool foo;}struct T2{struct Test {bool opCast(T :bool)() {returntrue; } } Test foo;}staticassert(allSatisfy!(ApplyRight!(hasMember,"foo"), T1, T2));staticassert(allSatisfy!(ApplyRight!(ifTestable, a => a.foo), T1, T2)); Examples:import std.traits : Largest;alias Types = AliasSeq!(byte,short,int,long);staticassert(is(staticMap!(ApplyLeft!(Largest,short), Types) == AliasSeq!(short,short,int,long)));staticassert(is(staticMap!(ApplyLeft!(Largest,int), Types) == AliasSeq!(int,int,int,long)));
Examples:import std.traits : FunctionAttribute, SetFunctionAttributes;staticvoid foo() @system;staticint bar(int) @system;alias SafeFunctions = AliasSeq!(voidfunction() @safe,intfunction(int) @safe);staticassert(is(staticMap!(ApplyRight!( SetFunctionAttributes,"D", FunctionAttribute.safe),typeof(&foo),typeof(&bar)) == SafeFunctions));
template
Repeat(size_t n, items...)
Creates anAliasSeq which repeatsitems exactlyn times.
Examples:alias ImInt0 =Repeat!(0,int);staticassert(is(ImInt0 == AliasSeq!()));alias ImInt1 =Repeat!(1,immutable(int));staticassert(is(ImInt1 == AliasSeq!(immutable(int))));alias Real3 =Repeat!(3,real);staticassert(is(Real3 == AliasSeq!(real,real,real)));alias Real12 =Repeat!(4, Real3);staticassert(is(Real12 == AliasSeq!(real,real,real,real,real,real,real,real,real,real,real,real)));alias Composite = AliasSeq!(uint,int);alias Composite2 =Repeat!(2, Composite);staticassert(is(Composite2 == AliasSeq!(uint,int,uint,int)));alias ImInt10 =Repeat!(10,int);staticassert(is(ImInt10 == AliasSeq!(int,int,int,int,int,int,int,int,int,int)));alias Big =Repeat!(1_000_000,int);
Examples:auto staticArray(T, size_t n)(Repeat!(n, T) elems){ T[n] a = [elems];return a;}auto a = staticArray!(long, 3)(3, 1, 4);assert(is(typeof(a) ==long[3]));writeln(a);// [3, 1, 4] template
staticSort(alias cmp, items...)
Parameterscmp = A template that returns abool (if its first argument is less than the second one) or anint (-1 means less than, 0 means equal, 1 means greater than)
items = The
AliasSeq to sort
Returns:The sorted alias sequence
Examples:alias Nums = AliasSeq!(7, 2, 3, 23);enum Comp(int N1,int N2) = N1 < N2;staticassert(AliasSeq!(2, 3, 7, 23) ==staticSort!(Comp, Nums));
Examples:alias Types = AliasSeq!(uint,short,ubyte,long,ulong);enum Comp(T1, T2) =__traits(isUnsigned, T2) -__traits(isUnsigned, T1);staticassert(is(AliasSeq!(uint,ubyte,ulong,short,long) ==staticSort!(Comp, Types)));
enum auto
staticIsSorted(alias cmp, items...);
Checks if an
AliasSeq is sorted according to
cmp.
Parameterscmp = A template that returns abool (if its first argument is less than the second one) or anint (-1 means less than, 0 means equal, 1 means greater than)
Seq = The
AliasSeq to check
Returns:true ifSeq is sorted; otherwisefalse
Examples:enum Comp(int N1,int N2) = N1 < N2;staticassert(staticIsSorted!(Comp, 2, 2));staticassert(staticIsSorted!(Comp, 2, 3, 7, 23));staticassert(!staticIsSorted!(Comp, 7, 2, 3, 23));
Examples:enum Comp(T1, T2) =__traits(isUnsigned, T2) -__traits(isUnsigned, T1);staticassert(staticIsSorted!(Comp,uint,ubyte,ulong,short,long));staticassert(!staticIsSorted!(Comp,uint,short,ubyte,long,ulong));
template
Stride(int stepSize, Args...) if (stepSize != 0)
Selects a subset ofArgs by stepping with fixedstepSize over the sequence.A negativestepSize starts iteration with the last element.
Parameters:| stepSize | Number of elements to increment on each iteration. Can't be0. |
| Args | Template arguments. |
Returns:AnAliasSeq filtered by the selected stride.
Examples:staticassert(is(Stride!(1,short,int,long) == AliasSeq!(short,int,long)));staticassert(is(Stride!(2,short,int,long) == AliasSeq!(short,long)));staticassert(is(Stride!(-1,short,int,long) == AliasSeq!(long,int,short)));staticassert(is(Stride!(-2,short,int,long) == AliasSeq!(long,short)));alias attribs = AliasSeq!(short,int,long,ushort,uint,ulong);staticassert(is(Stride!(3, attribs) == AliasSeq!(short,ushort)));staticassert(is(Stride!(3, attribs[1 .. $]) == AliasSeq!(int,uint)));staticassert(is(Stride!(-3, attribs) == AliasSeq!(ulong,long)));
template
Instantiate(alias Template, Params...)
Instantiates the given template with the given parameters.
Used to work around syntactic limitations of D with regard to instantiating a template from an alias sequence (e.g.T[0]!(...) is not valid) or a template returning another template (e.g.Foo!(Bar)!(Baz) is not allowed).
Parameters:| Template | The template to instantiate. |
| Params | The parameters with which to instantiate the template. |
Returns:The instantiated template.
Examples:// ApplyRight combined with Instantiate can be used to apply various// templates to the same parameters.import std.string : leftJustify, center, rightJustify;alias functions = staticMap!(ApplyRight!(Instantiate, string), leftJustify, center, rightJustify);string result ="";staticforeach (f; functions){ {auto x = &f;// not a template, but a function instantiation result ~= x("hello", 7); result ~=";"; }}writeln(result);// "hello ; hello ; hello;"