$(DDOC $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE ) $(SPEC_S Traits, $(DDOC_BLANKLINE ) $(HEADERNAV_TOC $(HEADERNAV_ITEM grammar, Grammar) $(HEADERNAV_SUBITEMS types, Type Traits, $(HEADERNAV_ITEM isArithmetic, isArithmetic) $(HEADERNAV_ITEM isFloating, isFloating) $(HEADERNAV_ITEM isIntegral, isIntegral) $(HEADERNAV_ITEM isScalar, isScalar) $(HEADERNAV_ITEM isUnsigned, isUnsigned) $(HEADERNAV_ITEM isStaticArray, isStaticArray) $(HEADERNAV_ITEM isAssociativeArray, isAssociativeArray) $(HEADERNAV_ITEM isAbstractClass, isAbstractClass) $(HEADERNAV_ITEM isFinalClass, isFinalClass) $(HEADERNAV_ITEM isCopyable, isCopyable) $(HEADERNAV_ITEM isPOD, isPOD) $(HEADERNAV_ITEM toType, toType) $(HEADERNAV_ITEM isZeroInit, isZeroInit) $(HEADERNAV_ITEM hasCopyConstructor, hasCopyConstructor) $(HEADERNAV_ITEM hasPostblit, hasPostblit) $(HEADERNAV_ITEM getAliasThis, getAliasThis) $(HEADERNAV_ITEM getPointerBitmap, getPointerBitmap) $(HEADERNAV_ITEM getVirtualFunctions, getVirtualFunctions) $(HEADERNAV_ITEM getVirtualMethods, getVirtualMethods) $(HEADERNAV_ITEM classInstanceSize, classInstanceSize) $(HEADERNAV_ITEM classInstanceAlignment, classInstanceAlignment) $(HEADERNAV_ITEM initSymbol, initSymbol) ) $(HEADERNAV_SUBITEMS functions, Function Traits, $(HEADERNAV_ITEM isDisabled, isDisabled) $(HEADERNAV_ITEM getVirtualIndex, getVirtualIndex) $(HEADERNAV_ITEM isVirtualFunction, isVirtualFunction) $(HEADERNAV_ITEM isVirtualMethod, isVirtualMethod) $(HEADERNAV_ITEM isAbstractFunction, isAbstractFunction) $(HEADERNAV_ITEM isFinalFunction, isFinalFunction) $(HEADERNAV_ITEM isOverrideFunction, isOverrideFunction) $(HEADERNAV_ITEM isStaticFunction, isStaticFunction) $(HEADERNAV_ITEM isReturnOnStack, isReturnOnStack) $(HEADERNAV_ITEM getFunctionVariadicStyle, getFunctionVariadicStyle) $(HEADERNAV_ITEM getFunctionAttributes, getFunctionAttributes) ) $(HEADERNAV_SUBITEMS function-parameters, Function Parameter Traits, $(HEADERNAV_ITEM isRef, isRef) $(HEADERNAV_ITEM getParameterStorageClasses, getParameterStorageClasses) $(HEADERNAV_ITEM parameters, parameters) ) $(HEADERNAV_SUBITEMS symbols, Symbol Traits, $(HEADERNAV_ITEM isNested, isNested) $(HEADERNAV_ITEM isFuture, isFuture) $(HEADERNAV_ITEM isDeprecated, isDeprecated) $(HEADERNAV_ITEM isTemplate, isTemplate) $(HEADERNAV_ITEM isModule, isModule) $(HEADERNAV_ITEM isPackage, isPackage) $(HEADERNAV_ITEM hasMember, hasMember) $(HEADERNAV_ITEM identifier, identifier) $(HEADERNAV_ITEM getAttributes, getAttributes) $(HEADERNAV_ITEM getLinkage, getLinkage) $(HEADERNAV_ITEM getLocation, getLocation) $(HEADERNAV_ITEM getMember, getMember) $(HEADERNAV_ITEM getOverloads, getOverloads) $(HEADERNAV_ITEM getCppNamespaces, getCppNamespaces) $(HEADERNAV_ITEM getVisibility, getVisibility) $(HEADERNAV_ITEM getProtection, getProtection) $(HEADERNAV_ITEM getTargetInfo, getTargetInfo) $(HEADERNAV_ITEM getUnitTests, getUnitTests) $(HEADERNAV_ITEM parent, parent) $(HEADERNAV_ITEM child, child) $(HEADERNAV_ITEM allMembers, allMembers) $(HEADERNAV_ITEM derivedMembers, derivedMembers) $(HEADERNAV_ITEM isSame, isSame) $(HEADERNAV_ITEM compiles, compiles) ) ) $(DDOC_BLANKLINE )

$(LNAME2 grammar, Grammar)

$(DDOC_BLANKLINE ) $(P Traits are extensions to the language to enable programs, at compile time, to get at information internal to the compiler. This is also known as compile time reflection. It is done as a special, easily extended syntax (similar to Pragmas) so that new capabilities can be added as required. ) $(DDOC_BLANKLINE ) $(GRAMMAR $(GNAME TraitsExpression): $(D __traits) $(D $(LPAREN)) $(GLINK TraitsKeyword) $(D ,) $(GLINK TraitsArguments) $(D $(RPAREN )) $(DDOC_BLANKLINE ) $(GNAME TraitsKeyword): $(RELATIVE_LINK2 isAbstractClass, $(D isAbstractClass)) $(RELATIVE_LINK2 isArithmetic, $(D isArithmetic)) $(RELATIVE_LINK2 isAssociativeArray, $(D isAssociativeArray)) $(RELATIVE_LINK2 isFinalClass, $(D isFinalClass)) $(RELATIVE_LINK2 isPOD, $(D isPOD)) $(RELATIVE_LINK2 isNested, $(D isNested)) $(RELATIVE_LINK2 isFuture, $(D isFuture)) $(RELATIVE_LINK2 isDeprecated, $(D isDeprecated)) $(RELATIVE_LINK2 isFloating, $(D isFloating)) $(RELATIVE_LINK2 isIntegral, $(D isIntegral)) $(RELATIVE_LINK2 isScalar, $(D isScalar)) $(RELATIVE_LINK2 isStaticArray, $(D isStaticArray)) $(RELATIVE_LINK2 isUnsigned, $(D isUnsigned)) $(RELATIVE_LINK2 isDisabled, $(D isDisabled)) $(RELATIVE_LINK2 isVirtualFunction, $(D isVirtualFunction)) $(RELATIVE_LINK2 isVirtualMethod, $(D isVirtualMethod)) $(RELATIVE_LINK2 isAbstractFunction, $(D isAbstractFunction)) $(RELATIVE_LINK2 isFinalFunction, $(D isFinalFunction)) $(RELATIVE_LINK2 isStaticFunction, $(D isStaticFunction)) $(RELATIVE_LINK2 isOverrideFunction, $(D isOverrideFunction)) $(RELATIVE_LINK2 isTemplate, $(D isTemplate)) $(RELATIVE_LINK2 isRef, $(D isRef)) $(RELATIVE_LINK2 isOut, $(D isOut)) $(RELATIVE_LINK2 isLazy, $(D isLazy)) $(RELATIVE_LINK2 isReturnOnStack, $(D isReturnOnStack)) $(RELATIVE_LINK2 isCopyable, $(D isCopyable)) $(RELATIVE_LINK2 isZeroInit, $(D isZeroInit)) $(RELATIVE_LINK2 isModule, $(D isModule)) $(RELATIVE_LINK2 isPackage, $(D isPackage)) $(RELATIVE_LINK2 hasMember, $(D hasMember)) $(RELATIVE_LINK2 hasCopyConstructor, $(D hasCopyConstructor)) $(RELATIVE_LINK2 hasPostblit, $(D hasPostblit)) $(RELATIVE_LINK2 identifier, $(D identifier)) $(RELATIVE_LINK2 getAliasThis, $(D getAliasThis)) $(RELATIVE_LINK2 getAttributes, $(D getAttributes)) $(RELATIVE_LINK2 getFunctionAttributes, $(D getFunctionAttributes)) $(RELATIVE_LINK2 getFunctionVariadicStyle, $(D getFunctionVariadicStyle)) $(RELATIVE_LINK2 getLinkage, $(D getLinkage)) $(RELATIVE_LINK2 getLocation, $(D getLocation)) $(RELATIVE_LINK2 getMember, $(D getMember)) $(RELATIVE_LINK2 getOverloads, $(D getOverloads)) $(RELATIVE_LINK2 getParameterStorageClasses, $(D getParameterStorageClasses)) $(RELATIVE_LINK2 getPointerBitmap, $(D getPointerBitmap)) $(RELATIVE_LINK2 getCppNamespaces, $(D getCppNamespaces)) $(RELATIVE_LINK2 getVisibility, $(D getVisibility)) $(RELATIVE_LINK2 getProtection, $(D getProtection)) $(RELATIVE_LINK2 getTargetInfo, $(D getTargetInfo)) $(RELATIVE_LINK2 getVirtualFunctions, $(D getVirtualFunctions)) $(RELATIVE_LINK2 getVirtualMethods, $(D getVirtualMethods)) $(RELATIVE_LINK2 getUnitTests, $(D getUnitTests)) $(RELATIVE_LINK2 parent, $(D parent)) $(RELATIVE_LINK2 child, $(D child)) $(RELATIVE_LINK2 classInstanceSize, $(D classInstanceSize)) $(RELATIVE_LINK2 classInstanceAlignment, $(D classInstanceAlignment)) $(RELATIVE_LINK2 getVirtualIndex, $(D getVirtualIndex)) $(RELATIVE_LINK2 allMembers, $(D allMembers)) $(RELATIVE_LINK2 derivedMembers, $(D derivedMembers)) $(RELATIVE_LINK2 isSame, $(D isSame)) $(RELATIVE_LINK2 compiles, $(D compiles)) $(RELATIVE_LINK2 toType, $(D toType)) $(RELATIVE_LINK2 initSymbol, $(D initSymbol)) $(RELATIVE_LINK2 parameters, $(D parameters)) $(DDOC_BLANKLINE ) $(GNAME TraitsArguments): $(GLINK TraitsArgument) $(GLINK TraitsArgument) $(D ,) $(GSELF TraitsArguments) $(DDOC_BLANKLINE ) $(GNAME TraitsArgument): $(GLINK2 expression, AssignExpression) $(GLINK2 type, Type) ) $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE )

