Templates which extract information about types and symbols at compile time.
isExpressions
), Andrei Alexandrescu, Shin Fujishiro, Robert Clipsham, David Nadlinger, Kenji Hara, Shoichi Kato Add the inout qualifier to the given type T.
Add the const qualifier to the given type T.
Add the shared qualifier to the given type T.
Add the shared and inout qualifiers to the given type T.
Add the shared and const qualifiers to the given type T.
Add the immutable qualifier to the given type T.
Get qualifier template from the given type T
Get the full package name for the given symbol.
Get the module name (including package) for the given symbol.
Get the fully qualified name of a type or a symbol. Can act as an intelligent type/symbol to string converter.
module myModule; struct MyStruct {} static assert(fullyQualifiedName!(const MyStruct[]) == "const(myModule.MyStruct[])");
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
).
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
.
Alternate name for Parameters
, kept for legacy compatibility.
Returns the number of arguments of function func
. arity
is undefined for variadic functions.
Get tuple, one per function parameter, of the storage classes of the parameters.
func | function symbol or type of function, delegate, or pointer to function |
ParameterStorageClass
bitsalias STC = ParameterStorageClass; // shorten the enum name void func(ref int ctx, out real result, real param) { } alias pstc = ParameterStorageClassTuple!func; 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);
These flags can be bitwise OR-ed together to represent complex storage class.
Convert string tuple Attribs to ParameterStorageClass bits
Attribs | string tuple |
Get, as a tuple, the identifiers of the parameters to a function symbol.
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.
Alternate name for ParameterDefaults
, kept for legacy compatibility.
Returns the FunctionAttribute
mask for function func
.
hasFunctionAttributes
import std.traits : functionAttributes, FunctionAttribute; alias FA = FunctionAttribute; // 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
These flags can be bitwise OR-ed together to represent a complex attribute.
Checks whether a function has the given attributes attached.
args | Function to check, followed by a variadic number of function attributes as strings |
true
, if the function has the list of attributes attached and false
otherwise. functionAttributes
real func(real x) pure nothrow @safe; static assert(hasFunctionAttributes!(func, "@safe", "pure")); static assert(!hasFunctionAttributes!(func, "@trusted")); // for templates attributes are automatically inferred bool myFunc(T)(T b) { return !b; } static assert(hasFunctionAttributes!(myFunc!bool, "@safe", "pure", "@nogc", "nothrow")); static assert(!hasFunctionAttributes!(myFunc!bool, "shared"));
true
if func
is @safe
or @trusted
.
true
if func
is @system
.
Determine the linkage attribute of the function.
func | the function symbol, or the type of a function, delegate, or pointer to function |
Determines what kind of variadic parameters function has.
func | function symbol or type of function, delegate, or pointer to function |
Variadic
void func() {} static assert(variadicFunctionStyle!func == Variadic.no); extern(C) int printf(in char*, ...); static assert(variadicFunctionStyle!printf == Variadic.c);
Function is not variadic.
Function is a C-style variadic function, which uses
core.stdc.stdarg Function is a D-style variadic function, which uses
_argptr and _arguments.
Function is a typesafe
variadic function.
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.
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.
T | The base type. |
linkage | The desired linkage of the result type. |
attrs | The desired FunctionAttribute s of the result type. |
Determines whether T
is a class nested inside another class and that T.outer
is the implicit reference to the outer class (i.e. outer
has not been used as a field or method name)
T | type to test |
true
if T
is a class nested inside another, with the conditions described above; false
otherwiseclass C { int outer; } static assert(!isInnerClass!C); class Outer1 { class Inner1 { } class Inner2 { int outer; } } static assert(isInnerClass!(Outer1.Inner1)); static assert(!isInnerClass!(Outer1.Inner2)); static class Outer2 { static class Inner { int outer; } } static assert(!isInnerClass!(Outer2.Inner));
Determines whether T
has its own context pointer. T
must be either class
, struct
, or union
.
Determines whether T
or any of its representation types have a context pointer.
Get as a tuple 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 a tuple with one element T
.
Alternate name for Fields
, kept for legacy compatibility.
Get as an expression tuple the names 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 an expression tuple with an empty string.
Get the primitive types of the fields of a struct or class, in topological order.
Returns true
if and only if T
's representation includes at least one of the following:
U*
and U
is not immutable;U[]
and U
is not immutable;C
and C
is not immutable.Returns true
if and only if T
's representation includes at least one of the following:
U*
;U[]
;C
.static assert( hasIndirections!(int[string])); static assert( hasIndirections!(void delegate())); static assert( hasIndirections!(void delegate() immutable)); static assert( hasIndirections!(immutable(void delegate()))); static assert( hasIndirections!(immutable(void delegate() immutable))); static assert(!hasIndirections!(void function())); static assert( hasIndirections!(void*[1])); static assert(!hasIndirections!(byte[1]));
Returns true
if and only if T
's representation includes at least one of the following:
U*
and U
is not immutable or shared;U[]
and U
is not immutable or shared;C
and C
is not immutable or shared.struct S1 { int a; Object b; } struct S2 { string a; } struct S3 { int a; immutable Object b; } static assert( hasUnsharedAliasing!S1); static assert(!hasUnsharedAliasing!S2); static assert(!hasUnsharedAliasing!S3); struct S4 { int a; shared Object b; } struct S5 { char[] a; } struct S6 { shared char[] b; } struct S7 { float[3] vals; } static assert(!hasUnsharedAliasing!S4); static assert( hasUnsharedAliasing!S5); static assert(!hasUnsharedAliasing!S6); static assert(!hasUnsharedAliasing!S7);
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.
static assert(!hasElaborateCopyConstructor!int); static struct S1 { } static struct S2 { this(this) {} } static struct S3 { S2 field; } static struct S4 { S3[1] field; } static struct S5 { S3[] field; } static struct S6 { S3[0] field; } static struct S7 { @disable this(); S3 field; } static assert(!hasElaborateCopyConstructor!S1); static assert( hasElaborateCopyConstructor!S2); static assert( hasElaborateCopyConstructor!(immutable S2)); static assert( hasElaborateCopyConstructor!S3); static assert( hasElaborateCopyConstructor!(S3[1])); static assert(!hasElaborateCopyConstructor!(S3[0])); static assert( hasElaborateCopyConstructor!S4); static assert(!hasElaborateCopyConstructor!S5); static assert(!hasElaborateCopyConstructor!S6); static assert( hasElaborateCopyConstructor!S7);
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
.
A type S
gets compiler-generated opAssign
in case it has an elaborate copy constructor or elaborate destructor.
Classes and unions never have elaborate assignments.
static assert(!hasElaborateAssign!int); static struct S { void opAssign(S) {} } static assert( hasElaborateAssign!S); static assert(!hasElaborateAssign!(const(S))); static struct S1 { void opAssign(ref S1) {} } static struct S2 { void opAssign(int) {} } static struct S3 { S s; } static assert( hasElaborateAssign!S1); static assert(!hasElaborateAssign!S2); static assert( hasElaborateAssign!S3); static assert( hasElaborateAssign!(S3[1])); static assert(!hasElaborateAssign!(S3[0]));
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()
.
static assert(!hasElaborateDestructor!int); static struct S1 { } static struct S2 { ~this() {} } static struct S3 { S2 field; } static struct S4 { S3[1] field; } static struct S5 { S3[] field; } static struct S6 { S3[0] field; } static struct S7 { @disable this(); S3 field; } static assert(!hasElaborateDestructor!S1); static assert( hasElaborateDestructor!S2); static assert( hasElaborateDestructor!(immutable S2)); static assert( hasElaborateDestructor!S3); static assert( hasElaborateDestructor!(S3[1])); static assert(!hasElaborateDestructor!(S3[0])); static assert( hasElaborateDestructor!S4); static assert(!hasElaborateDestructor!S5); static assert(!hasElaborateDestructor!S6); static assert( hasElaborateDestructor!S7);
Yields true
if and only if T
is an aggregate that defines a symbol called name
.
static assert(!hasMember!(int, "blah")); struct S1 { int blah; } struct S2 { int blah(){ return 0; } } class C1 { int blah; } class C2 { int blah(){ return 0; } } static assert(hasMember!(S1, "blah")); static assert(hasMember!(S2, "blah")); static assert(hasMember!(C1, "blah")); static assert(hasMember!(C2, "blah"));
Whether the symbol represented by the string, member, exists and is a static member of T.
T | Type containing symbol member . |
member | Name of symbol to test that resides in T . |
true
iff member
exists and is static.Retrieves the members of an enumerated type enum E
.
E | An enumerated type. E may have duplicated values. |
E
. The members are arranged in the same order as declared in E
. EnumMembers
to e.g. generate switch cases at compile-time, you should use the std.meta.NoDuplicates
template to avoid generating duplicate switch cases. 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.
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);
Get a AliasSeq of the base class and base interfaces of this class or interface. BaseTypeTuple
!Object returns the empty type tuple.
Get a AliasSeq of all base classes of this class, in decreasing order. Interfaces are not included. BaseClassesTuple
!Object yields the empty type tuple.
class C1 { } class C2 : C1 { } class C3 : C2 { } static assert(!BaseClassesTuple!Object.length); static assert(is(BaseClassesTuple!C1 == AliasSeq!(Object))); static assert(is(BaseClassesTuple!C2 == AliasSeq!(C1, Object))); static assert(is(BaseClassesTuple!C3 == AliasSeq!(C2, C1, Object)));
Get a AliasSeq 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.
Get a AliasSeq of all base classes of T, in decreasing order, followed by T's interfaces. TransitiveBaseTypeTuple
!Object yields the empty type tuple.
interface J1 {} interface J2 {} class B1 {} class B2 : B1, J1, J2 {} class B3 : B2, J1 {} alias TL = TransitiveBaseTypeTuple!B3; writeln(TL.length); // 5 assert(is (TL[0] == B2)); assert(is (TL[1] == B1)); assert(is (TL[2] == Object)); assert(is (TL[3] == J1)); assert(is (TL[4] == J2)); writeln(TransitiveBaseTypeTuple!Object.length); // 0
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.
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 foos = MemberFunctionsTuple!(C, "foo"); static assert(foos.length == 2); static assert(__traits(isSame, foos[0], C.foo)); static assert(__traits(isSame, foos[1], B.foo));
Returns an alias to the template that T
is an instance of.
Returns a AliasSeq
of the template arguments used to instantiate T
.
Returns class instance alignment.
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.
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.
Is From
implicitly convertible to To
?
static assert( isImplicitlyConvertible!(immutable(char), char)); static assert( isImplicitlyConvertible!(const(char), char)); static assert( isImplicitlyConvertible!(char, wchar)); static assert(!isImplicitlyConvertible!(wchar, char)); static assert(!isImplicitlyConvertible!(const(ushort), ubyte)); static assert(!isImplicitlyConvertible!(const(uint), ubyte)); static assert(!isImplicitlyConvertible!(const(ulong), ubyte)); static assert(!isImplicitlyConvertible!(const(char)[], string)); static assert( isImplicitlyConvertible!(string, const(char)[]));
Returns true
iff a value of type Rhs
can be assigned to a variable of type Lhs
.
isAssignable
returns whether both an lvalue and rvalue can be assigned.
If you omit Rhs
, isAssignable
will check identity assignable of Lhs
.
static assert( isAssignable!(long, int)); static assert(!isAssignable!(int, long)); static assert( isAssignable!(const(char)[], string)); static assert(!isAssignable!(string, char[])); // int is assignable to int static assert( isAssignable!int); // immutable int is not assignable to immutable int static assert(!isAssignable!(immutable int));
Determines whether the function type F
is covariant with G
, i.e., functions of the type F
can override ones of the type G
.
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)));
Creates an lvalue or rvalue of type T
for typeof(...)
and _traits(compiles, ...)
purposes. No actual value is returned.
// 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
Detect whether T
is a built-in boolean type.
Detect whether T
is a built-in integral type. Types bool
, char
, wchar
, and dchar
are not considered integral.
static assert( isIntegral!byte && isIntegral!short && isIntegral!int && isIntegral!long && isIntegral!(const(long)) && isIntegral!(immutable(long)) ); static assert( !isIntegral!bool && !isIntegral!char && !isIntegral!double ); // types which act as integral values do not pass struct S { int val; alias val this; } static assert(!isIntegral!S);
Detect whether T
is a built-in floating point type.
static assert( isFloatingPoint!float && isFloatingPoint!double && isFloatingPoint!real && isFloatingPoint!(const(real)) && isFloatingPoint!(immutable(real)) ); static assert(!isFloatingPoint!int); // complex and imaginary numbers do not pass static assert( !isFloatingPoint!cfloat && !isFloatingPoint!ifloat ); // types which act as floating point values do not pass struct S { float val; alias val this; } static assert(!isFloatingPoint!S);
Detect whether T
is a built-in numeric type (integral or floating point).
static assert( isNumeric!byte && isNumeric!short && isNumeric!int && isNumeric!long && isNumeric!float && isNumeric!double && isNumeric!real && isNumeric!(const(real)) && isNumeric!(immutable(real)) ); static assert( !isNumeric!void && !isNumeric!bool && !isNumeric!char && !isNumeric!wchar && !isNumeric!dchar ); // types which act as numeric values do not pass struct S { int val; alias val this; } static assert(!isIntegral!S);
Detect whether T
is a scalar type (a built-in numeric, character or boolean type).
static assert(!isScalarType!void); static assert( isScalarType!(immutable(byte))); static assert( isScalarType!(immutable(ushort))); static assert( isScalarType!(immutable(int))); static assert( isScalarType!(ulong)); static assert( isScalarType!(shared(float))); static assert( isScalarType!(shared(const bool))); static assert( isScalarType!(const(char))); static assert( isScalarType!(wchar)); static assert( isScalarType!(const(dchar))); static assert( isScalarType!(const(double))); static assert( isScalarType!(const(real)));
Detect whether T
is a basic type (scalar type or void).
static assert(isBasicType!void); static assert(isBasicType!(const(void))); static assert(isBasicType!(shared(void))); static assert(isBasicType!(immutable(void))); static assert(isBasicType!(shared const(void))); static assert(isBasicType!(shared inout(void))); static assert(isBasicType!(shared inout const(void))); static assert(isBasicType!(inout(void))); static assert(isBasicType!(inout const(void))); static assert(isBasicType!(immutable(int))); static assert(isBasicType!(shared(float))); static assert(isBasicType!(shared(const bool))); static assert(isBasicType!(const(dchar)));
Detect whether T
is a built-in unsigned numeric type.
Detect whether T
is a built-in signed numeric type.
Detect whether T
is one of the built-in character types.
The built-in char types are any of char
, wchar
or dchar
, with or without qualifiers.
//Char types static assert( isSomeChar!char); static assert( isSomeChar!wchar); static assert( isSomeChar!dchar); static assert( isSomeChar!(typeof('c'))); static assert( isSomeChar!(immutable char)); static assert( isSomeChar!(const dchar)); //Non char types static assert(!isSomeChar!int); static assert(!isSomeChar!byte); static assert(!isSomeChar!string); static assert(!isSomeChar!wstring); static assert(!isSomeChar!dstring); static assert(!isSomeChar!(char[4]));
Detect whether T
is one of the built-in string types.
The built-in string types are Char[]
, where Char
is any of char
, wchar
or dchar
, with or without qualifiers.
Static arrays of characters (like char[80]
) are not considered built-in string types.
//String types static assert( isSomeString!string); static assert( isSomeString!(wchar[])); static assert( isSomeString!(dchar[])); static assert( isSomeString!(typeof("aaa"))); static assert( isSomeString!(const(char)[])); enum ES : string { a = "aaa", b = "bbb" } static assert( isSomeString!ES); //Non string types static assert(!isSomeString!int); static assert(!isSomeString!(int[])); static assert(!isSomeString!(byte[])); static assert(!isSomeString!(typeof(null))); static assert(!isSomeString!(char[4]));
Detect whether type T
is a narrow string.
All arrays that use char, wchar, and their qualified versions are narrow strings. (Those include string and wstring).
Detects whether T
is a comparable type. Basic types and structs and classes that implement opCmp are ordering comparable.
static assert(isOrderingComparable!int); static assert(isOrderingComparable!string); static assert(!isOrderingComparable!creal); static struct Foo {} static assert(!isOrderingComparable!Foo); static struct Bar { int a; auto opCmp(Bar b1) const { return a - b1.a; } } Bar b1 = Bar(5); Bar b2 = Bar(7); assert(isOrderingComparable!Bar && b2 > b1);
Detect whether T
is a struct, static array, or enum that is implicitly convertible to a string.
static struct AliasedString { string s; alias s this; } enum StringEnum { a = "foo" } assert(!isConvertibleToString!string); assert(isConvertibleToString!AliasedString); assert(isConvertibleToString!StringEnum); assert(isConvertibleToString!(char[25])); assert(!isConvertibleToString!(char[]));
Detect whether type T
is a string that will be autodecoded.
All arrays that use char, wchar, and their qualified versions are narrow strings. (Those include string and wstring). Aggregates that implicitly cast to narrow strings are included.
T | type to be tested |
true
if T represents a string that is subject to autodecoding See Also: isNarrowString
Detect whether type T
is a static array.
static assert( isStaticArray!(int[3])); static assert( isStaticArray!(const(int)[5])); static assert( isStaticArray!(const(int)[][5])); static assert(!isStaticArray!(const(int)[])); static assert(!isStaticArray!(immutable(int)[])); static assert(!isStaticArray!(const(int)[4][])); static assert(!isStaticArray!(int[])); static assert(!isStaticArray!(int[char])); static assert(!isStaticArray!(int[1][])); static assert(!isStaticArray!(int[int])); static assert(!isStaticArray!int);
Detect whether type T
is a dynamic array.
Detect whether type T
is an array (static or dynamic; for associative arrays see isAssociativeArray
).
Detect whether T
is an associative array type
Detect whether type T
is a builtin type.
class C; union U; struct S; interface I; static assert( isBuiltinType!void); static assert( isBuiltinType!string); static assert( isBuiltinType!(int[])); static assert( isBuiltinType!(C[string])); static assert(!isBuiltinType!C); static assert(!isBuiltinType!U); static assert(!isBuiltinType!S); static assert(!isBuiltinType!I); static assert(!isBuiltinType!(void delegate(int)));
Detect whether type T
is a SIMD vector type.
Detect whether type T
is a pointer.
Returns the target type of a pointer.
Detect whether type T
is an aggregate type.
class C; union U; struct S; interface I; static assert( isAggregateType!C); static assert( isAggregateType!U); static assert( isAggregateType!S); static assert( isAggregateType!I); static assert(!isAggregateType!void); static assert(!isAggregateType!string); static assert(!isAggregateType!(int[])); static assert(!isAggregateType!(C[string])); static assert(!isAggregateType!(void delegate(int)));
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.
struct OpApply { int opApply(scope int delegate(ref uint) dg) { assert(0); } } struct Range { @property uint front() { assert(0); } void popFront() { assert(0); } enum bool empty = false; } static assert( isIterable!(uint[])); static assert( isIterable!OpApply); static assert( isIterable!(uint[string])); static assert( isIterable!Range); static assert(!isIterable!uint);
Returns true
if T is not const or immutable. Note that isMutable
is true
for string, or immutable(char)[], because the 'head' is mutable.
static assert( isMutable!int); static assert( isMutable!string); static assert( isMutable!(shared int)); static assert( isMutable!(shared const(int)[])); static assert(!isMutable!(const int)); static assert(!isMutable!(inout int)); static assert(!isMutable!(shared(const int))); static assert(!isMutable!(shared(inout int))); static assert(!isMutable!(immutable string));
Returns true
if T is an instance of the template S.
static struct Foo(T...) { } static struct Bar(T...) { } static struct Doo(T) { } static struct ABC(int x) { } static void fun(T)() { } template templ(T) { } static assert(isInstanceOf!(Foo, Foo!int)); static assert(!isInstanceOf!(Foo, Bar!int)); static assert(!isInstanceOf!(Foo, int)); static assert(isInstanceOf!(Doo, Doo!int)); static assert(isInstanceOf!(ABC, ABC!1)); static assert(!isInstanceOf!(Foo, Foo)); static assert(isInstanceOf!(fun, fun!int)); static assert(isInstanceOf!(templ, templ!int));
Check whether the tuple T is an expression tuple. An expression tuple only contains expressions.
isTypeTuple
.Alternate name for isExpressions
, kept for legacy compatibility.
Check whether the tuple T
is a type tuple. A type tuple only contains types.
isExpressions
.Detect whether symbol or type T
is a function pointer.
static void foo() {} void bar() {} auto fpfoo = &foo; static assert( isFunctionPointer!fpfoo); static assert( isFunctionPointer!(void function())); auto dgbar = &bar; static assert(!isFunctionPointer!dgbar); static assert(!isFunctionPointer!(void delegate())); static assert(!isFunctionPointer!foo); static assert(!isFunctionPointer!bar); static assert( isFunctionPointer!((int a) {}));
Detect whether symbol or type T
is a delegate.
Detect whether symbol or type T
is a function, a function pointer or a delegate.
Detect whether T
is a callable object, which can be called with the function call operator (...)
.
interface I { real value() @property; } struct S { static int opCall(int) { return 0; } } class C { int opCall(int) { return 0; } } auto c = new C; static assert( isCallable!c); static assert( isCallable!S); static assert( isCallable!(c.opCall)); static assert( isCallable!(I.value)); static assert( isCallable!((int a) { return a; })); static assert(!isCallable!I);
Detect whether T
is an abstract function.
Detect whether T
is a final function.
struct S { void bar() { } } final class FC { void foo(); } class C { void bar() { } final void foo(); } static assert(!isFinalFunction!(int)); static assert(!isFinalFunction!(S.bar)); static assert( isFinalFunction!(FC.foo)); static assert(!isFinalFunction!(C.bar)); static assert( isFinalFunction!(C.foo));
Determines whether function f
requires a context pointer.
Detect whether T
is an abstract class.
Detect whether T
is a final class.
class C { } abstract class AC { } final class FC1 : C { } final class FC2 { } static assert(!isFinalClass!C); static assert(!isFinalClass!AC); static assert( isFinalClass!FC1); static assert( isFinalClass!FC2); C c; static assert(!isFinalClass!c); FC1 fc1; static assert( isFinalClass!fc1);
Removes all qualifiers, if any, from type T
.
Copies type qualifiers from FromType
to ToType
.
Supported type qualifiers:
const
inout
immutable
shared
Returns the type of Target
with the "constness" of Source
. A type's constness refers to whether it is const
, immutable
, or inout
. If source
has no constness, the returned type will be the same as Target
.
const(int) i; CopyConstness!(typeof(i), float) f; assert( is(typeof(f) == const float)); CopyConstness!(char, uint) u; assert( is(typeof(u) == uint)); //The 'shared' qualifier will not be copied assert(!is(CopyConstness!(shared bool, int) == shared int)); //But the constness will be assert( is(CopyConstness!(shared const real, double) == const double)); //Careful, const(int)[] is a mutable array of const(int) alias MutT = CopyConstness!(const(int)[], int); assert(!is(MutT == const(int))); //Okay, const(int[]) applies to array and contained ints alias CstT = CopyConstness!(const(int[]), int); assert( is(CstT == const(int)));
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.
Strips off all enum
s from type T
.
Get the Key type of an Associative Array.
Get the Value type of an Associative Array.
Returns the corresponding unsigned type for T. T must be a numeric integral type, otherwise a compile-time error occurs.
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.
static assert(is(Largest!(uint, ubyte, ushort, real) == real)); static assert(is(Largest!(ulong, double) == ulong)); static assert(is(Largest!(double, ulong) == double)); static assert(is(Largest!(uint, byte, double, short) == double)); static if (is(ucent)) static assert(is(Largest!(uint, ubyte, ucent, ushort) == ucent));
Returns the corresponding signed type for T. T must be a numeric integral type, otherwise a compile-time error occurs.
Returns the most negative value of the numeric type T.
Get the type that a scalar type T
will promote to in multi-term arithmetic expressions.
Returns the mangled name of symbol or type sth
.
mangledName
is the same as builtin .mangleof
property, but might be more convenient in generic code, e.g. as a template argument when invoking staticMap.
Aliases itself to T[0]
if the boolean condition
is true
and to T[1]
otherwise.
// can select types static assert(is(Select!(true, int, long) == int)); static assert(is(Select!(false, int, long) == long)); static struct Foo {} static assert(is(Select!(false, const(int), const(Foo)) == const(Foo))); // can select symbols int a = 1; int b = 2; alias selA = Select!(true, a, b); alias selB = Select!(false, a, b); writeln(selA); // 1 writeln(selB); // 2 // can select (compile-time) expressions enum val = Select!(false, -4, 9 - 6); static assert(val == 3);
If cond
is true
, returns a
without evaluating b
. Otherwise, returns b
without evaluating a
.
Determine if a symbol has a given user-defined attribute.
getUDAs
enum E; struct S {} @("alpha") int a; static assert(hasUDA!(a, "alpha")); static assert(!hasUDA!(a, S)); static assert(!hasUDA!(a, E)); @(E) int b; static assert(!hasUDA!(b, "alpha")); static assert(!hasUDA!(b, S)); static assert(hasUDA!(b, E)); @E int c; static assert(!hasUDA!(c, "alpha")); static assert(!hasUDA!(c, S)); static assert(hasUDA!(c, E)); @(S, E) int d; static assert(!hasUDA!(d, "alpha")); static assert(hasUDA!(d, S)); static assert(hasUDA!(d, E)); @S int e; static assert(!hasUDA!(e, "alpha")); static assert(hasUDA!(e, S)); static assert(!hasUDA!(e, S())); static assert(!hasUDA!(e, E)); @S() int f; static assert(!hasUDA!(f, "alpha")); static assert(hasUDA!(f, S)); static assert(hasUDA!(f, S())); static assert(!hasUDA!(f, E)); @(S, E, "alpha") int g; static assert(hasUDA!(g, "alpha")); static assert(hasUDA!(g, S)); static assert(hasUDA!(g, E)); @(100) int h; static assert(hasUDA!(h, 100)); struct Named { string name; } @Named("abc") int i; static assert(hasUDA!(i, Named)); static assert(hasUDA!(i, Named("abc"))); static assert(!hasUDA!(i, Named("def"))); struct AttrT(T) { string name; T value; } @AttrT!int("answer", 42) int j; static assert(hasUDA!(j, AttrT)); static assert(hasUDA!(j, AttrT!int)); static assert(!hasUDA!(j, AttrT!string)); @AttrT!string("hello", "world") int k; static assert(hasUDA!(k, AttrT)); static assert(!hasUDA!(k, AttrT!int)); static assert(hasUDA!(k, AttrT!string)); struct FuncAttr(alias f) { alias func = f; } static int fourtyTwo() { return 42; } static size_t getLen(string s) { return s.length; } @FuncAttr!getLen int l; static assert(hasUDA!(l, FuncAttr)); static assert(!hasUDA!(l, FuncAttr!fourtyTwo)); static assert(hasUDA!(l, FuncAttr!getLen)); static assert(!hasUDA!(l, FuncAttr!fourtyTwo())); static assert(!hasUDA!(l, FuncAttr!getLen())); @FuncAttr!getLen() int m; static assert(hasUDA!(m, FuncAttr)); static assert(!hasUDA!(m, FuncAttr!fourtyTwo)); static assert(hasUDA!(m, FuncAttr!getLen)); static assert(!hasUDA!(m, FuncAttr!fourtyTwo())); static assert(hasUDA!(m, FuncAttr!getLen()));
Gets the matching user-defined attributes from the given symbol.
If the UDA is a type, then any UDAs of the same type on the symbol will match. If the UDA is a template for a type, then any UDA which is an instantiation of that template will match. And if the UDA is a value, then any UDAs on the symbol which are equal to that value will match.
hasUDA
struct Attr { string name; int value; } @Attr("Answer", 42) int a; static assert(getUDAs!(a, Attr).length == 1); static assert(getUDAs!(a, Attr)[0].name == "Answer"); static assert(getUDAs!(a, Attr)[0].value == 42); @(Attr("Answer", 42), "string", 9999) int b; static assert(getUDAs!(b, Attr).length == 1); static assert(getUDAs!(b, Attr)[0].name == "Answer"); static assert(getUDAs!(b, Attr)[0].value == 42); @Attr("Answer", 42) @Attr("Pi", 3) int c; static assert(getUDAs!(c, Attr).length == 2); static assert(getUDAs!(c, Attr)[0].name == "Answer"); static assert(getUDAs!(c, Attr)[0].value == 42); static assert(getUDAs!(c, Attr)[1].name == "Pi"); static assert(getUDAs!(c, Attr)[1].value == 3); static assert(getUDAs!(c, Attr("Answer", 42)).length == 1); static assert(getUDAs!(c, Attr("Answer", 42))[0].name == "Answer"); static assert(getUDAs!(c, Attr("Answer", 42))[0].value == 42); static assert(getUDAs!(c, Attr("Answer", 99)).length == 0); struct AttrT(T) { string name; T value; } @AttrT!uint("Answer", 42) @AttrT!int("Pi", 3) @AttrT int d; static assert(getUDAs!(d, AttrT).length == 2); static assert(getUDAs!(d, AttrT)[0].name == "Answer"); static assert(getUDAs!(d, AttrT)[0].value == 42); static assert(getUDAs!(d, AttrT)[1].name == "Pi"); static assert(getUDAs!(d, AttrT)[1].value == 3); static assert(getUDAs!(d, AttrT!uint).length == 1); static assert(getUDAs!(d, AttrT!uint)[0].name == "Answer"); static assert(getUDAs!(d, AttrT!uint)[0].value == 42); static assert(getUDAs!(d, AttrT!int).length == 1); static assert(getUDAs!(d, AttrT!int)[0].name == "Pi"); static assert(getUDAs!(d, AttrT!int)[0].value == 3); struct SimpleAttr {} @SimpleAttr int e; static assert(getUDAs!(e, SimpleAttr).length == 1); static assert(is(getUDAs!(e, SimpleAttr)[0] == SimpleAttr)); @SimpleAttr() int f; static assert(getUDAs!(f, SimpleAttr).length == 1); static assert(is(typeof(getUDAs!(f, SimpleAttr)[0]) == SimpleAttr)); struct FuncAttr(alias f) { alias func = f; } static int add42(int v) { return v + 42; } static string concat(string l, string r) { return l ~ r; } @FuncAttr!add42 int g; static assert(getUDAs!(g, FuncAttr).length == 1); static assert(getUDAs!(g, FuncAttr)[0].func(5) == 47); static assert(getUDAs!(g, FuncAttr!add42).length == 1); static assert(getUDAs!(g, FuncAttr!add42)[0].func(5) == 47); static assert(getUDAs!(g, FuncAttr!add42()).length == 0); static assert(getUDAs!(g, FuncAttr!concat).length == 0); static assert(getUDAs!(g, FuncAttr!concat()).length == 0); @FuncAttr!add42() int h; static assert(getUDAs!(h, FuncAttr).length == 1); static assert(getUDAs!(h, FuncAttr)[0].func(5) == 47); static assert(getUDAs!(h, FuncAttr!add42).length == 1); static assert(getUDAs!(h, FuncAttr!add42)[0].func(5) == 47); static assert(getUDAs!(h, FuncAttr!add42()).length == 1); static assert(getUDAs!(h, FuncAttr!add42())[0].func(5) == 47); static assert(getUDAs!(h, FuncAttr!concat).length == 0); static assert(getUDAs!(h, FuncAttr!concat()).length == 0); @("alpha") @(42) int i; static assert(getUDAs!(i, "alpha").length == 1); static assert(getUDAs!(i, "alpha")[0] == "alpha"); static assert(getUDAs!(i, 42).length == 1); static assert(getUDAs!(i, 42)[0] == 42); static assert(getUDAs!(i, 'c').length == 0);
Gets all symbols within symbol
that have the given user-defined attribute. This is not recursive; it will not search for symbols within symbols such as nested structs or unions.
enum Attr; static struct A { @Attr int a; int b; @Attr void doStuff() {} void doOtherStuff() {} static struct Inner { // Not found by getSymbolsByUDA @Attr int c; } } // Finds both variables and functions with the attribute, but // doesn't include the variables and functions without it. static assert(getSymbolsByUDA!(A, Attr).length == 2); // Can access attributes on the symbols returned by getSymbolsByUDA. static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr)); static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[1], Attr)); static struct UDA { string name; } static struct B { @UDA("X") int x; @UDA("Y") int y; @(100) int z; } // Finds both UDA attributes. static assert(getSymbolsByUDA!(B, UDA).length == 2); // Finds one `100` attribute. static assert(getSymbolsByUDA!(B, 100).length == 1); // Can get the value of the UDA from the return value static assert(getUDAs!(getSymbolsByUDA!(B, UDA)[0], UDA)[0].name == "X"); @UDA("A") static struct C { @UDA("B") int d; } // Also checks the symbol itself static assert(getSymbolsByUDA!(C, UDA).length == 2); static assert(getSymbolsByUDA!(C, UDA)[0].stringof == "C"); static assert(getSymbolsByUDA!(C, UDA)[1].stringof == "d"); static struct D { int x; } //Finds nothing if there is no member with specific UDA static assert(getSymbolsByUDA!(D,UDA).length == 0);
enum Attr; struct A { alias int INT; alias void function(INT) SomeFunction; @Attr int a; int b; @Attr private int c; private int d; } // Here everything is fine, we have access to private member c static assert(getSymbolsByUDA!(A, Attr).length == 2); static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr)); static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[1], Attr));
true
iff all types T
are the same.static assert(allSameType!(int, int)); static assert(allSameType!(int, int, int)); static assert(allSameType!(float, float, float)); static assert(!allSameType!(int, double)); static assert(!allSameType!(int, float, double)); static assert(!allSameType!(int, float, double, real)); static assert(!allSameType!(short, int, float, double, real));
true
iff the type T
can be tested in an if
-expression, that is if if (pred(T.init)) {}
is compilable.Detect whether X
is a type. Analogous to is(X)
. This is useful when used in conjunction with other templates, e.g. allSatisfy!(isType, X)
.
true
if X
is a type, false
otherwisestruct S { template Test() {} } class C {} interface I {} union U {} static assert(isType!int); static assert(isType!string); static assert(isType!(int[int])); static assert(isType!S); static assert(isType!C); static assert(isType!I); static assert(isType!U); int n; void func(){} static assert(!isType!n); static assert(!isType!func); static assert(!isType!(S.Test)); static assert(!isType!(S.Test!()));
Detect whether symbol or type X
is a function. This is different that finding if a symbol is callable or satisfying is(X == function)
, it finds specifically if the symbol represents a normal function declaration, i.e. not a delegate or a function pointer.
true
if X
is a function, false
otherwise isFunctionPointer
or isDelegate
for detecting those types respectively.Detect whether X
is a final method or class.
true
if X
is final, false
otherwiseDetermines whether the type S
can be copied. If a type cannot be copied, then code such as MyStruct x; auto y = x;
will fail to compile. Copying for structs can be disabled by using @disable this(this)
.
S | The type to check. |
true
if S
can be copied. false
otherwise.struct S1 {} // Fine. Can be copied struct S2 { this(this) {}} // Fine. Can be copied struct S3 {@disable this(this) {}} // Not fine. Copying is disabled. struct S4 {S3 s;} // Not fine. A field has copying disabled. class C1 {} static assert( isCopyable!S1); static assert( isCopyable!S2); static assert(!isCopyable!S3); static assert(!isCopyable!S4); static assert(isCopyable!C1); static assert(isCopyable!int); static assert(isCopyable!(int[]));
© 1999–2017 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_traits.html