Report a bug
		
				If you spot a problem with this page, click here to create a Bugzilla issue.
		
			Improve this page
		
			Quickly fork, edit online, and submit a pull request for this page.
			Requires a signed-in GitHub account. This works well for small changes.
			If you'd like to make larger changes you may want to consider using
			a local clone.
		
	std.meta
Templates to manipulate
 template parameter sequences
 (also known as alias sequences).
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.
 
  
| Category | Templates | 
|---|---|
| Building blocks | Alias AliasSeq aliasSeqOf | 
| Alias sequence filtering | Erase EraseAll Filter NoDuplicates Stride | 
| Alias sequence type hierarchy | DerivedToFront MostDerived | 
| Alias sequence transformation | Repeat Replace ReplaceAll Reverse staticMap staticSort | 
| Alias sequence searching | allSatisfy anySatisfy staticIndexOf | 
| Template predicates | templateAnd templateNot templateOr staticIsSorted | 
| Template instantiation | ApplyLeft ApplyRight Instantiate | 
References Based on ideas in Table 3.1 from Modern C++ Design, Andrei Alexandrescu (Addison-Wesley Professional, 2001)
License: 
Authors: 
Source std/meta.d
- templateAliasSeq(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 as TypeTuple.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); static assert(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 argument template Map(alias func, args...) { auto ref lazyItem() {return func(args[0]);} static if (args.length == 1) { alias Map = lazyItem; } else { // recurse alias Map = AliasSeq!(lazyItem, Map!(func, args[1 .. $])); } } static void test(int a, int b) { writeln(a); // 4 writeln(b); // 16 } static int a = 2; static int b = 4; test(Map!(i => i ^^ 2, a, b)); writeln(a); // 2 writeln(b); // 4 test(Map!((ref i) => i *= i, a, b)); writeln(a); // 4 writeln(b); // 16 static void testRef(ref int a, ref int b) { writeln(a++); // 16 writeln(b++); // 256 } testRef(Map!(function ref(ref i) => i *= i, a, b)); writeln(a); // 17 writeln(b); // 257 
- templateAlias(alias a)
 templateAlias(T)
- Allows aliasing 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 instead alias Head(Args...) = Alias!(Args[0]); alias Tail(Args...) = Args[1 .. $]; alias Blah = AliasSeq!(3, int, "hello"); static assert(Head!Blah == 3); static assert(is(Head!(Tail!Blah) == int)); static assert((Tail!Blah)[1] == "hello"); Examples:alias a = Alias!(123); static assert(a == 123); enum abc = 1; alias b = Alias!(abc); static assert(b == 1); alias c = Alias!(3 + 4); static assert(c == 7); alias concat = (s0, s1) => s0 ~ s1; alias d = Alias!(concat("Hello", " World!")); static assert(d == "Hello World!"); alias e = Alias!(int); static assert(is(e == int)); alias f = Alias!(AliasSeq!(int)); static assert(!is(typeof(f[0]))); //not an AliasSeq static assert(is(f == int)); auto g = 6; alias h = Alias!g; ++h; writeln(g); // 7 
- templatestaticIndexOf(args...) if (args.length >= 1)
- Returns the index of the first occurrence of args[0] in the sequence args[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 } 
- templateErase(args...) if (args.length >= 1)
- Returns an AliasSeq created from args[1 .. $] with the first occurrence, if any, of args[0] removed.Examples:alias Types = AliasSeq!(int, long, double, char); alias TL = Erase!(long, Types); static assert(is(TL == AliasSeq!(int, double, char))); 
- templateEraseAll(args...) if (args.length >= 1)
- Returns an AliasSeq created from args[1 .. $] with all occurrences, if any, of args[0] removed.Examples:alias Types = AliasSeq!(int, long, long, int); static assert(is(EraseAll!(long, Types) == AliasSeq!(int, int))); 
- templateNoDuplicates(args...)
- Returns an AliasSeq created from args with all duplicate types removed.Examples:alias Types = AliasSeq!(int, long, long, int, float); alias TL = NoDuplicates!(Types); static assert(is(TL == AliasSeq!(int, long, float))); 
- templateReplace(T, U, TList...)
 templateReplace(alias T, U, TList...)
 templateReplace(T, alias U, TList...)
 templateReplace(alias T, alias U, TList...)
- Returns an AliasSeq 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); static assert(is(TL == AliasSeq!(int, char, long, int, float))); 
- templateReplaceAll(args...)
- Returns an AliasSeq created from args[2 .. $] with all occurrences of args[0], if any, replaced with args[1].Examples:alias Types = AliasSeq!(int, long, long, int, float); alias TL = ReplaceAll!(long, char, Types); static assert(is(TL == AliasSeq!(int, char, char, int, float))); 
- templateReverse(args...)
- Returns an AliasSeq created from args with the order reversed.Examples:alias Types = AliasSeq!(int, long, long, int, float, byte, ubyte, short, ushort, uint); alias TL = Reverse!(Types); static assert(is(TL == AliasSeq!(uint, ushort, short, ubyte, byte, float, int, long, long, int))); 
- templateMostDerived(T, TList...)
- Returns the type from TList that is the most derived from type T. 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 C static assert(is(typeof(x) == C)); 
- templateDerivedToFront(TList...)
- Returns an AliasSeq 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); static assert(is(TL == AliasSeq!(C, B, A))); alias TL2 = DerivedToFront!(A, A, A, B, B, B, C, C, C); static assert(is(TL2 == AliasSeq!(C, C, C, B, B, B, A, A, A))); 
- templatestaticMap(alias fun, args...)
- Evaluates to AliasSeq!(fun!(args[0]), fun!(args[1]), ..., fun!(args[$ - 1])).Examples:import std.traits : Unqual; alias TL = staticMap!(Unqual, int, const int, immutable int, uint, ubyte, byte, short, ushort); static assert(is(TL == AliasSeq!(int, int, int, uint, ubyte, byte, short, ushort))); 
- templateallSatisfy(alias F, T...)
- Tests whether all given items satisfy a template predicate, i.e. evaluates to F!(T[0]) && F!(T[1]) && ... && F!(T[$ - 1]).Evaluation is not short-circuited if a false result is encountered; the template predicate must be instantiable with all the given items.
- templateanySatisfy(alias F, T...)
- Tests whether any given items satisfy a template predicate, i.e. evaluates to F!(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.
- templateFilter(alias pred, args...)
- Filters an AliasSeq using a template predicate. Returns an AliasSeq 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); static assert(is(TL1 == AliasSeq!(string, wstring, char[]))); alias Types2 = AliasSeq!(int, byte, ubyte, dstring, dchar, uint, ulong); alias TL2 = Filter!(isUnsigned, Types2); static assert(is(TL2 == AliasSeq!(ubyte, uint, ulong))); 
- templatetemplateNot(alias pred)
- Negates the passed template predicate.Examples:import std.traits : isPointer; alias isNoPointer = templateNot!isPointer; static assert(!isNoPointer!(int*)); static assert(allSatisfy!(isNoPointer, string, char, float)); 
- templatetemplateAnd(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); static assert(storesNegativeNumbers!int); static assert(!storesNegativeNumbers!string && !storesNegativeNumbers!uint); // An empty sequence of predicates always yields true. alias alwaysTrue = templateAnd!(); static assert(alwaysTrue!int); 
- templatetemplateOr(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); static assert( isPtrOrUnsigned!uint && isPtrOrUnsigned!(short*)); static assert(!isPtrOrUnsigned!int && !isPtrOrUnsigned!(string)); // An empty sequence of predicates never yields true. alias alwaysFalse = templateOr!(); static assert(!alwaysFalse!int); 
- templatealiasSeqOf(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 an AliasSeq. It must be able to be able to be iterated over using a foreach-statement. Returns:An AliasSeq containing the values produced by iterating over iter.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()); static assert(capMembers[0] == "A"); static assert(capMembers[1] == "B"); static assert(capMembers[2] == "C"); Examples:static immutable REF = [0, 1, 2, 3]; foreach (I, V; aliasSeqOf!([0, 1, 2, 3])) { static assert(V == I); static assert(V == REF[I]); } 
- templateApplyLeft(alias Template, args...)
 templateApplyRight(alias Template, args...)
- Behaves like the identity function when args is empty.Parameters:Template template to partially apply args arguments to bind Returns:Template with arity smaller than or equal to TemplateExamples:// enum bool isImplicitlyConvertible(From, To) import std.traits : isImplicitlyConvertible; static assert(allSatisfy!( ApplyLeft!(isImplicitlyConvertible, ubyte), short, ushort, int, uint, long, ulong)); static assert(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)() { return true; } } Test foo; } static assert(allSatisfy!(ApplyRight!(hasMember, "foo"), T1, T2)); static assert(allSatisfy!(ApplyRight!(ifTestable, a => a.foo), T1, T2)); Examples:import std.traits : Largest; alias Types = AliasSeq!(byte, short, int, long); static assert(is(staticMap!(ApplyLeft!(Largest, short), Types) == AliasSeq!(short, short, int, long))); static assert(is(staticMap!(ApplyLeft!(Largest, int), Types) == AliasSeq!(int, int, int, long))); Examples:import std.traits : FunctionAttribute, SetFunctionAttributes; static void foo() @system; static int bar(int) @system; alias SafeFunctions = AliasSeq!( void function() @safe, int function(int) @safe); static assert(is(staticMap!(ApplyRight!( SetFunctionAttributes, "D", FunctionAttribute.safe), typeof(&foo), typeof(&bar)) == SafeFunctions)); 
- templateRepeat(size_t n, items...)
- Creates an AliasSeq which repeats items exactly n times.Examples:alias ImInt0 = Repeat!(0, int); static assert(is(ImInt0 == AliasSeq!())); alias ImInt1 = Repeat!(1, immutable(int)); static assert(is(ImInt1 == AliasSeq!(immutable(int)))); alias Real3 = Repeat!(3, real); static assert(is(Real3 == AliasSeq!(real, real, real))); alias Real12 = Repeat!(4, Real3); static assert(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); static assert(is(Composite2 == AliasSeq!(uint, int, uint, int))); alias ImInt10 = Repeat!(10, int); static assert(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] 
- templatestaticSort(alias cmp, items...)
- Sorts an AliasSeq using cmp.Parameters cmp = A template that returns a bool (if its first argument is less than the second one) or an int (-1 means less than, 0 means equal, 1 means greater than) items = The AliasSeq to sortReturns:The sorted alias sequenceExamples:alias Nums = AliasSeq!(7, 2, 3, 23); enum Comp(int N1, int N2) = N1 < N2; static assert(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); static assert(is(AliasSeq!(uint, ubyte, ulong, short, long) == staticSort!(Comp, Types))); 
- enum autostaticIsSorted(alias cmp, items...);
- Checks if an AliasSeq is sorted according to cmp.Parameters cmp = A template that returns a bool (if its first argument is less than the second one) or an int (-1 means less than, 0 means equal, 1 means greater than) Seq = The AliasSeq to checkReturns:true if Seq is sorted; otherwise falseExamples:enum Comp(int N1, int N2) = N1 < N2; static assert( staticIsSorted!(Comp, 2, 2)); static assert( staticIsSorted!(Comp, 2, 3, 7, 23)); static assert(!staticIsSorted!(Comp, 7, 2, 3, 23)); Examples:enum Comp(T1, T2) = __traits(isUnsigned, T2) - __traits(isUnsigned, T1); static assert( staticIsSorted!(Comp, uint, ubyte, ulong, short, long)); static assert(!staticIsSorted!(Comp, uint, short, ubyte, long, ulong)); 
- templateStride(int stepSize, Args...) if (stepSize != 0)
- Selects a subset of Args by stepping with fixed stepSize over the sequence. A negative stepSize starts iteration with the last element.Parameters:stepSize Number of elements to increment on each iteration. Can't be 0. Args Template arguments. Returns:An AliasSeq filtered by the selected stride.Examples:static assert(is(Stride!(1, short, int, long) == AliasSeq!(short, int, long))); static assert(is(Stride!(2, short, int, long) == AliasSeq!(short, long))); static assert(is(Stride!(-1, short, int, long) == AliasSeq!(long, int, short))); static assert(is(Stride!(-2, short, int, long) == AliasSeq!(long, short))); alias attribs = AliasSeq!(short, int, long, ushort, uint, ulong); static assert(is(Stride!(3, attribs) == AliasSeq!(short, ushort))); static assert(is(Stride!(3, attribs[1 .. $]) == AliasSeq!(int, uint))); static assert(is(Stride!(-3, attribs) == AliasSeq!(ulong, long))); 
- templateInstantiate(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 = ""; static foreach (f; functions) { { auto x = &f; // not a template, but a function instantiation result ~= x("hello", 7); result ~= ";"; } } writeln(result); // "hello ; hello ; hello;" 
Copyright © 1999-2025 by the D Language Foundation | Page generated by
Ddoc on Mon Mar 31 10:28:14 2025