$(LNAME2 types, Type Traits)

$(DDOC_BLANKLINE )

$(GNAME isArithmetic)

$(DDOC_BLANKLINE ) $(P If the arguments are all either types that are arithmetic types, or expressions that are typed as arithmetic types, then $(D true) is returned. Otherwise, $(D false) is returned. If there are no arguments, $(D false) is returned.) $(DDOC_BLANKLINE ) $(P Arithmetic types are integral types and floating point types.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD void) main() { $(D_KEYWORD int) i; writeln($(D_KEYWORD __traits)(isArithmetic, $(D_KEYWORD int))); writeln($(D_KEYWORD __traits)(isArithmetic, i, i+1, $(D_KEYWORD int))); writeln($(D_KEYWORD __traits)(isArithmetic)); writeln($(D_KEYWORD __traits)(isArithmetic, $(D_KEYWORD int)*)); } ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE true true false false ) $(DDOC_BLANKLINE )

$(GNAME isFloating)

$(DDOC_BLANKLINE ) $(P If the arguments are all either types that are floating point types, or expressions that are typed as floating point types, then $(D true) is returned. Otherwise, $(D false) is returned. If there are no arguments, $(D false) is returned.) $(DDOC_BLANKLINE ) $(P The floating point types are: float, double, real, ifloat, idouble, ireal, cfloat, cdouble, creal, vectors of floating point types, and enums with a floating point base type.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.simd : float4; $(D_KEYWORD enum) E : $(D_KEYWORD float) { a, b } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isFloating, $(D_KEYWORD float))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isFloating, E)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isFloating, float4)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isFloating, $(D_KEYWORD float)[4])); ) ) $(DDOC_BLANKLINE )

$(GNAME isIntegral)

$(DDOC_BLANKLINE ) $(P If the arguments are all either types that are integral types, or expressions that are typed as integral types, then $(D true) is returned. Otherwise, $(D false) is returned. If there are no arguments, $(D false) is returned.) $(DDOC_BLANKLINE ) $(P The integral types are: byte, ubyte, short, ushort, int, uint, long, ulong, cent, ucent, bool, char, wchar, dchar, vectors of integral types, and enums with an integral base type.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.simd : int4; $(D_KEYWORD enum) E { a, b } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isIntegral, $(D_KEYWORD bool))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isIntegral, $(D_KEYWORD char))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isIntegral, $(D_KEYWORD int))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isIntegral, E)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isIntegral, int4)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isIntegral, $(D_KEYWORD float))); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isIntegral, $(D_KEYWORD int)[4])); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isIntegral, $(D_KEYWORD void)*)); ) ) $(DDOC_BLANKLINE )

$(GNAME isScalar)

$(DDOC_BLANKLINE ) $(P If the arguments are all either types that are scalar types, or expressions that are typed as scalar types, then $(D true) is returned. Otherwise, $(D false) is returned. If there are no arguments, $(D false) is returned.) $(DDOC_BLANKLINE ) $(P Scalar types are integral types, floating point types, pointer types, vectors of scalar types, and enums with a scalar base type.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.simd : int4, void16; $(D_KEYWORD enum) E { a, b } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isScalar, $(D_KEYWORD bool))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isScalar, $(D_KEYWORD char))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isScalar, $(D_KEYWORD int))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isScalar, $(D_KEYWORD float))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isScalar, E)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isScalar, int4)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isScalar, $(D_KEYWORD void)*)); $(D_COMMENT // Includes pointers! ) $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isScalar, $(D_KEYWORD int)[4])); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isScalar, void16)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isScalar, $(D_KEYWORD void))); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isScalar, $(D_KEYWORD typeof)($(D_KEYWORD null)))); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isScalar, Object)); ) ) $(DDOC_BLANKLINE )

$(GNAME isUnsigned)

$(DDOC_BLANKLINE ) $(P If the arguments are all either types that are unsigned types, or expressions that are typed as unsigned types, then $(D true) is returned. Otherwise, $(D false) is returned. If there are no arguments, $(D false) is returned.) $(DDOC_BLANKLINE ) $(P The unsigned types are: ubyte, ushort, uint, ulong, ucent, bool, char, wchar, dchar, vectors of unsigned types, and enums with an unsigned base type.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.simd : uint4; $(D_KEYWORD enum) SignedEnum { a, b } $(D_KEYWORD enum) UnsignedEnum : $(D_KEYWORD uint) { a, b } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isUnsigned, $(D_KEYWORD bool))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isUnsigned, $(D_KEYWORD char))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isUnsigned, $(D_KEYWORD uint))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isUnsigned, UnsignedEnum)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isUnsigned, uint4)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isUnsigned, $(D_KEYWORD int))); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isUnsigned, $(D_KEYWORD float))); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isUnsigned, SignedEnum)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isUnsigned, $(D_KEYWORD uint)[4])); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isUnsigned, $(D_KEYWORD void)*)); ) ) $(DDOC_BLANKLINE )

$(GNAME isStaticArray)

