// Written in the D programming language. /** * Templates which extract information about types and symbols at compile time. * * $(SCRIPT inhibitQuickIndex = 1;) * * $(DIVC quickindex, * $(BOOKTABLE , * $(TR $(TH Category) $(TH Templates)) * $(TR $(TD Symbol Name traits) $(TD * $(LREF fullyQualifiedName) * $(LREF mangledName) * $(LREF moduleName) * $(LREF packageName) * )) * $(TR $(TD Function traits) $(TD * $(LREF isFunction) * $(LREF arity) * $(LREF functionAttributes) * $(LREF hasFunctionAttributes) * $(LREF functionLinkage) * $(LREF FunctionTypeOf) * $(LREF isSafe) * $(LREF isUnsafe) * $(LREF isFinal) * $(LREF ParameterDefaults) * $(LREF ParameterIdentifierTuple) * $(LREF ParameterStorageClassTuple) * $(LREF Parameters) * $(LREF ReturnType) * $(LREF SetFunctionAttributes) * $(LREF variadicFunctionStyle) * )) * $(TR $(TD Aggregate Type traits) $(TD * $(LREF BaseClassesTuple) * $(LREF BaseTypeTuple) * $(LREF classInstanceAlignment) * $(LREF EnumMembers) * $(LREF FieldNameTuple) * $(LREF Fields) * $(LREF hasAliasing) * $(LREF hasElaborateAssign) * $(LREF hasElaborateCopyConstructor) * $(LREF hasElaborateDestructor) * $(LREF hasElaborateMove) * $(LREF hasIndirections) * $(LREF hasMember) * $(LREF hasStaticMember) * $(LREF hasNested) * $(LREF hasUnsharedAliasing) * $(LREF InterfacesTuple) * $(LREF isInnerClass) * $(LREF isNested) * $(LREF MemberFunctionsTuple) * $(LREF RepresentationTypeTuple) * $(LREF TemplateArgsOf) * $(LREF TemplateOf) * $(LREF TransitiveBaseTypeTuple) * )) * $(TR $(TD Type Conversion) $(TD * $(LREF CommonType) * $(LREF AllImplicitConversionTargets) * $(LREF ImplicitConversionTargets) * $(LREF CopyTypeQualifiers) * $(LREF CopyConstness) * $(LREF isAssignable) * $(LREF isCovariantWith) * $(LREF isImplicitlyConvertible) * $(LREF isQualifierConvertible) * )) * $(TR $(TD Type Constructors) $(TD * $(LREF InoutOf) * $(LREF ConstOf) * $(LREF SharedOf) * $(LREF SharedInoutOf) * $(LREF SharedConstOf) * $(LREF SharedConstInoutOf) * $(LREF ImmutableOf) * $(LREF QualifierOf) * )) * $(TR $(TD Categories of types) $(TD * $(LREF allSameType) * $(LREF ifTestable) * $(LREF isType) * $(LREF isAggregateType) * $(LREF isArray) * $(LREF isAssociativeArray) * $(LREF isAutodecodableString) * $(LREF isBasicType) * $(LREF isBoolean) * $(LREF isBuiltinType) * $(LREF isCopyable) * $(LREF isDynamicArray) * $(LREF isEqualityComparable) * $(LREF isFloatingPoint) * $(LREF isIntegral) * $(LREF isNarrowString) * $(LREF isConvertibleToString) * $(LREF isNumeric) * $(LREF isOrderingComparable) * $(LREF isPointer) * $(LREF isScalarType) * $(LREF isSigned) * $(LREF isSIMDVector) * $(LREF isSomeChar) * $(LREF isSomeString) * $(LREF isStaticArray) * $(LREF isUnsigned) * )) * $(TR $(TD Type behaviours) $(TD * $(LREF isAbstractClass) * $(LREF isAbstractFunction) * $(LREF isCallable) * $(LREF isDelegate) * $(LREF isExpressions) * $(LREF isFinalClass) * $(LREF isFinalFunction) * $(LREF isFunctionPointer) * $(LREF isInstanceOf) * $(LREF isIterable) * $(LREF isMutable) * $(LREF isSomeFunction) * $(LREF isTypeTuple) * )) * $(TR $(TD General Types) $(TD * $(LREF ForeachType) * $(LREF KeyType) * $(LREF Largest) * $(LREF mostNegative) * $(LREF OriginalType) * $(LREF PointerTarget) * $(LREF Signed) * $(LREF Unconst) * $(LREF Unshared) * $(LREF Unqual) * $(LREF Unsigned) * $(LREF ValueType) * $(LREF Promoted) * )) * $(TR $(TD Misc) $(TD * $(LREF lvalueOf) * $(LREF rvalueOf) * $(LREF Select) * $(LREF select) * )) * $(TR $(TD User-Defined Attributes) $(TD * $(LREF hasUDA) * $(LREF getUDAs) * $(LREF getSymbolsByUDA) * )) * ) * ) * * Copyright: Copyright The D Language Foundation 2005 - 2009. * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * Authors: $(HTTP digitalmars.com, Walter Bright), * Tomasz Stachowiak (`isExpressions`), * $(HTTP erdani.org, Andrei Alexandrescu), * Shin Fujishiro, * $(HTTP octarineparrot.com, Robert Clipsham), * $(HTTP klickverbot.at, David Nadlinger), * Kenji Hara, * Shoichi Kato * Source: $(PHOBOSSRC std/traits.d) *//* Copyright The D Language Foundation 2005 - 2009. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */module std.traits; import std.meta : AliasSeq, allSatisfy, anySatisfy, ApplyLeft; // Legacy inheritance from std.typetuple// See also: https://github.com/dlang/phobos/pull/5484#discussion_r122602797import std.meta : staticMapMeta = staticMap;// TODO: find a way to trigger deprecation warnings//deprecated("staticMap is part of std.meta: Please import std.meta")alias staticMap = staticMapMeta; ///////////////////////////////////////////////////////////////////////////////// Type lists/////////////////////////////////////////////////////////////////////////////// private{ static if (is(ucent)) { alias CentTypeList = AliasSeq!(cent, ucent); alias SignedCentTypeList = AliasSeq!(cent); alias UnsignedCentTypeList = AliasSeq!(ucent); } else { alias CentTypeList = AliasSeq!(); alias SignedCentTypeList = AliasSeq!(); alias UnsignedCentTypeList = AliasSeq!(); } alias IntegralTypeList = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList); alias SignedIntTypeList = AliasSeq!(byte, short, int, long, SignedCentTypeList); alias UnsignedIntTypeList = AliasSeq!(ubyte, ushort, uint, ulong, UnsignedCentTypeList); alias FloatingPointTypeList = AliasSeq!(float, double, real); alias ImaginaryTypeList = AliasSeq!(ifloat, idouble, ireal); alias ComplexTypeList = AliasSeq!(cfloat, cdouble, creal); alias NumericTypeList = AliasSeq!(IntegralTypeList, FloatingPointTypeList); alias CharTypeList = AliasSeq!(char, wchar, dchar);} /** * Params: * T = The type to qualify * Returns: * `T` with the `inout` qualifier added. */alias InoutOf(T) = inout(T); ///@safe unittest{ static assert(is(InoutOf!(int) == inout int)); static assert(is(InoutOf!(inout int) == inout int)); static assert(is(InoutOf!(const int) == inout const int)); static assert(is(InoutOf!(shared int) == inout shared int));} /** * Params: * T = The type to qualify * Returns: * `T` with the `const` qualifier added. */alias ConstOf(T) = const(T); ///@safe unittest{ static assert(is(ConstOf!(int) == const int)); static assert(is(ConstOf!(const int) == const int)); static assert(is(ConstOf!(inout int) == const inout int)); static assert(is(ConstOf!(shared int) == const shared int));} /** * Params: * T = The type to qualify * Returns: * `T` with the `shared` qualifier added. */alias SharedOf(T) = shared(T); ///@safe unittest{ static assert(is(SharedOf!(int) == shared int)); static assert(is(SharedOf!(shared int) == shared int)); static assert(is(SharedOf!(inout int) == shared inout int)); static assert(is(SharedOf!(immutable int) == shared immutable int));} /** * Params: * T = The type to qualify * Returns: * `T` with the `inout` and `shared` qualifiers added. */alias SharedInoutOf(T) = shared(inout(T)); ///@safe unittest{ static assert(is(SharedInoutOf!(int) == shared inout int)); static assert(is(SharedInoutOf!(int) == inout shared int)); static assert(is(SharedInoutOf!(const int) == shared inout const int)); static assert(is(SharedInoutOf!(immutable int) == shared inout immutable int));} /** * Params: * T = The type to qualify * Returns: * `T` with the `const` and `shared` qualifiers added. */alias SharedConstOf(T) = shared(const(T)); ///@safe unittest{ static assert(is(SharedConstOf!(int) == shared const int)); static assert(is(SharedConstOf!(int) == const shared int)); static assert(is(SharedConstOf!(inout int) == shared inout const int)); // immutable variables are implicitly shared and const static assert(is(SharedConstOf!(immutable int) == immutable int));} /** * Params: * T = The type to qualify * Returns: * `T` with the `const`, `shared`, and `inout` qualifiers added. */alias SharedConstInoutOf(T) = shared(const(inout(T))); ///@safe unittest{ static assert(is(SharedConstInoutOf!(int) == shared const inout int)); static assert(is(SharedConstInoutOf!(int) == const shared inout int)); static assert(is(SharedConstInoutOf!(inout int) == shared inout const int)); // immutable variables are implicitly shared and const static assert(is(SharedConstInoutOf!(immutable int) == immutable int));} /** * Params: * T = The type to qualify * Returns: * `T` with the `immutable` qualifier added. */alias ImmutableOf(T) = immutable(T); ///@safe unittest{ static assert(is(ImmutableOf!(int) == immutable int)); static assert(is(ImmutableOf!(const int) == immutable int)); static assert(is(ImmutableOf!(inout int) == immutable int)); static assert(is(ImmutableOf!(shared int) == immutable int));} @safe unittest{ static assert(is( InoutOf!int == inout int)); static assert(is( ConstOf!int == const int)); static assert(is( SharedOf!int == shared int)); static assert(is(SharedInoutOf!int == shared inout int)); static assert(is(SharedConstOf!int == shared const int)); static assert(is( ImmutableOf!int == immutable int));} /** * Gives a template that can be used to apply the same * attributes that are on the given type `T`. E.g. passing * `inout shared int` will return `SharedInoutOf`. * * Params: * T = the type to check qualifiers from * Returns: * The qualifier template from the given type `T` */template QualifierOf(T){ static if (is(immutable T == T)) { alias QualifierOf = ImmutableOf; } else { private enum quals = is(const T == T) | (is(inout T == T) << 1) | (is(shared T == T) << 2); static if (quals == 0) { import std.meta : Alias; alias QualifierOf = Alias; } else static if (quals == 1) alias QualifierOf = ConstOf; else static if (quals == 2) alias QualifierOf = InoutOf; else static if (quals == 3) alias QualifierOf = ConstInoutOf; else static if (quals == 4) alias QualifierOf = SharedOf; else static if (quals == 5) alias QualifierOf = SharedConstOf; else static if (quals == 6) alias QualifierOf = SharedInoutOf; else alias QualifierOf = SharedConstInoutOf; }} ///@safe unittest{ static assert(__traits(isSame, QualifierOf!(shared const inout int), SharedConstInoutOf)); static assert(__traits(isSame, QualifierOf!(immutable int), ImmutableOf)); static assert(__traits(isSame, QualifierOf!(shared int), SharedOf)); static assert(__traits(isSame, QualifierOf!(shared inout int), SharedInoutOf)); import std.meta : Alias; static assert(__traits(isSame, QualifierOf!(int), Alias));} @safe unittest{ alias Qual1 = QualifierOf!( int); static assert(is(Qual1!long == long)); alias Qual2 = QualifierOf!( inout int); static assert(is(Qual2!long == inout long)); alias Qual3 = QualifierOf!( const int); static assert(is(Qual3!long == const long)); alias Qual4 = QualifierOf!(shared int); static assert(is(Qual4!long == shared long)); alias Qual5 = QualifierOf!(shared inout int); static assert(is(Qual5!long == shared inout long)); alias Qual6 = QualifierOf!(shared const int); static assert(is(Qual6!long == shared const long)); alias Qual7 = QualifierOf!( immutable int); static assert(is(Qual7!long == immutable long));} version (StdUnittest){ import std.meta : Alias; alias TypeQualifierList = AliasSeq!(Alias, ConstOf, SharedOf, SharedConstOf, ImmutableOf); struct SubTypeOf(T) { T val; alias val this; }} private alias parentOf(alias sym) = Identity!(__traits(parent, sym));private alias parentOf(alias sym : T!Args, alias T, Args...) = Identity!(__traits(parent, T)); /** * Get the full package name for the given symbol. */template packageName(alias T){ import std.algorithm.searching : startsWith; enum bool isNotFunc = !isSomeFunction!(T); static if (__traits(compiles, parentOf!T)) enum parent = packageName!(parentOf!T); else enum string parent = null; static if (isNotFunc && T.stringof.startsWith("package ")) enum packageName = (parent.length ? parent ~ '.' : "") ~ T.stringof[8 .. $]; else static if (parent) enum packageName = parent; else static assert(false, T.stringof ~ " has no parent");} ///@safe unittest{ static assert(packageName!packageName == "std");} @safe unittest{ import std.array; static assert(packageName!std == "std"); static assert(packageName!(std.traits) == "std"); // this module static assert(packageName!packageName == "std"); // symbol in this module static assert(packageName!(std.array) == "std"); // other module from same package import core.sync.barrier; // local import static assert(packageName!core == "core"); static assert(packageName!(core.sync) == "core.sync"); static assert(packageName!Barrier == "core.sync"); struct X12287(T) { T i; } static assert(packageName!(X12287!int.i) == "std");} version (none) @safe unittest //Please uncomment me when changing packageName to test global imports{ import core.sync.barrier; // global import static assert(packageName!core == "core"); static assert(packageName!(core.sync) == "core.sync"); static assert(packageName!Barrier == "core.sync");} ///@safe unittest{ static assert(packageName!moduleName == "std");} // https://issues.dlang.org/show_bug.cgi?id=13741@safe unittest{ import std.ascii : isWhite; static assert(packageName!(isWhite) == "std"); struct Foo{void opCall(int){}} static assert(packageName!(Foo.opCall) == "std"); @property void function(int) vf; static assert(packageName!(vf) == "std");} /** * Get the module name (including package) for the given symbol. */template moduleName(alias T){ import std.algorithm.searching : startsWith; enum bool isNotFunc = !isSomeFunction!(T); static if (isNotFunc) static assert(!T.stringof.startsWith("package "), "cannot get the module name for a package"); static if (isNotFunc && T.stringof.startsWith("module ")) { static if (__traits(compiles, packageName!T))Lines 1–500 of 9319. Load more
// Written in the D programming language. /** * Templates which extract information about types and symbols at compile time. * * $(SCRIPT inhibitQuickIndex = 1;) * * $(DIVC quickindex, * $(BOOKTABLE , * $(TR $(TH Category) $(TH Templates)) * $(TR $(TD Symbol Name traits) $(TD * $(LREF fullyQualifiedName) * $(LREF mangledName) * $(LREF moduleName) * $(LREF packageName) * )) * $(TR $(TD Function traits) $(TD * $(LREF isFunction) * $(LREF arity) * $(LREF functionAttributes) * $(LREF hasFunctionAttributes) * $(LREF functionLinkage) * $(LREF FunctionTypeOf) * $(LREF isSafe) * $(LREF isUnsafe) * $(LREF isFinal) * $(LREF ParameterDefaults) * $(LREF ParameterIdentifierTuple) * $(LREF ParameterStorageClassTuple) * $(LREF Parameters) * $(LREF ReturnType) * $(LREF SetFunctionAttributes) * $(LREF variadicFunctionStyle) * )) * $(TR $(TD Aggregate Type traits) $(TD * $(LREF BaseClassesTuple) * $(LREF BaseTypeTuple) * $(LREF classInstanceAlignment) * $(LREF EnumMembers) * $(LREF FieldNameTuple) * $(LREF Fields) * $(LREF hasAliasing) * $(LREF hasElaborateAssign) * $(LREF hasElaborateCopyConstructor) * $(LREF hasElaborateDestructor) * $(LREF hasElaborateMove) * $(LREF hasIndirections) * $(LREF hasMember) * $(LREF hasStaticMember) * $(LREF hasNested) * $(LREF hasUnsharedAliasing) * $(LREF InterfacesTuple) * $(LREF isInnerClass) * $(LREF isNested) * $(LREF MemberFunctionsTuple) * $(LREF RepresentationTypeTuple) * $(LREF TemplateArgsOf) * $(LREF TemplateOf) * $(LREF TransitiveBaseTypeTuple) * )) * $(TR $(TD Type Conversion) $(TD * $(LREF CommonType) * $(LREF AllImplicitConversionTargets) * $(LREF ImplicitConversionTargets) * $(LREF CopyTypeQualifiers) * $(LREF CopyConstness) * $(LREF isAssignable) * $(LREF isCovariantWith) * $(LREF isImplicitlyConvertible) * $(LREF isQualifierConvertible) * )) * $(TR $(TD Type Constructors) $(TD * $(LREF InoutOf) * $(LREF ConstOf) * $(LREF SharedOf) * $(LREF SharedInoutOf) * $(LREF SharedConstOf) * $(LREF SharedConstInoutOf) * $(LREF ImmutableOf) * $(LREF QualifierOf) * )) * $(TR $(TD Categories of types) $(TD * $(LREF allSameType) * $(LREF ifTestable) * $(LREF isType) * $(LREF isAggregateType) * $(LREF isArray) * $(LREF isAssociativeArray) * $(LREF isAutodecodableString) * $(LREF isBasicType) * $(LREF isBoolean) * $(LREF isBuiltinType) * $(LREF isCopyable) * $(LREF isDynamicArray) * $(LREF isEqualityComparable) * $(LREF isFloatingPoint) * $(LREF isIntegral) * $(LREF isNarrowString) * $(LREF isConvertibleToString) * $(LREF isNumeric) * $(LREF isOrderingComparable) * $(LREF isPointer) * $(LREF isScalarType) * $(LREF isSigned) * $(LREF isSIMDVector) * $(LREF isSomeChar) * $(LREF isSomeString) * $(LREF isStaticArray) * $(LREF isUnsigned) * )) * $(TR $(TD Type behaviours) $(TD * $(LREF isAbstractClass) * $(LREF isAbstractFunction) * $(LREF isCallable) * $(LREF isDelegate) * $(LREF isExpressions) * $(LREF isFinalClass) * $(LREF isFinalFunction) * $(LREF isFunctionPointer) * $(LREF isInstanceOf) * $(LREF isIterable) * $(LREF isMutable) * $(LREF isSomeFunction) * $(LREF isTypeTuple) * )) * $(TR $(TD General Types) $(TD * $(LREF ForeachType) * $(LREF KeyType) * $(LREF Largest) * $(LREF mostNegative) * $(LREF OriginalType) * $(LREF PointerTarget) * $(LREF Signed) * $(LREF Unconst) * $(LREF Unshared) * $(LREF Unqual) * $(LREF Unsigned) * $(LREF ValueType) * $(LREF Promoted) * )) * $(TR $(TD Misc) $(TD * $(LREF lvalueOf) * $(LREF rvalueOf) * $(LREF Select) * $(LREF select) * )) * $(TR $(TD User-Defined Attributes) $(TD * $(LREF hasUDA) * $(LREF getUDAs) * $(LREF getSymbolsByUDA) * )) * ) * ) * * Copyright: Copyright The D Language Foundation 2005 - 2009. * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * Authors: $(HTTP digitalmars.com, Walter Bright), * Tomasz Stachowiak (`isExpressions`), * $(HTTP erdani.org, Andrei Alexandrescu), * Shin Fujishiro, * $(HTTP octarineparrot.com, Robert Clipsham), * $(HTTP klickverbot.at, David Nadlinger), * Kenji Hara, * Shoichi Kato * Source: $(PHOBOSSRC std/traits.d) */ /* Copyright The D Language Foundation 2005 - 2009. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ module std.traits; import std.meta : AliasSeq, allSatisfy, anySatisfy, ApplyLeft; // Legacy inheritance from std.typetuple // See also: https://github.com/dlang/phobos/pull/5484#discussion_r122602797 import std.meta : staticMapMeta = staticMap; // TODO: find a way to trigger deprecation warnings //deprecated("staticMap is part of std.meta: Please import std.meta") alias staticMap = staticMapMeta; /////////////////////////////////////////////////////////////////////////////// // Type lists /////////////////////////////////////////////////////////////////////////////// private { static if (is(ucent)) { alias CentTypeList = AliasSeq!(cent, ucent); alias SignedCentTypeList = AliasSeq!(cent); alias UnsignedCentTypeList = AliasSeq!(ucent); } else { alias CentTypeList = AliasSeq!(); alias SignedCentTypeList = AliasSeq!(); alias UnsignedCentTypeList = AliasSeq!(); } alias IntegralTypeList = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList); alias SignedIntTypeList = AliasSeq!(byte, short, int, long, SignedCentTypeList); alias UnsignedIntTypeList = AliasSeq!(ubyte, ushort, uint, ulong, UnsignedCentTypeList); alias FloatingPointTypeList = AliasSeq!(float, double, real); alias ImaginaryTypeList = AliasSeq!(ifloat, idouble, ireal); alias ComplexTypeList = AliasSeq!(cfloat, cdouble, creal); alias NumericTypeList = AliasSeq!(IntegralTypeList, FloatingPointTypeList); alias CharTypeList = AliasSeq!(char, wchar, dchar); } /** * Params: * T = The type to qualify * Returns: * `T` with the `inout` qualifier added. */ alias InoutOf(T) = inout(T); /// @safe unittest { static assert(is(InoutOf!(int) == inout int)); static assert(is(InoutOf!(inout int) == inout int)); static assert(is(InoutOf!(const int) == inout const int)); static assert(is(InoutOf!(shared int) == inout shared int)); } /** * Params: * T = The type to qualify * Returns: * `T` with the `const` qualifier added. */ alias ConstOf(T) = const(T); /// @safe unittest { static assert(is(ConstOf!(int) == const int)); static assert(is(ConstOf!(const int) == const int)); static assert(is(ConstOf!(inout int) == const inout int)); static assert(is(ConstOf!(shared int) == const shared int)); } /** * Params: * T = The type to qualify * Returns: * `T` with the `shared` qualifier added. */ alias SharedOf(T) = shared(T); /// @safe unittest { static assert(is(SharedOf!(int) == shared int)); static assert(is(SharedOf!(shared int) == shared int)); static assert(is(SharedOf!(inout int) == shared inout int)); static assert(is(SharedOf!(immutable int) == shared immutable int)); } /** * Params: * T = The type to qualify * Returns: * `T` with the `inout` and `shared` qualifiers added. */ alias SharedInoutOf(T) = shared(inout(T)); /// @safe unittest { static assert(is(SharedInoutOf!(int) == shared inout int)); static assert(is(SharedInoutOf!(int) == inout shared int)); static assert(is(SharedInoutOf!(const int) == shared inout const int)); static assert(is(SharedInoutOf!(immutable int) == shared inout immutable int)); } /** * Params: * T = The type to qualify * Returns: * `T` with the `const` and `shared` qualifiers added. */ alias SharedConstOf(T) = shared(const(T)); /// @safe unittest { static assert(is(SharedConstOf!(int) == shared const int)); static assert(is(SharedConstOf!(int) == const shared int)); static assert(is(SharedConstOf!(inout int) == shared inout const int)); // immutable variables are implicitly shared and const static assert(is(SharedConstOf!(immutable int) == immutable int)); } /** * Params: * T = The type to qualify * Returns: * `T` with the `const`, `shared`, and `inout` qualifiers added. */ alias SharedConstInoutOf(T) = shared(const(inout(T))); /// @safe unittest { static assert(is(SharedConstInoutOf!(int) == shared const inout int)); static assert(is(SharedConstInoutOf!(int) == const shared inout int)); static assert(is(SharedConstInoutOf!(inout int) == shared inout const int)); // immutable variables are implicitly shared and const static assert(is(SharedConstInoutOf!(immutable int) == immutable int)); } /** * Params: * T = The type to qualify * Returns: * `T` with the `immutable` qualifier added. */ alias ImmutableOf(T) = immutable(T); /// @safe unittest { static assert(is(ImmutableOf!(int) == immutable int)); static assert(is(ImmutableOf!(const int) == immutable int)); static assert(is(ImmutableOf!(inout int) == immutable int)); static assert(is(ImmutableOf!(shared int) == immutable int)); } @safe unittest { static assert(is( InoutOf!int == inout int)); static assert(is( ConstOf!int == const int)); static assert(is( SharedOf!int == shared int)); static assert(is(SharedInoutOf!int == shared inout int)); static assert(is(SharedConstOf!int == shared const int)); static assert(is( ImmutableOf!int == immutable int)); } /** * Gives a template that can be used to apply the same * attributes that are on the given type `T`. E.g. passing * `inout shared int` will return `SharedInoutOf`. * * Params: * T = the type to check qualifiers from * Returns: * The qualifier template from the given type `T` */ template QualifierOf(T) { static if (is(immutable T == T)) { alias QualifierOf = ImmutableOf; } else { private enum quals = is(const T == T) | (is(inout T == T) << 1) | (is(shared T == T) << 2); static if (quals == 0) { import std.meta : Alias; alias QualifierOf = Alias; } else static if (quals == 1) alias QualifierOf = ConstOf; else static if (quals == 2) alias QualifierOf = InoutOf; else static if (quals == 3) alias QualifierOf = ConstInoutOf; else static if (quals == 4) alias QualifierOf = SharedOf; else static if (quals == 5) alias QualifierOf = SharedConstOf; else static if (quals == 6) alias QualifierOf = SharedInoutOf; else alias QualifierOf = SharedConstInoutOf; } } /// @safe unittest { static assert(__traits(isSame, QualifierOf!(shared const inout int), SharedConstInoutOf)); static assert(__traits(isSame, QualifierOf!(immutable int), ImmutableOf)); static assert(__traits(isSame, QualifierOf!(shared int), SharedOf)); static assert(__traits(isSame, QualifierOf!(shared inout int), SharedInoutOf)); import std.meta : Alias; static assert(__traits(isSame, QualifierOf!(int), Alias)); } @safe unittest { alias Qual1 = QualifierOf!( int); static assert(is(Qual1!long == long)); alias Qual2 = QualifierOf!( inout int); static assert(is(Qual2!long == inout long)); alias Qual3 = QualifierOf!( const int); static assert(is(Qual3!long == const long)); alias Qual4 = QualifierOf!(shared int); static assert(is(Qual4!long == shared long)); alias Qual5 = QualifierOf!(shared inout int); static assert(is(Qual5!long == shared inout long)); alias Qual6 = QualifierOf!(shared const int); static assert(is(Qual6!long == shared const long)); alias Qual7 = QualifierOf!( immutable int); static assert(is(Qual7!long == immutable long)); } version (StdUnittest) { import std.meta : Alias; alias TypeQualifierList = AliasSeq!(Alias, ConstOf, SharedOf, SharedConstOf, ImmutableOf); struct SubTypeOf(T) { T val; alias val this; } } private alias parentOf(alias sym) = Identity!(__traits(parent, sym)); private alias parentOf(alias sym : T!Args, alias T, Args...) = Identity!(__traits(parent, T)); /** * Get the full package name for the given symbol. */ template packageName(alias T) { import std.algorithm.searching : startsWith; enum bool isNotFunc = !isSomeFunction!(T); static if (__traits(compiles, parentOf!T)) enum parent = packageName!(parentOf!T); else enum string parent = null; static if (isNotFunc && T.stringof.startsWith("package ")) enum packageName = (parent.length ? parent ~ '.' : "") ~ T.stringof[8 .. $]; else static if (parent) enum packageName = parent; else static assert(false, T.stringof ~ " has no parent"); } /// @safe unittest { static assert(packageName!packageName == "std"); } @safe unittest { import std.array; static assert(packageName!std == "std"); static assert(packageName!(std.traits) == "std"); // this module static assert(packageName!packageName == "std"); // symbol in this module static assert(packageName!(std.array) == "std"); // other module from same package import core.sync.barrier; // local import static assert(packageName!core == "core"); static assert(packageName!(core.sync) == "core.sync"); static assert(packageName!Barrier == "core.sync"); struct X12287(T) { T i; } static assert(packageName!(X12287!int.i) == "std"); } version (none) @safe unittest //Please uncomment me when changing packageName to test global imports { import core.sync.barrier; // global import static assert(packageName!core == "core"); static assert(packageName!(core.sync) == "core.sync"); static assert(packageName!Barrier == "core.sync"); } /// @safe unittest { static assert(packageName!moduleName == "std"); } // https://issues.dlang.org/show_bug.cgi?id=13741 @safe unittest { import std.ascii : isWhite; static assert(packageName!(isWhite) == "std"); struct Foo{void opCall(int){}} static assert(packageName!(Foo.opCall) == "std"); @property void function(int) vf; static assert(packageName!(vf) == "std"); } /** * Get the module name (including package) for the given symbol. */ template moduleName(alias T) { import std.algorithm.searching : startsWith; enum bool isNotFunc = !isSomeFunction!(T); static if (isNotFunc) static assert(!T.stringof.startsWith("package "), "cannot get the module name for a package"); static if (isNotFunc && T.stringof.startsWith("module ")) { static if (__traits(compiles, packageName!T))