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.
Page wiki
View or edit the community-maintained wiki page associated with this page.
std.traits
Templates with which to extract information about types and symbols at compile time.Boost License 1.0. Authors:
Walter Bright, Tomasz Stachowiak (isExpressionTuple), Andrei Alexandrescu, Shin Fujishiro, Robert Clipsham, David Nadlinger, Kenji Hara, Shoichi Kato Source:
std/traits.d
- template packageName(alias T)
- Get the full package name for the given symbol.
Example:
import std.traits; static assert(packageName!packageName == "std");
- template moduleName(alias T)
- Get the module name (including package) for the given symbol.
Example:
import std.traits; static assert(moduleName!moduleName == "std.traits");
- template fullyQualifiedName(T...) if (T.length == 1)
- Get the fully qualified name of a type or a symbol. Can act as an intelligent type/symbol to string converter.
Example:
module mymodule; import std.traits; struct MyStruct {} static assert(fullyQualifiedName!(const MyStruct[]) == "const(mymodule.MyStruct[])"); static assert(fullyQualifiedName!fullyQualifiedName == "std.traits.fullyQualifiedName");
- template ReturnType(func...) if (func.length == 1 && isCallable!func)
- Get the type of the return value from a function,
a pointer to function, a delegate, a struct
with an opCall, a pointer to a struct with an opCall,
or a class with an opCall. Please note that ref
is not part of a type, but the attribute of the function
(see template functionAttributes).
Example:
import std.traits; int foo(); ReturnType!foo x; // x is declared as int
- template ParameterTypeTuple(func...) if (func.length == 1 && isCallable!func)
- Get, as a tuple, the types of the parameters to a function, a pointer
to function, a delegate, a struct with an opCall, a pointer to a
struct with an opCall, or a class with an opCall.
Example:
import std.traits; int foo(int, long); void bar(ParameterTypeTuple!foo); // declares void bar(int, long); void abc(ParameterTypeTuple!foo[1]); // declares void abc(long);
- template arity(alias func) if (isCallable!func && variadicFunctionStyle!func == Variadic.no)
- Returns the number of arguments of function func.
arity is undefined for variadic functions.
Example:
void foo(){} static assert(arity!foo==0); void bar(uint){} static assert(arity!bar==1);
- enum ParameterStorageClass: uint;
template ParameterStorageClassTuple(func...) if (func.length == 1 && isCallable!func) - Returns a tuple consisting of the storage classes of the parameters of a
function func.
Example:
alias ParameterStorageClass STC; // shorten the enum name void func(ref int ctx, out real result, real param) { } alias ParameterStorageClassTuple!func pstc; static assert(pstc.length == 3); // three parameters static assert(pstc[0] == STC.ref_); static assert(pstc[1] == STC.out_); static assert(pstc[2] == STC.none);
- template ParameterIdentifierTuple(func...) if (func.length == 1 && isCallable!func)
- Get, as a tuple, the identifiers of the parameters to a function symbol.
Examples:
import std.traits; int foo(int num, string name); static assert([ParameterIdentifierTuple!foo] == ["num", "name"]);
- template ParameterDefaultValueTuple(func...) if (func.length == 1 && isCallable!func)
- Get, as a tuple, the default value of the parameters to a function symbol.
If a parameter doesn't have the default value, void is returned instead.
Examples:
import std.traits; int foo(int num, string name = "hello", int[] arr = [1,2,3]); static assert(is(ParameterDefaultValueTuple!foo[0] == void)); static assert( ParameterDefaultValueTuple!foo[1] == "hello"); static assert( ParameterDefaultValueTuple!foo[2] == [1,2,3]);
- enum FunctionAttribute: uint;
template functionAttributes(func...) if (func.length == 1 && isCallable!func) - Returns the attributes attached to a function func.
Example:
alias FunctionAttribute FA; // shorten the enum name real func(real x) pure nothrow @safe { return x; } static assert(functionAttributes!func & FA.pure_); static assert(functionAttributes!func & FA.safe); static assert(!(functionAttributes!func & FA.trusted)); // not @trusted
- template isSafe(alias func) if (isCallable!func)
- true if func is @safe or @trusted.
Example:
@safe int add(int a, int b) {return a+b;} @trusted int sub(int a, int b) {return a-b;} @system int mul(int a, int b) {return a*b;} static assert( isSafe!add); static assert( isSafe!sub); static assert(!isSafe!mul);
- template isUnsafe(alias func)
- true if func is @system.
Example:
@safe int add(int a, int b) {return a+b;} @trusted int sub(int a, int b) {return a-b;} @system int mul(int a, int b) {return a*b;} static assert(!isUnsafe!add); static assert(!isUnsafe!sub); static assert( isUnsafe!mul);
- template areAllSafe(funcs...) if (funcs.length > 0)
- Scheduled for deprecation in January 2013. It's badly named and provides
redundant functionality. It was also badly broken prior to 2.060 (bug# 8362), so
any code which uses it probably needs to be changed anyway. Please use
allSatisfy(isSafe, ...) instead.
true all functions are isSafe.
Example:
@safe int add(int a, int b) {return a+b;} @trusted int sub(int a, int b) {return a-b;} @system int mul(int a, int b) {return a*b;} static assert( areAllSafe!(add, add)); static assert( areAllSafe!(add, sub)); static assert(!areAllSafe!(sub, mul));
- template functionLinkage(func...) if (func.length == 1 && isCallable!func)
- Returns the calling convention of function as a string.
Example:
string a = functionLinkage!(writeln!(string, int)); assert(a == "D"); // extern(D) auto fp = &printf; string b = functionLinkage!fp; assert(b == "C"); // extern(C)
- enum Variadic: int;
template variadicFunctionStyle(func...) if (func.length == 1 && isCallable!func) - Determines what kind of variadic parameters function has.
Example:
void func() {} static assert(variadicFunctionStyle!func == Variadic.no); extern(C) int printf(in char*, ...); static assert(variadicFunctionStyle!printf == Variadic.c);
- template FunctionTypeOf(func...) if (func.length == 1 && isCallable!func)
- Get the function type from a callable object func.
Using builtin typeof on a property function yields the types of the
property value, not of the property function itself. Still,
FunctionTypeOf is able to obtain function types of properties.
class C { int value() @property; } static assert(is( typeof(C.value) == int )); static assert(is( FunctionTypeOf!(C.value) == function ));
Note:
Do not confuse function types with function pointer types; function types are usually used for compile-time reflection purposes. - template SetFunctionAttributes(T, string linkage, uint attrs) if (isFunctionPointer!T || isDelegate!T)
template SetFunctionAttributes(T, string linkage, uint attrs) if (is(T == function)) - Constructs a new function or delegate type with the same basic signature
as the given one, but different attributes (including linkage).
This is especially useful for adding/removing attributes to/from types in
generic code, where the actual type name cannot be spelt out.
Parameters:
Examples:T The base type. linkage The desired linkage of the result type. attrs The desired FunctionAttributes of the result type. template ExternC(T) if (isFunctionPointer!T || isDelegate!T || is(T == function)) { alias SetFunctionAttributes!(T, "C", functionAttributes!T) ExternC; }
auto assumePure(T)(T t) if (isFunctionPointer!T || isDelegate!T) { enum attrs = functionAttributes!T | FunctionAttribute.pure_; return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; }
- template isNested(T) if (is(T == class) || is(T == struct) || is(T == union))
- Determines whether T has its own context pointer. T must be either class, struct, or union.
- template hasNested(T)
- Determines whether T or any of its representation types have a context pointer.
- template FieldTypeTuple(T)
- Get as a typetuple the types of the fields of a struct, class, or union. This consists of the fields that take up memory space, excluding the hidden fields like the virtual function table pointer or a context pointer for nested types. If T isn't a struct, class, or union returns typetuple with one element T.
- template RepresentationTypeTuple(T)
- Get the primitive types of the fields of a struct or class, in
topological order.
Example:
struct S1 { int a; float b; } struct S2 { char[] a; union { S1 b; S1 * c; } } alias RepresentationTypeTuple!S2 R; assert(R.length == 4 && is(R[0] == char[]) && is(R[1] == int) && is(R[2] == float) && is(R[3] == S1*));
- template hasAliasing(T...)
- Returns true if and only if T's representation includes at
least one of the following:
- a raw pointer U* and U is not immutable;
- an array U[] and U is not immutable;
- a reference to a class or interface type C and C is not immutable.
- an associative array that is not immutable.
- a delegate.
- template hasIndirections(T)
- Returns true if and only if T's representation includes at
least one of the following:
- a raw pointer U*;
- an array U[];
- a reference to a class type C.
- an associative array.
- a delegate.
- template hasUnsharedAliasing(T...)
- Returns true if and only if T's representation includes at
least one of the following:
- a raw pointer U* and U is not immutable or shared;
- an array U[] and U is not immutable or shared;
- a reference to a class type C and C is not immutable or shared.
- an associative array that is not immutable or shared.
- a delegate that is not shared.
- template hasElaborateCopyConstructor(S)
- True if S or any type embedded directly in the representation of S defines an elaborate copy constructor. Elaborate copy constructors are introduced by defining this(this) for a struct. Classes and unions never have elaborate copy constructors.
- template hasElaborateAssign(S)
- True if S or any type directly embedded in the representation of S
defines an elaborate assignment. Elaborate assignments are introduced by
defining opAssign(typeof(this)) or opAssign(ref typeof(this))
for a struct or when there is a compiler-generated opAssign
(in case S has an elaborate copy constructor or destructor).
Classes and unions never have elaborate assignments.
Note:
Structs with (possibly nested) postblit operator(s) will have a hidden yet elaborate compiler generated assignement operator (unless explicitly disabled). - template hasElaborateDestructor(S)
- True if S or any type directly embedded in the representation of S defines an elaborate destructor. Elaborate destructors are introduced by defining ~this() for a struct. Classes and unions never have elaborate destructors, even though classes may define ~this().
- template hasMember(T, string name)
- Yields true if and only if T is an aggregate that defines a symbol called name.
- template EnumMembers(E) if (is(E == enum))
- Retrieves the members of an enumerated type enum E.
Parameters:
Returns:E An enumerated type. E may have duplicated values.
Static tuple composed of the members of the enumerated type E. The members are arranged in the same order as declared in E. Note:
An enum can have multiple members which have the same value. If you want to use EnumMembers to e.g. generate switch cases at compile-time, you should use the std.typetuple.NoDuplicates template to avoid generating duplicate switch cases. Note:
Returned values are strictly typed with E. Thus, the following code does not work without the explicit cast:enum E : int { a, b, c } int[] abc = cast(int[]) [ EnumMembers!E ];
Cast is not necessary if the type of the variable is inferred. See the example below. Examples:
Creating an array of enumerated values:enum Sqrts : real { one = 1, two = 1.41421, three = 1.73205, } auto sqrts = [ EnumMembers!Sqrts ]; assert(sqrts == [ Sqrts.one, Sqrts.two, Sqrts.three ]);
A generic function rank(v) in the following example uses this template for finding a member e in an enumerated type E.// Returns i if e is the i-th enumerator of E. size_t rank(E)(E e) if (is(E == enum)) { foreach (i, member; EnumMembers!E) { if (e == member) return i; } assert(0, "Not an enum member"); } enum Mode { read = 1, write = 2, map = 4, } assert(rank(Mode.read ) == 0); assert(rank(Mode.write) == 1); assert(rank(Mode.map ) == 2);
- template BaseTypeTuple(A)
- Get a TypeTuple of the base class and base interfaces of
this class or interface. BaseTypeTuple!Object returns
the empty type tuple.
Example:
import std.traits, std.typetuple, std.stdio; interface I { } class A { } class B : A, I { } void main() { alias BaseTypeTuple!B TL; writeln(typeid(TL)); // prints: (A,I) }
- template BaseClassesTuple(T) if (is(T == class))
- Get a TypeTuple of all base classes of this class,
in decreasing order. Interfaces are not included. BaseClassesTuple!Object yields the empty type tuple.
Example:
import std.traits, std.typetuple, std.stdio; interface I { } class A { } class B : A, I { } class C : B { } void main() { alias BaseClassesTuple!C TL; writeln(typeid(TL)); // prints: (B,A,Object) }
- template InterfacesTuple(T)
- Get a TypeTuple of all interfaces directly or
indirectly inherited by this class or interface. Interfaces do not
repeat if multiply implemented. InterfacesTuple!Object
yields the empty type tuple.
Example:
import std.traits, std.typetuple, std.stdio; interface I1 { } interface I2 { } class A : I1, I2 { } class B : A, I1 { } class C : B { } void main() { alias InterfacesTuple!C TL; writeln(typeid(TL)); // prints: (I1, I2) }
- template TransitiveBaseTypeTuple(T)
- Get a TypeTuple of all base classes of T, in decreasing order, followed by T's
interfaces. TransitiveBaseTypeTuple!Object yields the
empty type tuple.
Example:
import std.traits, std.typetuple, std.stdio; interface I { } class A { } class B : A, I { } class C : B { } void main() { alias TransitiveBaseTypeTuple!C TL; writeln(typeid(TL)); // prints: (B,A,Object,I) }
- template MemberFunctionsTuple(C, string name) if (is(C == class) || is(C == interface))
- Returns a tuple of non-static functions with the name name declared in the
class or interface C. Covariant duplicates are shrunk into the most
derived one.
Example:
interface I { I foo(); } class B { real foo(real v) { return v; } } class C : B, I { override C foo() { return this; } // covariant overriding of I.foo() } alias MemberFunctionsTuple!(C, "foo") foos; static assert(foos.length == 2); static assert(__traits(isSame, foos[0], C.foo)); static assert(__traits(isSame, foos[1], B.foo));
- template classInstanceAlignment(T) if (is(T == class))
- Returns class instance alignment.
Examples:
class A { byte b; } class B { long l; } // As class instance always has a hidden pointer static assert(classInstanceAlignment!A == (void*).alignof); static assert(classInstanceAlignment!B == long.alignof);
- template CommonType(T...)
- Get the type that all types can be implicitly converted to. Useful
e.g. in figuring out an array type from a bunch of initializing
values. Returns void if passed an empty list, or if the
types have no common type.
Examples:
alias X = CommonType!(int, long, short); assert(is(X == long)); alias Y = CommonType!(int, char[], short); assert(is(Y == void));
- template ImplicitConversionTargets(T)
- Returns a tuple with all possible target types of an implicit conversion of a value of type T. Important note: The possible targets are computed more conservatively than the D 2.005 compiler does, eliminating all dangerous conversions. For example, ImplicitConversionTargets!double does not include float.
- template isImplicitlyConvertible(From, To)
- Is From implicitly convertible to To?
- template isCovariantWith(F, G) if (is(F == function) && is(G == function))
- Determines whether the function type F is covariant with G, i.e.,
functions of the type F can override ones of the type G.
Example:
interface I { I clone(); } interface J { J clone(); } class C : I { override C clone() // covariant overriding of I.clone() { return new C; } } // C.clone() can override I.clone(), indeed. static assert(isCovariantWith!(typeof(C.clone), typeof(I.clone))); // C.clone() can't override J.clone(); the return type C is not implicitly // convertible to J. static assert(isCovariantWith!(typeof(C.clone), typeof(J.clone)));
- T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init); - Creates an lvalue or rvalue of type T for typeof(...) and
_traits(compiles, ...) purposes. No actual value is returned.
Note:
Trying to use returned value will result in a "Symbol Undefined" error at link time. Examples:// Note that `f` doesn't have to be implemented // as is isn't called. int f(int); bool f(ref int); static assert(is(typeof(f(rvalueOf!int)) == int)); static assert(is(typeof(f(lvalueOf!int)) == bool)); int i = rvalueOf!int; // error, no actual value is returned
- template isBoolean(T)
- Detect whether T is a built-in boolean type.
- template isIntegral(T)
- Detect whether T is a built-in integral type. Types bool, char, wchar, and dchar are not considered integral.
- template isFloatingPoint(T)
- Detect whether T is a built-in floating point type.
- template isNumeric(T)
- Detect whether T is a built-in numeric type (integral or floating point).
- template isScalarType(T)
- Detect whether T is a scalar type.
- template isBasicType(T)
- Detect whether T is a basic type.
- template isUnsigned(T)
- Detect whether T is a built-in unsigned numeric type.
- template isSigned(T)
- Detect whether T is a built-in signed numeric type.
- template isSomeChar(T)
- Detect whether T is one of the built-in character types.
- template isSomeString(T)
- Detect whether T is one of the built-in string types.
- template isStaticArray(T)
- Detect whether type T is a static array.
- template isDynamicArray(T)
- Detect whether type T is a dynamic array.
- template isArray(T)
- Detect whether type T is an array.
- template isAssociativeArray(T)
- Detect whether T is an associative array type
- template isPointer(T)
- Detect whether type T is a pointer.
- template PointerTarget(T : T*)
- Returns the target type of a pointer.
- alias pointerTarget = PointerTarget(T : T*);
- Scheduled for deprecation. Please use PointerTarget instead.
- template isAggregateType(T)
- Detect whether type T is an aggregate type.
- template isIterable(T)
- Returns true if T can be iterated over using a foreach loop with a single loop variable of automatically inferred type, regardless of how the foreach loop is implemented. This includes ranges, structs/classes that define opApply with a single loop variable, and builtin dynamic, static and associative arrays.
- template isMutable(T)
- Returns true if T is not const or immutable. Note that isMutable is true for string, or immutable(char)[], because the 'head' is mutable.
- template isInstanceOf(alias S, T)
- Returns true if T is an instance of the template S.
- template isExpressionTuple(T...)
- Tells whether the tuple T is an expression tuple.
- template isTypeTuple(T...)
- Detect whether tuple T is a type tuple.
- template isFunctionPointer(T...) if (T.length == 1)
- Detect whether symbol or type T is a function pointer.
- template isDelegate(T...) if (T.length == 1)
- Detect whether symbol or type T is a delegate.
- template isSomeFunction(T...) if (T.length == 1)
- Detect whether symbol or type T is a function, a function pointer or a delegate.
- template isCallable(T...) if (T.length == 1)
- Detect whether T is a callable object, which can be called with the function call operator (...).
- template isAbstractFunction(T...) if (T.length == 1)
- Detect whether T is a an abstract function.
- template isFinalFunction(T...) if (T.length == 1)
- Detect whether T is a a final function.
- template isNestedFunction(alias f)
- Determines whether function f requires a context pointer.
- template isAbstractClass(T...) if (T.length == 1)
- Detect whether T is a an abstract class.
- template isFinalClass(T...) if (T.length == 1)
- Detect whether T is a a final class.
- template Unqual(T)
- Removes all qualifiers, if any, from type T.
Example:
static assert(is(Unqual!int == int)); static assert(is(Unqual!(const int) == int)); static assert(is(Unqual!(immutable int) == int)); static assert(is(Unqual!(shared int) == int)); static assert(is(Unqual!(shared(const int)) == int));
- template ForeachType(T)
- Returns the inferred type of the loop variable when a variable of type T is iterated over using a foreach loop with a single loop variable and automatically inferred return type. Note that this may not be the same as std.range.ElementType!Range in the case of narrow strings, or if T has both opApply and a range interface.
- template OriginalType(T)
- Strips off all typedefs (including enum ones) from type T.
Example:
enum E : int { a } typedef E F; typedef const F G; static assert(is(OriginalType!G == const int));
- template KeyType(V : V[K], K)
- Get the Key type of an Associative Array.
Examples:
import std.traits; alias Hash = int[string]; static assert(is(KeyType!Hash == string)); static assert(is(ValueType!Hash == int)); KeyType!Hash str = "a"; // str is declared as string ValueType!Hash num = 1; // num is declared as int
- template ValueType(V : V[K], K)
- Get the Value type of an Associative Array.
Examples:
import std.traits; alias Hash = int[string]; static assert(is(KeyType!Hash == string)); static assert(is(ValueType!Hash == int)); KeyType!Hash str = "a"; // str is declared as string ValueType!Hash num = 1; // num is declared as int
- template Unsigned(T)
- Returns the corresponding unsigned type for T. T must be a numeric integral type, otherwise a compile-time error occurs.
- template Largest(T...) if (T.length >= 1)
- Returns the largest type, i.e. T such that T.sizeof is the largest. If more than one type is of the same size, the leftmost argument of these in will be returned.
- template Signed(T)
- Returns the corresponding signed type for T. T must be a numeric integral type, otherwise a compile-time error occurs.
- template mostNegative(T) if (isNumeric!T || isSomeChar!T || isBoolean!T)
- Returns the most negative value of the numeric type T.
- template mangledName(sth...) if (sth.length == 1)
- Returns the mangled name of symbol or type sth.
mangledName is the same as builtin .mangleof property, except that
the correct names of property functions are obtained.
module test; import std.traits : mangledName; class C { int value() @property; } pragma(msg, C.value.mangleof); // prints "i" pragma(msg, mangledName!(C.value)); // prints "_D4test1C5valueMFNdZi"
- template Select(bool condition, T...) if (T.length == 2)
- Aliases itself to T[0] if the boolean condition is true
and to T[1] otherwise.
Examples:
// can select types static assert(is(Select!(true, int, long) == int)); static assert(is(Select!(false, int, long) == long)); // can select symbols int a = 1; int b = 2; alias selA = Select!(true, a, b); alias selB = Select!(false, a, b); assert(selA == 1); assert(selB == 2);
- A select(bool cond : true, A, B)(A a, lazy B b);
B select(bool cond : false, A, B)(lazy A a, B b); - If cond is true, returns a without evaluating b. Otherwise, returns b without evaluating a.