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 local clone.

std.meta

Templates to manipulate template argument lists (also known as type lists).
Some operations on alias sequences are built in to the language, such as TL[n] which gets the nth type from the alias sequence. TL[lwr .. upr] returns a new type list that is a slice of the old one.

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.

References: Based on ideas in Table 3.1 from Modern C++ Design, Andrei Alexandrescu (Addison-Wesley Professional, 2001)

License:
Authors:

Source: std/typetuple.d

template AliasSeq(TList...)
Creates a sequence of zero or more aliases. This is most commonly used as template parameters or arguments.
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)));
enum staticIndexOf(T, TList...);
enum staticIndexOf(alias T, TList...);
Returns the index of the first occurrence of type T in the sequence of zero or more types TList. 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
}
alias IndexOf = staticIndexOf(T, TList...);
Kept for backwards compatibility
template Erase(T, TList...)
template Erase(alias T, TList...)
Returns a typetuple created from TList with the first occurrence, if any, of T removed.
Examples:
alias Types = AliasSeq!(int, long, double, char);
alias TL = Erase!(long, Types);
static assert(is(TL == AliasSeq!(int, double, char)));
template EraseAll(T, TList...)
template EraseAll(alias T, TList...)
Returns a typetuple created from TList with the all occurrences, if any, of T removed.
Examples:
alias Types = AliasSeq!(int, long, long, int);

alias TL = EraseAll!(long, Types);
static assert(is(TL == AliasSeq!(int, int)));
template NoDuplicates(TList...)
Returns a typetuple created from TList with the 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)));
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 a typetuple created from TList with the first occurrence of type T, if found, replaced with type 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)));
template ReplaceAll(T, U, TList...)
template ReplaceAll(alias T, U, TList...)
template ReplaceAll(T, alias U, TList...)
template ReplaceAll(alias T, alias U, TList...)
Returns a typetuple created from TList with all occurrences of type T, if found, replaced with type U.
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)));
template Reverse(TList...)
Returns a typetuple created from TList with the order reversed.
Examples:
alias Types = AliasSeq!(int, long, long, int, float);

alias TL = Reverse!(Types);
static assert(is(TL == AliasSeq!(float, int, long, long, int)));
template MostDerived(T, TList...)
Returns the type from TList that is the most derived from type T. If none are 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));
template DerivedToFront(TList...)
Returns the typetuple TList with the types 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)));
template staticMap(alias F, T...)
Evaluates to AliasSeq!(F!(T[0]), F!(T[1]), ..., F!(T[$ - 1])).
Examples:
import std.traits : Unqual;
alias TL = staticMap!(Unqual, int, const int, immutable int);
static assert(is(TL == AliasSeq!(int, int, int)));
template allSatisfy(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.
Examples:
import std.traits : isIntegral;

static assert(!allSatisfy!(isIntegral, int, double));
static assert( allSatisfy!(isIntegral, int, long));
template anySatisfy(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 not short-circuited if a true result is encountered; the template predicate must be instantiable with all the given items.
Examples:
import std.traits : isIntegral;

static assert(!anySatisfy!(isIntegral, string, double));
static assert( anySatisfy!(isIntegral, int, double));
template Filter(alias pred, TList...)
Filters an AliasSeq using a template predicate. Returns a 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)));
template templateNot(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));
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);
static assert(storesNegativeNumbers!int);
static assert(!storesNegativeNumbers!string && !storesNegativeNumbers!uint);

// An empty list of predicates always yields true.
alias alwaysTrue = templateAnd!();
static assert(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);
static assert( isPtrOrUnsigned!uint &&  isPtrOrUnsigned!(short*));
static assert(!isPtrOrUnsigned!int  && !isPtrOrUnsigned!(string));

// An empty list of predicates never yields true.
alias alwaysFalse = templateOr!();
static assert(!alwaysFalse!int);