$(DDOC_BLANKLINE ) $(P Works like $(D isArithmetic), except it's for static array types.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.simd : int4; $(D_KEYWORD enum) E : $(D_KEYWORD int)[4] { a = [1, 2, 3, 4] } $(D_KEYWORD static) array = [1, 2, 3]; $(D_COMMENT // Not a static array: the type is inferred as int[] not int[3]. ) $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isStaticArray, $(D_KEYWORD void)[0])); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isStaticArray, E)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isStaticArray, int4)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isStaticArray, array)); ) ) $(DDOC_BLANKLINE )

$(GNAME isAssociativeArray)

$(DDOC_BLANKLINE ) $(P Works like $(D isArithmetic), except it's for associative array types.) $(DDOC_BLANKLINE )

$(GNAME isAbstractClass)

$(DDOC_BLANKLINE ) $(P If the arguments are all either types that are abstract classes, or expressions that are typed as abstract classes, then $(D true) is returned. Otherwise, $(D false) is returned. If there are no arguments, $(D false) is returned.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD abstract) $(D_KEYWORD class) C { $(D_KEYWORD int) foo(); } $(D_KEYWORD void) main() { C c; writeln($(D_KEYWORD __traits)(isAbstractClass, C)); writeln($(D_KEYWORD __traits)(isAbstractClass, c, C)); writeln($(D_KEYWORD __traits)(isAbstractClass)); writeln($(D_KEYWORD __traits)(isAbstractClass, $(D_KEYWORD int)*)); } ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE true true false false ) $(DDOC_BLANKLINE )

$(GNAME isFinalClass)

$(DDOC_BLANKLINE ) $(P Works like $(D isAbstractClass), except it's for final classes.) $(DDOC_BLANKLINE )

$(GNAME isCopyable)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a copyable type then $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD struct) S { } $(D_KEYWORD static) $(D_KEYWORD assert)( $(D_KEYWORD __traits)(isCopyable, S)); $(D_KEYWORD struct) T { @disable $(D_KEYWORD this)($(D_KEYWORD this)); $(D_COMMENT // disable copy construction )} $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isCopyable, T)); ) ) $(DDOC_BLANKLINE )

$(GNAME isPOD)

$(DDOC_BLANKLINE ) $(P Takes one argument, which must be a type. It returns $(D true) if the type is a $(DDSUBLINK spec/glossary, pod, POD) type, otherwise $(D false).) $(DDOC_BLANKLINE )

$(GNAME toType)

$(DDOC_BLANKLINE ) $(P Takes a single argument, which must evaluate to an expression of type string. The contents of the string must correspond to the $(DDSUBLINK spec/abi, name_mangling, mangled contents of a type) that has been seen by the implementation.) $(DDOC_BLANKLINE ) $(P Only D mangling is supported. Other manglings, such as C++ mangling, are not.) $(DDOC_BLANKLINE ) $(P The value returned is a type.) $(DDOC_BLANKLINE ) $(D_CODE $(D_KEYWORD template) Type(T) { $(D_KEYWORD alias) Type = T; } Type!($(D_KEYWORD __traits)(toType, $(D_STRING "i"))) j = 3; $(D_COMMENT // j is declared as type `int` ) $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD is)(Type!($(D_KEYWORD __traits)(toType, ($(D_KEYWORD int)*).mangleof)) == $(D_KEYWORD int)*)); $(D_KEYWORD __traits)(toType, $(D_STRING "i")) x = 4; $(D_COMMENT // x is also declared as type `int` )) $(DDOC_BLANKLINE ) $(RATIONALE Provides the inverse operation of the $(DDSUBLINK spec/property, mangleof, .mangleof) property.) $(DDOC_BLANKLINE )

$(GNAME isZeroInit)

$(DDOC_BLANKLINE ) $(P Takes one argument which must be a type. If the type's $(DDSUBLINK spec/property, init, default initializer) is all zero bits then true is returned, otherwise false.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD struct) S1 { $(D_KEYWORD int) x; } $(D_KEYWORD struct) S2 { $(D_KEYWORD int) x = -1; } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isZeroInit, S1)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isZeroInit, S2)); $(D_KEYWORD void) test() { $(D_KEYWORD int) x = 3; $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isZeroInit, $(D_KEYWORD typeof)(x))); } $(D_COMMENT // `isZeroInit` will always return true for a class C )$(D_COMMENT // because `C.init` is null reference. ) $(D_KEYWORD class) C { $(D_KEYWORD int) x = -1; } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isZeroInit, C)); $(D_COMMENT // For initializing arrays of element type `void`. )$(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isZeroInit, $(D_KEYWORD void))); ) ) $(DDOC_BLANKLINE )

$(GNAME hasCopyConstructor)

$(DDOC_BLANKLINE ) $(P The argument is a type. If it is a struct with a copy constructor, returns $(D true). Otherwise, return $(D false). Note that a copy constructor is distinct from a postblit. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { } $(D_KEYWORD class) C { } $(D_KEYWORD struct) P { $(D_KEYWORD this)($(D_KEYWORD ref) P rhs) {} } $(D_KEYWORD struct) B { $(D_KEYWORD this)($(D_KEYWORD this)) {} } $(D_KEYWORD void) main() { writeln($(D_KEYWORD __traits)(hasCopyConstructor, S)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(hasCopyConstructor, C)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(hasCopyConstructor, P)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(hasCopyConstructor, B)); $(D_COMMENT // false, this is a postblit )} ) ) $(DDOC_BLANKLINE )

$(GNAME hasPostblit)

$(DDOC_BLANKLINE ) $(P The argument is a type. If it is a struct with a postblit, returns $(D true). Otherwise, return $(D false). Note a postblit is distinct from a copy constructor. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { } $(D_KEYWORD class) C { } $(D_KEYWORD struct) P { $(D_KEYWORD this)($(D_KEYWORD ref) P rhs) {} } $(D_KEYWORD struct) B { $(D_KEYWORD this)($(D_KEYWORD this)) {} } $(D_KEYWORD void) main() { writeln($(D_KEYWORD __traits)(hasPostblit, S)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(hasPostblit, C)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(hasPostblit, P)); $(D_COMMENT // false, this is a copy ctor ) writeln($(D_KEYWORD __traits)(hasPostblit, B)); $(D_COMMENT // true )} ) ) $(DDOC_BLANKLINE )

$(GNAME getAliasThis)

$(DDOC_BLANKLINE ) $(P Takes one argument, a type. If the type has alias this declarations, returns a ValueSeq of the names (as strings) of the members used in those declarations. Otherwise returns an empty sequence. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD alias) AliasSeq(T...) = T; $(D_KEYWORD struct) S1 { string var; $(D_KEYWORD alias) var $(D_KEYWORD this); } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getAliasThis, S1) == AliasSeq!($(D_STRING "var"))); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getAliasThis, $(D_KEYWORD int)).length == 0); $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getAliasThis, S1)); $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getAliasThis, $(D_KEYWORD int))); ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE tuple("var") tuple() ) $(DDOC_BLANKLINE )

$(GNAME getPointerBitmap)

$(DDOC_BLANKLINE ) $(P The argument is a type. The result is an array of $(D size_t) describing the memory used by an instance of the given type. ) $(P The first element of the array is the size of the type (for classes it is the $(GLINK classInstanceSize)).) $(P The following elements describe the locations of GC managed pointers within the memory occupied by an instance of the type. For type T, there are $(D T.sizeof / size_t.sizeof) possible pointers represented by the bits of the array values.) $(P This array can be used by a precise GC to avoid false pointers.) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD void) main() { $(D_KEYWORD static) $(D_KEYWORD class) C { $(D_COMMENT // implicit virtual function table pointer not marked ) $(D_COMMENT // implicit monitor field not marked, usually managed manually ) C next; size_t sz; $(D_KEYWORD void)* p; $(D_KEYWORD void) $(D_KEYWORD function) () fn; $(D_COMMENT // not a GC managed pointer ) } $(D_KEYWORD static) $(D_KEYWORD struct) S { size_t val1; $(D_KEYWORD void)* p; C c; $(D_KEYWORD byte)[] arr; $(D_COMMENT // { length, ptr } ) $(D_KEYWORD void) $(D_KEYWORD delegate) () dg; $(D_COMMENT // { context, func } ) } $(D_KEYWORD static) $(D_KEYWORD assert) ($(D_KEYWORD __traits)(getPointerBitmap, C) == [6*size_t.sizeof, 0b010100]); $(D_KEYWORD static) $(D_KEYWORD assert) ($(D_KEYWORD __traits)(getPointerBitmap, S) == [7*size_t.sizeof, 0b0110110]); } ) ) $(DDOC_BLANKLINE )

$(GNAME getVirtualFunctions)

$(DDOC_BLANKLINE ) $(P The same as $(GLINK getVirtualMethods), except that final functions that do not override anything are included. ) $(DDOC_BLANKLINE )

$(GNAME getVirtualMethods)

$(DDOC_BLANKLINE ) $(P The first argument is a class type or an expression of class type. The second argument is a string that matches the name of one of the functions of that class. The result is a symbol sequence of the virtual overloads of that function. It does not include final functions that do not override anything. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD class) D { $(D_KEYWORD this)() { } ~$(D_KEYWORD this)() { } $(D_KEYWORD void) foo() { } $(D_KEYWORD int) foo($(D_KEYWORD int)) { $(D_KEYWORD return) 2; } } $(D_KEYWORD void) main() { D d = $(D_KEYWORD new) D(); $(D_KEYWORD foreach) (t; $(D_KEYWORD __traits)(getVirtualMethods, D, $(D_STRING "foo"))) writeln($(D_KEYWORD typeid)($(D_KEYWORD typeof)(t))); $(D_KEYWORD alias) b = $(D_KEYWORD typeof)($(D_KEYWORD __traits)(getVirtualMethods, D, $(D_STRING "foo"))); $(D_KEYWORD foreach) (t; b) writeln($(D_KEYWORD typeid)(t)); $(D_KEYWORD auto) i = $(D_KEYWORD __traits)(getVirtualMethods, d, $(D_STRING "foo"))[1](1); writeln(i); } ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE void() int() void() int() 2 ) $(DDOC_BLANKLINE )

$(GNAME classInstanceSize)

$(DDOC_BLANKLINE ) $(P Takes a single argument, which must evaluate to either a class type or an expression of class type. The result is of type $(CODE size_t), and the value is the number of bytes in the runtime instance of the class type. It is based on the static type of a class, not the polymorphic type. ) $(DDOC_BLANKLINE )

$(GNAME classInstanceAlignment)

$(DDOC_BLANKLINE ) $(P Takes a single argument, which must evaluate to either a class type or an expression of class type. The result is of type $(CODE size_t), and the value is the alignment of a runtime instance of the class type. It is based on the static type of a class, not the polymorphic type. ) $(DDOC_BLANKLINE )

$(GNAME initSymbol)

$(DDOC_BLANKLINE ) $(P Takes a single argument, which must evaluate to a class, struct or union type. Returns a const(void)[] that holds the initial state of any instance of the supplied type. The slice is constructed for any type T as follows: $(UL $(LI ptr points to either the initializer symbol of T or null if T is a zero-initialized struct / unions. ) $(LI length is equal to the size of an instance, i.e. T.sizeof for structs / unions and $(RELATIVE_LINK2 classInstanceSize, $(D __traits(classInstanceSize, T)`)) for classes.) ) ) $(DDOC_BLANKLINE ) $(P This trait matches the behaviour of TypeInfo.initializer() but can also be used when TypeInfo is not available. ) $(DDOC_BLANKLINE ) $(P This traits is not available during $(DDSUBLINK spec/glossary, ctfe, CTFE) because the actual address of the initializer symbol will be set by the linker and hence is not available at compile time. ) $(DDOC_BLANKLINE ) $(D_CODE $(D_KEYWORD class) C { $(D_KEYWORD int) i = 4; } $(D_COMMENT /// Initializes a malloc'ed instance of `C` )$(D_KEYWORD void) main() { $(D_KEYWORD const) $(D_KEYWORD void)[] initSym = $(D_KEYWORD __traits)(initSymbol, C); $(D_KEYWORD void)* ptr = malloc(initSym.length); $(D_KEYWORD scope) (exit) free(ptr); ptr[0..initSym.length] = initSym[]; C c = $(D_KEYWORD cast)(C) ptr; $(D_KEYWORD assert)(c.i == 4); } ) $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE )

$(LNAME2 functions, Function Traits)

$(DDOC_BLANKLINE )

$(GNAME isDisabled)

$(DDOC_BLANKLINE ) $(P Takes one argument and returns true if it's a function declaration marked with @disable.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD struct) Foo { @disable $(D_KEYWORD void) foo(); $(D_KEYWORD void) bar(){} } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isDisabled, Foo.foo)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isDisabled, Foo.bar)); ) ) $(DDOC_BLANKLINE ) $(P For any other declaration even if @disable is a syntactically valid attribute false is returned because the annotation has no effect.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE @disable $(D_KEYWORD struct) Bar{} $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isDisabled, Bar)); ) ) $(DDOC_BLANKLINE )

$(GNAME getVirtualIndex)

$(DDOC_BLANKLINE ) $(P Takes a single argument which must evaluate to a function. The result is a $(CODE ptrdiff_t) containing the index of that function within the vtable of the parent type. If the function passed in is final and does not override a virtual function, $(D -1) is returned instead. ) $(DDOC_BLANKLINE )

$(GNAME isVirtualFunction)

$(DDOC_BLANKLINE ) $(P The same as $(GLINK isVirtualMethod), except that final functions that don't override anything return true. ) $(DDOC_BLANKLINE )

$(GNAME isVirtualMethod)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a virtual function, $(D true) is returned, otherwise $(D false). Final functions that don't override anything return false. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { $(D_KEYWORD void) bar() { } } $(D_KEYWORD class) C { $(D_KEYWORD void) bar() { } } $(D_KEYWORD void) main() { writeln($(D_KEYWORD __traits)(isVirtualMethod, C.bar)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(isVirtualMethod, S.bar)); $(D_COMMENT // false )} ) ) $(DDOC_BLANKLINE )

$(GNAME isAbstractFunction)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is an abstract function, $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { $(D_KEYWORD void) bar() { } } $(D_KEYWORD class) C { $(D_KEYWORD void) bar() { } } $(D_KEYWORD class) AC { $(D_KEYWORD abstract) $(D_KEYWORD void) foo(); } $(D_KEYWORD void) main() { writeln($(D_KEYWORD __traits)(isAbstractFunction, C.bar)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(isAbstractFunction, S.bar)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(isAbstractFunction, AC.foo)); $(D_COMMENT // true )} ) ) $(DDOC_BLANKLINE )

$(GNAME isFinalFunction)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a final function, $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { $(D_KEYWORD void) bar() { } } $(D_KEYWORD class) C { $(D_KEYWORD void) bar() { } $(D_KEYWORD final) $(D_KEYWORD void) foo(); } $(D_KEYWORD final) $(D_KEYWORD class) FC { $(D_KEYWORD void) foo(); } $(D_KEYWORD void) main() { writeln($(D_KEYWORD __traits)(isFinalFunction, C.bar)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(isFinalFunction, S.bar)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(isFinalFunction, C.foo)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(isFinalFunction, FC.foo)); $(D_COMMENT // true )} ) ) $(DDOC_BLANKLINE )

$(GNAME isOverrideFunction)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a function marked with $(D_KEYWORD override), $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD class) Base { $(D_KEYWORD void) foo() { } } $(D_KEYWORD class) Foo : Base { $(D_KEYWORD override) $(D_KEYWORD void) foo() { } $(D_KEYWORD void) bar() { } } $(D_KEYWORD void) main() { writeln($(D_KEYWORD __traits)(isOverrideFunction, Base.foo)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(isOverrideFunction, Foo.foo)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(isOverrideFunction, Foo.bar)); $(D_COMMENT // false )} ) ) $(DDOC_BLANKLINE )

$(GNAME isStaticFunction)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a static function, meaning it has no context pointer, $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD struct) A { $(D_KEYWORD int) foo() { $(D_KEYWORD return) 3; } $(D_KEYWORD static) $(D_KEYWORD int) boo($(D_KEYWORD int) a) { $(D_KEYWORD return) a; } } $(D_KEYWORD void) main() { $(D_KEYWORD assert)($(D_KEYWORD __traits)(isStaticFunction, A.boo)); $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isStaticFunction, A.foo)); $(D_KEYWORD assert)($(D_KEYWORD __traits)(isStaticFunction, main)); } ) ) $(DDOC_BLANKLINE )

$(GNAME isReturnOnStack)

$(DDOC_BLANKLINE ) $(P Takes one argument which must either be a function symbol, function literal, a delegate, or a function pointer. It returns a bool which is true if the return value of the function is returned on the stack via a pointer to it passed as a hidden extra parameter to the function. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD struct) S { $(D_KEYWORD int)[20] a; } $(D_KEYWORD int) test1(); S test2(); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isReturnOnStack, test1) == $(D_KEYWORD false)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isReturnOnStack, test2) == $(D_KEYWORD true)); ) ) $(DDOC_BLANKLINE ) $(IMPLEMENTATION_DEFINED This is determined by the function ABI calling convention in use, which is often complex. ) $(DDOC_BLANKLINE ) $(BEST_PRACTICE This has applications in: $(OL $(LI Returning values in registers is often faster, so this can be used as a check on a hot function to ensure it is using the fastest method.) $(LI When using inline assembly to correctly call a function.) $(LI Testing that the compiler does this correctly is normally hackish and awkward, this enables efficient, direct, and simple testing.) )) $(DDOC_BLANKLINE ) $(SECTION3 $(GNAME getFunctionVariadicStyle), $(P Takes one argument which must either be a function symbol, or a type that is a function, delegate or a function pointer. It returns a string identifying the kind of $(LINK2 function.html#variadic, variadic arguments) that are supported. ) $(DDOC_BLANKLINE ) $(TABLE2 getFunctionVariadicStyle, result, kind, access, example $(TROW $(D "none"), not a variadic function, $(NBSP ), $(D void foo();)) $(TROW $(D "argptr"), D style variadic function, $(D _argptr) and $(D _arguments), $(D void bar(...))) $(TROW $(D "stdarg"), C style variadic function, $(LINK2 $(ROOT_DIR )phobos/core_stdc_stdarg.html, $(D core.stdc.stdarg)), $(D extern (C) void abc(int, ...))) $(TROW $(D "typesafe"), typesafe variadic function, array on stack, $(D void def(int[] ...))) ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.stdc.stdarg; $(D_KEYWORD void) novar() {} $(D_KEYWORD extern)(C) $(D_KEYWORD void) cstyle($(D_KEYWORD int), ...) {} $(D_KEYWORD extern)(C++) $(D_KEYWORD void) cppstyle($(D_KEYWORD int), ...) {} $(D_KEYWORD void) dstyle(...) {} $(D_KEYWORD void) typesafe($(D_KEYWORD int)[]...) {} $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getFunctionVariadicStyle, novar) == $(D_STRING "none")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getFunctionVariadicStyle, cstyle) == $(D_STRING "stdarg")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getFunctionVariadicStyle, cppstyle) == $(D_STRING "stdarg")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getFunctionVariadicStyle, dstyle) == $(D_STRING "argptr")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getFunctionVariadicStyle, typesafe) == $(D_STRING "typesafe")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getFunctionVariadicStyle, ($(D_KEYWORD int)[] a...) {}) == $(D_STRING "typesafe")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getFunctionVariadicStyle, $(D_KEYWORD typeof)(cstyle)) == $(D_STRING "stdarg")); ) ) ) $(DDOC_BLANKLINE ) $(SECTION3 $(GNAME getFunctionAttributes), $(P Takes one argument which must either be a function symbol, function literal, or a function pointer. It returns a string ValueSeq of all the attributes of that function $(B excluding) any user-defined attributes (UDAs can be retrieved with the $(GLINK getAttributes) trait). If no attributes exist it will return an empty sequence. ) $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE ) $(B Note:) The order of the attributes in the returned sequence is implementation-defined and should not be relied upon. $(DDOC_BLANKLINE ) $(P A list of currently supported attributes are:) $(UL $(LI $(D pure), $(D nothrow), $(D @nogc), $(D @property), $(D @system), $(D @trusted), $(D @safe), $(D ref) and $(D @live))) $(B Note:) $(D ref) is a function attribute even though it applies to the return type. $(DDOC_BLANKLINE ) $(P Additionally the following attributes are only valid for non-static member functions:) $(UL $(LI $(D const), $(D immutable), $(D inout), $(D shared))) $(DDOC_BLANKLINE ) For example: $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD int) sum($(D_KEYWORD int) x, $(D_KEYWORD int) y) $(D_KEYWORD pure) $(D_KEYWORD nothrow) { $(D_KEYWORD return) x + y; } $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getFunctionAttributes, sum)); $(D_KEYWORD struct) S { $(D_KEYWORD void) test() $(D_KEYWORD const) @system { } } $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getFunctionAttributes, S.test)); ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE tuple("pure", "nothrow", "@system") tuple("const", "@system") ) $(DDOC_BLANKLINE ) $(P Note that some attributes can be inferred. For example:) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getFunctionAttributes, ($(D_KEYWORD int) x) @trusted { $(D_KEYWORD return) x * 2; })); ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE tuple("pure", "nothrow", "@nogc", "@trusted") ) ) ) $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE )

$(LNAME2 function-parameters, Function Parameter Traits)

$(DDOC_BLANKLINE )

$(GNAME isRef), $(GNAME isOut), $(GNAME isLazy)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a declaration, $(D true) is returned if it is $(D_KEYWORD ref), $(D_KEYWORD out), or $(D_KEYWORD lazy), otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD void) fooref($(D_KEYWORD ref) $(D_KEYWORD int) x) { $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isRef, x)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isOut, x)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isLazy, x)); } $(D_KEYWORD void) fooout($(D_KEYWORD out) $(D_KEYWORD int) x) { $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isRef, x)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isOut, x)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isLazy, x)); } $(D_KEYWORD void) foolazy($(D_KEYWORD lazy) $(D_KEYWORD int) x) { $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isRef, x)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isOut, x)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isLazy, x)); } ) ) $(DDOC_BLANKLINE )

$(GNAME getParameterStorageClasses)

$(DDOC_BLANKLINE ) $(P Takes two arguments. The first must either be a function symbol, a function call, or a type that is a function, delegate or a function pointer. The second is an integer identifying which parameter, where the first parameter is 0. It returns a ValueSeq of strings representing the storage classes of that parameter. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD ref) $(D_KEYWORD int) foo($(D_KEYWORD return) $(D_KEYWORD ref) $(D_KEYWORD const) $(D_KEYWORD int)* p, $(D_KEYWORD scope) $(D_KEYWORD int)* a, $(D_KEYWORD out) $(D_KEYWORD int) b, $(D_KEYWORD lazy) $(D_KEYWORD int) c); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, foo, 0)[0] == $(D_STRING "return")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, foo, 0)[1] == $(D_STRING "ref")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, foo, 1)[0] == $(D_STRING "scope")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, foo, 2)[0] == $(D_STRING "out")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, $(D_KEYWORD typeof)(&foo), 3)[0] == $(D_STRING "lazy")); $(D_KEYWORD int)* p, a; $(D_KEYWORD int) b, c; $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, foo(p, a, b, c), 1)[0] == $(D_STRING "scope")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, foo(p, a, b, c), 2)[0] == $(D_STRING "out")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getParameterStorageClasses, foo(p, a, b, c), 3)[0] == $(D_STRING "lazy")); ) ) $(DDOC_BLANKLINE )

$(GNAME parameters)

$(DDOC_BLANKLINE ) $(P May only be used inside a function. Takes no arguments, and returns a sequence of the enclosing function's parameters.) $(DDOC_BLANKLINE ) $(P If the function is nested, the parameters returned are those of the inner function, not the outer one.) $(DDOC_BLANKLINE ) $(D_CODE $(D_KEYWORD int) add($(D_KEYWORD int) x, $(D_KEYWORD int) y) { $(D_KEYWORD return) x + y; } $(D_KEYWORD int) forwardToAdd($(D_KEYWORD int) x, $(D_KEYWORD int) y) { $(D_KEYWORD return) add($(D_KEYWORD __traits)(parameters)); $(D_COMMENT // equivalent to; ) $(D_COMMENT //return add$(LPAREN)x, y$(RPAREN ); )} $(D_KEYWORD int) nestedExample($(D_KEYWORD int) x) { $(D_COMMENT // outer function's parameters ) $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD typeof)($(D_KEYWORD __traits)(parameters)).length == 1); $(D_KEYWORD int) add($(D_KEYWORD int) x, $(D_KEYWORD int) y) { $(D_COMMENT // inner function's parameters ) $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD typeof)($(D_KEYWORD __traits)(parameters)).length == 2); $(D_KEYWORD return) x + y; } $(D_KEYWORD return) add(x, x); } $(D_KEYWORD class) C { $(D_KEYWORD int) opApply($(D_KEYWORD int) $(D_KEYWORD delegate)(size_t, C) dg) { $(D_KEYWORD if) (dg(0, $(D_KEYWORD this))) $(D_KEYWORD return) 1; $(D_KEYWORD return) 0; } } $(D_KEYWORD void) foreachExample(C c, $(D_KEYWORD int) x) { $(D_KEYWORD foreach)(idx; 0..5) { $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD is)($(D_KEYWORD typeof)($(D_KEYWORD __traits)(parameters)) == AliasSeq!(C, $(D_KEYWORD int)))); } $(D_KEYWORD foreach)(idx, elem; c) { $(D_COMMENT // __traits$(LPAREN)parameters$(RPAREN ) sees past the delegate passed to opApply ) $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD is)($(D_KEYWORD typeof)($(D_KEYWORD __traits)(parameters)) == AliasSeq!(C, $(D_KEYWORD int)))); } } ) $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE )

$(LNAME2 symbols, Symbol Traits)

$(DDOC_BLANKLINE )

$(GNAME isNested)

$(DDOC_BLANKLINE ) $(P Takes one argument. It returns $(D true) if the argument is a nested type which internally stores a context pointer, otherwise it returns $(D false). Nested types can be $(DDSUBLINK spec/class, nested, classes), $(DDSUBLINK spec/struct, nested, structs), and $(DDSUBLINK spec/function, variadicnested, functions).) $(DDOC_BLANKLINE )

$(GNAME isFuture)

$(DDOC_BLANKLINE ) $(P Takes one argument. It returns true if the argument is a symbol marked with the @future keyword, otherwise false. Currently, only functions and variable declarations have support for the @future keyword.) $(DDOC_BLANKLINE )

$(GNAME isDeprecated)

$(DDOC_BLANKLINE ) $(P Takes one argument. It returns true if the argument is a symbol marked with the deprecated keyword, otherwise false.) $(DDOC_BLANKLINE )

$(GNAME isTemplate)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument or any of its overloads is a template then $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD void) foo(T)(){} $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isTemplate,foo)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isTemplate,foo!$(D_KEYWORD int)())); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isTemplate,$(D_STRING "string"))); ) ) $(DDOC_BLANKLINE )

$(GNAME isModule)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a symbol that refers to a $(DDLINK spec/module, Modules, module) then $(D true) is returned, otherwise $(D false). $(DDSUBLINK spec/module, package-module, Package modules) are considered to be modules even if they have not been directly imported as modules. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.thread; $(D_KEYWORD import) std.algorithm.sorting; $(D_COMMENT // A regular package $(LPAREN)no package.d$(RPAREN ) )$(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isModule, core)); $(D_COMMENT // A package module $(LPAREN)has a package.d file$(RPAREN ) )$(D_COMMENT // Note that we haven't imported std.algorithm directly. )$(D_COMMENT // $(LPAREN)In other words, we don't have an "import std.algorithm;" directive.$(RPAREN ) )$(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isModule, std.algorithm)); $(D_COMMENT // A regular module )$(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isModule, std.algorithm.sorting)); ) ) $(DDOC_BLANKLINE )

$(GNAME isPackage)

$(DDOC_BLANKLINE ) $(P Takes one argument. If that argument is a symbol that refers to a $(DDSUBLINK spec/module, PackageName, package) then $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(D_CODE $(D_KEYWORD import) std.algorithm.sorting; $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isPackage, std)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isPackage, std.algorithm)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isPackage, std.algorithm.sorting)); ) $(DDOC_BLANKLINE )

$(GNAME hasMember)

$(DDOC_BLANKLINE ) $(P The first argument is a type that has members, or is an expression of a type that has members. The second argument is a string. If the string is a valid property of the type, $(D true) is returned, otherwise $(D false). ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { $(D_KEYWORD int) m; } $(D_KEYWORD void) main() { S s; writeln($(D_KEYWORD __traits)(hasMember, S, $(D_STRING "m"))); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(hasMember, s, $(D_STRING "m"))); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(hasMember, S, $(D_STRING "y"))); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(hasMember, S, $(D_STRING "write"))); $(D_COMMENT // false, but callable like a member via UFCS ) writeln($(D_KEYWORD __traits)(hasMember, $(D_KEYWORD int), $(D_STRING "sizeof"))); $(D_COMMENT // true )} ) ) $(DDOC_BLANKLINE )

$(GNAME identifier)

$(DDOC_BLANKLINE ) $(P Takes one argument, a symbol. Returns the identifier for that symbol as a string literal. ) $(SPEC_RUNNABLE_EXAMPLE_RUN $(D_CODE $(D_KEYWORD int) var = 123; $(D_KEYWORD pragma)(msg, $(D_KEYWORD typeof)(var)); $(D_COMMENT // int )$(D_KEYWORD pragma)(msg, $(D_KEYWORD typeof)($(D_KEYWORD __traits)(identifier, var))); $(D_COMMENT // string )writeln(var); $(D_COMMENT // 123 )writeln($(D_KEYWORD __traits)(identifier, var)); $(D_COMMENT // "var" )) ) $(DDOC_BLANKLINE ) $(SECTION3 $(GNAME getAttributes), $(P Takes one argument, a symbol. Returns a sequence of all attached user-defined attributes. If no UDAs exist it will return an empty sequence ) $(DDOC_BLANKLINE ) $(P For more information, see: $(DDSUBLINK spec/attribute, uda, User-Defined Attributes) ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE @(3) $(D_KEYWORD int) a; @($(D_STRING "string"), 7) $(D_KEYWORD int) b; $(D_KEYWORD enum) Foo; @Foo $(D_KEYWORD int) c; $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getAttributes, a)); $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getAttributes, b)); $(D_KEYWORD pragma)(msg, $(D_KEYWORD __traits)(getAttributes, c)); ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE tuple(3) tuple("string", 7) tuple((Foo)) ) ) $(DDOC_BLANKLINE )

$(GNAME getLinkage)

$(DDOC_BLANKLINE ) $(P Takes one argument, which is a declaration symbol, or the type of a function, delegate, pointer to function, struct, class, or interface. Returns a string representing the $(LINK2 attribute.html#LinkageAttribute, LinkageAttribute) of the declaration. The string is one of: ) $(DDOC_BLANKLINE ) $(UL $(LI $(D "D")) $(LI $(D "C")) $(LI $(D "C++")) $(LI $(D "Windows")) $(LI $(D "Objective-C")) $(LI $(D "System")) ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD extern) (C) $(D_KEYWORD int) fooc(); $(D_KEYWORD alias) aliasc = fooc; $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getLinkage, fooc) == $(D_STRING "C")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getLinkage, aliasc) == $(D_STRING "C")); $(D_KEYWORD extern) (C++) $(D_KEYWORD struct) FooCPPStruct {} $(D_KEYWORD extern) (C++) $(D_KEYWORD class) FooCPPClass {} $(D_KEYWORD extern) (C++) $(D_KEYWORD interface) FooCPPInterface {} $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getLinkage, FooCPPStruct) == $(D_STRING "C++")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getLinkage, FooCPPClass) == $(D_STRING "C++")); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getLinkage, FooCPPInterface) == $(D_STRING "C++")); ) ) $(DDOC_BLANKLINE )

$(GNAME getLocation)

$(P Takes one argument which is a symbol. To disambiguate between overloads, pass the result of $(GLINK getOverloads) with the desired index, to getLocation. Returns a ValueSeq of a string and two ints which correspond to the filename, line number and column number where the argument was declared. ) $(DDOC_BLANKLINE )

$(GNAME getMember)

$(DDOC_BLANKLINE ) $(P Takes two arguments, the second must be a string. The result is an expression formed from the first argument, followed by a $(SINGLEQUOTE .), followed by the second argument as an identifier. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { $(D_KEYWORD int) mx; $(D_KEYWORD static) $(D_KEYWORD int) my; } $(D_KEYWORD void) main() { S s; $(D_KEYWORD __traits)(getMember, s, $(D_STRING "mx")) = 1; $(D_COMMENT // same as s.mx=1; ) writeln($(D_KEYWORD __traits)(getMember, s, $(D_STRING "m") ~ $(D_STRING "x"))); $(D_COMMENT // 1 ) $(D_COMMENT // __traits$(LPAREN)getMember, S, "mx"$(RPAREN ) = 1; // error, no this for S.mx ) $(D_KEYWORD __traits)(getMember, S, $(D_STRING "my")) = 2; $(D_COMMENT // ok )} ) ) $(DDOC_BLANKLINE )

$(GNAME getOverloads)

$(DDOC_BLANKLINE ) $(P The first argument is an aggregate (e.g. struct/class/module). The second argument is a string that matches the name of the member(s) to return. The third argument is a bool, and is optional. If true, the result will also include template overloads. The result is a symbol sequence of all the overloads of the supplied name. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD class) D { $(D_KEYWORD this)() { } ~$(D_KEYWORD this)() { } $(D_KEYWORD void) foo() { } $(D_KEYWORD int) foo($(D_KEYWORD int)) { $(D_KEYWORD return) 2; } $(D_KEYWORD void) bar(T)() { $(D_KEYWORD return) T.init; } $(D_KEYWORD class) bar($(D_KEYWORD int) n) {} } $(D_KEYWORD void) main() { D d = $(D_KEYWORD new) D(); $(D_KEYWORD foreach) (t; $(D_KEYWORD __traits)(getOverloads, D, $(D_STRING "foo"))) writeln($(D_KEYWORD typeid)($(D_KEYWORD typeof)(t))); $(D_KEYWORD alias) b = $(D_KEYWORD typeof)($(D_KEYWORD __traits)(getOverloads, D, $(D_STRING "foo"))); $(D_KEYWORD foreach) (t; b) writeln($(D_KEYWORD typeid)(t)); $(D_KEYWORD auto) i = $(D_KEYWORD __traits)(getOverloads, d, $(D_STRING "foo"))[1](1); writeln(i); $(D_KEYWORD foreach) (t; $(D_KEYWORD __traits)(getOverloads, D, $(D_STRING "bar"), $(D_KEYWORD true))) writeln(t.stringof); } ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE void() int() void() int() 2 bar(T)() bar(int n) ) $(DDOC_BLANKLINE )

$(GNAME getCppNamespaces)

$(P The argument is a symbol. The result is a ValueSeq of strings, possibly empty, that correspond to the namespaces the symbol resides in. ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD extern)(C++, $(D_STRING "ns")) $(D_KEYWORD struct) Foo {} $(D_KEYWORD struct) Bar {} $(D_KEYWORD extern)(C++, $(D_KEYWORD __traits)(getCppNamespaces, Foo)) $(D_KEYWORD struct) Baz {} $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getCppNamespaces, Foo) == $(D_KEYWORD __traits)(getCppNamespaces, Baz)); $(D_KEYWORD void) main() { $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getCppNamespaces, Foo)[0] == $(D_STRING "ns")); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(getCppNamespaces, Bar).length); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getCppNamespaces, Foo) == $(D_KEYWORD __traits)(getCppNamespaces, Baz)); } ) ) $(DDOC_BLANKLINE )

$(GNAME getVisibility)

$(DDOC_BLANKLINE ) $(P The argument is a symbol. The result is a string giving its visibility level: "public", "private", "protected", "export", or "package". ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD class) D { $(D_KEYWORD export) $(D_KEYWORD void) foo() { } $(D_KEYWORD public) $(D_KEYWORD int) bar; } $(D_KEYWORD void) main() { D d = $(D_KEYWORD new) D(); $(D_KEYWORD auto) i = $(D_KEYWORD __traits)(getVisibility, d.foo); writeln(i); $(D_KEYWORD auto) j = $(D_KEYWORD __traits)(getVisibility, d.bar); writeln(j); } ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE export public ) $(DDOC_BLANKLINE )

$(GNAME getProtection)

$(DDOC_BLANKLINE ) $(P A backward-compatible alias for $(GLINK getVisibility).) $(DDOC_BLANKLINE )

$(GNAME getTargetInfo)

$(DDOC_BLANKLINE ) $(P Receives a string key as argument. The result is an expression describing the requested target information. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD version) (CppRuntime_Microsoft) $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(getTargetInfo, $(D_STRING "cppRuntimeLibrary")) == $(D_STRING "libcmt")); ) ) $(DDOC_BLANKLINE ) $(P Keys are implementation defined, allowing relevant data for exotic targets. A reliable subset exists which are always available: ) $(DDOC_BLANKLINE ) $(UL $(LI $(D "cppRuntimeLibrary") - The C++ runtime library affinity for this toolchain) $(LI $(D "cppStd") - The version of the C++ standard supported by $(D extern$(LPAREN)C++$(RPAREN )) code, equivalent to the __cplusplus macro in a C++ compiler) $(LI $(D "floatAbi") - Floating point ABI; may be $(D "hard"), $(D "soft"), or $(D "softfp")) $(LI $(D "objectFormat") - Target object format) ) $(DDOC_BLANKLINE )

$(GNAME getUnitTests)

$(DDOC_BLANKLINE ) $(P Takes one argument, a symbol of an aggregate (e.g. struct/class/module). The result is a symbol sequence of all the unit test functions of that aggregate. The functions returned are like normal nested static functions, $(DDSUBLINK spec/glossary, ctfe, CTFE) will work and $(DDSUBLINK spec/attribute, uda, UDAs) will be accessible. ) $(DDOC_BLANKLINE )

Note:

$(DDOC_BLANKLINE ) $(P The -unittest flag needs to be passed to the compiler. If the flag is not passed $(CODE __traits(getUnitTests)) will always return an empty sequence. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD module) foo; $(D_KEYWORD import) core.runtime; $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) name { string name; } $(D_KEYWORD class) Foo { $(D_KEYWORD unittest) { writeln($(D_STRING "foo.Foo.unittest")); } } @name($(D_STRING "foo")) $(D_KEYWORD unittest) { writeln($(D_STRING "foo.unittest")); } $(D_KEYWORD template) Tuple (T...) { $(D_KEYWORD alias) Tuple = T; } $(D_KEYWORD shared) $(D_KEYWORD static) $(D_KEYWORD this)() { $(D_COMMENT // Override the default unit test runner to do nothing. After that, "main" will ) $(D_COMMENT // be called. ) Runtime.moduleUnitTester = { $(D_KEYWORD return) $(D_KEYWORD true); }; } $(D_KEYWORD void) main() { writeln($(D_STRING "start main")); $(D_KEYWORD alias) tests = Tuple!($(D_KEYWORD __traits)(getUnitTests, foo)); $(D_KEYWORD static) $(D_KEYWORD assert)(tests.length == 1); $(D_KEYWORD alias) attributes = Tuple!($(D_KEYWORD __traits)(getAttributes, tests[0])); $(D_KEYWORD static) $(D_KEYWORD assert)(attributes.length == 1); $(D_KEYWORD foreach) (test; tests) test(); $(D_KEYWORD foreach) (test; $(D_KEYWORD __traits)(getUnitTests, Foo)) test(); } ) ) $(DDOC_BLANKLINE ) $(P By default, the above will print:) $(DDOC_BLANKLINE ) $(CONSOLE start main foo.unittest foo.Foo.unittest ) $(DDOC_BLANKLINE )

$(GNAME parent)

$(DDOC_BLANKLINE ) $(P Takes a single argument which must evaluate to a symbol. The result is the symbol that is the parent of it. ) $(DDOC_BLANKLINE )

$(GNAME child)

$(DDOC_BLANKLINE ) $(P Takes two arguments. The first must be a symbol or expression. The second is a symbol, such as an alias to a member of the first argument. The result is the second argument interpreted with its $(D this) context set to the value of the first argument. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) A { $(D_KEYWORD int) i; $(D_KEYWORD int) foo($(D_KEYWORD int) j) { $(D_KEYWORD return) i * j; } T bar(T)(T t) { $(D_KEYWORD return) i + t; } } $(D_KEYWORD alias) Ai = A.i; $(D_KEYWORD alias) Abar = A.bar!$(D_KEYWORD int); $(D_KEYWORD void) main() { A a; $(D_KEYWORD __traits)(child, a, Ai) = 3; writeln(a.i); writeln($(D_KEYWORD __traits)(child, a, A.foo)(2)); writeln($(D_KEYWORD __traits)(child, a, Abar)(5)); } ) ) $(DDOC_BLANKLINE ) Prints: $(DDOC_BLANKLINE ) $(CONSOLE 3 6 8 ) $(DDOC_BLANKLINE )

$(GNAME allMembers)

$(DDOC_BLANKLINE ) $(P Takes a single argument, which must evaluate to either a module, a struct, a union, a class, an interface, an enum, or a template instantiation. $(DDOC_BLANKLINE ) A sequence of string literals is returned, each of which is the name of a member of that argument combined with all of the members of its base classes (if the argument is a class). No name is repeated. Builtin properties are not included. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD class) D { $(D_KEYWORD this)() { } ~$(D_KEYWORD this)() { } $(D_KEYWORD void) foo() { } $(D_KEYWORD int) foo($(D_KEYWORD int)) { $(D_KEYWORD return) 0; } } $(D_KEYWORD void) main() { $(D_KEYWORD auto) b = [ $(D_KEYWORD __traits)(allMembers, D) ]; writeln(b); $(D_COMMENT // ["__ctor", "__dtor", "foo", "toString", "toHash", "opCmp", "opEquals", ) $(D_COMMENT // "Monitor", "factory"] )} ) ) $(DDOC_BLANKLINE ) $(P The order in which the strings appear in the result is not defined.) $(DDOC_BLANKLINE )

$(GNAME derivedMembers)

$(DDOC_BLANKLINE ) $(P Takes a single argument, which must evaluate to either a type or an expression of type. A sequence of string literals is returned, each of which is the name of a member of that type. No name is repeated. Base class member names are not included. Builtin properties are not included. ) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD class) D { $(D_KEYWORD this)() { } ~$(D_KEYWORD this)() { } $(D_KEYWORD void) foo() { } $(D_KEYWORD int) foo($(D_KEYWORD int)) { $(D_KEYWORD return) 0; } } $(D_KEYWORD void) main() { $(D_KEYWORD auto) a = [$(D_KEYWORD __traits)(derivedMembers, D)]; writeln(a); $(D_COMMENT // ["__ctor", "__dtor", "foo"] )} ) ) $(DDOC_BLANKLINE ) $(P The order in which the strings appear in the result is not defined.) $(DDOC_BLANKLINE )

$(GNAME isSame)

$(DDOC_BLANKLINE ) $(P Compares two arguments and evaluates to bool.) $(DDOC_BLANKLINE ) $(P The result is true if the two arguments are the same symbol (once aliases are resolved).) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD struct) S { } $(D_KEYWORD int) foo(); $(D_KEYWORD int) bar(); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, foo, foo)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, foo, bar)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, foo, S)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, S, S)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, object, S)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, object, object)); $(D_KEYWORD alias) daz = foo; $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, foo, daz)); ) ) $(DDOC_BLANKLINE ) $(P The result is true if the two arguments are expressions made up of literals or enums that evaluate to the same value.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD enum) e = 3; $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, (e), 3)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, 5, 2 + e)); ) ) $(P If the two arguments are both $(DDSUBLINK spec/expression, function_literals, lambda functions) (or aliases to lambda functions), then they are compared for equality. For the comparison to be computed correctly, the following conditions must be met for both lambda functions:) $(DDOC_BLANKLINE ) $(OL $(LI The lambda function arguments must not have a template instantiation as an explicit argument type. Any other argument types (basic, user-defined, template) are supported.) $(LI The lambda function body must contain a single expression (no return statement) which contains only numeric values, manifest constants, enum values, function arguments and function calls. If the expression contains local variables or return statements, the function is considered incomparable.) ) $(DDOC_BLANKLINE ) $(P If these constraints aren't fulfilled, the function is considered incomparable and the result is $(D false).) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, (a, b) => a + b, (c, d) => c + d)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, a => ++a, b => ++b)); $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, ($(D_KEYWORD int) a, $(D_KEYWORD int) b) => a + b, (a, b) => a + b)); $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, (a, b) => a + b + 10, (c, d) => c + d + 10)); ) ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD int) f() { $(D_KEYWORD return) 2; } $(D_KEYWORD void) test($(D_KEYWORD alias) pred)() { $(D_COMMENT // f$(LPAREN)$(RPAREN ) from main is a different function from top-level f$(LPAREN)$(RPAREN ) ) $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, ($(D_KEYWORD int) a) => a + f(), pred)); } $(D_KEYWORD void) main() { $(D_COMMENT // lambdas accessing local variables are considered incomparable ) $(D_KEYWORD int) b; $(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, a => a + b, a => a + b)); $(D_COMMENT // lambdas calling other functions are comparable ) $(D_KEYWORD int) f() { $(D_KEYWORD return) 3;} $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, a => a + f(), a => a + f())); test!(($(D_KEYWORD int) a) => a + f())(); } ) ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD class) A { $(D_KEYWORD int) a; $(D_KEYWORD this)($(D_KEYWORD int) a) { $(D_KEYWORD this).a = a; } } $(D_KEYWORD class) B { $(D_KEYWORD int) a; $(D_KEYWORD this)($(D_KEYWORD int) a) { $(D_KEYWORD this).a = a; } } $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, (A a) => ++a.a, (A b) => ++b.a)); $(D_COMMENT // lambdas with different data types are considered incomparable, )$(D_COMMENT // even if the memory layout is the same )$(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, (A a) => ++a.a, (B a) => ++a.a)); ) ) $(DDOC_BLANKLINE ) $(P If the two arguments are tuples then the result is true if the two tuples, after expansion, have the same length and if each pair of nth argument respects the constraints previously specified.) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.meta; $(D_KEYWORD struct) S { } $(D_COMMENT // like __traits$(LPAREN)isSame,0,0$(RPAREN ) && __traits$(LPAREN)isSame,1,1$(RPAREN ) )$(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD __traits)(isSame, AliasSeq!(0,1), AliasSeq!(0,1))); $(D_COMMENT // like __traits$(LPAREN)isSame,S,std.meta$(RPAREN ) && __traits$(LPAREN)isSame,1,1$(RPAREN ) )$(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, AliasSeq!(S,1), AliasSeq!(std.meta,1))); $(D_COMMENT // the length of the sequences is different )$(D_KEYWORD static) $(D_KEYWORD assert)(!$(D_KEYWORD __traits)(isSame, AliasSeq!(1), AliasSeq!(1,2))); ) ) $(DDOC_BLANKLINE )

$(GNAME compiles)

$(DDOC_BLANKLINE ) $(P Returns a bool $(D true) if all of the arguments compile (are semantically correct). The arguments can be symbols, types, or expressions that are syntactically correct. The arguments cannot be statements or declarations. ) $(DDOC_BLANKLINE ) $(P If there are no arguments, the result is $(D false).) $(DDOC_BLANKLINE ) $(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) std.stdio; $(D_KEYWORD struct) S { $(D_KEYWORD static) $(D_KEYWORD int) s1; $(D_KEYWORD int) s2; } $(D_KEYWORD int) foo(); $(D_KEYWORD int) bar(); $(D_KEYWORD void) main() { writeln($(D_KEYWORD __traits)(compiles)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(compiles, foo)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(compiles, foo + 1)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(compiles, &foo + 1)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(compiles, $(D_KEYWORD typeof)(1))); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(compiles, S.s1)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(compiles, S.s3)); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(compiles, 1,2,3,$(D_KEYWORD int),$(D_KEYWORD long),std)); $(D_COMMENT // true ) writeln($(D_KEYWORD __traits)(compiles, 3[1])); $(D_COMMENT // false ) writeln($(D_KEYWORD __traits)(compiles, 1,2,3,$(D_KEYWORD int),$(D_KEYWORD long),3[1])); $(D_COMMENT // false )} ) ) $(DDOC_BLANKLINE ) $(P This is useful for:) $(DDOC_BLANKLINE ) $(UL $(LI Giving better error messages inside generic code than the sometimes hard to follow compiler ones.) $(LI Doing a finer grained specialization than template partial specialization allows for.) ) $(DDOC_BLANKLINE ) $(SPEC_SUBNAV_PREV_NEXT version, Conditional Compilation, errors, Error Handling) )