// 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))
            enum packagePrefix = packageName!T ~ '.';
        else
            enum packagePrefix = "";

        enum moduleName = packagePrefix ~ T.stringof[7..$];
    }
    else
        alias moduleName = moduleName!(parentOf!T); // If you use enum, it will cause compiler ICE
}

///
@safe unittest
{
    static assert(moduleName!moduleName == "std.traits");
}

@safe unittest
{
    import std.array;

    static assert(!__traits(compiles, moduleName!std));
    static assert(moduleName!(std.traits) == "std.traits");            // this module
    static assert(moduleName!moduleName == "std.traits");              // symbol in this module
    static assert(moduleName!(std.array) == "std.array");      // other module
    static assert(moduleName!(std.array.array) == "std.array");  // symbol in other module

    import core.sync.barrier;  // local import
    static assert(!__traits(compiles, moduleName!(core.sync)));
    static assert(moduleName!(core.sync.barrier) == "core.sync.barrier");
    static assert(moduleName!Barrier == "core.sync.barrier");

    struct X12287(T) { T i; }
    static assert(moduleName!(X12287!int.i) == "std.traits");
}

// https://issues.dlang.org/show_bug.cgi?id=13741
@safe unittest
{
    import std.ascii : isWhite;
    static assert(moduleName!(isWhite) == "std.ascii");

    struct Foo{void opCall(int){}}
    static assert(moduleName!(Foo.opCall) == "std.traits");

    @property void function(int) vf;
    static assert(moduleName!(vf) == "std.traits");
}

version (none) @safe unittest //Please uncomment me when changing moduleName to test global imports
{
    import core.sync.barrier;  // global import
    static assert(!__traits(compiles, moduleName!(core.sync)));
    static assert(moduleName!(core.sync.barrier) == "core.sync.barrier");
    static assert(moduleName!Barrier == "core.sync.barrier");
}

/***
 * Get the fully qualified name of a type or a symbol. Can act as an intelligent type/symbol to string  converter.

Example:
-----------------
module myModule;
struct MyStruct {}
static assert(fullyQualifiedName!(const MyStruct[]) == "const(myModule.MyStruct[])");
-----------------
*/
enum fullyQualifiedName(T) = fqnType!(T, false, false, false, false);

/// ditto
enum fullyQualifiedName(alias T) = fqnSym!(T);

///
@safe unittest
{
    static assert(fullyQualifiedName!fullyQualifiedName == "std.traits.fullyQualifiedName");
}

version (StdUnittest)
{
    // Used for both fqnType and fqnSym unittests
    private struct QualifiedNameTests
    {
        struct Inner
        {
            bool value;
        }

        ref const(Inner[string]) func( ref Inner var1, lazy scope string var2 );
        ref const(Inner[string]) retfunc( return ref Inner var1 );
        Inner inoutFunc(inout Inner) inout;
        shared(const(Inner[string])[]) data;
        const Inner delegate(double, string) @safe nothrow deleg;
        inout(int) delegate(inout int) inout inoutDeleg;
        Inner function(out double, string) funcPtr;
        extern(C) Inner function(double, string) cFuncPtr;

        extern(C) void cVarArg(int, ...);
        void dVarArg(...);
        void dVarArg2(int, ...);
        void typesafeVarArg(int[] ...);

        Inner[] array;
        Inner[16] sarray;
        Inner[Inner] aarray;
        const(Inner[const(Inner)]) qualAarray;

        shared(immutable(Inner) delegate(ref double, scope string) const shared @trusted nothrow) attrDeleg;

        struct Data(T) { int x; }
        void tfunc(T...)(T args) {}

        template Inst(alias A) { int x; }

        class Test12309(T, int x, string s) {}
    }

    private enum QualifiedEnum
    {
        a = 42
    }
}

private template fqnSym(alias T : X!A, alias X, A...)
{
    template fqnTuple(T...)
    {
        static if (T.length == 0)
            enum fqnTuple = "";
        else static if (T.length == 1)
        {
            static if (isExpressionTuple!T)
                enum fqnTuple = T[0].stringof;
            else
                enum fqnTuple = fullyQualifiedName!(T[0]);
        }
        else
            enum fqnTuple = fqnTuple!(T[0]) ~ ", " ~ fqnTuple!(T[1 .. $]);
    }

    enum fqnSym =
        fqnSym!(__traits(parent, X)) ~
        '.' ~ __traits(identifier, X) ~ "!(" ~ fqnTuple!A ~ ")";
}

private template fqnSym(alias T)
{
    static if (__traits(compiles, __traits(parent, T)) && !__traits(isSame, T, __traits(parent, T)))
        enum parentPrefix = fqnSym!(__traits(parent, T)) ~ ".";
    else
        enum parentPrefix = null;

    static string adjustIdent(string s)
    {
        import std.algorithm.searching : findSplit, skipOver;

        if (s.skipOver("package ") || s.skipOver("module "))
            return s;
        return s.findSplit("(")[0];
    }
    enum fqnSym = parentPrefix ~ adjustIdent(__traits(identifier, T));
}

@safe unittest
{
    alias fqn = fullyQualifiedName;

    // Make sure those 2 are the same
    static assert(fqnSym!fqn == fqn!fqn);

    static assert(fqn!fqn == "std.traits.fullyQualifiedName");

    alias qnTests = QualifiedNameTests;
    enum prefix = "std.traits.QualifiedNameTests.";
    static assert(fqn!(qnTests.Inner)           == prefix ~ "Inner");
    static assert(fqn!(qnTests.func)            == prefix ~ "func");
    static assert(fqn!(qnTests.Data!int)        == prefix ~ "Data!(int)");
    static assert(fqn!(qnTests.Data!int.x)      == prefix ~ "Data!(int).x");
    static assert(fqn!(qnTests.tfunc!(int[]))   == prefix ~ "tfunc!(int[])");
    static assert(fqn!(qnTests.Inst!(Object))   == prefix ~ "Inst!(object.Object)");
    static assert(fqn!(qnTests.Inst!(Object).x) == prefix ~ "Inst!(object.Object).x");

    static assert(fqn!(qnTests.Test12309!(int, 10, "str"))
                                                == prefix ~ "Test12309!(int, 10, \"str\")");

    import core.sync.barrier;
    static assert(fqn!Barrier == "core.sync.barrier.Barrier");
}

@safe unittest
{
    struct TemplatedStruct()
    {
        enum foo = 0;
    }
    alias TemplatedStructAlias = TemplatedStruct;
    assert("TemplatedStruct.foo" == fullyQualifiedName!(TemplatedStructAlias!().foo));
}

private template fqnType(T,
    bool alreadyConst, bool alreadyImmutable, bool alreadyShared, bool alreadyInout)
{
    // Convenience tags
    enum {
        _const = 0,
        _immutable = 1,
        _shared = 2,
        _inout = 3
    }

    alias qualifiers   = AliasSeq!(is(T == const), is(T == immutable), is(T == shared), is(T == inout));
    alias noQualifiers = AliasSeq!(false, false, false, false);

    string storageClassesString(uint psc)() @property
    {
        import std.conv : text;

        alias PSC = ParameterStorageClass;

        return text(
            psc & PSC.scope_ ? "scope " : "",
            psc & PSC.return_ ? "return " : "",
            psc & PSC.in_ ? "in " : "",
            psc & PSC.out_ ? "out " : "",
            psc & PSC.ref_ ? "ref " : "",
            psc & PSC.lazy_ ? "lazy " : "",
        );
    }

    string parametersTypeString(T)() @property
    {
        alias parameters   = Parameters!(T);
        alias parameterStC = ParameterStorageClassTuple!(T);

        enum variadic = variadicFunctionStyle!T;
        static if (variadic == Variadic.no)
            enum variadicStr = "";
        else static if (variadic == Variadic.c)
            enum variadicStr = ", ...";
        else static if (variadic == Variadic.d)
            enum variadicStr = parameters.length ? ", ..." : "...";
        else static if (variadic == Variadic.typesafe)
            enum variadicStr = " ...";
        else
            static assert(0, "New variadic style has been added, please update fullyQualifiedName implementation");

        static if (parameters.length)
        {
            import std.algorithm.iteration : map;
            import std.array : join;
            import std.meta : staticMap;
            import std.range : zip;

            string result = join(
                map!(a => (a[0] ~ a[1]))(
                    zip([staticMap!(storageClassesString, parameterStC)],
                        [staticMap!(fullyQualifiedName, parameters)])
                ),
                ", "
            );

            return result ~= variadicStr;
        }
        else
            return variadicStr;
    }

    string linkageString(T)() @property
    {
        enum linkage = functionLinkage!T;

        if (linkage != "D")
            return "extern(" ~ linkage ~ ") ";
        else
            return "";
    }

    string functionAttributeString(T)() @property
    {
        alias FA = FunctionAttribute;
        enum attrs = functionAttributes!T;

        static if (attrs == FA.none)
            return "";
        else
            return
                (attrs & FA.pure_ ? " pure" : "")
                ~ (attrs & FA.nothrow_ ? " nothrow" : "")
                ~ (attrs & FA.ref_ ? " ref" : "")
                ~ (attrs & FA.property ? " @property" : "")
                ~ (attrs & FA.trusted ? " @trusted" : "")
                ~ (attrs & FA.safe ? " @safe" : "")
                ~ (attrs & FA.nogc ? " @nogc" : "")
                ~ (attrs & FA.return_ ? " return" : "")
                ~ (attrs & FA.live ? " @live" : "");
    }

    string addQualifiers(string typeString,
        bool addConst, bool addImmutable, bool addShared, bool addInout)
    {
        auto result = typeString;
        if (addShared)
        {
            result = "shared(" ~ result ~")";
        }
        if (addConst || addImmutable || addInout)
        {
            result = (addConst ? "const" : addImmutable ? "immutable" : "inout")
                ~ "(" ~ result ~ ")";
        }
        return result;
    }

    // Convenience template to avoid copy-paste
    template chain(string current)
    {
        enum chain = addQualifiers(current,
            qualifiers[_const]     && !alreadyConst,
            qualifiers[_immutable] && !alreadyImmutable,
            qualifiers[_shared]    && !alreadyShared,
            qualifiers[_inout]     && !alreadyInout);
    }

    static if (is(T == string))
    {
        enum fqnType = "string";
    }
    else static if (is(T == wstring))
    {
        enum fqnType = "wstring";
    }
    else static if (is(T == dstring))
    {
        enum fqnType = "dstring";
    }
    else static if (is(T == typeof(null)))
    {
        enum fqnType = "typeof(null)";
    }
    else static if (isBasicType!T && !is(T == enum))
    {
        enum fqnType = chain!((Unqual!T).stringof);
    }
    else static if (isAggregateType!T || is(T == enum))
    {
        enum fqnType = chain!(fqnSym!T);
    }
    else static if (isStaticArray!T)
    {
        import std.conv : to;
        enum fqnType = chain!(
            fqnType!(typeof(T.init[0]), qualifiers) ~ "[" ~ to!string(T.length) ~ "]"
        );
    }
    else static if (isArray!T)
    {
        enum fqnType = chain!(
            fqnType!(typeof(T.init[0]), qualifiers) ~ "[]"
        );
    }
    else static if (isAssociativeArray!T)
    {
        enum fqnType = chain!(
            fqnType!(ValueType!T, qualifiers) ~ '[' ~ fqnType!(KeyType!T, noQualifiers) ~ ']'
        );
    }
    else static if (isSomeFunction!T)
    {
        static if (is(T F == delegate))
        {
            enum qualifierString =
                (is(F == shared) ? " shared" : "")
                ~ (is(F == inout) ? " inout" :
                    is(F == immutable) ? " immutable" :
                    is(F == const) ? " const" : "");
            enum fqnType = chain!(
                linkageString!T
                ~ fqnType!(ReturnType!T, noQualifiers)
                ~ " delegate(" ~ parametersTypeString!(T) ~ ")"
                ~ functionAttributeString!T
                ~ qualifierString
            );
        }
        else
        {
            enum fqnType = chain!(
                linkageString!T
                ~ fqnType!(ReturnType!T, noQualifiers)
                ~ (isFunctionPointer!T ? " function(" : "(")
                ~ parametersTypeString!(T) ~ ")"
                ~ functionAttributeString!T
            );
        }
    }
    else static if (is(T == U*, U))
    {
        enum fqnType = chain!(
            fqnType!(U, qualifiers) ~ "*"
        );
    }
    else static if (is(T : __vector(V[N]), V, size_t N))
    {
        import std.conv : to;
        enum fqnType = chain!(
            "__vector(" ~ fqnType!(V, qualifiers) ~ "[" ~ N.to!string ~ "])"
        );
    }
    else
        // In case something is forgotten
        static assert(0, "Unrecognized type " ~ T.stringof ~ ", can't convert to fully qualified string");
}

@safe unittest
{
    import std.format : format;
    alias fqn = fullyQualifiedName;

    // Verify those 2 are the same for simple case
    alias Ambiguous = const(QualifiedNameTests.Inner);
    static assert(fqn!Ambiguous == fqnType!(Ambiguous, false, false, false, false));

    // Main tests
    enum inner_name = "std.traits.QualifiedNameTests.Inner";
    with (QualifiedNameTests)
    {
        // Special cases
        static assert(fqn!(string) == "string");
        static assert(fqn!(wstring) == "wstring");
        static assert(fqn!(dstring) == "dstring");
        static assert(fqn!(typeof(null)) == "typeof(null)");
        static assert(fqn!(void) == "void");
        static assert(fqn!(const(void)) == "const(void)");
        static assert(fqn!(shared(void)) == "shared(void)");
        static assert(fqn!(shared const(void)) == "const(shared(void))");
        static assert(fqn!(shared inout(void)) == "inout(shared(void))");
        static assert(fqn!(shared inout const(void)) == "const(shared(void))");
        static assert(fqn!(inout(void)) == "inout(void)");
        static assert(fqn!(inout const(void)) == "const(void)");
        static assert(fqn!(immutable(void)) == "immutable(void)");

        // Basic qualified name
        static assert(fqn!(Inner) == inner_name);
        static assert(fqn!(QualifiedEnum) == "std.traits.QualifiedEnum"); // type
        static assert(fqn!(QualifiedEnum.a) == "std.traits.QualifiedEnum.a"); // symbol

        // Array types
        static assert(fqn!(typeof(array)) == format("%s[]", inner_name));
        static assert(fqn!(typeof(sarray)) == format("%s[16]", inner_name));
        static assert(fqn!(typeof(aarray)) == format("%s[%s]", inner_name, inner_name));

        // qualified key for AA
        static assert(fqn!(typeof(qualAarray)) == format("const(%s[const(%s)])", inner_name, inner_name));

        // Qualified composed data types
        static assert(fqn!(typeof(data)) == format("shared(const(%s[string])[])", inner_name));

        // Function types + function attributes
        static assert(fqn!(typeof(func)) == format("const(%s[string])(ref %s, scope lazy string) ref",
                    inner_name, inner_name));
        static assert(fqn!(typeof(retfunc)) == format("const(%s[string])(return %s) ref", inner_name, inner_name));
        static assert(fqn!(typeof(inoutFunc)) == format("inout(%s(inout(%s)))", inner_name, inner_name));
        static assert(fqn!(typeof(deleg)) == format("const(%s delegate(double, string) nothrow @safe)", inner_name));
        static assert(fqn!(typeof(inoutDeleg)) == "inout(int) delegate(inout(int)) inout");
        static assert(fqn!(typeof(funcPtr)) == format("%s function(out double, string)", inner_name));
        static assert(fqn!(typeof(cFuncPtr)) == format("extern(C) %s function(double, string)", inner_name));

        // Delegate type with qualified function type
        static assert(fqn!(typeof(attrDeleg)) == format("shared(immutable(%s) "~
            "delegate(ref double, scope string) nothrow @trusted shared const)", inner_name));

        // Variable argument function types
        static assert(fqn!(typeof(cVarArg)) == "extern(C) void(int, ...)");
        static assert(fqn!(typeof(dVarArg)) == "void(...)");
        static assert(fqn!(typeof(dVarArg2)) == "void(int, ...)");
        static assert(fqn!(typeof(typesafeVarArg)) == "void(int[] ...)");

        // SIMD vector
        static if (is(__vector(float[4])))
        {
            static assert(fqn!(__vector(float[4])) == "__vector(float[4])");
        }
    }
}

/***
 * Get the type of the return value from a function,
 * a pointer to function, a delegate, a struct
 * with an opCall, a pointer to a struct with an opCall,
 * or a class with an `opCall`. Please note that $(D_KEYWORD ref)
 * is not part of a type, but the attribute of the function
 * (see template $(LREF functionAttributes)).
 *
 * $(NOTE To reduce template instantiations, consider instead using
 * $(D typeof(() { return func(args); } ())) if the argument types are known or
 * $(D static if (is(typeof(func) Ret == return))) if only that basic test is needed.)
 */
template ReturnType(alias func)
if (isCallable!func)
{
    static if (is(FunctionTypeOf!func R == return))
        alias ReturnType = R;
    else
        static assert(0, "argument has no return type");
}

///
@safe unittest
{
    int foo();
    ReturnType!foo x;   // x is declared as int
}

@safe unittest
{
    struct G
    {
        int opCall (int i) { return 1;}
    }

    alias ShouldBeInt = ReturnType!G;
    static assert(is(ShouldBeInt == int));

    G g;
    static assert(is(ReturnType!g == int));

    G* p;
    alias pg = ReturnType!p;
    static assert(is(pg == int));

    class C
    {
        int opCall (int i) { return 1;}
    }

    static assert(is(ReturnType!C == int));

    C c;
    static assert(is(ReturnType!c == int));

    class Test
    {
        int prop() @property { return 0; }
    }
    alias R_Test_prop = ReturnType!(Test.prop);
    static assert(is(R_Test_prop == int));

    alias R_dglit = ReturnType!((int a) { return a; });
    static assert(is(R_dglit == int));
}

/***
Get, as a tuple, the types of the parameters to a function, a pointer
to function, a delegate, a struct with an `opCall`, a pointer to a
struct with an `opCall`, or a class with an `opCall`.
*/
template Parameters(alias func)
if (isCallable!func)
{
    static if (is(FunctionTypeOf!func P == function))
        alias Parameters = P;
    else
        static assert(0, "argument has no parameters");
}

///
@safe unittest
{
    int foo(int, long);
    void bar(Parameters!foo);      // declares void bar(int, long);
    void abc(Parameters!foo[1]);   // declares void abc(long);
}

/**
 * Alternate name for $(LREF Parameters), kept for legacy compatibility.
 */
alias ParameterTypeTuple = Parameters;

@safe unittest
{
    int foo(int i, bool b) { return 0; }
    static assert(is(ParameterTypeTuple!foo == AliasSeq!(int, bool)));
    static assert(is(ParameterTypeTuple!(typeof(&foo)) == AliasSeq!(int, bool)));

    struct S { real opCall(real r, int i) { return 0.0; } }
    S s;
    static assert(is(ParameterTypeTuple!S == AliasSeq!(real, int)));
    static assert(is(ParameterTypeTuple!(S*) == AliasSeq!(real, int)));
    static assert(is(ParameterTypeTuple!s == AliasSeq!(real, int)));

    class Test
    {
        int prop() @property { return 0; }
    }
    alias P_Test_prop = ParameterTypeTuple!(Test.prop);
    static assert(P_Test_prop.length == 0);

    alias P_dglit = ParameterTypeTuple!((int a){});
    static assert(P_dglit.length == 1);
    static assert(is(P_dglit[0] == int));
}

/**
Returns the number of arguments of function `func`.
arity is undefined for variadic functions.
*/
template arity(alias func)
if (isCallable!func && variadicFunctionStyle!func == Variadic.no)
{
    enum size_t arity = Parameters!func.length;
}

///
@safe unittest
{
    void foo(){}
    static assert(arity!foo == 0);
    void bar(uint){}
    static assert(arity!bar == 1);
    void variadicFoo(uint...){}
    static assert(!__traits(compiles, arity!variadicFoo));
}

// https://issues.dlang.org/show_bug.cgi?id=11389
@safe unittest
{
    alias TheType = size_t function( string[] );
    static assert(arity!TheType == 1);
}

/**
Get a tuple of the storage classes of a function's parameters.
Params:
    func = function symbol or type of function, delegate, or pointer to function
Returns:
    A tuple of ParameterStorageClass bits
 */
enum ParameterStorageClass : uint
{
    /**
     * These flags can be bitwise OR-ed together to represent complex storage
     * class.
     */
    none    = 0x00,
    in_     = 0x01, /// ditto
    ref_    = 0x02, /// ditto
    out_    = 0x04, /// ditto
    lazy_   = 0x08, /// ditto
    scope_  = 0x10, /// ditto
    return_ = 0x20, /// ditto
}

/// ditto
template ParameterStorageClassTuple(alias func)
if (isCallable!func)
{
    alias Func = FunctionTypeOf!func;

    static if (is(Func PT == __parameters))
    {
        alias ParameterStorageClassTuple = AliasSeq!();
        static foreach (i; 0 .. PT.length)
        {
            ParameterStorageClassTuple = AliasSeq!(ParameterStorageClassTuple,
                extractParameterStorageClassFlags!(__traits(getParameterStorageClasses, Func, i)));
        }
    }
    else
    {
        static assert(0, func.stringof, " is not a function");
        alias ParameterStorageClassTuple = AliasSeq!();
    }
}

///
@safe unittest
{
    alias STC = ParameterStorageClass; // shorten the enum name

    void func(ref int ctx, out real result, in real param, void* ptr)
    {
    }
    alias pstc = ParameterStorageClassTuple!func;
    static assert(pstc.length == 4); // number of parameters
    static assert(pstc[0] == STC.ref_);
    static assert(pstc[1] == STC.out_);
    static assert(pstc[2] == STC.in_);
    static assert(pstc[3] == STC.none);
}

/**
Convert the result of $(DDSUBLINK spec/traits, getParameterStorageClasses, `__traits(getParameterStorageClasses)`)
to $(LREF ParameterStorageClass) `enum`s.

Params:
    Attribs = The return value of `__traits(getParameterStorageClasses)`
Returns:
    The bitwise OR of the equivalent $(LREF ParameterStorageClass) `enum`s.
 */
template extractParameterStorageClassFlags(Attribs...)
{
    enum ParameterStorageClass extractParameterStorageClassFlags = ()
    {
        auto result = ParameterStorageClass.none;
        static if (Attribs.length > 0)
        {
            static foreach (attrib; Attribs)
            {
                final switch (attrib) with (ParameterStorageClass)
                {
                    case "scope":  result |= scope_;  break;
                    case "in":     result |= in_;    break;
                    case "out":    result |= out_;    break;
                    case "ref":    result |= ref_;    break;
                    case "lazy":   result |= lazy_;   break;
                    case "return": result |= return_; break;
                }
            }
            /* Mimic behavor of original version of ParameterStorageClassTuple()
             * to avoid breaking existing code.
             */
            if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_))
                result = ParameterStorageClass.return_;
        }
        return result;
    }();
}

///
@safe unittest
{
    static void func(ref int ctx, out real result);

    enum param1 = extractParameterStorageClassFlags!(
        __traits(getParameterStorageClasses, func, 0)
    );
    static assert(param1 == ParameterStorageClass.ref_);

    enum param2 = extractParameterStorageClassFlags!(
        __traits(getParameterStorageClasses, func, 1)
    );
    static assert(param2 == ParameterStorageClass.out_);

    enum param3 = extractParameterStorageClassFlags!(
        __traits(getParameterStorageClasses, func, 0),
        __traits(getParameterStorageClasses, func, 1)
    );
    static assert(param3 == (ParameterStorageClass.ref_ | ParameterStorageClass.out_));
}

@safe unittest
{
    alias STC = ParameterStorageClass;

    void noparam() {}
    static assert(ParameterStorageClassTuple!noparam.length == 0);

    ref int test(scope int*, ref int, out int, lazy int, int, return ref int i) { return i; }
    alias test_pstc = ParameterStorageClassTuple!test;
    static assert(test_pstc.length == 6);
    static assert(test_pstc[0] == STC.scope_);
    static assert(test_pstc[1] == STC.ref_);
    static assert(test_pstc[2] == STC.out_);
    static assert(test_pstc[3] == STC.lazy_);
    static assert(test_pstc[4] == STC.none);
    static assert(test_pstc[5] == STC.return_);

    interface Test
    {
        void test_const(int) const;
        void test_sharedconst(int) shared const;
    }
    Test testi;

    alias test_const_pstc = ParameterStorageClassTuple!(Test.test_const);
    static assert(test_const_pstc.length == 1);
    static assert(test_const_pstc[0] == STC.none);

    alias test_sharedconst_pstc = ParameterStorageClassTuple!(testi.test_sharedconst);
    static assert(test_sharedconst_pstc.length == 1);
    static assert(test_sharedconst_pstc[0] == STC.none);

    alias dglit_pstc = ParameterStorageClassTuple!((ref int a) {});
    static assert(dglit_pstc.length == 1);
    static assert(dglit_pstc[0] == STC.ref_);

    // https://issues.dlang.org/show_bug.cgi?id=9317
    static inout(int) func(inout int param) { return param; }
    static assert(ParameterStorageClassTuple!(typeof(func))[0] == STC.none);
}

@safe unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=14253
    static struct Foo {
        ref Foo opAssign(ref Foo rhs) return { return this; }
    }

    alias tup = ParameterStorageClassTuple!(__traits(getOverloads, Foo, "opAssign")[0]);
}


/**
Get, as a tuple, the identifiers of the parameters to a function symbol.
 */
template ParameterIdentifierTuple(alias func)
if (isCallable!func)
{
    static if (is(FunctionTypeOf!func PT == __parameters))
    {
        alias ParameterIdentifierTuple = AliasSeq!();
        static foreach (i; 0 .. PT.length)
        {
            static if (!isFunctionPointer!func && !isDelegate!func
                       // Unnamed parameters yield CT error.
                       && is(typeof(__traits(identifier, PT[i .. i+1])))
                       // Filter out unnamed args, which look like (Type) instead of (Type name).
                       && PT[i].stringof != PT[i .. i+1].stringof[1..$-1])
            {
                ParameterIdentifierTuple = AliasSeq!(ParameterIdentifierTuple,
                    __traits(identifier, PT[i .. i+1]));
            }
            else
            {
                ParameterIdentifierTuple = AliasSeq!(ParameterIdentifierTuple, "");
            }
        }
    }
    else
    {
        static assert(0, func.stringof ~ " is not a function");
        // avoid pointless errors
        alias ParameterIdentifierTuple = AliasSeq!();
    }
}

///
@safe unittest
{
    int foo(int num, string name, int);
    static assert([ParameterIdentifierTuple!foo] == ["num", "name", ""]);
}

// https://issues.dlang.org/show_bug.cgi?id=19456
@safe unittest
{
    struct SomeType {}
    void foo(SomeType);
    void bar(int);
    static assert([ParameterIdentifierTuple!foo] == [""]);
    static assert([ParameterIdentifierTuple!bar] == [""]);
}

@safe unittest
{
    alias PIT = ParameterIdentifierTuple;

    void bar(int num, string name, int[] array){}
    static assert([PIT!bar] == ["num", "name", "array"]);

    // might be changed in the future?
    void function(int num, string name) fp;
    static assert([PIT!fp] == ["", ""]);

    // might be changed in the future?
    void delegate(int num, string name, int[long] aa) dg;
    static assert([PIT!dg] == ["", "", ""]);

    interface Test
    {
        @property string getter();
        @property void setter(int a);
        Test method(int a, long b, string c);
    }
    static assert([PIT!(Test.getter)] == []);
    static assert([PIT!(Test.setter)] == ["a"]);
    static assert([PIT!(Test.method)] == ["a", "b", "c"]);

/+
    // depends on internal
    void baw(int, string, int[]){}
    static assert([PIT!baw] == ["_param_0", "_param_1", "_param_2"]);

    // depends on internal
    void baz(AliasSeq!(int, string, int[]) args){}
    static assert([PIT!baz] == ["_param_0", "_param_1", "_param_2"]);
+/
}


/**
Get, as a tuple, the default values of the parameters to a function symbol.
If a parameter doesn't have the default value, `void` is returned instead.
 */
template ParameterDefaults(alias func)
if (isCallable!func)
{
    alias param_names = ParameterIdentifierTuple!func;
    static if (is(FunctionTypeOf!(func) PT == __parameters))
    {
        template Get(size_t i)
        {
            // `PT[i .. i+1]` declares a parameter with an arbitrary name.
            // To avoid a name clash, generate local names that are distinct
            // from the parameter name, and mix them in.
            enum name = param_names[i];
            enum args = "args" ~ (name == "args" ? "_" : "");
            enum val = "val" ~ (name == "val" ? "_" : "");
            enum ptr = "ptr" ~ (name == "ptr" ? "_" : "");
            enum hasDefaultArg = mixin("(PT[i .. i+1] ", args, ") => true");
            static if (is(typeof(hasDefaultArg())))
            {
                enum get = mixin("(return scope PT[i .. i+1] ", args, ")
                {
                    // If the parameter is lazy, we force it to be evaluated
                    // like this.
                    auto ", val, " = ", args, "[0];
                    auto ", ptr, " = &", val, ";
                    return *", ptr, ";
                }");
                enum Get = get();
            }
            else
                alias Get = void;
                // If default arg doesn't exist, returns void instead.
        }
        alias ParameterDefaults = AliasSeq!();
        static foreach (i; 0 .. PT.length)
        {
            ParameterDefaults = AliasSeq!(ParameterDefaults,
                Get!i);
        }
    }
    else
    {
        static assert(0, func.stringof ~ " is not a function");
        // avoid pointless errors
        alias ParameterDefaults = AliasSeq!();
    }
}

///
@safe unittest
{
    int foo(int num, string name = "hello", int[] = [1,2,3], lazy int x = 0);
    static assert(is(ParameterDefaults!foo[0] == void));
    static assert(   ParameterDefaults!foo[1] == "hello");
    static assert(   ParameterDefaults!foo[2] == [1,2,3]);
    static assert(   ParameterDefaults!foo[3] == 0);
}

// https://issues.dlang.org/show_bug.cgi?id=17192
@safe unittest
{
    static void func(int i, int PT, int __pd_value, int __pd_val, int __args,
        int name, int args, int val, int ptr, int args_, int val_, int ptr_)
    {
    }
    alias Voids = ParameterDefaults!func;
    static assert(Voids.length == 12);
    static foreach (V; Voids) static assert(is(V == void));
}

// https://issues.dlang.org/show_bug.cgi?id=20182
@safe pure nothrow @nogc unittest
{
    struct S
    {
        this(ref S) {}
    }

    static assert(__traits(compiles, ParameterDefaults!(S.__ctor)));
}

/**
 * Alternate name for $(LREF ParameterDefaults), kept for legacy compatibility.
 */
alias ParameterDefaultValueTuple = ParameterDefaults;

@safe unittest
{
    alias PDVT = ParameterDefaultValueTuple;

    void bar(int n = 1, string s = "hello"){}
    static assert(PDVT!bar.length == 2);
    static assert(PDVT!bar[0] == 1);
    static assert(PDVT!bar[1] == "hello");
    static assert(is(typeof(PDVT!bar) == typeof(AliasSeq!(1, "hello"))));

    void baz(int x, int n = 1, string s = "hello"){}
    static assert(PDVT!baz.length == 3);
    static assert(is(PDVT!baz[0] == void));
    static assert(   PDVT!baz[1] == 1);
    static assert(   PDVT!baz[2] == "hello");
    static assert(is(typeof(PDVT!baz) == typeof(AliasSeq!(void, 1, "hello"))));

    // property functions return empty string
    // https://issues.dlang.org/show_bug.cgi?id=10800
    @property void foo(int x = 3) { }
    static assert(PDVT!foo.length == 1);
    static assert(PDVT!foo[0] == 3);
    static assert(is(typeof(PDVT!foo) == typeof(AliasSeq!(3))));

    struct Colour
    {
        ubyte a,r,g,b;

        static immutable Colour white = Colour(255,255,255,255);
    }
    // https://issues.dlang.org/show_bug.cgi?id=8106
    void bug8106(Colour c = Colour.white) {}
    //pragma(msg, PDVT!bug8106);
    static assert(PDVT!bug8106[0] == Colour.white);
    // https://issues.dlang.org/show_bug.cgi?id=16582
    void bug16582(scope int* val = null) {}
    static assert(PDVT!bug16582[0] is null);
}


/**
Returns the FunctionAttribute mask for function `func`.

See_Also:
    $(LREF hasFunctionAttributes)
 */
enum FunctionAttribute : uint
{
    /**
     * These flags can be bitwise OR-ed together to represent a complex attribute.
     */
    none       = 0,
    pure_      = 1 << 0,  /// ditto
    nothrow_   = 1 << 1,  /// ditto
    ref_       = 1 << 2,  /// ditto
    property   = 1 << 3,  /// ditto
    trusted    = 1 << 4,  /// ditto
    safe       = 1 << 5,  /// ditto
    nogc       = 1 << 6,  /// ditto
    system     = 1 << 7,  /// ditto
    const_     = 1 << 8,  /// ditto
    immutable_ = 1 << 9,  /// ditto
    inout_     = 1 << 10, /// ditto
    shared_    = 1 << 11, /// ditto
    return_    = 1 << 12, /// ditto
    scope_     = 1 << 13, /// ditto
    live       = 1 << 14, /// ditto
}

/// ditto
template functionAttributes(alias func)
if (isCallable!func)
{
    // @bug: workaround for opCall
    alias FuncSym = Select!(is(typeof(__traits(getFunctionAttributes, func))),
                            func, Unqual!(FunctionTypeOf!func));

    enum FunctionAttribute functionAttributes =
        extractAttribFlags!(__traits(getFunctionAttributes, FuncSym))();
}

///
@safe unittest
{
    alias FA = FunctionAttribute; // shorten the enum name

    real func(real x) pure nothrow @safe
    {
        return x;
    }
    static assert(functionAttributes!func & FA.pure_);
    static assert(functionAttributes!func & FA.safe);
    static assert(!(functionAttributes!func & FA.trusted)); // not @trusted
}

@system unittest
{
    alias FA = FunctionAttribute;

    struct S
    {
        int noF() { return 0; }
        int constF() const { return 0; }
        int immutableF() immutable { return 0; }
        int inoutF() inout { return 0; }
        int sharedF() shared { return 0; }

        int x;
        ref int refF() return { return x; }
        int propertyF() @property { return 0; }
        int nothrowF() nothrow { return 0; }
        int nogcF() @nogc { return 0; }

        int systemF() @system { return 0; }
        int trustedF() @trusted { return 0; }
        int safeF() @safe { return 0; }

        int pureF() pure { return 0; }

        int liveF() @live { return 0; }
    }

    static assert(functionAttributes!(S.noF) == FA.system);
    static assert(functionAttributes!(typeof(S.noF)) == FA.system);

    static assert(functionAttributes!(S.constF) == (FA.const_ | FA.system));
    static assert(functionAttributes!(typeof(S.constF)) == (FA.const_ | FA.system));

    static assert(functionAttributes!(S.immutableF) == (FA.immutable_ | FA.system));
    static assert(functionAttributes!(typeof(S.immutableF)) == (FA.immutable_ | FA.system));

    static assert(functionAttributes!(S.inoutF) == (FA.inout_ | FA.system));
    static assert(functionAttributes!(typeof(S.inoutF)) == (FA.inout_ | FA.system));

    static assert(functionAttributes!(S.sharedF) == (FA.shared_ | FA.system));
    static assert(functionAttributes!(typeof(S.sharedF)) == (FA.shared_ | FA.system));

    static assert(functionAttributes!(S.refF) == (FA.ref_ | FA.system | FA.return_));
    static assert(functionAttributes!(typeof(S.refF)) == (FA.ref_ | FA.system | FA.return_));

    static assert(functionAttributes!(S.propertyF) == (FA.property | FA.system));
    static assert(functionAttributes!(typeof(&S.propertyF)) == (FA.property | FA.system));

    static assert(functionAttributes!(S.nothrowF) == (FA.nothrow_ | FA.system));
    static assert(functionAttributes!(typeof(S.nothrowF)) == (FA.nothrow_ | FA.system));

    static assert(functionAttributes!(S.nogcF) == (FA.nogc | FA.system));
    static assert(functionAttributes!(typeof(S.nogcF)) == (FA.nogc | FA.system));

    static assert(functionAttributes!(S.systemF) == FA.system);
    static assert(functionAttributes!(typeof(S.systemF)) == FA.system);

    static assert(functionAttributes!(S.trustedF) == FA.trusted);
    static assert(functionAttributes!(typeof(S.trustedF)) == FA.trusted);

    static assert(functionAttributes!(S.safeF) == FA.safe);
    static assert(functionAttributes!(typeof(S.safeF)) == FA.safe);

    static assert(functionAttributes!(S.pureF) == (FA.pure_ | FA.system));
    static assert(functionAttributes!(typeof(S.pureF)) == (FA.pure_ | FA.system));

    static assert(functionAttributes!(S.liveF) == (FA.live | FA.system));
    static assert(functionAttributes!(typeof(S.liveF)) == (FA.live | FA.system));

    int pure_nothrow() nothrow pure;
    void safe_nothrow() @safe nothrow;
    static ref int static_ref_property() @property;
    ref int ref_property() @property;

    static assert(functionAttributes!(pure_nothrow) == (FA.pure_ | FA.nothrow_ | FA.system));
    static assert(functionAttributes!(typeof(pure_nothrow)) == (FA.pure_ | FA.nothrow_ | FA.system));

    static assert(functionAttributes!(safe_nothrow) == (FA.safe | FA.nothrow_));
    static assert(functionAttributes!(typeof(safe_nothrow)) == (FA.safe | FA.nothrow_));

    static assert(functionAttributes!(static_ref_property) == (FA.property | FA.ref_ | FA.system));
    static assert(functionAttributes!(typeof(&static_ref_property)) == (FA.property | FA.ref_ | FA.system));

    static assert(functionAttributes!(ref_property) == (FA.property | FA.ref_ | FA.system));
    static assert(functionAttributes!(typeof(&ref_property)) == (FA.property | FA.ref_ | FA.system));

    struct S2
    {
        int pure_const() const pure { return 0; }
        int pure_sharedconst() const shared pure { return 0; }
    }

    static assert(functionAttributes!(S2.pure_const) == (FA.const_ | FA.pure_ | FA.system));
    static assert(functionAttributes!(typeof(S2.pure_const)) == (FA.const_ | FA.pure_ | FA.system));

    static assert(functionAttributes!(S2.pure_sharedconst) == (FA.const_ | FA.shared_ | FA.pure_ | FA.system));
    static assert(functionAttributes!(typeof(S2.pure_sharedconst)) == (FA.const_ | FA.shared_ | FA.pure_ | FA.system));

    static assert(functionAttributes!((int a) { }) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));
    static assert(functionAttributes!(typeof((int a) { })) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));

    auto safeDel = delegate() @safe { };
    static assert(functionAttributes!(safeDel) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));
    static assert(functionAttributes!(typeof(safeDel)) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.safe));

    auto trustedDel = delegate() @trusted { };
    static assert(functionAttributes!(trustedDel) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.trusted));
    static assert(functionAttributes!(typeof(trustedDel)) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.trusted));

    auto systemDel = delegate() @system { };
    static assert(functionAttributes!(systemDel) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.system));
    static assert(functionAttributes!(typeof(systemDel)) == (FA.pure_ | FA.nothrow_ | FA.nogc | FA.system));
}

private FunctionAttribute extractAttribFlags(Attribs...)()
{
    auto res = FunctionAttribute.none;

    static foreach (attrib; Attribs)
    {
        switch (attrib) with (FunctionAttribute)
        {
            case "pure":      res |= pure_; break;
            case "nothrow":   res |= nothrow_; break;
            case "ref":       res |= ref_; break;
            case "@property": res |= property; break;
            case "@trusted":  res |= trusted; break;
            case "@safe":     res |= safe; break;
            case "@nogc":     res |= nogc; break;
            case "@system":   res |= system; break;
            case "const":     res |= const_; break;
            case "immutable": res |= immutable_; break;
            case "inout":     res |= inout_; break;
            case "shared":    res |= shared_; break;
            case "return":    res |= return_; break;
            case "scope":     res |= scope_; break;
            case "@live":     res |= live; break;
            default: assert(0, attrib);
        }
    }

    return res;
}

/**
Checks whether a function has the given attributes attached.

Params:
    args = Function to check, followed by a
    variadic number of function attributes as strings

Returns:
    `true`, if the function has the list of attributes attached and `false` otherwise.

See_Also:
    $(LREF functionAttributes)
*/
template hasFunctionAttributes(args...)
if (args.length > 0 && isCallable!(args[0])
     && allSatisfy!(isSomeString, typeof(args[1 .. $])))
{
    enum bool hasFunctionAttributes = {
        import std.algorithm.searching : canFind;
        import std.range : only;
        enum funcAttribs = only(__traits(getFunctionAttributes, args[0]));
        static foreach (attribute; args[1 .. $])
        {
            if (!funcAttribs.canFind(attribute))
                return false;
        }
        return true;
    }();
}

///
@safe unittest
{
    real func(real x) pure nothrow @safe;
    static assert(hasFunctionAttributes!(func, "@safe", "pure"));
    static assert(!hasFunctionAttributes!(func, "@trusted"));

    // for templates attributes are automatically inferred
    bool myFunc(T)(T b)
    {
        return !b;
    }
    static assert(hasFunctionAttributes!(myFunc!bool, "@safe", "pure", "@nogc", "nothrow"));
    static assert(!hasFunctionAttributes!(myFunc!bool, "shared"));
}

@system unittest
{
    struct S
    {
        int noF();
        int constF() const;
        int immutableF() immutable;
        int inoutF() inout;
        int sharedF() shared;

        ref int refF() return;
        int propertyF() @property;
        int nothrowF() nothrow;
        int nogcF() @nogc;

        int systemF() @system;
        int trustedF() @trusted;
        int safeF() @safe;

        int pureF() pure;

        int liveF() @live;
    }

    // true if no args passed
    static assert(hasFunctionAttributes!(S.noF));

    static assert(hasFunctionAttributes!(S.noF, "@system"));
    static assert(hasFunctionAttributes!(typeof(S.noF), "@system"));
    static assert(!hasFunctionAttributes!(S.noF, "@system", "pure"));

    static assert(hasFunctionAttributes!(S.constF, "const", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.constF), "const", "@system"));
    static assert(!hasFunctionAttributes!(S.constF, "const", "@system", "@nogc"));

    static assert(hasFunctionAttributes!(S.immutableF, "immutable", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.immutableF), "immutable", "@system"));
    static assert(!hasFunctionAttributes!(S.immutableF, "immutable", "@system", "pure"));

    static assert(hasFunctionAttributes!(S.inoutF, "inout", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.inoutF), "inout", "@system"));
    static assert(!hasFunctionAttributes!(S.inoutF, "inout", "@system", "pure"));

    static assert(hasFunctionAttributes!(S.sharedF, "shared", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.sharedF), "shared", "@system"));
    static assert(!hasFunctionAttributes!(S.sharedF, "shared", "@system", "@trusted"));

    static assert(hasFunctionAttributes!(S.refF, "ref", "@system", "return"));
    static assert(hasFunctionAttributes!(typeof(S.refF), "ref", "@system", "return"));
    static assert(!hasFunctionAttributes!(S.refF, "ref", "@system", "return", "pure"));

    static assert(hasFunctionAttributes!(S.propertyF, "@property", "@system"));
    static assert(hasFunctionAttributes!(typeof(&S.propertyF), "@property", "@system"));
    static assert(!hasFunctionAttributes!(S.propertyF, "@property", "@system", "ref"));

    static assert(hasFunctionAttributes!(S.nothrowF, "nothrow", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.nothrowF), "nothrow", "@system"));
    static assert(!hasFunctionAttributes!(S.nothrowF, "nothrow", "@system", "@trusted"));

    static assert(hasFunctionAttributes!(S.nogcF, "@nogc", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.nogcF), "@nogc", "@system"));
    static assert(!hasFunctionAttributes!(S.nogcF, "@nogc", "@system", "ref"));

    static assert(hasFunctionAttributes!(S.systemF, "@system"));
    static assert(hasFunctionAttributes!(typeof(S.systemF), "@system"));
    static assert(!hasFunctionAttributes!(S.systemF, "@system", "ref"));

    static assert(hasFunctionAttributes!(S.trustedF, "@trusted"));
    static assert(hasFunctionAttributes!(typeof(S.trustedF), "@trusted"));
    static assert(!hasFunctionAttributes!(S.trustedF, "@trusted", "@safe"));

    static assert(hasFunctionAttributes!(S.safeF, "@safe"));
    static assert(hasFunctionAttributes!(typeof(S.safeF), "@safe"));
    static assert(!hasFunctionAttributes!(S.safeF, "@safe", "nothrow"));

    static assert(hasFunctionAttributes!(S.pureF, "pure", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.pureF), "pure", "@system"));
    static assert(!hasFunctionAttributes!(S.pureF, "pure", "@system", "ref"));

    static assert(hasFunctionAttributes!(S.liveF, "@live", "@system"));
    static assert(hasFunctionAttributes!(typeof(S.liveF), "@live", "@system"));
    static assert(!hasFunctionAttributes!(S.liveF, "@live", "@system", "ref"));

    int pure_nothrow() nothrow pure { return 0; }
    void safe_nothrow() @safe nothrow { }
    static ref int static_ref_property() @property { return *(new int); }
    ref int ref_property() @property { return *(new int); }

    static assert(hasFunctionAttributes!(pure_nothrow, "pure", "nothrow", "@safe"));
    static assert(hasFunctionAttributes!(typeof(pure_nothrow), "pure", "nothrow", "@safe"));
    static assert(!hasFunctionAttributes!(pure_nothrow, "pure", "nothrow", "@safe", "@trusted"));

    static assert(hasFunctionAttributes!(safe_nothrow, "@safe", "nothrow"));
    static assert(hasFunctionAttributes!(typeof(safe_nothrow), "@safe", "nothrow"));
    static assert(hasFunctionAttributes!(safe_nothrow, "@safe", "nothrow", "pure"));
    static assert(!hasFunctionAttributes!(safe_nothrow, "@safe", "nothrow", "pure", "@trusted"));

    static assert(hasFunctionAttributes!(static_ref_property, "@property", "ref", "@safe"));
    static assert(hasFunctionAttributes!(typeof(&static_ref_property), "@property", "ref", "@safe"));
    static assert(hasFunctionAttributes!(static_ref_property, "@property", "ref", "@safe", "nothrow"));
    static assert(!hasFunctionAttributes!(static_ref_property, "@property", "ref", "@safe", "nothrow", "@nogc"));

    static assert(hasFunctionAttributes!(ref_property, "@property", "ref", "@safe"));
    static assert(hasFunctionAttributes!(typeof(&ref_property), "@property", "ref", "@safe"));
    static assert(!hasFunctionAttributes!(ref_property, "@property", "ref", "@safe", "@nogc"));

    struct S2
    {
        int pure_const() const pure { return 0; }
        int pure_sharedconst() const shared pure { return 0; }
    }

    static assert(hasFunctionAttributes!(S2.pure_const, "const", "pure", "@system"));
    static assert(hasFunctionAttributes!(typeof(S2.pure_const), "const", "pure", "@system"));
    static assert(!hasFunctionAttributes!(S2.pure_const, "const", "pure", "@system", "ref"));

    static assert(hasFunctionAttributes!(S2.pure_sharedconst, "const", "shared", "pure", "@system"));
    static assert(hasFunctionAttributes!(typeof(S2.pure_sharedconst), "const", "shared", "pure", "@system"));
    static assert(!hasFunctionAttributes!(S2.pure_sharedconst, "const", "shared", "pure", "@system", "@nogc"));

    static assert(hasFunctionAttributes!((int a) { }, "pure", "nothrow", "@nogc", "@safe"));
    static assert(hasFunctionAttributes!(typeof((int a) { }), "pure", "nothrow", "@nogc", "@safe"));
    static assert(!hasFunctionAttributes!((int a) { }, "pure", "nothrow", "@nogc", "@safe", "ref"));

    auto safeDel = delegate() @safe { };
    static assert(hasFunctionAttributes!(safeDel, "pure", "nothrow", "@nogc", "@safe"));
    static assert(hasFunctionAttributes!(typeof(safeDel), "pure", "nothrow", "@nogc", "@safe"));
    static assert(!hasFunctionAttributes!(safeDel, "pure", "nothrow", "@nogc", "@safe", "@system"));

    auto trustedDel = delegate() @trusted { };
    static assert(hasFunctionAttributes!(trustedDel, "pure", "nothrow", "@nogc", "@trusted"));
    static assert(hasFunctionAttributes!(typeof(trustedDel), "pure", "nothrow", "@nogc", "@trusted"));
    static assert(!hasFunctionAttributes!(trustedDel, "pure", "nothrow", "@nogc", "@trusted", "ref"));

    auto systemDel = delegate() @system { };
    static assert(hasFunctionAttributes!(systemDel, "pure", "nothrow", "@nogc", "@system"));
    static assert(hasFunctionAttributes!(typeof(systemDel), "pure", "nothrow", "@nogc", "@system"));
    static assert(!hasFunctionAttributes!(systemDel, "pure", "nothrow", "@nogc", "@system", "@property"));


    // call functions to make CodeCov happy
    {
        assert(pure_nothrow == 0);
        safe_nothrow;
        assert(static_ref_property == 0);
        assert(ref_property == 0);
        assert(S2().pure_const == 0);
        assert((shared S2()).pure_sharedconst == 0);
        cast(void) safeDel;
        cast(void) trustedDel;
        cast(void) systemDel;
    }
}

/**
`true` if `func` is `@safe` or `@trusted`.
 */
template isSafe(alias func)
if (isCallable!func)
{
    enum isSafe = (functionAttributes!func & FunctionAttribute.safe) != 0 ||
                  (functionAttributes!func & FunctionAttribute.trusted) != 0;
}

///
@safe unittest
{
    @safe    int add(int a, int b) {return a+b;}
    @trusted int sub(int a, int b) {return a-b;}
    @system  int mul(int a, int b) {return a*b;}

    static assert( isSafe!add);
    static assert( isSafe!sub);
    static assert(!isSafe!mul);
}


@safe unittest
{
    //Member functions
    interface Set
    {
        int systemF() @system;
        int trustedF() @trusted;
        int safeF() @safe;
    }
    static assert( isSafe!(Set.safeF));
    static assert( isSafe!(Set.trustedF));
    static assert(!isSafe!(Set.systemF));

    //Functions
    @safe static void safeFunc() {}
    @trusted static void trustedFunc() {}
    @system static void systemFunc() {}

    static assert( isSafe!safeFunc);
    static assert( isSafe!trustedFunc);
    static assert(!isSafe!systemFunc);

    //Delegates
    auto safeDel = delegate() @safe {};
    auto trustedDel = delegate() @trusted {};
    auto systemDel = delegate() @system {};

    static assert( isSafe!safeDel);
    static assert( isSafe!trustedDel);
    static assert(!isSafe!systemDel);

    //Lambdas
    static assert( isSafe!({safeDel();}));
    static assert( isSafe!({trustedDel();}));
    static assert(!isSafe!({systemDel();}));

    //Static opCall
    struct SafeStatic { @safe static SafeStatic opCall() { return SafeStatic.init; } }
    struct TrustedStatic { @trusted static TrustedStatic opCall() { return TrustedStatic.init; } }
    struct SystemStatic { @system static SystemStatic opCall() { return SystemStatic.init; } }

    static assert( isSafe!(SafeStatic()));
    static assert( isSafe!(TrustedStatic()));
    static assert(!isSafe!(SystemStatic()));

    //Non-static opCall
    struct Safe { @safe Safe opCall() { return Safe.init; } }
    struct Trusted { @trusted Trusted opCall() { return Trusted.init; } }
    struct System { @system System opCall() { return System.init; } }

    static assert( isSafe!(Safe.init()));
    static assert( isSafe!(Trusted.init()));
    static assert(!isSafe!(System.init()));
}


/**
`true` if `func` is `@system`.
*/
template isUnsafe(alias func)
{
    enum isUnsafe = !isSafe!func;
}

///
@safe unittest
{
    @safe    int add(int a, int b) {return a+b;}
    @trusted int sub(int a, int b) {return a-b;}
    @system  int mul(int a, int b) {return a*b;}

    static assert(!isUnsafe!add);
    static assert(!isUnsafe!sub);
    static assert( isUnsafe!mul);
}

@safe unittest
{
    //Member functions
    interface Set
    {
        int systemF() @system;
        int trustedF() @trusted;
        int safeF() @safe;
    }
    static assert(!isUnsafe!(Set.safeF));
    static assert(!isUnsafe!(Set.trustedF));
    static assert( isUnsafe!(Set.systemF));

    //Functions
    @safe static void safeFunc() {}
    @trusted static void trustedFunc() {}
    @system static void systemFunc() {}

    static assert(!isUnsafe!safeFunc);
    static assert(!isUnsafe!trustedFunc);
    static assert( isUnsafe!systemFunc);

    //Delegates
    auto safeDel = delegate() @safe {};
    auto trustedDel = delegate() @trusted {};
    auto systemDel = delegate() @system {};

    static assert(!isUnsafe!safeDel);
    static assert(!isUnsafe!trustedDel);
    static assert( isUnsafe!systemDel);

    //Lambdas
    static assert(!isUnsafe!({safeDel();}));
    static assert(!isUnsafe!({trustedDel();}));
    static assert( isUnsafe!({systemDel();}));

    //Static opCall
    struct SafeStatic { @safe static SafeStatic opCall() { return SafeStatic.init; } }
    struct TrustedStatic { @trusted static TrustedStatic opCall() { return TrustedStatic.init; } }
    struct SystemStatic { @system static SystemStatic opCall() { return SystemStatic.init; } }

    static assert(!isUnsafe!(SafeStatic()));
    static assert(!isUnsafe!(TrustedStatic()));
    static assert( isUnsafe!(SystemStatic()));

    //Non-static opCall
    struct Safe { @safe Safe opCall() { return Safe.init; } }
    struct Trusted { @trusted Trusted opCall() { return Trusted.init; } }
    struct System { @system System opCall() { return System.init; } }

    static assert(!isUnsafe!(Safe.init()));
    static assert(!isUnsafe!(Trusted.init()));
    static assert( isUnsafe!(System.init()));
}


/**
Determine the linkage attribute of the function.
Params:
    func = the function symbol, or the type of a function, delegate, or pointer to function
Returns:
    one of the strings "D", "C", "C++", "Windows", "Objective-C", or "System".
*/
template functionLinkage(alias func)
if (isCallable!func)
{
    enum string functionLinkage = __traits(getLinkage, FunctionTypeOf!func);
}

///
@safe unittest
{
    extern(D) void Dfunc() {}
    extern(C) void Cfunc() {}
    static assert(functionLinkage!Dfunc == "D");
    static assert(functionLinkage!Cfunc == "C");

    string a = functionLinkage!Dfunc;
    assert(a == "D");

    auto fp = &Cfunc;
    string b = functionLinkage!fp;
    assert(b == "C");
}

@safe unittest
{
    interface Test
    {
        void const_func() const;
        void sharedconst_func() shared const;
    }
    static assert(functionLinkage!(Test.const_func) == "D");
    static assert(functionLinkage!(Test.sharedconst_func) == "D");

    static assert(functionLinkage!((int a){}) == "D");
}


/**
Determines what kind of variadic parameters function has.
Params:
    func = function symbol or type of function, delegate, or pointer to function
Returns:
    enum Variadic
 */
enum Variadic
{
    /// Function is not variadic.
    no,
    /// Function is a _C-style variadic function, which uses
    /// `core.stdc.stdarg`
    c,
    /// Function is a _D-style variadic function, which uses
    /// `__argptr` and `__arguments`.
    d,
    /// Function is a typesafe variadic function.
    typesafe,
}

/// ditto
template variadicFunctionStyle(alias func)
if (isCallable!func)
{
    enum string varargs = __traits(getFunctionVariadicStyle, FunctionTypeOf!func);
    enum Variadic variadicFunctionStyle =
        (varargs == "stdarg") ? Variadic.c :
        (varargs == "argptr") ? Variadic.d :
        (varargs == "typesafe") ? Variadic.typesafe :
        (varargs == "none") ? Variadic.no : Variadic.no;
}

///
@safe unittest
{
    void func() {}
    static assert(variadicFunctionStyle!func == Variadic.no);

    extern(C) int printf(const char*, ...);
    static assert(variadicFunctionStyle!printf == Variadic.c);
}

@safe unittest
{
    import core.vararg;

    extern(D) void novar() {}
    extern(C) void cstyle(int, ...) {}
    extern(D) void dstyle(...) {}
    extern(D) void typesafe(int[]...) {}

    static assert(variadicFunctionStyle!novar == Variadic.no);
    static assert(variadicFunctionStyle!cstyle == Variadic.c);
    static assert(variadicFunctionStyle!dstyle == Variadic.d);
    static assert(variadicFunctionStyle!typesafe == Variadic.typesafe);

    static assert(variadicFunctionStyle!((int[] a...) {}) == Variadic.typesafe);
}


/**
Get the function type from a callable object `func`, or from a function pointer/delegate type.

Using builtin `typeof` on a property function yields the types of the
property value, not of the property function itself.  Still,
`FunctionTypeOf` is able to obtain function types of properties.

Note:
Do not confuse function types with function pointer types; function types are
usually used for compile-time reflection purposes.
 */
template FunctionTypeOf(alias func)
if (isCallable!func)
{
    static if ((is(typeof(& func) Fsym : Fsym*) && is(Fsym == function)) || is(typeof(& func) Fsym == delegate))
    {
        alias FunctionTypeOf = Fsym; // HIT: (nested) function symbol
    }
    else static if (is(typeof(& func.opCall) Fobj == delegate) || is(typeof(& func.opCall!()) Fobj == delegate))
    {
        alias FunctionTypeOf = Fobj; // HIT: callable object
    }
    else static if (
            (is(typeof(& func.opCall) Ftyp : Ftyp*) && is(Ftyp == function)) ||
            (is(typeof(& func.opCall!()) Ftyp : Ftyp*) && is(Ftyp == function))
        )
    {
        alias FunctionTypeOf = Ftyp; // HIT: callable type
    }
    else static if (is(func T) || is(typeof(func) T))
    {
        static if (is(T == function))
            alias FunctionTypeOf = T;    // HIT: function
        else static if (is(T Fptr : Fptr*) && is(Fptr == function))
            alias FunctionTypeOf = Fptr; // HIT: function pointer
        else static if (is(T Fdlg == delegate))
            alias FunctionTypeOf = Fdlg; // HIT: delegate
        else
            static assert(0);
    }
    else
        static assert(0);
}

///
@safe unittest
{
    class C
    {
        int value() @property => 0;
        static string opCall() => "hi";
    }
    static assert(is( typeof(C.value) == int ));
    static assert(is( FunctionTypeOf!(C.value) == function ));
    static assert(is( FunctionTypeOf!C == typeof(C.opCall) ));

    int function() fp;
    alias IntFn = int();
    static assert(is( typeof(fp) == IntFn* ));
    static assert(is( FunctionTypeOf!fp == IntFn ));
}

@system unittest
{
    int test(int a);
    int propGet() @property;
    int propSet(int a) @property;
    int function(int) test_fp;
    int delegate(int) test_dg;
    static assert(is( typeof(test) == FunctionTypeOf!(typeof(test)) ));
    static assert(is( typeof(test) == FunctionTypeOf!test ));
    static assert(is( typeof(test) == FunctionTypeOf!test_fp ));
    static assert(is( typeof(test) == FunctionTypeOf!test_dg ));
    alias int GetterType() @property;
    alias int SetterType(int) @property;
    static assert(is( FunctionTypeOf!propGet == GetterType ));
    static assert(is( FunctionTypeOf!propSet == SetterType ));

    interface Prop { int prop() @property; }
    Prop prop;
    static assert(is( FunctionTypeOf!(Prop.prop) == GetterType ));
    static assert(is( FunctionTypeOf!(prop.prop) == GetterType ));

    class Callable { int opCall(int) { return 0; } }
    auto call = new Callable;
    static assert(is( FunctionTypeOf!call == typeof(test) ));

    struct StaticCallable { static int opCall(int) { return 0; } }
    StaticCallable stcall_val;
    StaticCallable* stcall_ptr;
    static assert(is( FunctionTypeOf!stcall_val == typeof(test) ));
    static assert(is( FunctionTypeOf!stcall_ptr == typeof(test) ));

    struct TemplatedOpCallF { int opCall()(int) { return 0; } }
    static assert(is( FunctionTypeOf!TemplatedOpCallF == typeof(TemplatedOpCallF.opCall!()) ));

    int foovar;
    struct TemplatedOpCallDg { int opCall()() { return foovar; } }
    static assert(is( FunctionTypeOf!TemplatedOpCallDg == typeof(TemplatedOpCallDg.opCall!()) ));

    interface Overloads
    {
        void test(string);
        real test(real);
        int  test(int);
        int  test() @property;
    }
    alias ov = __traits(getVirtualMethods, Overloads, "test");
    alias F_ov0 = FunctionTypeOf!(ov[0]);
    alias F_ov1 = FunctionTypeOf!(ov[1]);
    alias F_ov2 = FunctionTypeOf!(ov[2]);
    alias F_ov3 = FunctionTypeOf!(ov[3]);
    static assert(is(F_ov0* == void function(string)));
    static assert(is(F_ov1* == real function(real)));
    static assert(is(F_ov2* == int function(int)));
    static assert(is(F_ov3* == int function() @property));

    alias F_dglit = FunctionTypeOf!((int a){ return a; });
    static assert(is(F_dglit* : int function(int)));
}

/**
 * Constructs a new function or delegate type with the same basic signature
 * as the given one, but different attributes (including linkage).
 *
 * This is especially useful for adding/removing attributes to/from types in
 * generic code, where the actual type name cannot be spelt out.
 *
 * Params:
 *    T = The base type.
 *    linkage = The desired linkage of the result type.
 *    attrs = The desired $(LREF FunctionAttribute)s of the result type.
 */
template SetFunctionAttributes(T, string linkage, uint attrs)
if (isFunctionPointer!T || isDelegate!T)
{
    mixin({
        import std.algorithm.searching : canFind;

        static assert(!(attrs & FunctionAttribute.trusted) ||
            !(attrs & FunctionAttribute.safe),
            "Cannot have a function/delegate that is both trusted and safe.");

        static immutable linkages = ["D", "C", "Windows", "C++", "System"];
        static assert(canFind(linkages, linkage), "Invalid linkage '" ~
            linkage ~ "', must be one of " ~ linkages.stringof ~ ".");

        string result = "alias ";

        static if (linkage != "D")
            result ~= "extern(" ~ linkage ~ ") ";

        static if (attrs & FunctionAttribute.ref_)
            result ~= "ref ";

        result ~= "ReturnType!T";

        static if (isDelegate!T)
            result ~= " delegate";
        else
            result ~= " function";

        result ~= "(";

        static if (Parameters!T.length > 0)
            result ~= "Parameters!T";

        enum varStyle = variadicFunctionStyle!T;
        static if (varStyle == Variadic.c)
            result ~= ", ...";
        else static if (varStyle == Variadic.d)
            result ~= "...";
        else static if (varStyle == Variadic.typesafe)
            result ~= "...";

        result ~= ")";

        static if (attrs & FunctionAttribute.pure_)
            result ~= " pure";
        static if (attrs & FunctionAttribute.nothrow_)
            result ~= " nothrow";
        static if (attrs & FunctionAttribute.property)
            result ~= " @property";
        static if (attrs & FunctionAttribute.trusted)
            result ~= " @trusted";
        static if (attrs & FunctionAttribute.safe)
            result ~= " @safe";
        static if (attrs & FunctionAttribute.nogc)
            result ~= " @nogc";
        static if (attrs & FunctionAttribute.system)
            result ~= " @system";
        static if (attrs & FunctionAttribute.const_)
            result ~= " const";
        static if (attrs & FunctionAttribute.immutable_)
            result ~= " immutable";
        static if (attrs & FunctionAttribute.inout_)
            result ~= " inout";
        static if (attrs & FunctionAttribute.shared_)
            result ~= " shared";
        static if (attrs & FunctionAttribute.return_)
            result ~= " return";
        static if (attrs & FunctionAttribute.live)
            result ~= " @live";

        result ~= " SetFunctionAttributes;";
        return result;
    }());
}

/// Ditto
template SetFunctionAttributes(T, string linkage, uint attrs)
if (is(T == function))
{
    // To avoid a lot of syntactic headaches, we just use the above version to
    // operate on the corresponding function pointer type and then remove the
    // indirection again.
    alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T*, linkage, attrs));
}

///
@safe unittest
{
    alias ExternC(T) = SetFunctionAttributes!(T, "C", functionAttributes!T);

    auto assumePure(T)(T t)
    if (isFunctionPointer!T || isDelegate!T)
    {
        enum attrs = functionAttributes!T | FunctionAttribute.pure_;
        return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
    }

    int f()
    {
        import core.thread : getpid;
        return getpid();
    }

    int g() pure @trusted
    {
        auto pureF = assumePure(&f);
        return pureF();
    }
    assert(g() > 0);
}

version (StdUnittest)
{
private:
    // Some function types to test.
    int sc(scope int, ref int, out int, lazy int, int);
    extern(System) int novar();
    extern(C) int cstyle(int, ...);
    extern(D) int dstyle(...);
    extern(D) int typesafe(int[]...);
}
@safe unittest
{
    import std.algorithm.iteration : reduce;

    alias FA = FunctionAttribute;
    static foreach (BaseT; AliasSeq!(typeof(&sc), typeof(&novar), typeof(&cstyle),
        typeof(&dstyle), typeof(&typesafe)))
    {
        static foreach (T; AliasSeq!(BaseT, FunctionTypeOf!BaseT))
        {{
            enum linkage = functionLinkage!T;
            enum attrs = functionAttributes!T;

            static assert(is(SetFunctionAttributes!(T, linkage, attrs) == T),
                "Identity check failed for: " ~ T.stringof);

            // Check that all linkage types work (D-style variadics require D linkage).
            static if (variadicFunctionStyle!T != Variadic.d)
            {
                static foreach (newLinkage; AliasSeq!("D", "C", "Windows", "C++"))
                {{
                    alias New = SetFunctionAttributes!(T, newLinkage, attrs);
                    static assert(functionLinkage!New == newLinkage,
                        "Linkage test failed for: " ~ T.stringof ~ ", " ~ newLinkage ~
                        " (got " ~ New.stringof ~ ")");
                }}
            }

            // Add @safe.
            alias T1 = SetFunctionAttributes!(T, functionLinkage!T, FA.safe);
            static assert(functionAttributes!T1 == FA.safe);

            // Add all known attributes, excluding conflicting ones.
            enum allAttrs = reduce!"a | b"([EnumMembers!FA])
                & ~FA.safe & ~FA.property & ~FA.const_ & ~FA.immutable_ & ~FA.inout_
                & ~FA.shared_ & ~FA.system & ~FA.return_ & ~FA.scope_;

            alias T2 = SetFunctionAttributes!(T1, functionLinkage!T, allAttrs);
            static assert(functionAttributes!T2 == allAttrs);

            // Strip all attributes again.
            alias T3 = SetFunctionAttributes!(T2, functionLinkage!T, FA.none);
            static assert(is(T3 == T));
        }}
    }
}


//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
// Aggregate Types
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

/**
Determines whether `T` is a class nested inside another class
and that `T.outer` is the implicit reference to the outer class
(i.e. `outer` has not been used as a field or method name)

Params:
    T = type to test

Returns:
`true` if `T` is a class nested inside another, with the conditions described above;
`false` otherwise
*/
template isInnerClass(T)
if (is(T == class))
{
    static if (is(typeof(T.outer)))
    {
        bool hasOuterMember(string[] members...)
        {
            foreach (m; members)
            {
                if (m == "outer")
                    return true;
            }
            return false;
        }
        enum isInnerClass = __traits(isSame, typeof(T.outer), __traits(parent, T)) &&
                            !hasOuterMember(__traits(allMembers, T));
    }
    else
        enum isInnerClass = false;
}

///
@safe unittest
{
    class C
    {
        int outer;
    }
    static assert(!isInnerClass!C);

    class Outer1
    {
        class Inner1 { }
        class Inner2
        {
            int outer;
        }
    }
    static assert(isInnerClass!(Outer1.Inner1));
    static assert(!isInnerClass!(Outer1.Inner2));

    static class Outer2
    {
        static class Inner
        {
            int outer;
        }
    }
    static assert(!isInnerClass!(Outer2.Inner));
}

/**
Determines whether `T` has its own context pointer.
`T` must be either `class`, `struct`, or `union`.

See also: $(DDSUBLINK spec/traits, isNested, `__traits(isNested, T)`)
*/
template isNested(T)
if (is(T == class) || is(T == struct) || is(T == union))
{
    enum isNested = __traits(isNested, T);
}

///
@safe unittest
{
    static struct S { }
    static assert(!isNested!S);

    int i;
    struct NestedStruct { void f() { ++i; } }
    static assert(isNested!NestedStruct);
}

/**
Determines whether `T` or any of its representation types
have a context pointer.
*/
template hasNested(T)
{
    import std.meta : Filter;

    static if (isStaticArray!T && T.length)
        enum hasNested = hasNested!(typeof(T.init[0]));
    else static if (is(T == class) || is(T == struct) || is(T == union))
    {
        // prevent infinite recursion for class with member of same type
        enum notSame(U) = !is(immutable T == immutable U);
        enum hasNested = isNested!T ||
            anySatisfy!(.hasNested, Filter!(notSame, Fields!T));
    }
    else
        enum hasNested = false;
}

///
@safe unittest
{
    static struct S { }

    int i;
    struct NS { void f() { ++i; } }

    static assert(!hasNested!(S[2]));
    static assert(hasNested!(NS[2]));
}

@safe unittest
{
    static assert(!__traits(compiles, isNested!int));
    static assert(!hasNested!int);

    static struct StaticStruct { }
    static assert(!isNested!StaticStruct);
    static assert(!hasNested!StaticStruct);

    int i;
    struct NestedStruct { void f() { ++i; } }
    static assert( isNested!NestedStruct);
    static assert( hasNested!NestedStruct);
    static assert( isNested!(immutable NestedStruct));
    static assert( hasNested!(immutable NestedStruct));

    static assert(!__traits(compiles, isNested!(NestedStruct[1])));
    static assert( hasNested!(NestedStruct[1]));
    static assert(!hasNested!(NestedStruct[0]));

    struct S1 { NestedStruct nested; }
    static assert(!isNested!S1);
    static assert( hasNested!S1);

    static struct S2 { NestedStruct nested; }
    static assert(!isNested!S2);
    static assert( hasNested!S2);

    static struct S3 { NestedStruct[0] nested; }
    static assert(!isNested!S3);
    static assert(!hasNested!S3);

    static union U { NestedStruct nested; }
    static assert(!isNested!U);
    static assert( hasNested!U);

    static class StaticClass { }
    static assert(!isNested!StaticClass);
    static assert(!hasNested!StaticClass);

    class NestedClass { void f() { ++i; } }
    static assert( isNested!NestedClass);
    static assert( hasNested!NestedClass);
    static assert( isNested!(immutable NestedClass));
    static assert( hasNested!(immutable NestedClass));

    static assert(!__traits(compiles, isNested!(NestedClass[1])));
    static assert( hasNested!(NestedClass[1]));
    static assert(!hasNested!(NestedClass[0]));

    static class A
    {
        A a;
    }
    static assert(!hasNested!A);
}


/***
 * Get as a tuple the types of the fields of a struct, class, or union.
 * This consists of the fields that take up memory space,
 * excluding the hidden fields like the virtual function
 * table pointer or a context pointer for nested types.
 * If `T` isn't a struct, class, interface or union returns a tuple
 * with one element `T`.
 *
 * History:
 *   - Returned `AliasSeq!(Interface)` for interfaces prior to 2.097
 */
template Fields(T)
{
    import core.internal.traits : _Fields = Fields;
    alias Fields = _Fields!T;
}

///
@safe unittest
{
    import std.meta : AliasSeq;
    struct S { int x; float y; }
    static assert(is(Fields!S == AliasSeq!(int, float)));
}

/**
 * Alternate name for $(LREF Fields), kept for legacy compatibility.
 */
alias FieldTypeTuple = Fields;

@safe unittest
{
    static assert(is(FieldTypeTuple!int == AliasSeq!int));

    static struct StaticStruct1 { }
    static assert(is(FieldTypeTuple!StaticStruct1 == AliasSeq!()));

    static struct StaticStruct2 { int a, b; }
    static assert(is(FieldTypeTuple!StaticStruct2 == AliasSeq!(int, int)));

    int i;

    struct NestedStruct1 { void f() { ++i; } }
    static assert(is(FieldTypeTuple!NestedStruct1 == AliasSeq!()));

    struct NestedStruct2 { int a; void f() { ++i; } }
    static assert(is(FieldTypeTuple!NestedStruct2 == AliasSeq!int));

    class NestedClass { int a; void f() { ++i; } }
    static assert(is(FieldTypeTuple!NestedClass == AliasSeq!int));

    static interface I {}
    static assert(is(Fields!I == AliasSeq!()));
}

//Required for FieldNameTuple
private enum NameOf(alias T) = T.stringof;

/**
 * Get as an expression tuple the names of the fields of a struct, class, or
 * union. This consists of the fields that take up memory space, excluding the
 * hidden fields like the virtual function table pointer or a context pointer
 * for nested types.
 * Inherited fields (for classes) are not included.
 * If `T` isn't a struct, class, interface or union, an
 * expression tuple with an empty string is returned.
 *
 * History:
 *   - Returned `AliasSeq!""` for interfaces prior to 2.097
 */
template FieldNameTuple(T)
{
    import std.meta : staticMap;
    static if (is(T == struct) || is(T == union))
        alias FieldNameTuple = staticMap!(NameOf, T.tupleof[0 .. $ - isNested!T]);
    else static if (is(T == class) || is(T == interface))
        alias FieldNameTuple = staticMap!(NameOf, T.tupleof);
    else
        alias FieldNameTuple = AliasSeq!"";
}

///
@safe unittest
{
    import std.meta : AliasSeq;
    struct S { int x; float y; }
    static assert(FieldNameTuple!S == AliasSeq!("x", "y"));
    static assert(FieldNameTuple!int == AliasSeq!"");
}

@safe unittest
{
    static assert(FieldNameTuple!int == AliasSeq!"");

    static struct StaticStruct1 { }
    static assert(is(FieldNameTuple!StaticStruct1 == AliasSeq!()));

    static struct StaticStruct2 { int a, b; }
    static assert(FieldNameTuple!StaticStruct2 == AliasSeq!("a", "b"));

    static class StaticClass1 { }
    static assert(is(FieldNameTuple!StaticClass1 == AliasSeq!()));

    static class StaticClass2 : StaticClass1 { int a, b; }
    static assert(FieldNameTuple!StaticClass2 == AliasSeq!("a", "b"));

    static class StaticClass3 : StaticClass2 { int c; }
    static assert(FieldNameTuple!StaticClass3 == AliasSeq!("c"));

    int i;

    struct NestedStruct1 { void f() { ++i; } }
    static assert(is(FieldNameTuple!NestedStruct1 == AliasSeq!()));

    struct NestedStruct2 { int a; void f() { ++i; } }
    static assert(FieldNameTuple!NestedStruct2 == AliasSeq!"a");

    class NestedClass { int a; void f() { ++i; } }
    static assert(FieldNameTuple!NestedClass == AliasSeq!"a");

    interface I {}
    static assert(FieldNameTuple!I == AliasSeq!());
}


/***
Get the primitive types of the fields of a struct or class, in
topological order.
*/
template RepresentationTypeTuple(T)
{
    static if (is(T == struct) || is(T == union) || is(T == class))
    {
        alias RepresentationTypeTuple = staticMapMeta!(RepresentationTypeTupleImpl, FieldTypeTuple!T);
    }
    else
    {
        alias RepresentationTypeTuple = RepresentationTypeTupleImpl!T;
    }
}

///
@safe unittest
{
    struct S1 { int a; float b; }
    struct S2 { char[] a; union { S1 b; S1 * c; } }
    alias R = RepresentationTypeTuple!S2;
    assert(R.length == 4
        && is(R[0] == char[]) && is(R[1] == int)
        && is(R[2] == float) && is(R[3] == S1*));
}

@safe unittest
{
    alias S1 = RepresentationTypeTuple!int;
    static assert(is(S1 == AliasSeq!int));

    struct S2 { int a; }
    struct S3 { int a; char b; }
    struct S4 { S1 a; int b; S3 c; }
    static assert(is(RepresentationTypeTuple!S2 == AliasSeq!int));
    static assert(is(RepresentationTypeTuple!S3 == AliasSeq!(int, char)));
    static assert(is(RepresentationTypeTuple!S4 == AliasSeq!(int, int, int, char)));

    struct S11 { int a; float b; }
    struct S21 { char[] a; union { S11 b; S11 * c; } }
    alias R = RepresentationTypeTuple!S21;
    assert(R.length == 4
           && is(R[0] == char[]) && is(R[1] == int)
           && is(R[2] == float) && is(R[3] == S11*));

    class C { int a; float b; }
    alias R1 = RepresentationTypeTuple!C;
    static assert(R1.length == 2 && is(R1[0] == int) && is(R1[1] == float));

    /* https://issues.dlang.org/show_bug.cgi?id=6642 */
    import std.typecons : Rebindable;

    struct S5 { int a; Rebindable!(immutable Object) b; }
    alias R2 = RepresentationTypeTuple!S5;
    static assert(R2.length == 2 && is(R2[0] == int) && is(R2[1] == immutable(Object)));

    static assert(is(RepresentationTypeTuple!noreturn == AliasSeq!noreturn));
}

@safe unittest
{
    struct VeryLargeType
    {
        import std.format : format;
        import std.range : iota;

        static foreach (i; 500.iota)
        {
            mixin(format!"int v%s;"(i));
        }
    }

    alias BigList = RepresentationTypeTuple!VeryLargeType;
}

private template RepresentationTypeTupleImpl(T)
{
    import std.typecons : Rebindable;

    static if (is(immutable T == immutable Rebindable!R, R))
    {
        alias RepresentationTypeTupleImpl
            = staticMapMeta!(.RepresentationTypeTupleImpl, RepresentationTypeTupleImpl!R);
    }
    else  static if (is(T == struct) || is(T == union))
    {
        // @@@BUG@@@ this should work
        //alias .RepresentationTypes!(T[0].tupleof)
        //    RepresentationTypes;
        alias RepresentationTypeTupleImpl
            = staticMapMeta!(.RepresentationTypeTupleImpl, FieldTypeTuple!(T));
    }
    else
    {
        alias RepresentationTypeTupleImpl
            = AliasSeq!T;
    }
}

/*
Statically evaluates to `true` if and only if `T`'s
representation contains at least one field of pointer or array type.
Members of class types are not considered raw pointers. Pointers to
immutable objects are not considered raw aliasing.
*/
private template hasRawAliasing(T)
{
    enum hasRawAliasing = anySatisfy!(hasRawAliasingImpl, RepresentationTypeTuple!T);
}

//
@safe unittest
{
    // simple types
    static assert(!hasRawAliasing!int);
    static assert( hasRawAliasing!(char*));
    // references aren't raw pointers
    static assert(!hasRawAliasing!Object);
    // built-in arrays do contain raw pointers
    static assert( hasRawAliasing!(int[]));
    // aggregate of simple types
    struct S1 { int a; double b; }
    static assert(!hasRawAliasing!S1);
    // indirect aggregation
    struct S2 { S1 a; double b; }
    static assert(!hasRawAliasing!S2);
}

// https://issues.dlang.org/show_bug.cgi?id=19228
@safe unittest
{
    static struct C
    {
        int*[1] a;
    }
    static assert(hasRawAliasing!C);
}

@safe unittest
{
    // struct with a pointer member
    struct S3 { int a; double * b; }
    static assert( hasRawAliasing!S3);
    // struct with an indirect pointer member
    struct S4 { S3 a; double b; }
    static assert( hasRawAliasing!S4);
    struct S5 { int a; Object z; int c; }
    static assert( hasRawAliasing!S3);
    static assert( hasRawAliasing!S4);
    static assert(!hasRawAliasing!S5);

    union S6 { int a; int b; }
    union S7 { int a; int * b; }
    static assert(!hasRawAliasing!S6);
    static assert( hasRawAliasing!S7);

    static assert(!hasRawAliasing!(void delegate()));
    static assert(!hasRawAliasing!(void delegate() const));
    static assert(!hasRawAliasing!(void delegate() immutable));
    static assert(!hasRawAliasing!(void delegate() shared));
    static assert(!hasRawAliasing!(void delegate() shared const));
    static assert(!hasRawAliasing!(const(void delegate())));
    static assert(!hasRawAliasing!(immutable(void delegate())));

    struct S8 { void delegate() a; int b; Object c; }
    class S12 { typeof(S8.tupleof) a; }
    class S13 { typeof(S8.tupleof) a; int* b; }
    static assert(!hasRawAliasing!S8);
    static assert(!hasRawAliasing!S12);
    static assert( hasRawAliasing!S13);

    enum S9 { a }
    static assert(!hasRawAliasing!S9);

    // indirect members
    struct S10 { S7 a; int b; }
    struct S11 { S6 a; int b; }
    static assert( hasRawAliasing!S10);
    static assert(!hasRawAliasing!S11);

    static assert( hasRawAliasing!(int[string]));
    static assert(!hasRawAliasing!(immutable(int[string])));
}

private template hasRawAliasingImpl(T)
{
    static if (is(T foo : U*, U) && !isFunctionPointer!T)
        enum hasRawAliasingImpl = !is(U == immutable);
    else static if (is(T foo : U[N], U, size_t N))
        // separate static ifs to avoid forward reference
        static if (is(U == class) || is(U == interface))
            enum hasRawAliasingImpl = false;
        else
            enum hasRawAliasingImpl = hasRawAliasingImpl!U;
    else static if (is(T foo : U[], U) && !isStaticArray!(T))
        enum hasRawAliasingImpl = !is(U == immutable);
    else static if (isAssociativeArray!(T))
        enum hasRawAliasingImpl = !is(T == immutable);
    else
        enum hasRawAliasingImpl = false;
}

/*
Statically evaluates to `true` if and only if `T`'s
representation contains at least one non-shared field of pointer or
array type.  Members of class types are not considered raw pointers.
Pointers to immutable objects are not considered raw aliasing.
*/
private template hasRawUnsharedAliasing(T)
{
    enum hasRawUnsharedAliasing = anySatisfy!(hasRawUnsharedAliasingImpl, RepresentationTypeTuple!T);
}

//
@safe unittest
{
    // simple types
    static assert(!hasRawUnsharedAliasing!int);
    static assert( hasRawUnsharedAliasing!(char*));
    static assert(!hasRawUnsharedAliasing!(shared char*));
    // references aren't raw pointers
    static assert(!hasRawUnsharedAliasing!Object);
    // built-in arrays do contain raw pointers
    static assert( hasRawUnsharedAliasing!(int[]));
    static assert(!hasRawUnsharedAliasing!(shared int[]));
    // aggregate of simple types
    struct S1 { int a; double b; }
    static assert(!hasRawUnsharedAliasing!S1);
    // indirect aggregation
    struct S2 { S1 a; double b; }
    static assert(!hasRawUnsharedAliasing!S2);
    // struct with a pointer member
    struct S3 { int a; double * b; }
    static assert( hasRawUnsharedAliasing!S3);
    struct S4 { int a; shared double * b; }
    static assert(!hasRawUnsharedAliasing!S4);
}

@safe unittest
{
    // struct with a pointer member
    struct S3 { int a; double * b; }
    static assert( hasRawUnsharedAliasing!S3);
    struct S4 { int a; shared double * b; }
    static assert(!hasRawUnsharedAliasing!S4);
    // struct with an indirect pointer member
    struct S5 { S3 a; double b; }
    static assert( hasRawUnsharedAliasing!S5);
    struct S6 { S4 a; double b; }
    static assert(!hasRawUnsharedAliasing!S6);
    struct S7 { int a; Object z;      int c; }
    static assert( hasRawUnsharedAliasing!S5);
    static assert(!hasRawUnsharedAliasing!S6);
    static assert(!hasRawUnsharedAliasing!S7);

    union S8  { int a; int b; }
    union S9  { int a; int* b; }
    union S10 { int a; shared int* b; }
    static assert(!hasRawUnsharedAliasing!S8);
    static assert( hasRawUnsharedAliasing!S9);
    static assert(!hasRawUnsharedAliasing!S10);

    static assert(!hasRawUnsharedAliasing!(void delegate()));
    static assert(!hasRawUnsharedAliasing!(void delegate() const));
    static assert(!hasRawUnsharedAliasing!(void delegate() immutable));
    static assert(!hasRawUnsharedAliasing!(void delegate() shared));
    static assert(!hasRawUnsharedAliasing!(void delegate() shared const));
    static assert(!hasRawUnsharedAliasing!(const(void delegate())));
    static assert(!hasRawUnsharedAliasing!(const(void delegate() const)));
    static assert(!hasRawUnsharedAliasing!(const(void delegate() immutable)));
    static assert(!hasRawUnsharedAliasing!(const(void delegate() shared)));
    static assert(!hasRawUnsharedAliasing!(const(void delegate() shared const)));
    static assert(!hasRawUnsharedAliasing!(immutable(void delegate())));
    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() const)));
    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() immutable)));
    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() shared)));
    static assert(!hasRawUnsharedAliasing!(immutable(void delegate() shared const)));
    static assert(!hasRawUnsharedAliasing!(shared(void delegate())));
    static assert(!hasRawUnsharedAliasing!(shared(void delegate() const)));
    static assert(!hasRawUnsharedAliasing!(shared(void delegate() immutable)));
    static assert(!hasRawUnsharedAliasing!(shared(void delegate() shared)));
    static assert(!hasRawUnsharedAliasing!(shared(void delegate() shared const)));
    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate()))));
    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() const))));
    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() immutable))));
    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() shared))));
    static assert(!hasRawUnsharedAliasing!(shared(const(void delegate() shared const))));
    static assert(!hasRawUnsharedAliasing!(void function()));

    enum S13 { a }
    static assert(!hasRawUnsharedAliasing!S13);

    // indirect members
    struct S14 { S9  a; int b; }
    struct S15 { S10 a; int b; }
    struct S16 { S6  a; int b; }
    static assert( hasRawUnsharedAliasing!S14);
    static assert(!hasRawUnsharedAliasing!S15);
    static assert(!hasRawUnsharedAliasing!S16);

    static assert( hasRawUnsharedAliasing!(int[string]));
    static assert(!hasRawUnsharedAliasing!(shared(int[string])));
    static assert(!hasRawUnsharedAliasing!(immutable(int[string])));

    struct S17
    {
        void delegate() shared a;
        void delegate() immutable b;
        void delegate() shared const c;
        shared(void delegate()) d;
        shared(void delegate() shared) e;
        shared(void delegate() immutable) f;
        shared(void delegate() shared const) g;
        immutable(void delegate()) h;
        immutable(void delegate() shared) i;
        immutable(void delegate() immutable) j;
        immutable(void delegate() shared const) k;
        shared(const(void delegate())) l;
        shared(const(void delegate() shared)) m;
        shared(const(void delegate() immutable)) n;
        shared(const(void delegate() shared const)) o;
    }
    struct S18 { typeof(S17.tupleof) a; void delegate() p; }
    struct S19 { typeof(S17.tupleof) a; Object p; }
    struct S20 { typeof(S17.tupleof) a; int* p; }
    class S21 { typeof(S17.tupleof) a; }
    class S22 { typeof(S17.tupleof) a; void delegate() p; }
    class S23 { typeof(S17.tupleof) a; Object p; }
    class S24 { typeof(S17.tupleof) a; int* p; }
    static assert(!hasRawUnsharedAliasing!S17);
    static assert(!hasRawUnsharedAliasing!(immutable(S17)));
    static assert(!hasRawUnsharedAliasing!(shared(S17)));
    static assert(!hasRawUnsharedAliasing!S18);
    static assert(!hasRawUnsharedAliasing!(immutable(S18)));
    static assert(!hasRawUnsharedAliasing!(shared(S18)));
    static assert(!hasRawUnsharedAliasing!S19);
    static assert(!hasRawUnsharedAliasing!(immutable(S19)));
    static assert(!hasRawUnsharedAliasing!(shared(S19)));
    static assert( hasRawUnsharedAliasing!S20);
    static assert(!hasRawUnsharedAliasing!(immutable(S20)));
    static assert(!hasRawUnsharedAliasing!(shared(S20)));
    static assert(!hasRawUnsharedAliasing!S21);
    static assert(!hasRawUnsharedAliasing!(immutable(S21)));
    static assert(!hasRawUnsharedAliasing!(shared(S21)));
    static assert(!hasRawUnsharedAliasing!S22);
    static assert(!hasRawUnsharedAliasing!(immutable(S22)));
    static assert(!hasRawUnsharedAliasing!(shared(S22)));
    static assert(!hasRawUnsharedAliasing!S23);
    static assert(!hasRawUnsharedAliasing!(immutable(S23)));
    static assert(!hasRawUnsharedAliasing!(shared(S23)));
    static assert( hasRawUnsharedAliasing!S24);
    static assert(!hasRawUnsharedAliasing!(immutable(S24)));
    static assert(!hasRawUnsharedAliasing!(shared(S24)));
    struct S25 {}
    class S26 {}
    interface S27 {}
    union S28 {}
    static assert(!hasRawUnsharedAliasing!S25);
    static assert(!hasRawUnsharedAliasing!S26);
    static assert(!hasRawUnsharedAliasing!S27);
    static assert(!hasRawUnsharedAliasing!S28);
}

private template hasRawUnsharedAliasingImpl(T)
{
    static if (is(T foo : U*, U) && !isFunctionPointer!T)
        enum hasRawUnsharedAliasingImpl = !is(U == immutable) && !is(U == shared);
    else static if (is(T foo : U[], U) && !isStaticArray!T)
        enum hasRawUnsharedAliasingImpl = !is(U == immutable) && !is(U == shared);
    else static if (isAssociativeArray!T)
        enum hasRawUnsharedAliasingImpl = !is(T == immutable) && !is(T == shared);
    else
        enum hasRawUnsharedAliasingImpl = false;
}

/*
Statically evaluates to `true` if and only if `T`'s
representation includes at least one non-immutable object reference.
*/

private template hasObjects(T)
{
    static if (is(T == struct))
    {
        enum hasObjects = anySatisfy!(.hasObjects, RepresentationTypeTuple!T);
    }
    else
    {
        enum hasObjects = (is(T == class) || is(T == interface)) && !is(T == immutable);
    }
}

/*
Statically evaluates to `true` if and only if `T`'s
representation includes at least one non-immutable non-shared object
reference.
*/
private template hasUnsharedObjects(T)
{
    static if (is(T == struct))
    {
        enum hasUnsharedObjects = anySatisfy!(.hasUnsharedObjects, RepresentationTypeTuple!T);
    }
    else
    {
        enum hasUnsharedObjects = (is(T == class) || is(T == interface)) &&
                                  !is(T == immutable) && !is(T == shared);
    }
}

/**
Returns `true` if and only if `T`'s representation includes at
least one of the following: $(OL $(LI a raw pointer `U*` and `U`
is not immutable;) $(LI an array `U[]` and `U` is not
immutable;) $(LI a reference to a class or interface type `C` and `C` is
not immutable.) $(LI an associative array that is not immutable.)
$(LI a delegate.))
*/
template hasAliasing(T...)
{
    enum hasAliasing = anySatisfy!(hasAliasingImpl, T);
}

///
@safe unittest
{
    struct S1 { int a; Object b; }
    struct S2 { string a; }
    struct S3 { int a; immutable Object b; }
    struct S4 { float[3] vals; }
    static assert( hasAliasing!S1);
    static assert(!hasAliasing!S2);
    static assert(!hasAliasing!S3);
    static assert(!hasAliasing!S4);
}

@safe unittest
{
    static assert( hasAliasing!(uint[uint]));
    static assert(!hasAliasing!(immutable(uint[uint])));
    static assert( hasAliasing!(void delegate()));
    static assert( hasAliasing!(void delegate() const));
    static assert(!hasAliasing!(void delegate() immutable));
    static assert( hasAliasing!(void delegate() shared));
    static assert( hasAliasing!(void delegate() shared const));
    static assert( hasAliasing!(const(void delegate())));
    static assert( hasAliasing!(const(void delegate() const)));
    static assert(!hasAliasing!(const(void delegate() immutable)));
    static assert( hasAliasing!(const(void delegate() shared)));
    static assert( hasAliasing!(const(void delegate() shared const)));
    static assert(!hasAliasing!(immutable(void delegate())));
    static assert(!hasAliasing!(immutable(void delegate() const)));
    static assert(!hasAliasing!(immutable(void delegate() immutable)));
    static assert(!hasAliasing!(immutable(void delegate() shared)));
    static assert(!hasAliasing!(immutable(void delegate() shared const)));
    static assert( hasAliasing!(shared(const(void delegate()))));
    static assert( hasAliasing!(shared(const(void delegate() const))));
    static assert(!hasAliasing!(shared(const(void delegate() immutable))));
    static assert( hasAliasing!(shared(const(void delegate() shared))));
    static assert( hasAliasing!(shared(const(void delegate() shared const))));
    static assert(!hasAliasing!(void function()));

    interface I;
    static assert( hasAliasing!I);

    import std.typecons : Rebindable;
    static assert( hasAliasing!(Rebindable!(const Object)));
    static assert(!hasAliasing!(Rebindable!(immutable Object)));
    static assert( hasAliasing!(Rebindable!(shared Object)));
    static assert( hasAliasing!(Rebindable!Object));

    struct S5
    {
        void delegate() immutable b;
        shared(void delegate() immutable) f;
        immutable(void delegate() immutable) j;
        shared(const(void delegate() immutable)) n;
    }
    struct S6 { typeof(S5.tupleof) a; void delegate() p; }
    static assert(!hasAliasing!S5);
    static assert( hasAliasing!S6);

    struct S7 { void delegate() a; int b; Object c; }
    class S8 { int a; int b; }
    class S9 { typeof(S8.tupleof) a; }
    class S10 { typeof(S8.tupleof) a; int* b; }
    static assert( hasAliasing!S7);
    static assert( hasAliasing!S8);
    static assert( hasAliasing!S9);
    static assert( hasAliasing!S10);
    struct S11 {}
    class S12 {}
    interface S13 {}
    union S14 {}
    static assert(!hasAliasing!S11);
    static assert( hasAliasing!S12);
    static assert( hasAliasing!S13);
    static assert(!hasAliasing!S14);

    class S15 { S15[1] a; }
    static assert( hasAliasing!S15);
    static assert(!hasAliasing!(immutable(S15)));

    static assert(!hasAliasing!noreturn);
}

private template hasAliasingImpl(T)
{
    import std.typecons : Rebindable;

    static if (is(immutable T == immutable Rebindable!R, R))
    {
        enum hasAliasingImpl = hasAliasingImpl!R;
    }
    else
    {
        template isAliasingDelegate(T)
        {
            enum isAliasingDelegate = isDelegate!T
                                  && !is(T == immutable)
                                  && !is(FunctionTypeOf!T == immutable);
        }
        enum hasAliasingImpl = hasRawAliasing!T || hasObjects!T ||
            anySatisfy!(isAliasingDelegate, T, RepresentationTypeTuple!T);
    }
}

/**
Returns `true` if and only if `T`'s representation includes at
least one of the following: $(OL $(LI a raw pointer `U*`;) $(LI an
array `U[]`;) $(LI a reference to a class type `C`;)
$(LI an associative array;) $(LI a delegate;)
$(LI a [context pointer][isNested].))
 */
template hasIndirections(T)
{
    import core.internal.traits : _hasIndirections = hasIndirections;
    alias hasIndirections = _hasIndirections!T;
}

///
@safe unittest
{
    static assert( hasIndirections!(int[string]));
    static assert( hasIndirections!(void delegate()));
    static assert( hasIndirections!(void delegate() immutable));
    static assert( hasIndirections!(immutable(void delegate())));
    static assert( hasIndirections!(immutable(void delegate() immutable)));

    static assert(!hasIndirections!(void function()));
    static assert( hasIndirections!(void*[1]));
    static assert(!hasIndirections!(byte[1]));
}

@safe unittest
{
    // void static array hides actual type of bits, so "may have indirections".
    static assert( hasIndirections!(void[1]));
    interface I {}
    struct S1 {}
    struct S2 { int a; }
    struct S3 { int a; int b; }
    struct S4 { int a; int* b; }
    struct S5 { int a; Object b; }
    struct S6 { int a; string b; }
    struct S7 { int a; immutable Object b; }
    struct S8 { int a; immutable I b; }
    struct S9 { int a; void delegate() b; }
    struct S10 { int a; immutable(void delegate()) b; }
    struct S11 { int a; void delegate() immutable b; }
    struct S12 { int a; immutable(void delegate() immutable) b; }
    class S13 {}
    class S14 { int a; }
    class S15 { int a; int b; }
    class S16 { int a; Object b; }
    class S17 { string a; }
    class S18 { int a; immutable Object b; }
    class S19 { int a; immutable(void delegate() immutable) b; }
    union S20 {}
    union S21 { int a; }
    union S22 { int a; int b; }
    union S23 { int a; Object b; }
    union S24 { string a; }
    union S25 { int a; immutable Object b; }
    union S26 { int a; immutable(void delegate() immutable) b; }
    static assert( hasIndirections!I);
    static assert(!hasIndirections!S1);
    static assert(!hasIndirections!S2);
    static assert(!hasIndirections!S3);
    static assert( hasIndirections!S4);
    static assert( hasIndirections!S5);
    static assert( hasIndirections!S6);
    static assert( hasIndirections!S7);
    static assert( hasIndirections!S8);
    static assert( hasIndirections!S9);
    static assert( hasIndirections!S10);
    static assert( hasIndirections!S12);
    static assert( hasIndirections!S13);
    static assert( hasIndirections!S14);
    static assert( hasIndirections!S15);
    static assert( hasIndirections!S16);
    static assert( hasIndirections!S17);
    static assert( hasIndirections!S18);
    static assert( hasIndirections!S19);
    static assert(!hasIndirections!S20);
    static assert(!hasIndirections!S21);
    static assert(!hasIndirections!S22);
    static assert( hasIndirections!S23);
    static assert( hasIndirections!S24);
    static assert( hasIndirections!S25);
    static assert( hasIndirections!S26);
    int local;
    struct HasContextPointer { int opCall() { return ++local; } }
    static assert(hasIndirections!HasContextPointer);

    static assert(!hasIndirections!noreturn);
}

// https://issues.dlang.org/show_bug.cgi?id=12000
@safe unittest
{
    static struct S(T)
    {
        static assert(hasIndirections!T);
    }

    static class A(T)
    {
        S!A a;
    }

    A!int dummy;
}

/**
Returns `true` if and only if `T`'s representation includes at
least one of the following: $(OL $(LI a raw pointer `U*` and `U`
is not immutable or shared;) $(LI an array `U[]` and `U` is not
immutable or shared;) $(LI a reference to a class type `C` and
`C` is not immutable or shared.) $(LI an associative array that is not
immutable or shared.) $(LI a delegate that is not shared.))
*/

template hasUnsharedAliasing(T...)
{
    enum hasUnsharedAliasing = anySatisfy!(hasUnsharedAliasingImpl, T);
}

///
@safe unittest
{
    struct S1 { int a; Object b; }
    struct S2 { string a; }
    struct S3 { int a; immutable Object b; }
    static assert( hasUnsharedAliasing!S1);
    static assert(!hasUnsharedAliasing!S2);
    static assert(!hasUnsharedAliasing!S3);

    struct S4 { int a; shared Object b; }
    struct S5 { char[] a; }
    struct S6 { shared char[] b; }
    struct S7 { float[3] vals; }
    static assert(!hasUnsharedAliasing!S4);
    static assert( hasUnsharedAliasing!S5);
    static assert(!hasUnsharedAliasing!S6);
    static assert(!hasUnsharedAliasing!S7);
}

@safe unittest
{
    /* https://issues.dlang.org/show_bug.cgi?id=6642 */
    import std.typecons : Rebindable;
    struct S8 { int a; Rebindable!(immutable Object) b; }
    static assert(!hasUnsharedAliasing!S8);

    static assert( hasUnsharedAliasing!(uint[uint]));

    static assert( hasUnsharedAliasing!(void delegate()));
    static assert( hasUnsharedAliasing!(void delegate() const));
    static assert(!hasUnsharedAliasing!(void delegate() immutable));
    static assert(!hasUnsharedAliasing!(void delegate() shared));
    static assert(!hasUnsharedAliasing!(void delegate() shared const));
}

@safe unittest
{
    import std.typecons : Rebindable;
    static assert( hasUnsharedAliasing!(const(void delegate())));
    static assert( hasUnsharedAliasing!(const(void delegate() const)));
    static assert(!hasUnsharedAliasing!(const(void delegate() immutable)));
    static assert(!hasUnsharedAliasing!(const(void delegate() shared)));
    static assert(!hasUnsharedAliasing!(const(void delegate() shared const)));
    static assert(!hasUnsharedAliasing!(immutable(void delegate())));
    static assert(!hasUnsharedAliasing!(immutable(void delegate() const)));
    static assert(!hasUnsharedAliasing!(immutable(void delegate() immutable)));
    static assert(!hasUnsharedAliasing!(immutable(void delegate() shared)));
    static assert(!hasUnsharedAliasing!(immutable(void delegate() shared const)));
    static assert(!hasUnsharedAliasing!(shared(void delegate())));
    static assert(!hasUnsharedAliasing!(shared(void delegate() const)));
    static assert(!hasUnsharedAliasing!(shared(void delegate() immutable)));
    static assert(!hasUnsharedAliasing!(shared(void delegate() shared)));
    static assert(!hasUnsharedAliasing!(shared(void delegate() shared const)));
    static assert(!hasUnsharedAliasing!(shared(const(void delegate()))));
    static assert(!hasUnsharedAliasing!(shared(const(void delegate() const))));
    static assert(!hasUnsharedAliasing!(shared(const(void delegate() immutable))));
    static assert(!hasUnsharedAliasing!(shared(const(void delegate() shared))));
    static assert(!hasUnsharedAliasing!(shared(const(void delegate() shared const))));
    static assert(!hasUnsharedAliasing!(void function()));

    interface I {}
    static assert(hasUnsharedAliasing!I);

    static assert( hasUnsharedAliasing!(Rebindable!(const Object)));
    static assert(!hasUnsharedAliasing!(Rebindable!(immutable Object)));
    static assert(!hasUnsharedAliasing!(Rebindable!(shared Object)));
    static assert( hasUnsharedAliasing!(Rebindable!Object));

    /* https://issues.dlang.org/show_bug.cgi?id=6979 */
    static assert(!hasUnsharedAliasing!(int, shared(int)*));
    static assert( hasUnsharedAliasing!(int, int*));
    static assert( hasUnsharedAliasing!(int, const(int)[]));
    static assert( hasUnsharedAliasing!(int, shared(int)*, Rebindable!Object));
    static assert(!hasUnsharedAliasing!(shared(int)*, Rebindable!(shared Object)));
    static assert(!hasUnsharedAliasing!());

    struct S9
    {
        void delegate() shared a;
        void delegate() immutable b;
        void delegate() shared const c;
        shared(void delegate()) d;
        shared(void delegate() shared) e;
        shared(void delegate() immutable) f;
        shared(void delegate() shared const) g;
        immutable(void delegate()) h;
        immutable(void delegate() shared) i;
        immutable(void delegate() immutable) j;
        immutable(void delegate() shared const) k;
        shared(const(void delegate())) l;
        shared(const(void delegate() shared)) m;
        shared(const(void delegate() immutable)) n;
        shared(const(void delegate() shared const)) o;
    }
    struct S10 { typeof(S9.tupleof) a; void delegate() p; }
    struct S11 { typeof(S9.tupleof) a; Object p; }
    struct S12 { typeof(S9.tupleof) a; int* p; }
    class S13 { typeof(S9.tupleof) a; }
    class S14 { typeof(S9.tupleof) a; void delegate() p; }
    class S15 { typeof(S9.tupleof) a; Object p; }
    class S16 { typeof(S9.tupleof) a; int* p; }
    static assert(!hasUnsharedAliasing!S9);
    static assert(!hasUnsharedAliasing!(immutable(S9)));
    static assert(!hasUnsharedAliasing!(shared(S9)));
    static assert( hasUnsharedAliasing!S10);
    static assert(!hasUnsharedAliasing!(immutable(S10)));
    static assert(!hasUnsharedAliasing!(shared(S10)));
    static assert( hasUnsharedAliasing!S11);
    static assert(!hasUnsharedAliasing!(immutable(S11)));
    static assert(!hasUnsharedAliasing!(shared(S11)));
    static assert( hasUnsharedAliasing!S12);
    static assert(!hasUnsharedAliasing!(immutable(S12)));
    static assert(!hasUnsharedAliasing!(shared(S12)));
    static assert( hasUnsharedAliasing!S13);
    static assert(!hasUnsharedAliasing!(immutable(S13)));
    static assert(!hasUnsharedAliasing!(shared(S13)));
    static assert( hasUnsharedAliasing!S14);
    static assert(!hasUnsharedAliasing!(immutable(S14)));
    static assert(!hasUnsharedAliasing!(shared(S14)));
    static assert( hasUnsharedAliasing!S15);
    static assert(!hasUnsharedAliasing!(immutable(S15)));
    static assert(!hasUnsharedAliasing!(shared(S15)));
    static assert( hasUnsharedAliasing!S16);
    static assert(!hasUnsharedAliasing!(immutable(S16)));
    static assert(!hasUnsharedAliasing!(shared(S16)));
    struct S17 {}
    class S18 {}
    interface S19 {}
    union S20 {}
    static assert(!hasUnsharedAliasing!S17);
    static assert( hasUnsharedAliasing!S18);
    static assert( hasUnsharedAliasing!S19);
    static assert(!hasUnsharedAliasing!S20);

    static assert(!hasUnsharedAliasing!noreturn);
}

private template hasUnsharedAliasingImpl(T)
{
    import std.typecons : Rebindable;

    static if (is(immutable T == immutable Rebindable!R, R))
    {
        enum hasUnsharedAliasingImpl = hasUnsharedAliasingImpl!R;
    }
    else
    {
        template unsharedDelegate(T)
        {
            enum bool unsharedDelegate = isDelegate!T
                                     && !is(T == shared)
                                     && !is(T == immutable)
                                     && !is(FunctionTypeOf!T == shared)
                                     && !is(FunctionTypeOf!T == immutable);
        }

        enum hasUnsharedAliasingImpl =
            hasRawUnsharedAliasing!T ||
            anySatisfy!(unsharedDelegate, RepresentationTypeTuple!T) ||
            hasUnsharedObjects!T;
    }
}

version (StdDdoc)
{
    /**
       True if `S` or any type embedded directly in the representation of `S`
       defines an elaborate copy constructor. Elaborate copy constructors are
       introduced by defining `this(this)` for a `struct`.

       Classes and unions never have elaborate copy constructors.
    */
    template hasElaborateCopyConstructor(S)
    {
        import core.internal.traits : hasElabCCtor = hasElaborateCopyConstructor;
        alias hasElaborateCopyConstructor = hasElabCCtor!(S);
    }
}
else
{
    import core.internal.traits : hasElabCCtor = hasElaborateCopyConstructor;
    alias hasElaborateCopyConstructor = hasElabCCtor;
}

///
@safe unittest
{
    static assert(!hasElaborateCopyConstructor!int);

    static struct S1 { }
    static struct S2 { this(this) {} }
    static struct S3 { S2 field; }
    static struct S4 { S3[1] field; }
    static struct S5 { S3[] field; }
    static struct S6 { S3[0] field; }
    static struct S7 { @disable this(); S3 field; }
    static assert(!hasElaborateCopyConstructor!S1);
    static assert( hasElaborateCopyConstructor!S2);
    static assert( hasElaborateCopyConstructor!(immutable S2));
    static assert( hasElaborateCopyConstructor!S3);
    static assert( hasElaborateCopyConstructor!(S3[1]));
    static assert(!hasElaborateCopyConstructor!(S3[0]));
    static assert( hasElaborateCopyConstructor!S4);
    static assert(!hasElaborateCopyConstructor!S5);
    static assert(!hasElaborateCopyConstructor!S6);
    static assert( hasElaborateCopyConstructor!S7);
}

/**
   True if `S` or any type directly embedded in the representation of `S`
   defines an elaborate assignment. Elaborate assignments are introduced by
   defining `opAssign(typeof(this))` or $(D opAssign(ref typeof(this)))
   for a `struct` or when there is a compiler-generated `opAssign`.

   A type `S` gets compiler-generated `opAssign` if it has
   an elaborate destructor.

   Classes and unions never have elaborate assignments.

   Note: Structs with (possibly nested) postblit operator(s) will have a
   hidden yet elaborate compiler generated assignment operator (unless
   explicitly disabled).
 */
template hasElaborateAssign(S)
{
    static if (isStaticArray!S && S.length)
    {
        enum bool hasElaborateAssign = hasElaborateAssign!(typeof(S.init[0]));
    }
    else static if (is(S == struct))
    {
        enum hasElaborateAssign = is(typeof(S.init.opAssign(rvalueOf!S))) ||
                                  is(typeof(S.init.opAssign(lvalueOf!S))) ||
            anySatisfy!(.hasElaborateAssign, FieldTypeTuple!S);
    }
    else
    {
        enum bool hasElaborateAssign = false;
    }
}

///
@safe unittest
{
    static assert(!hasElaborateAssign!int);

    static struct S  { void opAssign(S) {} }
    static assert( hasElaborateAssign!S);
    static assert(!hasElaborateAssign!(const(S)));

    static struct S1 { void opAssign(ref S1) {} }
    static struct S2 { void opAssign(int) {} }
    static struct S3 { S s; }
    static assert( hasElaborateAssign!S1);
    static assert(!hasElaborateAssign!S2);
    static assert( hasElaborateAssign!S3);
    static assert( hasElaborateAssign!(S3[1]));
    static assert(!hasElaborateAssign!(S3[0]));
}

@safe unittest
{
    static struct S  { void opAssign(S) {} }
    static struct S4
    {
        void opAssign(U)(U u) {}
        @disable void opAssign(U)(ref U u);
    }
    static assert( hasElaborateAssign!S4);

    static struct S41
    {
        void opAssign(U)(ref U u) {}
        @disable void opAssign(U)(U u);
    }
    static assert( hasElaborateAssign!S41);

    static struct S5 { @disable this(); this(int n){ s = S(); } S s; }
    static assert( hasElaborateAssign!S5);

    static struct S6 { this(this) {} }
    static struct S7 { this(this) {} @disable void opAssign(S7); }
    static struct S8 { this(this) {} @disable void opAssign(S8); void opAssign(int) {} }
    static struct S9 { this(this) {}                             void opAssign(int) {} }
    static struct S10 { ~this() { } }
    static assert( hasElaborateAssign!S6);
    static assert(!hasElaborateAssign!S7);
    static assert(!hasElaborateAssign!S8);
    static assert( hasElaborateAssign!S9);
    static assert( hasElaborateAssign!S10);
    static struct SS6 { S6 s; }
    static struct SS7 { S7 s; }
    static struct SS8 { S8 s; }
    static struct SS9 { S9 s; }
    static assert( hasElaborateAssign!SS6);
    static assert(!hasElaborateAssign!SS7);
    static assert(!hasElaborateAssign!SS8);
    static assert( hasElaborateAssign!SS9);
}

version (StdDdoc)
{
    /**
       True if `S` or any type directly embedded in the representation
       of `S` defines an elaborate destructor. Elaborate destructors
       are introduced by defining `~this()` for a $(D
       struct).

       Classes and unions never have elaborate destructors, even
       though classes may define `~this()`.
    */
    template hasElaborateDestructor(S)
    {
        import core.internal.traits : hasElabDest = hasElaborateDestructor;
        alias hasElaborateDestructor = hasElabDest!(S);
    }
}
else
{
    import core.internal.traits : hasElabDest = hasElaborateDestructor;
    alias hasElaborateDestructor = hasElabDest;
}

///
@safe unittest
{
    static assert(!hasElaborateDestructor!int);

    static struct S1 { }
    static struct S2 { ~this() {} }
    static struct S3 { S2 field; }
    static struct S4 { S3[1] field; }
    static struct S5 { S3[] field; }
    static struct S6 { S3[0] field; }
    static struct S7 { @disable this(); S3 field; }
    static assert(!hasElaborateDestructor!S1);
    static assert( hasElaborateDestructor!S2);
    static assert( hasElaborateDestructor!(immutable S2));
    static assert( hasElaborateDestructor!S3);
    static assert( hasElaborateDestructor!(S3[1]));
    static assert(!hasElaborateDestructor!(S3[0]));
    static assert( hasElaborateDestructor!S4);
    static assert(!hasElaborateDestructor!S5);
    static assert(!hasElaborateDestructor!S6);
    static assert( hasElaborateDestructor!S7);
}

version (StdDdoc)
{
    /**
       True if `S` or any type embedded directly in the representation of `S`
       defines elaborate move semantics. Elaborate move semantics are
       introduced by defining `opPostMove(ref typeof(this))` for a `struct`.

       Classes and unions never have elaborate move semantics.
    */
    template hasElaborateMove(S)
    {
        import core.internal.traits : hasElabMove = hasElaborateMove;
        alias hasElaborateMove = hasElabMove!(S);
    }
}
else
{
    import core.internal.traits : hasElabMove = hasElaborateMove;
    alias hasElaborateMove = hasElabMove;
}

///
@safe unittest
{
    static assert(!hasElaborateMove!int);

    static struct S1 { }
    static struct S2 { void opPostMove(ref S2) {} }
    static struct S3 { void opPostMove(inout ref S3) inout {} }
    static struct S4 { void opPostMove(const ref S4) {} }
    static struct S5 { void opPostMove(S5) {} }
    static struct S6 { void opPostMove(int) {} }
    static struct S7 { S3[1] field; }
    static struct S8 { S3[] field; }
    static struct S9 { S3[0] field; }
    static struct S10 { @disable this(); S3 field; }
    static assert(!hasElaborateMove!S1);
    static assert( hasElaborateMove!S2);
    static assert( hasElaborateMove!S3);
    static assert( hasElaborateMove!(immutable S3));
    static assert( hasElaborateMove!S4);
    static assert(!hasElaborateMove!S5);
    static assert(!hasElaborateMove!S6);
    static assert( hasElaborateMove!S7);
    static assert(!hasElaborateMove!S8);
    static assert(!hasElaborateMove!S9);
    static assert( hasElaborateMove!S10);
}

package alias Identity(alias A) = A;

/**
   Yields `true` if and only if `T` is an aggregate that defines
   a symbol called `name`.

   See also: $(DDSUBLINK spec/traits, hasMember, `__traits(hasMember, T, name)`)
 */
enum hasMember(T, string name) = __traits(hasMember, T, name);

///
@safe unittest
{
    static assert(!hasMember!(int, "blah"));
    struct S1 { int blah; }
    struct S2 { int blah(){ return 0; } }
    class C1 { int blah; }
    class C2 { int blah(){ return 0; } }
    static assert(hasMember!(S1, "blah"));
    static assert(hasMember!(S2, "blah"));
    static assert(hasMember!(C1, "blah"));
    static assert(hasMember!(C2, "blah"));
}

@safe unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=8321
    struct S {
        int x;
        void f(){}
        void t()(){}
        template T(){}
    }
    struct R1(T) {
        T t;
        alias t this;
    }
    struct R2(T) {
        T t;
        @property ref inout(T) payload() inout { return t; }
        alias t this;
    }
    static assert(hasMember!(S, "x"));
    static assert(hasMember!(S, "f"));
    static assert(hasMember!(S, "t"));
    static assert(hasMember!(S, "T"));
    static assert(hasMember!(R1!S, "x"));
    static assert(hasMember!(R1!S, "f"));
    static assert(hasMember!(R1!S, "t"));
    static assert(hasMember!(R1!S, "T"));
    static assert(hasMember!(R2!S, "x"));
    static assert(hasMember!(R2!S, "f"));
    static assert(hasMember!(R2!S, "t"));
    static assert(hasMember!(R2!S, "T"));
}

@safe unittest
{
    static struct S
    {
        void opDispatch(string n, A)(A dummy) {}
    }
    static assert(hasMember!(S, "foo"));
}

/**
 * Whether the symbol represented by the string, member, exists and is a static member of T.
 *
 * Params:
 *     T = Type containing symbol `member`.
 *     member = Name of symbol to test that resides in `T`.
 *
 * Returns:
 *     `true` iff `member` exists and is static.
 */
template hasStaticMember(T, string member)
{
    static if (__traits(hasMember, T, member))
    {
        static if (is(T == V*, V))
            alias U = V;
        else
            alias U = T;

        import std.meta : Alias;
        alias sym = Alias!(__traits(getMember, U, member));

        static if (__traits(getOverloads, U, member).length == 0)
            enum bool hasStaticMember = __traits(compiles, &sym);
        else
            enum bool hasStaticMember = __traits(isStaticFunction, sym);
    }
    else
    {
        enum bool hasStaticMember = false;
    }
}

///
@safe unittest
{
    static struct S
    {
        static void sf() {}
        void f() {}

        static int si;
        int i;
    }

    static assert( hasStaticMember!(S, "sf"));
    static assert(!hasStaticMember!(S, "f"));

    static assert( hasStaticMember!(S, "si"));
    static assert(!hasStaticMember!(S, "i"));

    static assert(!hasStaticMember!(S, "hello"));
}

@safe unittest
{
    static struct S
    {
        enum X = 10;
        enum Y
        {
            i = 10
        }
        struct S {}
        class C {}

        static int sx = 0;
        __gshared int gx = 0;

        Y y;
        static Y sy;

        static void f();
        static void f2() pure nothrow @nogc @safe;

        void g() shared;

        static void function() fp;
        __gshared void function() gfp;
        void function() fpm;

        void delegate() dm;
        static void delegate() sd;

        void m();
        void m2() const pure nothrow @nogc @safe;

        inout(int) iom() inout;
        static inout(int) iosf(inout int x);

        @property int p();
        static @property int sp();
    }

    static class C
    {
        enum X = 10;
        enum Y
        {
            i = 10
        }
        struct S {}
        class C {}

        static int sx = 0;
        __gshared int gx = 0;

        Y y;
        static Y sy;

        static void f();
        static void f2() pure nothrow @nogc @safe;

        void g() shared { }

        static void function() fp;
        __gshared void function() gfp;
        void function() fpm;

        void delegate() dm;
        static void delegate() sd;

        void m() {}
        final void m2() const pure nothrow @nogc @safe;

        inout(int) iom() inout { return 10; }
        static inout(int) iosf(inout int x);

        @property int p() { return 10; }
        static @property int sp();
    }

    static assert(!hasStaticMember!(S, "na"));
    static assert(!hasStaticMember!(S, "X"));
    static assert(!hasStaticMember!(S, "Y"));
    static assert(!hasStaticMember!(S, "Y.i"));
    static assert(!hasStaticMember!(S, "S"));
    static assert(!hasStaticMember!(S, "C"));
    static assert( hasStaticMember!(S, "sx"));
    static assert( hasStaticMember!(S, "gx"));
    static assert(!hasStaticMember!(S, "y"));
    static assert( hasStaticMember!(S, "sy"));
    static assert( hasStaticMember!(S, "f"));
    static assert( hasStaticMember!(S, "f2"));
    static assert(!hasStaticMember!(S, "dm"));
    static assert( hasStaticMember!(S, "sd"));
    static assert(!hasStaticMember!(S, "g"));
    static assert( hasStaticMember!(S, "fp"));
    static assert( hasStaticMember!(S, "gfp"));
    static assert(!hasStaticMember!(S, "fpm"));
    static assert(!hasStaticMember!(S, "m"));
    static assert(!hasStaticMember!(S, "m2"));
    static assert(!hasStaticMember!(S, "iom"));
    static assert( hasStaticMember!(S, "iosf"));
    static assert(!hasStaticMember!(S, "p"));
    static assert( hasStaticMember!(S, "sp"));

    static assert(!hasStaticMember!(C, "na"));
    static assert(!hasStaticMember!(C, "X"));
    static assert(!hasStaticMember!(C, "Y"));
    static assert(!hasStaticMember!(C, "Y.i"));
    static assert(!hasStaticMember!(C, "S"));
    static assert(!hasStaticMember!(C, "C"));
    static assert( hasStaticMember!(C, "sx"));
    static assert( hasStaticMember!(C, "gx"));
    static assert(!hasStaticMember!(C, "y"));
    static assert( hasStaticMember!(C, "sy"));
    static assert( hasStaticMember!(C, "f"));
    static assert( hasStaticMember!(C, "f2"));
    static assert(!hasStaticMember!(C, "dm"));
    static assert( hasStaticMember!(C, "sd"));
    static assert(!hasStaticMember!(C, "g"));
    static assert( hasStaticMember!(C, "fp"));
    static assert( hasStaticMember!(C, "gfp"));
    static assert(!hasStaticMember!(C, "fpm"));
    static assert(!hasStaticMember!(C, "m"));
    static assert(!hasStaticMember!(C, "m2"));
    static assert(!hasStaticMember!(C, "iom"));
    static assert( hasStaticMember!(C, "iosf"));
    static assert(!hasStaticMember!(C, "p"));
    static assert( hasStaticMember!(C, "sp"));

    alias P = S*;
    static assert(!hasStaticMember!(P, "na"));
    static assert(!hasStaticMember!(P, "X"));
    static assert(!hasStaticMember!(P, "Y"));
    static assert(!hasStaticMember!(P, "Y.i"));
    static assert(!hasStaticMember!(P, "S"));
    static assert(!hasStaticMember!(P, "C"));
    static assert( hasStaticMember!(P, "sx"));
    static assert( hasStaticMember!(P, "gx"));
    static assert(!hasStaticMember!(P, "y"));
    static assert( hasStaticMember!(P, "sy"));
    static assert( hasStaticMember!(P, "f"));
    static assert( hasStaticMember!(P, "f2"));
    static assert(!hasStaticMember!(P, "dm"));
    static assert( hasStaticMember!(P, "sd"));
    static assert(!hasStaticMember!(P, "g"));
    static assert( hasStaticMember!(P, "fp"));
    static assert( hasStaticMember!(P, "gfp"));
    static assert(!hasStaticMember!(P, "fpm"));
    static assert(!hasStaticMember!(P, "m"));
    static assert(!hasStaticMember!(P, "m2"));
    static assert(!hasStaticMember!(P, "iom"));
    static assert( hasStaticMember!(P, "iosf"));
    static assert(!hasStaticMember!(P, "p"));
    static assert( hasStaticMember!(P, "sp"));
}

/**
Retrieves the members of an enumerated type `enum E`.

Params:
    E = An enumerated type. `E` may have duplicated values.

Returns:
    Static tuple composed of the members of the enumerated type `E`.
    The members are arranged in the same order as declared in `E`.
    The name of the enum can be found by querying the compiler for the
    name of the identifier, i.e. `__traits(identifier, EnumMembers!MyEnum[i])`.
    For enumerations with unique values, $(REF to, std,conv) can also be used.

Note:
    An enum can have multiple members which have the same value. If you want
    to use EnumMembers to e.g. generate switch cases at compile-time,
    you should use the $(REF NoDuplicates, std,meta) template to avoid
    generating duplicate switch cases.

Note:
    Returned values are strictly typed with `E`. Thus, the following code
    does not work without the explicit cast:
--------------------
enum E : int { a, b, c }
int[] abc = cast(int[]) [ EnumMembers!E ];
--------------------
    Cast is not necessary if the type of the variable is inferred. See the
    example below.
 */
template EnumMembers(E)
if (is(E == enum))
{
    alias EnumMembers = AliasSeq!();
    static foreach (M; __traits(allMembers, E))
        EnumMembers = AliasSeq!(EnumMembers, __traits(getMember, E, M));
}

/// Create an array of enumerated values
@safe unittest
{
    enum Sqrts : real
    {
        one = 1,
        two = 1.41421,
        three = 1.73205
    }
    auto sqrts = [EnumMembers!Sqrts];
    assert(sqrts == [Sqrts.one, Sqrts.two, Sqrts.three]);
}

/**
A generic function `rank(v)` in the following example uses this
template for finding a member `e` in an enumerated type `E`.
 */
@safe unittest
{
    // Returns i if e is the i-th enumerator of E.
    static size_t rank(E)(E e)
    if (is(E == enum))
    {
        static foreach (i, member; EnumMembers!E)
        {
            if (e == member)
                return i;
        }
        assert(0, "Not an enum member");
    }

    enum Mode
    {
        read = 1,
        write = 2,
        map = 4
    }
    assert(rank(Mode.read) == 0);
    assert(rank(Mode.write) == 1);
    assert(rank(Mode.map) == 2);
}

/**
Use EnumMembers to generate a switch statement using static foreach.
*/

@safe unittest
{
    import std.conv : to;
    class FooClass
    {
        string calledMethod;
        void foo() @safe { calledMethod = "foo"; }
        void bar() @safe { calledMethod = "bar"; }
        void baz() @safe { calledMethod = "baz"; }
    }

    enum FooEnum { foo, bar, baz }

    auto var = FooEnum.bar;
    auto fooObj = new FooClass();
    s: final switch (var)
    {
        static foreach (member; EnumMembers!FooEnum)
        {
            case member: // Generate a case for each enum value.
                // Call fooObj.{name of enum value}().
                __traits(getMember, fooObj, to!string(member))();
                break s;
        }
    }
    // As we pass in FooEnum.bar, the bar() method gets called.
    assert(fooObj.calledMethod == "bar");
}

@safe unittest
{
    enum A { a }
    static assert([ EnumMembers!A ] == [ A.a ]);
    enum B { a, b, c, d, e }
    static assert([ EnumMembers!B ] == [ B.a, B.b, B.c, B.d, B.e ]);
}

@safe unittest    // typed enums
{
    enum A : string { a = "alpha", b = "beta" }
    static assert([ EnumMembers!A ] == [ A.a, A.b ]);

    static struct S
    {
        int value;
        int opCmp(S rhs) const nothrow { return value - rhs.value; }
    }
    enum B : S { a = S(1), b = S(2), c = S(3) }
    static assert([ EnumMembers!B ] == [ B.a, B.b, B.c ]);
}

@safe unittest    // duplicated values
{
    enum A
    {
        a = 0, b = 0,
        c = 1, d = 1, e
    }
    static assert([ EnumMembers!A ] == [ A.a, A.b, A.c, A.d, A.e ]);
}

// https://issues.dlang.org/show_bug.cgi?id=14561: huge enums
@safe unittest
{
    string genEnum()
    {
        string result = "enum TLAs {";
        foreach (c0; '0'..'2'+1)
            foreach (c1; '0'..'9'+1)
                foreach (c2; '0'..'9'+1)
                    foreach (c3; '0'..'9'+1)
        {
            result ~= '_';
            result ~= c0;
            result ~= c1;
            result ~= c2;
            result ~= c3;
            result ~= ',';
        }
        result ~= '}';
        return result;
    }
    mixin(genEnum);
    static assert(EnumMembers!TLAs[0] == TLAs._0000);
    static assert(EnumMembers!TLAs[$-1] == TLAs._2999);
}

@safe unittest
{
    enum E { member, a = 0, b = 0 }
    static assert(__traits(identifier, EnumMembers!E[0]) == "member");
    static assert(__traits(identifier, EnumMembers!E[1]) == "a");
    static assert(__traits(identifier, EnumMembers!E[2]) == "b");
}


//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
// Classes and Interfaces
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

/***
 * Get a $(D_PARAM AliasSeq) of the base class and base interfaces of
 * this class or interface. $(D_PARAM BaseTypeTuple!Object) returns
 * the empty type tuple.
 */
template BaseTypeTuple(A)
{
    static if (is(A P == super))
        alias BaseTypeTuple = P;
    else
        static assert(0, "argument is not a class or interface");
}

///
@safe unittest
{
    import std.meta : AliasSeq;

    interface I1 { }
    interface I2 { }
    interface I12 : I1, I2 { }
    static assert(is(BaseTypeTuple!I12 == AliasSeq!(I1, I2)));

    interface I3 : I1 { }
    interface I123 : I1, I2, I3 { }
    static assert(is(BaseTypeTuple!I123 == AliasSeq!(I1, I2, I3)));
}

@safe unittest
{
    interface I1 { }
    interface I2 { }
    class A { }
    class C : A, I1, I2 { }

    alias TL = BaseTypeTuple!C;
    assert(TL.length == 3);
    assert(is (TL[0] == A));
    assert(is (TL[1] == I1));
    assert(is (TL[2] == I2));

    assert(BaseTypeTuple!Object.length == 0);
}

/**
 * Get a $(D_PARAM AliasSeq) of $(I all) base classes of this class,
 * in decreasing order. Interfaces are not included. $(D_PARAM
 * BaseClassesTuple!Object) yields the empty type tuple.
 */
template BaseClassesTuple(T)
if (is(T == class))
{
    static if (is(T == Object))
    {
        alias BaseClassesTuple = AliasSeq!();
    }
    else static if (is(BaseTypeTuple!T[0] == Object))
    {
        alias BaseClassesTuple = AliasSeq!Object;
    }
    else static if (!is(BaseTypeTuple!T[0] == Object) && !is(BaseTypeTuple!T[0] == class))
    {
        alias BaseClassesTuple = AliasSeq!();
    }
    else
    {
        alias BaseClassesTuple =
            AliasSeq!(BaseTypeTuple!T[0],
                       BaseClassesTuple!(BaseTypeTuple!T[0]));
    }
}

///
@safe unittest
{
    import std.meta : AliasSeq;

    class C1 { }
    class C2 : C1 { }
    class C3 : C2 { }
    static assert(!BaseClassesTuple!Object.length);
    static assert(is(BaseClassesTuple!C1 == AliasSeq!(Object)));
    static assert(is(BaseClassesTuple!C2 == AliasSeq!(C1, Object)));
    static assert(is(BaseClassesTuple!C3 == AliasSeq!(C2, C1, Object)));
}

// https://issues.dlang.org/show_bug.cgi?id=17276
@safe unittest
{
    extern (C++) static interface Ext
    {
        void someext();
    }

    extern (C++) static class E : Ext
    {
        void someext() {}
    }

    alias BaseClassesWithNoObject = BaseClassesTuple!E;
}

@safe unittest
{
    struct S { }
    static assert(!__traits(compiles, BaseClassesTuple!S));
    interface I { }
    static assert(!__traits(compiles, BaseClassesTuple!I));
    class C4 : I { }
    class C5 : C4, I { }
    static assert(is(BaseClassesTuple!C5 == AliasSeq!(C4, Object)));
}

/**
Params:
    T = The `class` or `interface` to search.

Returns:
    $(REF AliasSeq,std,meta) of all interfaces directly or
    indirectly inherited by this class or interface. Interfaces
    do not repeat if multiply implemented.

    `InterfacesTuple!Object` yields an empty `AliasSeq`.
 */
template InterfacesTuple(T)
{
    import std.meta : NoDuplicates;
    template Flatten(H, T...)
    {
        static if (T.length)
        {
            alias Flatten = AliasSeq!(Flatten!H, Flatten!T);
        }
        else
        {
            static if (is(H == interface))
                alias Flatten = AliasSeq!(H, InterfacesTuple!H);
            else
                alias Flatten = InterfacesTuple!H;
        }
    }

    static if (is(T S == super) && S.length)
        alias InterfacesTuple = NoDuplicates!(Flatten!S);
    else
        alias InterfacesTuple = AliasSeq!();
}

///
@safe unittest
{
    interface I1 {}
    interface I2 {}
    class A : I1, I2 {}
    class B : A, I1 {}
    class C : B {}

    alias TL = InterfacesTuple!C;
    static assert(is(TL[0] == I1) && is(TL[1] == I2));
}

@safe unittest
{
    interface Iaa {}
    interface Iab {}
    interface Iba {}
    interface Ibb {}
    interface Ia : Iaa, Iab {}
    interface Ib : Iba, Ibb {}
    interface I : Ia, Ib {}
    interface J {}
    class B2 : J {}
    class C2 : B2, Ia, Ib {}
    static assert(is(InterfacesTuple!I ==
                    AliasSeq!(Ia, Iaa, Iab, Ib, Iba, Ibb)));
    static assert(is(InterfacesTuple!C2 ==
                    AliasSeq!(J, Ia, Iaa, Iab, Ib, Iba, Ibb)));

}

/**
 * Get a $(D_PARAM AliasSeq) of $(I all) base classes of $(D_PARAM
 * T), in decreasing order, followed by $(D_PARAM T)'s
 * interfaces. $(D_PARAM TransitiveBaseTypeTuple!Object) yields the
 * empty type tuple.
 */
alias TransitiveBaseTypeTuple(T) = AliasSeq!(BaseClassesTuple!T, InterfacesTuple!T);

///
@safe unittest
{
    interface J1 {}
    interface J2 {}
    class B1 {}
    class B2 : B1, J1, J2 {}
    class B3 : B2, J1 {}
    alias TL = TransitiveBaseTypeTuple!B3;
    assert(TL.length == 5);
    assert(is (TL[0] == B2));
    assert(is (TL[1] == B1));
    assert(is (TL[2] == Object));
    assert(is (TL[3] == J1));
    assert(is (TL[4] == J2));

    assert(TransitiveBaseTypeTuple!Object.length == 0);
}


/**
Returns a tuple of non-static functions with the name `name` declared in the
class or interface `C`.  Covariant duplicates are shrunk into the most
derived one.
 */
template MemberFunctionsTuple(C, string name)
if (is(C == class) || is(C == interface))
{
    static if (__traits(hasMember, C, name))
    {
        /*
         * First, collect all overloads in the class hierarchy.
         */
        template CollectOverloads(Node)
        {
            static if (__traits(hasMember, Node, name) && __traits(compiles, __traits(getMember, Node, name)))
            {
                // Get all overloads in sight (not hidden).
                alias inSight = __traits(getVirtualMethods, Node, name);

                // And collect all overloads in ancestor classes to reveal hidden
                // methods.  The result may contain duplicates.
                template walkThru(Parents...)
                {
                    static if (Parents.length > 0)
                        alias walkThru = AliasSeq!(
                                    CollectOverloads!(Parents[0]),
                                    walkThru!(Parents[1 .. $])
                                );
                    else
                        alias walkThru = AliasSeq!();
                }

                static if (is(Node Parents == super))
                    alias CollectOverloads = AliasSeq!(inSight, walkThru!Parents);
                else
                    alias CollectOverloads = AliasSeq!inSight;
            }
            else
                alias CollectOverloads = AliasSeq!(); // no overloads in this hierarchy
        }

        static if (name == "__ctor" || name == "__dtor")
            alias overloads = AliasSeq!(__traits(getOverloads, C, name));
        else
            // duplicates in this tuple will be removed by shrink()
            alias overloads = CollectOverloads!C;

        // shrinkOne!args[0]    = the most derived one in the covariant siblings of target
        // shrinkOne!args[1..$] = non-covariant others
        template shrinkOne(/+ alias target, rest... +/ args...)
        {
            import std.meta : AliasSeq;
            alias target = args[0 .. 1]; // prevent property functions from being evaluated
            alias rest = args[1 .. $];

            static if (rest.length > 0)
            {
                alias Target = FunctionTypeOf!target;
                alias Rest0 = FunctionTypeOf!(rest[0]);

                static if (isCovariantWith!(Target, Rest0) && isCovariantWith!(Rest0, Target))
                {
                    // One of these overrides the other. Choose the one from the most derived parent.
                    static if (is(__traits(parent, target) : __traits(parent, rest[0])))
                        alias shrinkOne = shrinkOne!(target, rest[1 .. $]);
                    else
                        alias shrinkOne = shrinkOne!(rest[0], rest[1 .. $]);
                }
                else static if (isCovariantWith!(Target, Rest0))
                    // target overrides rest[0] -- erase rest[0].
                    alias shrinkOne = shrinkOne!(target, rest[1 .. $]);
                else static if (isCovariantWith!(Rest0, Target))
                    // rest[0] overrides target -- erase target.
                    alias shrinkOne = shrinkOne!(rest[0], rest[1 .. $]);
                else
                    // target and rest[0] are distinct.
                    alias shrinkOne = AliasSeq!(
                                shrinkOne!(target, rest[1 .. $]),
                                rest[0] // keep
                            );
            }
            else
                alias shrinkOne = AliasSeq!target; // done
        }

        /*
         * Now shrink covariant overloads into one.
         */
        template shrink(overloads...)
        {
            static if (overloads.length > 0)
            {
                alias temp = shrinkOne!overloads;
                alias shrink = AliasSeq!(temp[0], shrink!(temp[1 .. $]));
            }
            else
                alias shrink = AliasSeq!(); // done
        }

        // done.
        alias MemberFunctionsTuple = shrink!overloads;
    }
    else
        alias MemberFunctionsTuple = AliasSeq!();
}

///
@safe unittest
{
    interface I { I foo(); }
    class B
    {
        real foo(real v) { return v; }
    }
    class C : B, I
    {
        override C foo() { return this; } // covariant overriding of I.foo()
    }
    alias foos = MemberFunctionsTuple!(C, "foo");
    static assert(foos.length == 2);
    static assert(__traits(isSame, foos[0], C.foo));
    static assert(__traits(isSame, foos[1], B.foo));
}

// https://issues.dlang.org/show_bug.cgi?id=15920
@safe unittest
{
    import std.meta : AliasSeq;
    class A
    {
        void f(){}
        void f(int){}
    }
    class B : A
    {
        override void f(){}
        override void f(int){}
    }
    alias fs = MemberFunctionsTuple!(B, "f");
    alias bfs = __traits(getOverloads, B, "f");
    assert(__traits(isSame, fs[0], bfs[0]) || __traits(isSame, fs[0], bfs[1]));
    assert(__traits(isSame, fs[1], bfs[0]) || __traits(isSame, fs[1], bfs[1]));
}

// https://issues.dlang.org/show_bug.cgi?id=8388
@safe unittest
{
    class C
    {
        this() {}
        this(int i) {}
        this(int i, float j) {}
        this(string s) {}

        /*
         Commented out, because this causes a cyclic dependency
         between module constructors/destructors error. Might
         be caused by https://issues.dlang.org/show_bug.cgi?id=20529. */
        // static this() {}

        ~this() {}
    }

    class D : C
    {
        this() {}
        ~this() {}
    }

    alias test_ctor = MemberFunctionsTuple!(C, "__ctor");
    assert(test_ctor.length == 4);
    alias test_dtor = MemberFunctionsTuple!(C, "__dtor");
    assert(test_dtor.length == 1);
    alias test2_ctor = MemberFunctionsTuple!(D, "__ctor");
    assert(test2_ctor.length == 1);
    alias test2_dtor = MemberFunctionsTuple!(D, "__dtor");
    assert(test2_dtor.length == 1);
}

@safe unittest
{
    interface I     { I test(); }
    interface J : I { J test(); }
    interface K     { K test(int); }
    class B : I, K
    {
        K test(int) { return this; }
        B test() { return this; }
        static void test(string) { }
    }
    class C : B, J
    {
        override C test() { return this; }
    }
    alias test =MemberFunctionsTuple!(C, "test");
    static assert(test.length == 2);
    static assert(is(FunctionTypeOf!(test[0]) == FunctionTypeOf!(C.test)));
    static assert(is(FunctionTypeOf!(test[1]) == FunctionTypeOf!(K.test)));
    alias noexist = MemberFunctionsTuple!(C, "noexist");
    static assert(noexist.length == 0);

    interface L { int prop() @property; }
    alias prop = MemberFunctionsTuple!(L, "prop");
    static assert(prop.length == 1);

    interface Test_I
    {
        void foo();
        void foo(int);
        void foo(int, int);
    }
    interface Test : Test_I {}
    alias Test_foo = MemberFunctionsTuple!(Test, "foo");
    static assert(Test_foo.length == 3);
    static assert(is(typeof(&Test_foo[0]) == void function()));
    static assert(is(typeof(&Test_foo[2]) == void function(int)));
    static assert(is(typeof(&Test_foo[1]) == void function(int, int)));
}


/**
Returns an alias to the template that `T` is an instance of.
It will return `void` if a symbol without a template is given.
 */
alias TemplateOf(alias T : Base!Args, alias Base, Args...) = Base;

/// ditto
alias TemplateOf(alias T) = void;

///
@safe unittest
{
    struct Foo(T, U) {}
    static assert(__traits(isSame, TemplateOf!(Foo!(int, real)), Foo));
}

@safe unittest
{
    template Foo1(A) {}
    template Foo2(A, B) {}
    template Foo3(alias A) {}
    template Foo4(string A) {}
    struct Foo5(A) {}
    struct Foo6(A, B) {}
    struct Foo7(alias A) {}
    template Foo8(A) { template Foo9(B) {} }
    template Foo10() {}

    static assert(__traits(isSame, TemplateOf!(Foo1!(int)), Foo1));
    static assert(__traits(isSame, TemplateOf!(Foo2!(int, int)), Foo2));
    static assert(__traits(isSame, TemplateOf!(Foo3!(123)), Foo3));
    static assert(__traits(isSame, TemplateOf!(Foo4!("123")), Foo4));
    static assert(__traits(isSame, TemplateOf!(Foo5!(int)), Foo5));
    static assert(__traits(isSame, TemplateOf!(Foo6!(int, int)), Foo6));
    static assert(__traits(isSame, TemplateOf!(Foo7!(123)), Foo7));
    static assert(__traits(isSame, TemplateOf!(Foo8!(int).Foo9!(real)), Foo8!(int).Foo9));
    static assert(__traits(isSame, TemplateOf!(Foo10!()), Foo10));
}

// https://issues.dlang.org/show_bug.cgi?id=18214
@safe unittest
{
    static assert(is(TemplateOf!(int[]) == void));
    static assert(is(TemplateOf!bool == void));

    // https://github.com/dlang/phobos/issues/10527
    static void foo() {}
    static assert(is(TemplateOf!foo == void));
}

/**
Returns a `AliasSeq` of the template arguments used to instantiate `T`.
 */
alias TemplateArgsOf(alias T : Base!Args, alias Base, Args...) = Args;

/// ditto
alias TemplateArgsOf(T : Base!Args, alias Base, Args...) = Args;

///
@safe unittest
{
    import std.meta : AliasSeq;

    struct Foo(T, U) {}
    static assert(is(TemplateArgsOf!(Foo!(int, real)) == AliasSeq!(int, real)));
}

@safe unittest
{
    template Foo1(A) {}
    template Foo2(A, B) {}
    template Foo3(alias A) {}
    template Foo4(string A) {}
    struct Foo5(A) {}
    struct Foo6(A, B) {}
    struct Foo7(alias A) {}
    template Foo8(A) { template Foo9(B) {} }
    template Foo10() {}

    enum x = 123;
    enum y = "123";
    static assert(is(TemplateArgsOf!(Foo1!(int)) == AliasSeq!(int)));
    static assert(is(TemplateArgsOf!(Foo2!(int, int)) == AliasSeq!(int, int)));
    static assert(__traits(isSame, TemplateArgsOf!(Foo3!(x)), AliasSeq!(x)));
    static assert(TemplateArgsOf!(Foo4!(y)) == AliasSeq!(y));
    static assert(is(TemplateArgsOf!(Foo5!(int)) == AliasSeq!(int)));
    static assert(is(TemplateArgsOf!(Foo6!(int, int)) == AliasSeq!(int, int)));
    static assert(__traits(isSame, TemplateArgsOf!(Foo7!(x)), AliasSeq!(x)));
    static assert(is(TemplateArgsOf!(Foo8!(int).Foo9!(real)) == AliasSeq!(real)));
    static assert(is(TemplateArgsOf!(Foo10!()) == AliasSeq!()));
}

// Returns the largest alignment in a type tuple.
package enum maxAlignment(U...) =
{
    size_t result = U[0].alignof;
    static foreach (T; U[1 .. $])
        if (result < T.alignof)
            result = T.alignof;
    return result;
}();

/**
Returns class instance alignment.

See also: $(DDSUBLINK spec/traits, classInstanceAlignment, `__traits(classInstanceAlignment, T)`)
 */
template classInstanceAlignment(T)
if (is(T == class))
{
    enum classInstanceAlignment = __traits(classInstanceAlignment, T);
}

///
@safe unittest
{
    class A { byte b; }
    class B { long l; }

    // As class instance always has a hidden pointer
    static assert(classInstanceAlignment!A == (void*).alignof);
    static assert(classInstanceAlignment!B == long.alignof);
}


//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
// Type Conversion
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

/**
Get the type that all types can be implicitly converted to. Useful
e.g. in figuring out an array type from a bunch of initializing
values. Returns $(D_PARAM void) if passed an empty list, or if the
types have no common type.
 */
template CommonType(T...)
{
    static if (T.length == 1)
        alias CommonType = typeof(T[0].init);
    else static if (is(typeof(true ? T[0].init : T[1].init) U))
        alias CommonType = CommonType!(U, T[2 .. $]);
    else
        alias CommonType = void;
}

///
@safe unittest
{
    alias X = CommonType!(int, long, short);
    assert(is(X == long));
    alias Y = CommonType!(int, char[], short);
    assert(is(Y == void));
}

///
@safe unittest
{
    static assert(is(CommonType!(3) == int));
    static assert(is(CommonType!(double, 4, float) == double));
    static assert(is(CommonType!(string, char[]) == const(char)[]));
    static assert(is(CommonType!(3, 3U) == uint));
    static assert(is(CommonType!(double, int) == double));
}


/**
Params:
    T = The type to check

Returns:
    An $(REF AliasSeq,std,meta) with all possible target types of an implicit
    conversion `T`.

    If `T` is a class derived from `Object`, the result of
    $(LREF TransitiveBaseTypeTuple) is returned.

    If the type is not a built-in value type or a class derived from
    `Object`, an empty $(REF AliasSeq,std,meta) is returned.

See_Also:
    $(LREF isImplicitlyConvertible)
 */
template AllImplicitConversionTargets(T)
{
    static if (is(T == bool))
        alias AllImplicitConversionTargets =
            AliasSeq!(byte, AllImplicitConversionTargets!byte);
    else static if (is(T == byte))
        alias AllImplicitConversionTargets =
            AliasSeq!(char, ubyte, short, AllImplicitConversionTargets!short);
    else static if (is(T == ubyte))
        alias AllImplicitConversionTargets =
            AliasSeq!(byte, char, short, AllImplicitConversionTargets!short);
    else static if (is(T == short))
        alias AllImplicitConversionTargets =
            AliasSeq!(ushort, wchar, int, AllImplicitConversionTargets!int);
    else static if (is(T == ushort))
        alias AllImplicitConversionTargets =
            AliasSeq!(short, wchar, dchar, AllImplicitConversionTargets!dchar);
    else static if (is(T == int))
        alias AllImplicitConversionTargets =
            AliasSeq!(dchar, uint, long, AllImplicitConversionTargets!long);
    else static if (is(T == uint))
        alias AllImplicitConversionTargets =
            AliasSeq!(dchar, int, long, AllImplicitConversionTargets!long);
    else static if (is(T == long))
        alias AllImplicitConversionTargets = AliasSeq!(ulong, CentTypeList, float, double, real);
    else static if (is(T == ulong))
        alias AllImplicitConversionTargets = AliasSeq!(long, CentTypeList, float, double, real);
    else static if (is(T == float))
        alias AllImplicitConversionTargets = AliasSeq!(double, real);
    else static if (is(T == double))
        alias AllImplicitConversionTargets = AliasSeq!(float, real);
    else static if (is(T == real))
        alias AllImplicitConversionTargets = AliasSeq!(float, double);
    else static if (is(T == char))
        alias AllImplicitConversionTargets =
            AliasSeq!(byte, ubyte, short, AllImplicitConversionTargets!short);
    else static if (is(T == wchar))
        alias AllImplicitConversionTargets =
            AliasSeq!(short, ushort, dchar, AllImplicitConversionTargets!dchar);
    else static if (is(T == dchar))
        alias AllImplicitConversionTargets =
            AliasSeq!(int, uint, long, AllImplicitConversionTargets!long);
    else static if (is(T == class))
        alias AllImplicitConversionTargets = staticMap!(ApplyLeft!(CopyConstness, T), TransitiveBaseTypeTuple!T);
    else static if (is(T == interface))
        alias AllImplicitConversionTargets = staticMap!(ApplyLeft!(CopyConstness, T), InterfacesTuple!T);
    else static if (isDynamicArray!T && !is(typeof(T.init[0]) == const))
    {
       static if (is(typeof(T.init[0]) == shared))
           alias AllImplicitConversionTargets =
           AliasSeq!(const(shared(Unqual!(typeof(T.init[0]))))[]);
       else
           alias AllImplicitConversionTargets =
           AliasSeq!(const(Unqual!(typeof(T.init[0])))[]);
    }
    else static if (is(T : void*) && !is(T == void*))
        alias AllImplicitConversionTargets = AliasSeq!(void*);
    else static if (is(cent) && is(T == cent))
        alias AllImplicitConversionTargets = AliasSeq!(UnsignedCentTypeList, float, double, real);
    else static if (is(ucent) && is(T == ucent))
        alias AllImplicitConversionTargets = AliasSeq!(SignedCentTypeList, float, double, real);
    else
        alias AllImplicitConversionTargets = AliasSeq!();
}

///
@safe unittest
{
    import std.meta : AliasSeq;

    static assert(is(AllImplicitConversionTargets!(ulong) == AliasSeq!(long, float, double, real)));
    static assert(is(AllImplicitConversionTargets!(int) == AliasSeq!(dchar, uint, long, ulong, float, double, real)));
    static assert(is(AllImplicitConversionTargets!(float) == AliasSeq!(double, real)));
    static assert(is(AllImplicitConversionTargets!(double) == AliasSeq!(float, real)));

    static assert(is(AllImplicitConversionTargets!(char) ==
        AliasSeq!(byte, ubyte, short, ushort, wchar, int, dchar, uint, long,
            ulong, float, double, real)
    ));
    static assert(is(AllImplicitConversionTargets!(wchar) == AliasSeq!(
        short, ushort, dchar, int, uint, long, ulong, float, double, real
    )));
    static assert(is(AllImplicitConversionTargets!(dchar) == AliasSeq!(
        int, uint, long, ulong, float, double, real
    )));

    static assert(is(AllImplicitConversionTargets!(string) == AliasSeq!(const(char)[])));
    static assert(is(AllImplicitConversionTargets!(int*) == AliasSeq!(void*)));

    interface A {}
    interface B {}
    class C : A, B {}

    static assert(is(AllImplicitConversionTargets!(C) == AliasSeq!(Object, A, B)));
    static assert(is(AllImplicitConversionTargets!(const C) == AliasSeq!(const Object, const A, const B)));
    static assert(is(AllImplicitConversionTargets!(immutable C) == AliasSeq!(
        immutable Object, immutable A, immutable B
    )));

    interface I : A, B {}

    static assert(is(AllImplicitConversionTargets!(I) == AliasSeq!(A, B)));
    static assert(is(AllImplicitConversionTargets!(const I) == AliasSeq!(const A, const B)));
    static assert(is(AllImplicitConversionTargets!(immutable I) == AliasSeq!(
        immutable A, immutable B
    )));
}

@safe unittest
{
    static assert(is(AllImplicitConversionTargets!(double)[0] == float));
    static assert(is(AllImplicitConversionTargets!(double)[1] == real));
    static assert(is(AllImplicitConversionTargets!(string)[0] == const(char)[]));
}


/**
Params:
    T = The type to check

Warning:
    This template is considered out-dated. It will be removed from
    Phobos in 2.107.0. Please use $(LREF AllImplicitConversionTargets) instead.

Returns:
    An $(REF AliasSeq,std,meta) with all possible target types of an implicit
    conversion `T`.

    If `T` is a class derived from `Object`, the result of
    $(LREF TransitiveBaseTypeTuple) is returned.

    If the type is not a built-in value type or a class derived from
    `Object`, an empty $(REF AliasSeq,std,meta) is returned.

Note:
    The possible targets are computed more conservatively than the
    language allows, eliminating all dangerous conversions. For example,
    `ImplicitConversionTargets!double` does not include `float`.

See_Also:
    $(LREF isImplicitlyConvertible)
 */
// @@@DEPRECATED_[2.107.0]@@@
deprecated("ImplicitConversionTargets has been deprecated in favour of AllImplicitConversionTargets "
   ~ "and will be removed in 2.107.0")
template ImplicitConversionTargets(T)
{
    static if (is(T == bool))
        alias ImplicitConversionTargets =
            AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real, char, wchar, dchar);
    else static if (is(T == byte))
        alias ImplicitConversionTargets =
            AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real, char, wchar, dchar);
    else static if (is(T == ubyte))
        alias ImplicitConversionTargets =
            AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real, char, wchar, dchar);
    else static if (is(T == short))
        alias ImplicitConversionTargets =
            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);
    else static if (is(T == ushort))
        alias ImplicitConversionTargets =
            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);
    else static if (is(T == int))
        alias ImplicitConversionTargets =
            AliasSeq!(long, ulong, CentTypeList, float, double, real);
    else static if (is(T == uint))
        alias ImplicitConversionTargets =
            AliasSeq!(long, ulong, CentTypeList, float, double, real);
    else static if (is(T == long))
        alias ImplicitConversionTargets = AliasSeq!(float, double, real);
    else static if (is(T == ulong))
        alias ImplicitConversionTargets = AliasSeq!(float, double, real);
    else static if (is(cent) && is(T == cent))
        alias ImplicitConversionTargets = AliasSeq!(float, double, real);
    else static if (is(ucent) && is(T == ucent))
        alias ImplicitConversionTargets = AliasSeq!(float, double, real);
    else static if (is(T == float))
        alias ImplicitConversionTargets = AliasSeq!(double, real);
    else static if (is(T == double))
        alias ImplicitConversionTargets = AliasSeq!real;
    else static if (is(T == char))
        alias ImplicitConversionTargets =
            AliasSeq!(wchar, dchar, byte, ubyte, short, ushort,
                       int, uint, long, ulong, CentTypeList, float, double, real);
    else static if (is(T == wchar))
        alias ImplicitConversionTargets =
            AliasSeq!(dchar, short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real);
    else static if (is(T == dchar))
        alias ImplicitConversionTargets =
            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);
    else static if (is(T : typeof(null)))
        alias ImplicitConversionTargets = AliasSeq!(typeof(null));
    else static if (is(T == class))
        alias ImplicitConversionTargets = staticMap!(ApplyLeft!(CopyConstness, T), TransitiveBaseTypeTuple!(T));
    else static if (isDynamicArray!T && !is(typeof(T.init[0]) == const))
    {
       static if (is(typeof(T.init[0]) == shared))
           alias ImplicitConversionTargets =
           AliasSeq!(const(shared(Unqual!(typeof(T.init[0]))))[]);
       else
           alias ImplicitConversionTargets =
           AliasSeq!(const(Unqual!(typeof(T.init[0])))[]);
    }
    else static if (is(T : void*))
        alias ImplicitConversionTargets = AliasSeq!(void*);
    else
        alias ImplicitConversionTargets = AliasSeq!();
}

deprecated @safe unittest
{
    import std.meta : AliasSeq;

    static assert(is(ImplicitConversionTargets!(ulong) == AliasSeq!(float, double, real)));
    static assert(is(ImplicitConversionTargets!(int) == AliasSeq!(long, ulong, float, double, real)));
    static assert(is(ImplicitConversionTargets!(float) == AliasSeq!(double, real)));
    static assert(is(ImplicitConversionTargets!(double) == AliasSeq!(real)));

    static assert(is(ImplicitConversionTargets!(char) == AliasSeq!(
        wchar, dchar, byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real
    )));
    static assert(is(ImplicitConversionTargets!(wchar) == AliasSeq!(
        dchar, short, ushort, int, uint, long, ulong, float, double, real
    )));
    static assert(is(ImplicitConversionTargets!(dchar) == AliasSeq!(
        int, uint, long, ulong, float, double, real
    )));

    static assert(is(ImplicitConversionTargets!(string) == AliasSeq!(const(char)[])));
    static assert(is(ImplicitConversionTargets!(void*) == AliasSeq!(void*)));

    interface A {}
    interface B {}
    class C : A, B {}

    static assert(is(ImplicitConversionTargets!(C) == AliasSeq!(Object, A, B)));
    static assert(is(ImplicitConversionTargets!(const C) == AliasSeq!(const Object, const A, const B)));
    static assert(is(ImplicitConversionTargets!(immutable C) == AliasSeq!(
        immutable Object, immutable A, immutable B
    )));
}

deprecated @safe unittest
{
    static assert(is(ImplicitConversionTargets!(double)[0] == real));
    static assert(is(ImplicitConversionTargets!(string)[0] == const(char)[]));
}

/**
Is `From` implicitly convertible to `To`?
 */
enum bool isImplicitlyConvertible(From, To) = is(From : To);

///
@safe unittest
{
    static assert( isImplicitlyConvertible!(immutable(char), char));
    static assert( isImplicitlyConvertible!(const(char), char));
    static assert( isImplicitlyConvertible!(char, wchar));
    static assert(!isImplicitlyConvertible!(wchar, char));

    static assert(!isImplicitlyConvertible!(const(ushort), ubyte));
    static assert(!isImplicitlyConvertible!(const(uint), ubyte));
    static assert(!isImplicitlyConvertible!(const(ulong), ubyte));

    static assert(!isImplicitlyConvertible!(const(char)[], string));
    static assert( isImplicitlyConvertible!(string, const(char)[]));
}

/**
Is `From` $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible) to `To`?
*/
enum bool isQualifierConvertible(From, To) =
    is(immutable From == immutable To) && is(From* : To*);

///
@safe unittest
{
    // Mutable and immmutable both convert to const...
    static assert( isQualifierConvertible!(char, const(char)));
    static assert( isQualifierConvertible!(immutable(char), const(char)));
    // ...but const does not convert back to mutable or immutable
    static assert(!isQualifierConvertible!(const(char), char));
    static assert(!isQualifierConvertible!(const(char), immutable(char)));
}

@safe unittest
{
    import std.meta : AliasSeq;

    alias Ts = AliasSeq!(int, const int, shared int, inout int, const shared int,
        const inout int, inout shared int, const inout shared int, immutable int);

    // https://dlang.org/spec/const3.html#implicit_qualifier_conversions
    enum _ = 0;
    static immutable bool[Ts.length][Ts.length] conversions = [
    //   m   c   s   i   cs  ci  is  cis im
        [1,  1,  _,  _,  _,  _,  _,  _,  _],  // mutable
        [_,  1,  _,  _,  _,  _,  _,  _,  _],  // const
        [_,  _,  1,  _,  1,  _,  _,  _,  _],  // shared
        [_,  1,  _,  1,  _,  1,  _,  _,  _],  // inout
        [_,  _,  _,  _,  1,  _,  _,  _,  _],  // const shared
        [_,  1,  _,  _,  _,  1,  _,  _,  _],  // const inout
        [_,  _,  _,  _,  1,  _,  1,  1,  _],  // inout shared
        [_,  _,  _,  _,  1,  _,  _,  1,  _],  // const inout shared
        [_,  1,  _,  _,  1,  1,  _,  1,  1],  // immutable
    ];

    static foreach (i, From; Ts)
    {
        static foreach (j, To; Ts)
        {
            static assert(isQualifierConvertible!(From, To) == conversions[i][j],
                "`isQualifierConvertible!(" ~ From.stringof ~ ", " ~ To.stringof ~ ")`"
                ~ " should be `" ~ (conversions[i][j] ? "true" : "false") ~ "`");
        }
    }
}

@safe unittest
{
    // int* -> void* is not a qualifier conversion
    static assert(!isQualifierConvertible!(int, void));
}

/**
Returns `true` iff a value of type `Rhs` can be assigned to a variable of
type `Lhs`.

`isAssignable` returns whether both an lvalue and rvalue can be assigned.

If you omit `Rhs`, `isAssignable` will check identity assignable of `Lhs`.
*/
enum isAssignable(Lhs, Rhs = Lhs) = isRvalueAssignable!(Lhs, Rhs) && isLvalueAssignable!(Lhs, Rhs);

///
@safe unittest
{
    static assert( isAssignable!(long, int));
    static assert(!isAssignable!(int, long));
    static assert( isAssignable!(const(char)[], string));
    static assert(!isAssignable!(string, char[]));

    // int is assignable to int
    static assert( isAssignable!int);

    // immutable int is not assignable to immutable int
    static assert(!isAssignable!(immutable int));
}

/**
Returns `true` iff an rvalue of type `Rhs` can be assigned to a variable of
type `Lhs`.
*/
enum isRvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, { lvalueOf!Lhs = rvalueOf!Rhs; });

///
@safe unittest
{
    struct S1
    {
        void opAssign(S1);
    }

    struct S2
    {
        void opAssign(ref S2);
    }

    static assert( isRvalueAssignable!(long, int));
    static assert(!isRvalueAssignable!(int, long));
    static assert( isRvalueAssignable!S1);
    static assert(!isRvalueAssignable!S2);
}

/**
Returns `true` iff an lvalue of type `Rhs` can be assigned to a variable of
type `Lhs`.
*/
enum isLvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, { lvalueOf!Lhs = lvalueOf!Rhs; });

///
@safe unittest
{
    struct S1
    {
        void opAssign(S1);
    }

    struct S2
    {
        void opAssign(ref S2);
    }

    static assert( isLvalueAssignable!(long, int));
    static assert(!isLvalueAssignable!(int, long));
    static assert( isLvalueAssignable!S1);
    static assert( isLvalueAssignable!S2);
}

@safe unittest
{
    static assert(!isAssignable!(immutable int, int));
    static assert( isAssignable!(int, immutable int));

    static assert(!isAssignable!(inout int, int));
    static assert( isAssignable!(int, inout int));
    static assert(!isAssignable!(inout int));

    static assert( isAssignable!(shared int, int));
    static assert( isAssignable!(int, shared int));
    static assert( isAssignable!(shared int));

    static assert( isAssignable!(void[1], void[1]));

    struct S { @disable this(); this(int n){} }
    static assert( isAssignable!(S, S));

    struct S2 { this(int n){} }
    static assert( isAssignable!(S2, S2));
    static assert(!isAssignable!(S2, int));

    struct S3 { @disable void opAssign(); }
    static assert( isAssignable!(S3, S3));

    struct S3X { @disable void opAssign(S3X); }
    static assert(!isAssignable!(S3X, S3X));

    struct S4 { void opAssign(int); }
    static assert( isAssignable!(S4, S4));
    static assert( isAssignable!(S4, int));
    static assert( isAssignable!(S4, immutable int));

    struct S5 { @disable this(); @disable this(this); }
    // https://issues.dlang.org/show_bug.cgi?id=21210
    static assert(!isAssignable!S5);

    // `-preview=in` is enabled
    alias DScannerBug895 = int[256];
    static if (((in DScannerBug895 a) { return __traits(isRef, a); })(DScannerBug895.init))
    {
        struct S6 { void opAssign(in S5); }

        static assert(isRvalueAssignable!(S6, S5));
        static assert(isLvalueAssignable!(S6, S5));
        static assert(isAssignable!(S6, S5));
        static assert(isAssignable!(S6, immutable S5));
    }
    else
    {
        mixin(q{ struct S6 { void opAssign(scope const ref S5); } });

        static assert(!isRvalueAssignable!(S6, S5));
        static assert( isLvalueAssignable!(S6, S5));
        static assert(!isAssignable!(S6, S5));
        static assert( isLvalueAssignable!(S6, immutable S5));
    }
}


// Equivalent with TypeStruct::isAssignable in compiler code.
package template isBlitAssignable(T)
{
    static if (is(T == enum))
    {
        enum isBlitAssignable = isBlitAssignable!(OriginalType!T);
    }
    else static if (isStaticArray!T && is(T == E[n], E, size_t n))
    // Workaround for https://issues.dlang.org/show_bug.cgi?id=11499 : isStaticArray!T should not be necessary.
    {
        enum isBlitAssignable = isBlitAssignable!E;
    }
    else static if (is(T == struct) || is(T == union))
    {
        enum isBlitAssignable = isMutable!T &&
        {
            size_t offset = 0;
            bool assignable = true;
            foreach (i, F; FieldTypeTuple!T)
            {
                static if (i == 0)
                {
                }
                else
                {
                    if (T.tupleof[i].offsetof == offset)
                    {
                        if (assignable)
                            continue;
                    }
                    else
                    {
                        if (!assignable)
                            return false;
                    }
                }
                assignable = isBlitAssignable!(typeof(T.tupleof[i]));
                offset = T.tupleof[i].offsetof;
            }
            return assignable;
        }();
    }
    else
        enum isBlitAssignable = isMutable!T;
}

@safe unittest
{
    static assert( isBlitAssignable!int);
    static assert(!isBlitAssignable!(const int));

    class C{ const int i; }
    static assert( isBlitAssignable!C);

    struct S1{ int i; }
    struct S2{ const int i; }
    static assert( isBlitAssignable!S1);
    static assert(!isBlitAssignable!S2);

    struct S3X { union {       int x;       int y; } }
    struct S3Y { union {       int x; const int y; } }
    struct S3Z { union { const int x; const int y; } }
    static assert( isBlitAssignable!(S3X));
    static assert( isBlitAssignable!(S3Y));
    static assert(!isBlitAssignable!(S3Z));
    static assert(!isBlitAssignable!(const S3X));
    static assert(!isBlitAssignable!(inout S3Y));
    static assert(!isBlitAssignable!(immutable S3Z));
    static assert( isBlitAssignable!(S3X[3]));
    static assert( isBlitAssignable!(S3Y[3]));
    static assert(!isBlitAssignable!(S3Z[3]));
    enum ES3X : S3X { a = S3X() }
    enum ES3Y : S3Y { a = S3Y() }
    enum ES3Z : S3Z { a = S3Z() }
    static assert( isBlitAssignable!(ES3X));
    static assert( isBlitAssignable!(ES3Y));
    static assert(!isBlitAssignable!(ES3Z));
    static assert(!isBlitAssignable!(const ES3X));
    static assert(!isBlitAssignable!(inout ES3Y));
    static assert(!isBlitAssignable!(immutable ES3Z));
    static assert( isBlitAssignable!(ES3X[3]));
    static assert( isBlitAssignable!(ES3Y[3]));
    static assert(!isBlitAssignable!(ES3Z[3]));

    union U1X {       int x;       int y; }
    union U1Y {       int x; const int y; }
    union U1Z { const int x; const int y; }
    static assert( isBlitAssignable!(U1X));
    static assert( isBlitAssignable!(U1Y));
    static assert(!isBlitAssignable!(U1Z));
    static assert(!isBlitAssignable!(const U1X));
    static assert(!isBlitAssignable!(inout U1Y));
    static assert(!isBlitAssignable!(immutable U1Z));
    static assert( isBlitAssignable!(U1X[3]));
    static assert( isBlitAssignable!(U1Y[3]));
    static assert(!isBlitAssignable!(U1Z[3]));
    enum EU1X : U1X { a = U1X() }
    enum EU1Y : U1Y { a = U1Y() }
    enum EU1Z : U1Z { a = U1Z() }
    static assert( isBlitAssignable!(EU1X));
    static assert( isBlitAssignable!(EU1Y));
    static assert(!isBlitAssignable!(EU1Z));
    static assert(!isBlitAssignable!(const EU1X));
    static assert(!isBlitAssignable!(inout EU1Y));
    static assert(!isBlitAssignable!(immutable EU1Z));
    static assert( isBlitAssignable!(EU1X[3]));
    static assert( isBlitAssignable!(EU1Y[3]));
    static assert(!isBlitAssignable!(EU1Z[3]));

    struct SA
    {
        @property int[3] foo() { return [1,2,3]; }
        alias foo this;
        const int x;    // SA is not blit assignable
    }
    static assert(!isStaticArray!SA);
    static assert(!isBlitAssignable!(SA[3]));
}


/*
Works like `isImplicitlyConvertible`, except this cares only about storage
classes of the arguments.
 */
private template isStorageClassImplicitlyConvertible(From, To)
{
    alias Pointify(T) = void*;

    enum isStorageClassImplicitlyConvertible = is(
            ModifyTypePreservingTQ!(Pointify, From) :
            ModifyTypePreservingTQ!(Pointify,   To) );
}

@safe unittest
{
    static assert( isStorageClassImplicitlyConvertible!(          int, const int));
    static assert( isStorageClassImplicitlyConvertible!(immutable int, const int));

    static assert(!isStorageClassImplicitlyConvertible!(const int,           int));
    static assert(!isStorageClassImplicitlyConvertible!(const int, immutable int));
    static assert(!isStorageClassImplicitlyConvertible!(int, shared int));
    static assert(!isStorageClassImplicitlyConvertible!(shared int, int));
}


/**
Determines whether the function type `F` is covariant with `G`, i.e.,
functions of the type `F` can override ones of the type `G`.
 */
template isCovariantWith(F, G)
if (is(F == function) && is(G == function) ||
    is(F == delegate) && is(G == delegate) ||
    isFunctionPointer!F && isFunctionPointer!G)
{
    static if (is(F : G))
        enum isCovariantWith = true;
    else
    {
        alias Upr = F;
        alias Lwr = G;

        /*
         * Check for calling convention: require exact match.
         */
        template checkLinkage()
        {
            enum ok = functionLinkage!Upr == functionLinkage!Lwr;
        }
        /*
         * Check for variadic parameter: require exact match.
         */
        template checkVariadicity()
        {
            enum ok = variadicFunctionStyle!Upr == variadicFunctionStyle!Lwr;
        }
        /*
         * Check for function storage class:
         *  - overrider can have narrower storage class than base
         */
        template checkSTC()
        {
            // Note the order of arguments.  The convertion order Lwr -> Upr is
            // correct since Upr should be semantically 'narrower' than Lwr.
            enum ok = isStorageClassImplicitlyConvertible!(Lwr, Upr);
        }
        /*
         * Check for function attributes:
         *  - require exact match for ref and @property
         *  - overrider can add pure and nothrow, but can't remove them
         *  - @safe and @trusted are covariant with each other, unremovable
         */
        template checkAttributes()
        {
            alias FA = FunctionAttribute;
            enum uprAtts = functionAttributes!Upr;
            enum lwrAtts = functionAttributes!Lwr;
            //
            enum wantExact = FA.ref_ | FA.property;
            enum safety = FA.safe | FA.trusted;
            enum ok =
                (  (uprAtts & wantExact)   == (lwrAtts & wantExact)) &&
                (  (uprAtts & FA.pure_   ) >= (lwrAtts & FA.pure_   )) &&
                (  (uprAtts & FA.nothrow_) >= (lwrAtts & FA.nothrow_)) &&
                (!!(uprAtts & safety    )  >= !!(lwrAtts & safety    )) ;
        }
        /*
         * Check for return type: usual implicit convertion.
         */
        template checkReturnType()
        {
            enum ok = is(ReturnType!Upr : ReturnType!Lwr);
        }
        /*
         * Check for parameters:
         *  - require exact match for types
         *    (cf. https://issues.dlang.org/show_bug.cgi?id=3075)
         *  - require exact match for in, out, ref and lazy
         *  - overrider can add scope, but can't remove
         */
        template checkParameters()
        {
            alias STC = ParameterStorageClass;
            alias UprParams = Parameters!Upr;
            alias LwrParams = Parameters!Lwr;
            alias UprPSTCs  = ParameterStorageClassTuple!Upr;
            alias LwrPSTCs  = ParameterStorageClassTuple!Lwr;
            //
            template checkNext(size_t i)
            {
                static if (i < UprParams.length)
                {
                    enum uprStc = UprPSTCs[i];
                    enum lwrStc = LwrPSTCs[i];
                    //
                    enum wantExact = STC.out_ | STC.ref_ | STC.lazy_ | STC.return_;
                    enum ok =
                        ((uprStc & wantExact )  == (lwrStc & wantExact )) &&
                        ((uprStc & STC.scope_)  >= (lwrStc & STC.scope_)) &&
                        checkNext!(i + 1).ok;
                }
                else
                    enum ok = true; // done
            }
            static if (UprParams.length == LwrParams.length)
                enum ok = is(UprParams == LwrParams) && checkNext!(0).ok;
            else
                enum ok = false;
        }

        /* run all the checks */
        enum isCovariantWith =
            checkLinkage    !().ok &&
            checkVariadicity!().ok &&
            checkSTC        !().ok &&
            checkAttributes !().ok &&
            checkReturnType !().ok &&
            checkParameters !().ok ;
    }
}

///
@safe unittest
{
    interface I { I clone(); }
    interface J { J clone(); }
    class C : I
    {
        override C clone()   // covariant overriding of I.clone()
        {
            return new C;
        }
    }

    // C.clone() can override I.clone(), indeed.
    static assert(isCovariantWith!(typeof(C.clone), typeof(I.clone)));

    // C.clone() can't override J.clone(); the return type C is not implicitly
    // convertible to J.
    static assert(!isCovariantWith!(typeof(C.clone), typeof(J.clone)));
}

@safe unittest
{
    enum bool isCovariantWith(alias f, alias g) = .isCovariantWith!(typeof(f), typeof(g));

    // covariant return type
    interface I     {}
    interface J : I {}
    interface BaseA            {          const(I) test(int); }
    interface DerivA_1 : BaseA { override const(J) test(int); }
    interface DerivA_2 : BaseA { override       J  test(int); }
    static assert( isCovariantWith!(DerivA_1.test, BaseA.test));
    static assert( isCovariantWith!(DerivA_2.test, BaseA.test));
    static assert(!isCovariantWith!(BaseA.test, DerivA_1.test));
    static assert(!isCovariantWith!(BaseA.test, DerivA_2.test));
    static assert( isCovariantWith!(BaseA.test, BaseA.test));
    static assert( isCovariantWith!(DerivA_1.test, DerivA_1.test));
    static assert( isCovariantWith!(DerivA_2.test, DerivA_2.test));

     // function, function pointer and delegate
     J function() derived_function;
     I function() base_function;
     J delegate() derived_delegate;
     I delegate() base_delegate;
     static assert(.isCovariantWith!(typeof(derived_function), typeof(base_function)));
     static assert(.isCovariantWith!(typeof(*derived_function), typeof(*base_function)));
     static assert(.isCovariantWith!(typeof(derived_delegate), typeof(base_delegate)));

    // scope parameter
    interface BaseB            {          void test(      int*,       int*); }
    interface DerivB_1 : BaseB { override void test(scope int*,       int*); }
    interface DerivB_2 : BaseB { override void test(      int*, scope int*); }
    interface DerivB_3 : BaseB { override void test(scope int*, scope int*); }
    static assert( isCovariantWith!(DerivB_1.test, BaseB.test));
    static assert( isCovariantWith!(DerivB_2.test, BaseB.test));
    static assert( isCovariantWith!(DerivB_3.test, BaseB.test));
    static assert(!isCovariantWith!(BaseB.test, DerivB_1.test));
    static assert(!isCovariantWith!(BaseB.test, DerivB_2.test));
    static assert(!isCovariantWith!(BaseB.test, DerivB_3.test));

    // function storage class
    interface BaseC            {          void test()      ; }
    interface DerivC_1 : BaseC { override void test() const; }
    static assert( isCovariantWith!(DerivC_1.test, BaseC.test));
    static assert(!isCovariantWith!(BaseC.test, DerivC_1.test));

    // increasing safety
    interface BaseE            {          void test()         ; }
    interface DerivE_1 : BaseE { override void test() @safe   ; }
    interface DerivE_2 : BaseE { override void test() @trusted; }
    static assert( isCovariantWith!(DerivE_1.test, BaseE.test));
    static assert( isCovariantWith!(DerivE_2.test, BaseE.test));
    static assert(!isCovariantWith!(BaseE.test, DerivE_1.test));
    static assert(!isCovariantWith!(BaseE.test, DerivE_2.test));

    // @safe and @trusted
    interface BaseF
    {
        void test1() @safe;
        void test2() @trusted;
    }
    interface DerivF : BaseF
    {
        override void test1() @trusted;
        override void test2() @safe;
    }
    static assert( isCovariantWith!(DerivF.test1, BaseF.test1));
    static assert( isCovariantWith!(DerivF.test2, BaseF.test2));
}


// Needed for rvalueOf/lvalueOf because "inout on return means
// inout must be on a parameter as well"
private struct __InoutWorkaroundStruct{}

/**
Creates an lvalue or rvalue of type `T` for `typeof(...)` and
$(DDSUBLINK spec/traits, compiles, `__traits(compiles, ...)`) purposes. No actual value is returned.

Params:
    T = The type to transform

Note: Trying to use returned value will result in a
"Symbol Undefined" error at link time.
*/
@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);

/// ditto
@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);

// Note: can't put these unittests together as function overloads
// aren't allowed inside functions.
///
@system unittest
{
    static int f(int);
    static assert(is(typeof(f(rvalueOf!int)) == int));
}

///
@system unittest
{
    static bool f(ref int);
    static assert(is(typeof(f(lvalueOf!int)) == bool));
}

@system unittest
{
    void needLvalue(T)(ref T);
    static struct S { }
    int i;
    struct Nested { void f() { ++i; } }
    static foreach (T; AliasSeq!(int, immutable int, inout int, string, S, Nested, Object))
    {
        static assert(!__traits(compiles, needLvalue(rvalueOf!T)));
        static assert( __traits(compiles, needLvalue(lvalueOf!T)));
        static assert(is(typeof(rvalueOf!T) == T));
        static assert(is(typeof(lvalueOf!T) == T));
    }

    static assert(!__traits(compiles, rvalueOf!int = 1));
    static assert( __traits(compiles, lvalueOf!byte = 127));
    static assert(!__traits(compiles, lvalueOf!byte = 128));
}


//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
// SomethingTypeOf
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

/*
 */
template BooleanTypeOf(T)
{
    static if (is(typeof(__traits(getMember, T.init, __traits(getAliasThis, T)[0])) AT) && !is(AT[] == AT))
        alias X = BooleanTypeOf!AT;
    else
        alias X = OriginalType!T;

    static if (is(immutable X == immutable bool))
    {
        alias BooleanTypeOf = X;
    }
    else
        static assert(0, T.stringof~" is not boolean type");
}

@safe unittest
{
    // unexpected failure, maybe dmd type-merging bug
    static foreach (T; AliasSeq!bool)
        static foreach (Q; TypeQualifierList)
        {
            static assert( is(Q!T == BooleanTypeOf!(            Q!T  )));
            static assert( is(Q!T == BooleanTypeOf!( SubTypeOf!(Q!T) )));
        }

    static foreach (T; AliasSeq!(void, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList,*/ CharTypeList))
        static foreach (Q; TypeQualifierList)
        {
            static assert(!is(BooleanTypeOf!(            Q!T  )), Q!T.stringof);
            static assert(!is(BooleanTypeOf!( SubTypeOf!(Q!T) )));
        }
}

@safe unittest
{
    struct B
    {
        bool val;
        alias val this;
    }
    struct S
    {
        B b;
        alias b this;
    }
    static assert(is(BooleanTypeOf!B == bool));
    static assert(is(BooleanTypeOf!S == bool));
}

/*
 */
template IntegralTypeOf(T)
{
    static if (is(typeof(__traits(getMember, T.init, __traits(getAliasThis, T)[0])) AT) && !is(AT[] == AT))
        alias X = IntegralTypeOf!AT;
    else
        alias X = OriginalType!T;

    static if (__traits(isIntegral, X) && __traits(isZeroInit, X) // Not char, wchar, or dchar.
        && !is(immutable X == immutable bool) && !is(X == __vector))
    {
        alias IntegralTypeOf = X;
    }
    else
        static assert(0, T.stringof~" is not an integral type");
}

@safe unittest
{
    static foreach (T; IntegralTypeList)
        static foreach (Q; TypeQualifierList)
        {
            static assert( is(Q!T == IntegralTypeOf!(            Q!T  )));
            static assert( is(Q!T == IntegralTypeOf!( SubTypeOf!(Q!T) )));
        }

    static foreach (T; AliasSeq!(void, bool, FloatingPointTypeList,
                /*ImaginaryTypeList, ComplexTypeList,*/ CharTypeList))
        static foreach (Q; TypeQualifierList)
        {
            static assert(!is(IntegralTypeOf!(            Q!T  )));
            static assert(!is(IntegralTypeOf!( SubTypeOf!(Q!T) )));
        }
}

/*
 */
template FloatingPointTypeOf(T)
{
    static if (is(typeof(__traits(getMember, T.init, __traits(getAliasThis, T)[0])) AT) && !is(AT[] == AT))
        alias X = FloatingPointTypeOf!AT;
    else
        alias X = OriginalType!T;

    static if (is(immutable X == immutable U, U) && is(U == float) || is(U == double) || is(U == real))
    {
        alias FloatingPointTypeOf = X;
    }
    else
        static assert(0, T.stringof~" is not a floating point type");
}

@safe unittest
{
    static foreach (T; FloatingPointTypeList)
        static foreach (Q; TypeQualifierList)
        {
            static assert( is(Q!T == FloatingPointTypeOf!(            Q!T  )));
            static assert( is(Q!T == FloatingPointTypeOf!( SubTypeOf!(Q!T) )));
        }

    static foreach (T; AliasSeq!(void, bool, IntegralTypeList, /*ImaginaryTypeList, ComplexTypeList,*/ CharTypeList))
        static foreach (Q; TypeQualifierList)
        {
            static assert(!is(FloatingPointTypeOf!(            Q!T  )));
            static assert(!is(FloatingPointTypeOf!( SubTypeOf!(Q!T) )));
        }
}

/*
 */
template NumericTypeOf(T)
{
    static if (is(IntegralTypeOf!T X) || is(FloatingPointTypeOf!T X))
    {
        alias NumericTypeOf = X;
    }
    else
        static assert(0, T.stringof~" is not a numeric type");
}

@safe unittest
{
    static foreach (T; NumericTypeList)
        static foreach (Q; TypeQualifierList)
        {
            static assert( is(Q!T == NumericTypeOf!(            Q!T  )));
            static assert( is(Q!T == NumericTypeOf!( SubTypeOf!(Q!T) )));
        }

    static foreach (T; AliasSeq!(void, bool, CharTypeList, /*ImaginaryTypeList, ComplexTypeList*/))
        static foreach (Q; TypeQualifierList)
        {
            static assert(!is(NumericTypeOf!(            Q!T  )));
            static assert(!is(NumericTypeOf!( SubTypeOf!(Q!T) )));
        }
}

/*
 */
template UnsignedTypeOf(T)
{
    static if (is(IntegralTypeOf!T X) && __traits(isUnsigned, X))
        alias UnsignedTypeOf = X;
    else
        static assert(0, T.stringof~" is not an unsigned type.");
}

/*
 */
template SignedTypeOf(T)
{
    static if (is(IntegralTypeOf!T X) && !__traits(isUnsigned, X))
        alias SignedTypeOf = X;
    else static if (is(FloatingPointTypeOf!T X))
        alias SignedTypeOf = X;
    else
        static assert(0, T.stringof~" is not an signed type.");
}

/*
 */
template CharTypeOf(T)
{
    static if (is(typeof(__traits(getMember, T.init, __traits(getAliasThis, T)[0])) AT) && !is(AT[] == AT))
        alias X = CharTypeOf!AT;
    else
        alias X = OriginalType!T;

    static if (is(immutable X == immutable U, U) && is(U == char) || is(U == wchar) || is(U == dchar))
    {
        alias CharTypeOf = X;
    }
    else
        static assert(0, T.stringof~" is not a character type");
}

@safe unittest
{
    static foreach (T; CharTypeList)
        static foreach (Q; TypeQualifierList)
        {
            static assert( is(CharTypeOf!(            Q!T  )));
            static assert( is(CharTypeOf!( SubTypeOf!(Q!T) )));
        }

    static foreach (T; AliasSeq!(void, bool, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList*/))
        static foreach (Q; TypeQualifierList)
        {
            static assert(!is(CharTypeOf!(            Q!T  )));
            static assert(!is(CharTypeOf!( SubTypeOf!(Q!T) )));
        }

    static foreach (T; AliasSeq!(string, wstring, dstring, char[4]))
        static foreach (Q; TypeQualifierList)
        {
            static assert(!is(CharTypeOf!(            Q!T  )));
            static assert(!is(CharTypeOf!( SubTypeOf!(Q!T) )));
        }
}

/*
 */
template StaticArrayTypeOf(T)
{
    static if (is(typeof(__traits(getMember, T.init, __traits(getAliasThis, T)[0])) AT) && !is(AT[] == AT))
        alias X = StaticArrayTypeOf!AT;
    else
        alias X = OriginalType!T;

    static if (__traits(isStaticArray, X))
        alias StaticArrayTypeOf = X;
    else
        static assert(0, T.stringof~" is not a static array type");
}

@safe unittest
{
    static foreach (T; AliasSeq!(bool, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList*/))
        static foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))
        {
            static assert(is( Q!(   T[1] ) == StaticArrayTypeOf!( Q!(              T[1]  ) ) ));

            static foreach (P; TypeQualifierList)
            { // SubTypeOf cannot have inout type
                static assert(is( Q!(P!(T[1])) == StaticArrayTypeOf!( Q!(SubTypeOf!(P!(T[1]))) ) ));
            }
        }

    static foreach (T; AliasSeq!void)
        static foreach (Q; AliasSeq!TypeQualifierList)
        {
            static assert(is( StaticArrayTypeOf!( Q!(void[1]) ) == Q!(void[1]) ));
        }
}

/*
 */
template DynamicArrayTypeOf(T)
{
    import core.internal.traits : _DynamicArrayTypeOf = DynamicArrayTypeOf;
    alias DynamicArrayTypeOf = _DynamicArrayTypeOf!T;
}

@safe unittest
{
    import std.meta : Alias;
    static foreach (T; AliasSeq!(/*void, */bool, NumericTypeList, /*ImaginaryTypeList, ComplexTypeList*/))
        static foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))
        {
            static assert(is( Q!T[]  == DynamicArrayTypeOf!( Q!T[] ) ));
            static assert(is( Q!(T[])  == DynamicArrayTypeOf!( Q!(T[]) ) ));

            static foreach (P; AliasSeq!(Alias, ConstOf, ImmutableOf))
            {
                static assert(is( Q!(P!T[]) == DynamicArrayTypeOf!( Q!(SubTypeOf!(P!T[])) ) ));
                static assert(is( Q!(P!(T[])) == DynamicArrayTypeOf!( Q!(SubTypeOf!(P!(T[]))) ) ));
            }
        }

    static assert(!is(DynamicArrayTypeOf!(int[3])));
    static assert(!is(DynamicArrayTypeOf!(void[3])));
    static assert(!is(DynamicArrayTypeOf!(typeof(null))));
}

/*
 */
template ArrayTypeOf(T)
{
    static if (is(StaticArrayTypeOf!T X) || is(DynamicArrayTypeOf!T X))
    {
        alias ArrayTypeOf = X;
    }
    else
        static assert(0, T.stringof~" is not an array type");
}

/*
 * Converts strings and string-like types to the corresponding dynamic array of characters.
 * Params:
 * T = one of the following:
 * 1. dynamic arrays of `char`, `wchar`, or `dchar` that are implicitly convertible to `const`
 *    (`shared` is rejected)
 * 2. static arrays of `char`, `wchar`, or `dchar` that are implicitly convertible to `const`
 *    (`shared` is rejected)
 * 3. aggregates that use `alias this` to refer to a field that is (1), (2), or (3)
 *
 * Other cases are rejected with a compile time error.
 * `typeof(null)` is rejected.
 *
 * Returns:
 *  The result of `[]` applied to the qualified character type.
 */
template StringTypeOf(T)
{
    static if (is(T == typeof(null)))
    {
        // It is impossible to determine exact string type from typeof(null) -
        // it means that StringTypeOf!(typeof(null)) is undefined.
        // Then this behavior is convenient for template constraint.
        static assert(0, T.stringof~" is not a string type");
    }
    else static if (is(T : const char[]) || is(T : const wchar[]) || is(T : const dchar[]))
    {
        static if (is(T : U[], U))
            alias StringTypeOf = U[];
        else
            static assert(0);
    }
    else
        static assert(0, T.stringof~" is not a string type");
}

@safe unittest
{
    import std.meta : Alias;
    static foreach (T; CharTypeList)
        static foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf, InoutOf))
        {
            static assert(is(Q!T[] == StringTypeOf!( Q!T[] )));

            static if (!__traits(isSame, Q, InoutOf))
            {{
                static assert(is(Q!T[] == StringTypeOf!( SubTypeOf!(Q!T[]) )));

                alias Str = Q!T[];
                struct C(S) { S val;  alias val this; }
                static assert(is(StringTypeOf!(C!Str) == Str));
            }}
        }

    static foreach (T; CharTypeList)
        static foreach (Q; AliasSeq!(SharedOf, SharedConstOf, SharedInoutOf))
        {
            static assert(!is(StringTypeOf!( Q!T[] )));
        }
}

@safe unittest
{
    static assert(is(StringTypeOf!(char[4]) == char[]));

    struct S
    {
        string s;
        alias s this;
    }

    struct T
    {
        S s;
        alias s this;
    }

    static assert(is(StringTypeOf!S == string));
    static assert(is(StringTypeOf!T == string));
}

/*
 */
template AssocArrayTypeOf(T)
{
    static if (is(typeof(__traits(getMember, T.init, __traits(getAliasThis, T)[0])) AT) && !is(AT[] == AT))
        alias X = AssocArrayTypeOf!AT;
    else
        alias X = OriginalType!T;

    static if (__traits(isAssociativeArray, X))
    {
        alias AssocArrayTypeOf = X;
    }
    else
        static assert(0, T.stringof~" is not an associative array type");
}

@safe unittest
{
    static foreach (T; AliasSeq!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/))
        static foreach (P; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))
            static foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))
                static foreach (R; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))
                {
                    static assert(is( P!(Q!T[R!T]) == AssocArrayTypeOf!(            P!(Q!T[R!T])  ) ));
                }

    static foreach (T; AliasSeq!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/))
        static foreach (O; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf))
            static foreach (P; AliasSeq!TypeQualifierList)
                static foreach (Q; AliasSeq!TypeQualifierList)
                    static foreach (R; AliasSeq!TypeQualifierList)
                    {
                        static assert(is( O!(P!(Q!T[R!T])) == AssocArrayTypeOf!( O!(SubTypeOf!(P!(Q!T[R!T]))) ) ));
                    }
}

/*
 */
template BuiltinTypeOf(T)
{
    static if (is(T : void))
        alias BuiltinTypeOf = void;
    else
    {
        static if (is(typeof(__traits(getMember, T.init, __traits(getAliasThis, T)[0])) AT) && !is(AT[] == AT))
            alias X = BuiltinTypeOf!AT;
        else
            alias X = OriginalType!T;
        static if (__traits(isArithmetic, X) && !is(X == __vector) ||
                __traits(isStaticArray, X) || is(X == E[], E) ||
                __traits(isAssociativeArray, X) || is(X == typeof(null)))
            alias BuiltinTypeOf = X;
        else
            static assert(0);
    }
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
// isSomething
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

/**
 * Detect whether `T` is a built-in boolean type or enum of boolean base type.
 */
enum bool isBoolean(T) = __traits(isUnsigned, T) && is(T : bool);

///
@safe unittest
{
    static assert( isBoolean!bool);
    enum EB : bool { a = true }
    static assert( isBoolean!EB);

    struct SubTypeOfBool
    {
        bool val;
        alias val this;
    }
    static assert(!isBoolean!(SubTypeOfBool));
}

@safe unittest
{
    static struct S(T)
    {
        T t;
        alias t this;
    }
    static assert(!isIntegral!(S!bool));
}

/**
 * Detect whether `T` is a built-in integral type.
 * Integral types are `byte`, `ubyte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `cent`, `ucent`,
 * and enums with an integral type as its base type.
 * Params:
 *      T = type to test
 * Returns:
 *      `true` if `T` is an integral type
 * Note:
 *      this is not the same as $(LINK2 https://dlang.org/spec/traits.html#isIntegral, `__traits(isIntegral)`)
 */
template isIntegral(T)
{
    static if (!__traits(isIntegral, T))
        enum isIntegral = false;
    else static if (is(T U == enum))
        enum isIntegral = isIntegral!U;
    else
        enum isIntegral = __traits(isZeroInit, T) // Not char, wchar, or dchar.
            && !is(immutable T == immutable bool) && !is(T == __vector);
}

///
@safe unittest
{
    static assert(
        isIntegral!byte &&
        isIntegral!short &&
        isIntegral!int &&
        isIntegral!long &&
        isIntegral!(const(long)) &&
        isIntegral!(immutable(long))
    );

    static assert(
        !isIntegral!bool &&
        !isIntegral!char &&
        !isIntegral!double
    );

    // types which act as integral values do not pass
    struct S
    {
        int val;
        alias val this;
    }

    static assert(!isIntegral!S);
}

@safe unittest
{
    static foreach (T; IntegralTypeList)
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isIntegral!(Q!T));
            static assert(!isIntegral!(SubTypeOf!(Q!T)));
        }
    }

    static assert(!isIntegral!float);

    enum EU : uint { a = 0, b = 1, c = 2 }  // base type is unsigned
    // base type is signed (https://issues.dlang.org/show_bug.cgi?id=7909)
    enum EI : int { a = -1, b = 0, c = 1 }
    static assert(isIntegral!EU &&  isUnsigned!EU && !isSigned!EU);
    static assert(isIntegral!EI && !isUnsigned!EI &&  isSigned!EI);
}

/**
 * Detect whether `T` is a built-in floating point type.
 *
 * See also: $(DDSUBLINK spec/traits, isFloating, `__traits(isFloating, T)`)
 */
// is(T : real) to discount complex types
enum bool isFloatingPoint(T) = __traits(isFloating, T) && is(T : real);

///
@safe unittest
{
    static assert(
        isFloatingPoint!float &&
        isFloatingPoint!double &&
        isFloatingPoint!real &&
        isFloatingPoint!(const(real)) &&
        isFloatingPoint!(immutable(real))
    );

    static assert(!isFloatingPoint!int);

    // types which act as floating point values do not pass
    struct S
    {
        float val;
        alias val this;
    }

    static assert(!isFloatingPoint!S);
}

@safe unittest
{
    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }

    static foreach (T; AliasSeq!(FloatingPointTypeList, EF))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isFloatingPoint!(Q!T));
            static assert(!isFloatingPoint!(SubTypeOf!(Q!T)));
        }
    }
    static foreach (T; IntegralTypeList)
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert(!isFloatingPoint!(Q!T));
        }
    }
    static if (is(__vector(float[4])))
    {
        static assert(!isFloatingPoint!(__vector(float[4])));
    }
}

/**
 * Detect whether `T` is a built-in numeric type (integral or floating
 * point).
 */
template isNumeric(T)
{
    static if (!__traits(isArithmetic, T))
        enum isNumeric = false;
    else static if (__traits(isFloating, T))
        enum isNumeric = is(T : real); // Not __vector, imaginary, or complex.
    else static if (is(T U == enum))
        enum isNumeric = isNumeric!U;
    else
        enum isNumeric = __traits(isZeroInit, T) // Not char, wchar, or dchar.
            && !is(immutable T == immutable bool) && !is(T == __vector);
}

///
@safe unittest
{
    static assert(
        isNumeric!byte &&
        isNumeric!short &&
        isNumeric!int &&
        isNumeric!long &&
        isNumeric!float &&
        isNumeric!double &&
        isNumeric!real &&
        isNumeric!(const(real)) &&
        isNumeric!(immutable(real))
    );

    static assert(
        !isNumeric!void &&
        !isNumeric!bool &&
        !isNumeric!char &&
        !isNumeric!wchar &&
        !isNumeric!dchar
    );

    // types which act as numeric values do not pass
    struct S
    {
        int val;
        alias val this;
    }

    static assert(!isNumeric!S);
}

@safe unittest
{
    static foreach (T; AliasSeq!(NumericTypeList))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isNumeric!(Q!T));
            static assert(!isNumeric!(SubTypeOf!(Q!T)));
        }
    }

    static struct S(T)
    {
        T t;
        alias t this;
    }
    static assert(!isNumeric!(S!int));

    enum EChar : char { a = 0, }
    static assert(!isNumeric!EChar);

    static if (is(__vector(float[4])))
    {
        static assert(!isNumeric!(__vector(float[4])));
    }
    static if (is(__vector(int[4])))
    {
        static assert(!isNumeric!(__vector(int[4])));
    }

    static assert(!isNumeric!ifloat);
    static assert(!isNumeric!cfloat);
}

/**
 * Detect whether `T` is a scalar type (a built-in numeric, character or
 * boolean type).
 *
 * See also: $(DDSUBLINK spec/traits, isScalar, `__traits(isScalar, T)`)
 */
// is(T : real) to discount complex types
enum bool isScalarType(T) = __traits(isScalar, T) && is(T : real);

///
@safe unittest
{
    static assert(!isScalarType!void);
    static assert( isScalarType!(immutable(byte)));
    static assert( isScalarType!(immutable(ushort)));
    static assert( isScalarType!(immutable(int)));
    static assert( isScalarType!(ulong));
    static assert( isScalarType!(shared(float)));
    static assert( isScalarType!(shared(const bool)));
    static assert( isScalarType!(const(char)));
    static assert( isScalarType!(wchar));
    static assert( isScalarType!(const(dchar)));
    static assert( isScalarType!(const(double)));
    static assert( isScalarType!(const(real)));
}

@safe unittest
{
    static struct S(T)
    {
        T t;
        alias t this;
    }
    static assert(!isScalarType!(S!int));
}

/**
 * Detect whether `T` is a basic type (scalar type or void).
 */
enum bool isBasicType(T) = isScalarType!T || is(immutable T == immutable void);

///
@safe unittest
{
    static assert(isBasicType!void);
    static assert(isBasicType!(const(void)));
    static assert(isBasicType!(shared(void)));
    static assert(isBasicType!(immutable(void)));
    static assert(isBasicType!(shared const(void)));
    static assert(isBasicType!(shared inout(void)));
    static assert(isBasicType!(shared inout const(void)));
    static assert(isBasicType!(inout(void)));
    static assert(isBasicType!(inout const(void)));
    static assert(isBasicType!(immutable(int)));
    static assert(isBasicType!(shared(float)));
    static assert(isBasicType!(shared(const bool)));
    static assert(isBasicType!(const(dchar)));
}

/**
 * Detect whether `T` is a built-in unsigned numeric type.
 */
template isUnsigned(T)
{
    static if (!__traits(isUnsigned, T))
        enum isUnsigned = false;
    else static if (is(T U == enum))
        enum isUnsigned = isUnsigned!U;
    else
        enum isUnsigned = __traits(isZeroInit, T) // Not char, wchar, or dchar.
            && !is(immutable T == immutable bool) && !is(T == __vector);
}

///
@safe unittest
{
    static assert(
        isUnsigned!uint &&
        isUnsigned!ulong
    );

    static assert(
        !isUnsigned!char &&
        !isUnsigned!int &&
        !isUnsigned!long &&
        !isUnsigned!char &&
        !isUnsigned!wchar &&
        !isUnsigned!dchar
    );
}

@safe unittest
{
    static foreach (T; AliasSeq!(UnsignedIntTypeList))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isUnsigned!(Q!T));
            static assert(!isUnsigned!(SubTypeOf!(Q!T)));
        }
    }

    static struct S(T)
    {
        T t;
        alias t this;
    }
    static assert(!isUnsigned!(S!uint));

    enum EChar : char { a = 0, }
    static assert(!isUnsigned!EChar);

    static if (is(__vector(uint[4])))
    {
        static assert(!isUnsigned!(__vector(uint[4])));
    }
}

/**
 * Detect whether `T` is a built-in signed numeric type.
 */
enum bool isSigned(T) = __traits(isArithmetic, T) && !__traits(isUnsigned, T)
                                                  && is(T : real);

///
@safe unittest
{
    static assert(
        isSigned!int &&
        isSigned!long
    );

    static assert(
        !isSigned!uint &&
        !isSigned!ulong
    );
}

@safe unittest
{
    enum E { e1 = 0 }
    static assert(isSigned!E);

    enum Eubyte : ubyte { e1 = 0 }
    static assert(!isSigned!Eubyte);

    static foreach (T; AliasSeq!(SignedIntTypeList))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isSigned!(Q!T));
            static assert(!isSigned!(SubTypeOf!(Q!T)));
        }
    }

    static struct S(T)
    {
        T t;
        alias t this;
    }
    static assert(!isSigned!(S!uint));

    static if (is(__vector(int[4])))
    {
        static assert(!isSigned!(__vector(int[4])));
    }

    static assert(!isSigned!ifloat);
    static assert(!isSigned!cfloat);
}

// https://issues.dlang.org/show_bug.cgi?id=17196
@safe unittest
{
    static assert(isUnsigned!bool == false);
    static assert(isSigned!bool == false);
}

/**
 * Detect whether `T` is one of the built-in character types.
 *
 * The built-in char types are any of `char`, `wchar` or `dchar`, with
 * or without qualifiers.
 */
template isSomeChar(T)
{
    static if (!__traits(isUnsigned, T))
        enum isSomeChar = false;
    else static if (is(T U == enum))
        enum isSomeChar = isSomeChar!U;
    else
        enum isSomeChar = !__traits(isZeroInit, T);
}

///
@safe unittest
{
    //Char types
    static assert( isSomeChar!char);
    static assert( isSomeChar!wchar);
    static assert( isSomeChar!dchar);
    static assert( isSomeChar!(typeof('c')));
    static assert( isSomeChar!(immutable char));
    static assert( isSomeChar!(const dchar));

    //Non char types
    static assert(!isSomeChar!int);
    static assert(!isSomeChar!byte);
    static assert(!isSomeChar!string);
    static assert(!isSomeChar!wstring);
    static assert(!isSomeChar!dstring);
    static assert(!isSomeChar!(char[4]));
}

@safe unittest
{
    enum EC : char { a = 'x', b = 'y' }

    static foreach (T; AliasSeq!(CharTypeList, EC))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isSomeChar!(            Q!T  ));
            static assert(!isSomeChar!( SubTypeOf!(Q!T) ));
        }
    }

    // alias-this types are not allowed
    static struct S(T)
    {
        T t;
        alias t this;
    }
    static assert(!isSomeChar!(S!char));
}

/**
Detect whether `T` is one of the built-in string types.

The built-in string types are `Char[]`, where `Char` is any of `char`,
`wchar` or `dchar`, with or without qualifiers.

Static arrays of characters (like `char[80]`) are not considered
built-in string types.
 */
enum bool isSomeString(T) = is(immutable T == immutable C[], C) && (is(C == char) || is(C == wchar) || is(C == dchar));

///
@safe unittest
{
    //String types
    static assert( isSomeString!string);
    static assert( isSomeString!(wchar[]));
    static assert( isSomeString!(dchar[]));
    static assert( isSomeString!(typeof("aaa")));
    static assert( isSomeString!(const(char)[]));

    //Non string types
    static assert(!isSomeString!int);
    static assert(!isSomeString!(int[]));
    static assert(!isSomeString!(byte[]));
    static assert(!isSomeString!(typeof(null)));
    static assert(!isSomeString!(char[4]));

    enum ES : string { a = "aaa", b = "bbb" }
    static assert(!isSomeString!ES);

    static struct Stringish
    {
        string str;
        alias str this;
    }
    static assert(!isSomeString!Stringish);
}

@safe unittest
{
    static foreach (T; AliasSeq!(char[], dchar[], string, wstring, dstring))
    {
        static assert( isSomeString!(           T ));
        static assert(!isSomeString!(SubTypeOf!(T)));
    }
    enum C : char { _ = 0 }
    static assert(!isSomeString!(C[]));
}

/**
 * Detect whether type `T` is a narrow string.
 *
 * All arrays that use char, wchar, and their qualified versions are narrow
 * strings. (Those include string and wstring).
 */
enum bool isNarrowString(T) = is(immutable T == immutable C[], C) && (is(C == char) || is(C == wchar));

///
@safe unittest
{
    static assert(isNarrowString!string);
    static assert(isNarrowString!wstring);
    static assert(isNarrowString!(char[]));
    static assert(isNarrowString!(wchar[]));

    static assert(!isNarrowString!dstring);
    static assert(!isNarrowString!(dchar[]));

    static assert(!isNarrowString!(typeof(null)));
    static assert(!isNarrowString!(char[4]));

    enum ES : string { a = "aaa", b = "bbb" }
    static assert(!isNarrowString!ES);

    static struct Stringish
    {
        string str;
        alias str this;
    }
    static assert(!isNarrowString!Stringish);
}

@safe unittest
{
    import std.meta : Alias;
    static foreach (T; AliasSeq!(char[], string, wstring))
    {
        static foreach (Q; AliasSeq!(Alias, ConstOf, ImmutableOf)/*TypeQualifierList*/)
        {
            static assert( isNarrowString!(            Q!T  ));
            static assert(!isNarrowString!( SubTypeOf!(Q!T) ));
        }
    }

    static foreach (T; AliasSeq!(int, int[], byte[], dchar[], dstring, char[4]))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert(!isNarrowString!(            Q!T  ));
            static assert(!isNarrowString!( SubTypeOf!(Q!T) ));
        }
    }
    enum C : char { _ = 0 }
    static assert(!isNarrowString!(C[]));
}

/**
 * Detects whether `T` is a comparable type. Basic types and structs and
 * classes that implement opCmp are ordering comparable.
 */
enum bool isOrderingComparable(T) = is(typeof((ref T a) => a < a ? 1 : 0));

///
@safe unittest
{
    static assert(isOrderingComparable!int);
    static assert(isOrderingComparable!string);

    static struct Foo {}
    static assert(!isOrderingComparable!Foo);

    static struct Bar
    {
        int a;
        auto opCmp(Bar b1) const { return a - b1.a; }
    }

    Bar b1 = Bar(5);
    Bar b2 = Bar(7);
    assert(isOrderingComparable!Bar && b2 > b1);
}

/// ditto
enum bool isEqualityComparable(T) = is(typeof((ref T a) => a == a ? 1 : 0));

@safe unittest
{
    static assert(isEqualityComparable!int);
    static assert(isEqualityComparable!string);
    static assert(!isEqualityComparable!void);

    struct Foo {}
    static assert(isEqualityComparable!Foo);

    struct Bar
    {
        int a;
        auto opEquals(Bar b1) const { return a == b1.a; }
    }

    Bar b1 = Bar(5);
    Bar b2 = Bar(5);
    Bar b3 = Bar(7);
    static assert(isEqualityComparable!Bar);
    assert(b1 == b2);
    assert(b1 != b3);
}

/**
  $(RED Warning: This trait will be deprecated as soon as it is no longer used
                 in Phobos. For a function parameter to safely accept a type
                 that implicitly converts to string as a string, the conversion
                 needs to happen at the callsite; otherwise, the conversion is
                 done inside the function, and in many cases, that means that
                 local memory is sliced (e.g. if a static array is passed to
                 the function, then it's copied, and the resulting dynamic
                 array will be a slice of a local variable). So, if the
                 resulting string escapes the function, the string refers to
                 invalid memory, and accessing it would mean accessing invalid
                 memory. As such, the only safe way for a function to accept
                 types that implicitly convert to string is for the implicit
                 conversion to be done at the callsite, and that can only occur
                 if the parameter is explicitly typed as an array, whereas
                 using isConvertibleToString in a template constraint would
                 result in the conversion being done inside the function. As
                 such, isConvertibleToString is inherently unsafe and is going
                 to be deprecated.)

   Detect whether `T` is a struct, static array, or enum that is implicitly
   convertible to a string.
 */
template isConvertibleToString(T)
{
    enum isConvertibleToString =
        (isAggregateType!T || isStaticArray!T || is(T == enum))
        && is(StringTypeOf!T);
}

///
@safe unittest
{
    static struct AliasedString
    {
        string s;
        alias s this;
    }

    enum StringEnum { a = "foo" }

    assert(!isConvertibleToString!string);
    assert(isConvertibleToString!AliasedString);
    assert(isConvertibleToString!StringEnum);
    assert(isConvertibleToString!(char[25]));
    assert(!isConvertibleToString!(char[]));
}

// https://issues.dlang.org/show_bug.cgi?id=16573
@safe unittest
{
    enum I : int { foo = 1 }
    enum S : string { foo = "foo" }
    assert(!isConvertibleToString!I);
    assert(isConvertibleToString!S);
}

package template convertToString(T)
{
    static if (isConvertibleToString!T)
        alias convertToString = StringTypeOf!T;
    else
        alias convertToString = T;
}

/**
 * Detect whether type `T` is a string that will be autodecoded.
 *
 * Given a type `S` that is one of:
 * $(OL
 *  $(LI `const(char)[]`)
 *  $(LI `const(wchar)[]`)
 * )
 * Type `T` can be one of:
 * $(OL
 *    $(LI `S`)
 *    $(LI implicitly convertible to `T`)
 *    $(LI an enum with a base type `T`)
 *    $(LI an aggregate with a base type `T`)
 * )
 * with the proviso that `T` cannot be a static array.
 *
 * Params:
 *      T = type to be tested
 *
 * Returns:
 *      true if T represents a string that is subject to autodecoding
 *
 * See Also:
 *      $(LREF isNarrowString)
 */
template isAutodecodableString(T)
{
    import std.range.primitives : autodecodeStrings;

    enum isAutodecodableString = autodecodeStrings &&
        (is(T : const char[]) || is(T : const wchar[]))
        && !is(T : U[n], U, size_t n)
        && !is(immutable T : immutable noreturn[]);
}

///
@safe unittest
{
    static struct Stringish
    {
        string s;
        alias s this;
    }
    static assert(isAutodecodableString!wstring);
    static assert(isAutodecodableString!Stringish);
    static assert(!isAutodecodableString!dstring);

    enum E : const(char)[3] { X = "abc" }
    enum F : const(char)[] { X = "abc" }
    enum G : F { X = F.init }

    static assert(isAutodecodableString!(char[]));
    static assert(!isAutodecodableString!(E));
    static assert(isAutodecodableString!(F));
    static assert(isAutodecodableString!(G));

    struct Stringish2
    {
        Stringish s;
        alias s this;
    }

    enum H : Stringish { X = Stringish() }
    enum I : Stringish2 { X = Stringish2() }

    static assert(isAutodecodableString!(H));
    static assert(isAutodecodableString!(I));

    static assert(!isAutodecodableString!(noreturn[]));
    static assert(!isAutodecodableString!(immutable(noreturn)[]));
}

/**
 * Detect whether type `T` is a static array.
 *
 * See also: $(DDSUBLINK spec/traits, isStaticArray, `__traits(isStaticArray, T)`)
 */
enum bool isStaticArray(T) = __traits(isStaticArray, T);

///
@safe unittest
{
    static assert( isStaticArray!(int[3]));
    static assert( isStaticArray!(const(int)[5]));
    static assert( isStaticArray!(const(int)[][5]));

    static assert(!isStaticArray!(const(int)[]));
    static assert(!isStaticArray!(immutable(int)[]));
    static assert(!isStaticArray!(const(int)[4][]));
    static assert(!isStaticArray!(int[]));
    static assert(!isStaticArray!(int[char]));
    static assert(!isStaticArray!(int[1][]));
    static assert(!isStaticArray!(int[int]));
    static assert(!isStaticArray!int);
}

@safe unittest
{
    static foreach (T; AliasSeq!(int[51], int[][2],
                           char[][int][11], immutable char[13u],
                           const(real)[1], const(real)[1][1], void[0]))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isStaticArray!(            Q!T  ));
            static assert(!isStaticArray!( SubTypeOf!(Q!T) ));
        }
    }

    //enum ESA : int[1] { a = [1], b = [2] }
    //static assert( isStaticArray!ESA);
}

/**
 * Detect whether type `T` is a dynamic array.
 */
template isDynamicArray(T)
{
    static if (is(T == U[], U))
        enum bool isDynamicArray = true;
    else static if (is(T U == enum))
        // BUG: isDynamicArray / isStaticArray considers enums
        // with appropriate base types as dynamic/static arrays
        // Retain old behaviour for now, see
        // https://github.com/dlang/phobos/pull/7574
        enum bool isDynamicArray = isDynamicArray!U;
    else
        enum bool isDynamicArray = false;
}

///
@safe unittest
{
    static assert( isDynamicArray!(int[]));
    static assert( isDynamicArray!(string));
    static assert( isDynamicArray!(long[3][]));

    static assert(!isDynamicArray!(int[5]));
    static assert(!isDynamicArray!(typeof(null)));
}

@safe unittest
{
    import std.meta : AliasSeq;
    static foreach (T; AliasSeq!(int[], char[], string, long[3][], double[string][]))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isDynamicArray!(            Q!T  ));
            static assert(!isDynamicArray!( SubTypeOf!(Q!T) ));
        }
    }

    static assert(!isDynamicArray!(int[5]));

    static struct AliasThis
    {
        int[] values;
        alias values this;
    }

    static assert(!isDynamicArray!AliasThis);

    // https://github.com/dlang/phobos/pull/7574/files#r464115492
    enum E : string
    {
        a = "a",
        b = "b",
    }
    static assert( isDynamicArray!E);
}

/**
 * Detect whether type `T` is an array (static or dynamic; for associative
 *  arrays see $(LREF isAssociativeArray)).
 */
enum bool isArray(T) = isStaticArray!T || isDynamicArray!T;

///
@safe unittest
{
    static assert( isArray!(int[]));
    static assert( isArray!(int[5]));
    static assert( isArray!(string));

    static assert(!isArray!uint);
    static assert(!isArray!(uint[uint]));
    static assert(!isArray!(typeof(null)));
}

@safe unittest
{
    import std.meta : AliasSeq;
    static foreach (T; AliasSeq!(int[], int[5], void[]))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isArray!(Q!T));
            static assert(!isArray!(SubTypeOf!(Q!T)));
        }
    }
}

/**
 * Detect whether `T` is an associative array type
 *
 * See also: $(DDSUBLINK spec/traits, isAssociativeArray, `__traits(isAssociativeArray, T)`)
 */
enum bool isAssociativeArray(T) = __traits(isAssociativeArray, T);

///
@safe unittest
{
    struct S;

    static assert( isAssociativeArray!(int[string]));
    static assert( isAssociativeArray!(S[S]));
    static assert(!isAssociativeArray!(string[]));
    static assert(!isAssociativeArray!S);
    static assert(!isAssociativeArray!(int[4]));
}

@safe unittest
{
    struct Foo
    {
        @property uint[] keys()   { return null; }
        @property uint[] values() { return null; }
    }

    static foreach (T; AliasSeq!(int[int], int[string], immutable(char[5])[int]))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isAssociativeArray!(Q!T));
            static assert(!isAssociativeArray!(SubTypeOf!(Q!T)));
        }
    }

    static assert(!isAssociativeArray!Foo);
    static assert(!isAssociativeArray!int);
    static assert(!isAssociativeArray!(int[]));
    static assert(!isAssociativeArray!(typeof(null)));

    //enum EAA : int[int] { a = [1:1], b = [2:2] }
    //static assert( isAssociativeArray!EAA);
}

/**
 * Detect whether type `T` is a builtin type.
 */
enum bool isBuiltinType(T) = is(BuiltinTypeOf!T) && !isAggregateType!T;

///
@safe unittest
{
    class C;
    union U;
    struct S;
    interface I;

    static assert( isBuiltinType!void);
    static assert( isBuiltinType!string);
    static assert( isBuiltinType!(int[]));
    static assert( isBuiltinType!(C[string]));
    static assert( isBuiltinType!(typeof(null)));
    static assert(!isBuiltinType!C);
    static assert(!isBuiltinType!U);
    static assert(!isBuiltinType!S);
    static assert(!isBuiltinType!I);
    static assert(!isBuiltinType!(void delegate(int)));
}

/**
 * Detect whether type `T` is a SIMD vector type.
 */
enum bool isSIMDVector(T) = is(T : __vector(V[N]), V, size_t N);

///
@safe unittest
{
    static if (is(__vector(float[4])))
    {
        alias SimdVec = __vector(float[4]);
        static assert(isSIMDVector!(__vector(float[4])));
        static assert(isSIMDVector!SimdVec);
    }
    static assert(!isSIMDVector!uint);
    static assert(!isSIMDVector!(float[4]));
}

/**
 * Detect whether type `T` is a pointer.
 */
enum bool isPointer(T) = is(T == U*, U);

///
@safe unittest
{
    void fun();

    static assert( isPointer!(int*));
    static assert( isPointer!(int function()));
    static assert(!isPointer!int);
    static assert(!isPointer!string);
    static assert(!isPointer!(typeof(null)));
    static assert(!isPointer!(typeof(fun)));
    static assert(!isPointer!(int delegate()));
}

@safe unittest
{
    static foreach (T; AliasSeq!(int*, void*, char[]*))
    {
        static foreach (Q; TypeQualifierList)
        {
            static assert( isPointer!(Q!T));
            static assert(!isPointer!(SubTypeOf!(Q!T)));
        }
    }

    static assert(!isPointer!uint);
    static assert(!isPointer!(uint[uint]));
    static assert(!isPointer!(char[]));
    static assert(!isPointer!(typeof(null)));
}

/**
Returns the target type of a pointer.
*/
alias PointerTarget(T : T*) = T;

///
@safe unittest
{
    static assert(is(PointerTarget!(int*) == int));
    static assert(is(PointerTarget!(void*) == void));
}

/**
 * Detect whether type `T` is an aggregate type.
 */
template isAggregateType(T)
{
    static if (is(T == enum))
        enum isAggregateType = isAggregateType!(OriginalType!T);
    else
        enum isAggregateType = is(T == struct) || is(T == class) || is(T == interface) || is(T == union);
}

///
@safe unittest
{
    class C {}
    union U {}
    struct S {}
    interface I {}

    static assert( isAggregateType!C);
    static assert( isAggregateType!U);
    static assert( isAggregateType!S);
    static assert( isAggregateType!I);
    static assert(!isAggregateType!void);
    static assert(!isAggregateType!string);
    static assert(!isAggregateType!(int[]));
    static assert(!isAggregateType!(C[string]));
    static assert(!isAggregateType!(void delegate(int)));

    enum ES : S { a = S.init }
    enum EC : C { a = C.init }
    enum EI : I { a = I.init }
    enum EU : U { a = U.init }

    static assert( isAggregateType!ES);
    static assert( isAggregateType!EC);
    static assert( isAggregateType!EI);
    static assert( isAggregateType!EU);
}

/**
 * Returns `true` if T can be iterated over using a `foreach` loop with
 * a single loop variable of automatically inferred type, regardless of how
 * the `foreach` loop is implemented.  This includes ranges, structs/classes
 * that define `opApply` with a single loop variable, and builtin dynamic,
 * static and associative arrays.
 */
enum bool isIterable(T) = is(typeof({ foreach (elem; T.init) {} }));

///
@safe unittest
{
    struct OpApply
    {
        int opApply(scope int delegate(ref uint) dg) { assert(0); }
    }

    struct Range
    {
        @property uint front() { assert(0); }
        void popFront() { assert(0); }
        enum bool empty = false;
    }

    static assert( isIterable!(uint[]));
    static assert( isIterable!OpApply);
    static assert( isIterable!(uint[string]));
    static assert( isIterable!Range);

    static assert(!isIterable!uint);
}

/**
 * Returns true if T is not const or immutable.  Note that isMutable is true for
 * string, or immutable(char)[], because the 'head' is mutable.
 */
enum bool isMutable(T) = !is(T == const) && !is(T == immutable) && !is(T == inout);

///
@safe unittest
{
    static assert( isMutable!int);
    static assert( isMutable!string);
    static assert( isMutable!(shared int));
    static assert( isMutable!(shared const(int)[]));

    static assert(!isMutable!(const int));
    static assert(!isMutable!(inout int));
    static assert(!isMutable!(shared(const int)));
    static assert(!isMutable!(shared(inout int)));
    static assert(!isMutable!(immutable string));
}

/**
 * Returns true if T is an instance of the template S.
 */
enum bool isInstanceOf(alias S, T) = is(T == S!Args, Args...);
/// ditto
template isInstanceOf(alias S, alias T)
{
    enum impl(alias T : S!Args, Args...) = true;
    enum impl(alias T) = false;
    enum isInstanceOf = impl!T;
}

///
@safe unittest
{
    static struct Foo(T...) { }
    static struct Bar(T...) { }
    static struct Doo(T) { }
    static struct ABC(int x) { }
    static void fun(T)() { }
    template templ(T) { }

    static assert(isInstanceOf!(Foo, Foo!int));
    static assert(!isInstanceOf!(Foo, Bar!int));
    static assert(!isInstanceOf!(Foo, int));
    static assert(isInstanceOf!(Doo, Doo!int));
    static assert(isInstanceOf!(ABC, ABC!1));
    static assert(!isInstanceOf!(Foo, Foo));
    static assert(isInstanceOf!(fun, fun!int));
    static assert(isInstanceOf!(templ, templ!int));
}

/**
 * To use `isInstanceOf` to check the identity of a template while inside of said
 * template, use $(LREF TemplateOf).
 */
@safe unittest
{
    static struct A(T = void)
    {
        // doesn't work as expected, only accepts A when T = void
        void func(B)(B b)
        if (isInstanceOf!(A, B)) {}

        // correct behavior
        void method(B)(B b)
        if (isInstanceOf!(TemplateOf!(A), B)) {}
    }

    A!(void) a1;
    A!(void) a2;
    A!(int) a3;

    static assert(!__traits(compiles, a1.func(a3)));
    static assert( __traits(compiles, a1.method(a2)));
    static assert( __traits(compiles, a1.method(a3)));
}

@safe unittest
{
    static void fun1(T)() { }
    static void fun2(T)() { }
    template templ1(T) { }
    template templ2(T) { }

    static assert(!isInstanceOf!(fun1, fun2!int));
    static assert(!isInstanceOf!(templ1, templ2!int));
}

/**
 * Check whether the tuple T is an expression tuple.
 * An expression tuple only contains expressions.
 *
 * See_Also: $(LREF isTypeTuple).
 */
template isExpressions(T...)
{
    static foreach (Ti; T)
    {
        static if (!is(typeof(isExpressions) == bool) && // not yet defined
                   (is(Ti) || !__traits(compiles, { auto ex = Ti; })))
        {
            enum isExpressions = false;
        }
    }
    static if (!is(typeof(isExpressions) == bool)) // if not yet defined
    {
        enum isExpressions = true;
    }
}

///
@safe unittest
{
    static assert(isExpressions!(1, 2.0, "a"));
    static assert(!isExpressions!(int, double, string));
    static assert(!isExpressions!(int, 2.0, "a"));
}

/**
 * Alternate name for $(LREF isExpressions), kept for legacy compatibility.
 */

alias isExpressionTuple = isExpressions;

@safe unittest
{
    void foo();
    static int bar() { return 42; }
    immutable aa = [ 1: -1 ];
    alias myint = int;

    static assert( isExpressionTuple!(42));
    static assert( isExpressionTuple!aa);
    static assert( isExpressionTuple!("cattywampus", 2.7, aa));
    static assert( isExpressionTuple!(bar()));

    static assert(!isExpressionTuple!isExpressionTuple);
    static assert(!isExpressionTuple!foo);
    static assert(!isExpressionTuple!( (a) { } ));
    static assert(!isExpressionTuple!int);
    static assert(!isExpressionTuple!myint);
}


/**
 * Check whether the tuple `T` is a type tuple.
 * A type tuple only contains types.
 *
 * See_Also: $(LREF isExpressions).
 */
enum isTypeTuple(T...) =
{
    static foreach (U; T)
        static if (!is(U))
            if (__ctfe)
                return false;
    return true;
}();

///
@safe unittest
{
    static assert(isTypeTuple!(int, float, string));
    static assert(!isTypeTuple!(1, 2.0, "a"));
    static assert(!isTypeTuple!(1, double, string));
}

@safe unittest
{
    class C {}
    void func(int) {}
    auto c = new C;
    enum CONST = 42;

    static assert( isTypeTuple!int);
    static assert( isTypeTuple!string);
    static assert( isTypeTuple!C);
    static assert( isTypeTuple!(typeof(func)));
    static assert( isTypeTuple!(int, char, double));

    static assert(!isTypeTuple!c);
    static assert(!isTypeTuple!isTypeTuple);
    static assert(!isTypeTuple!CONST);
}


/**
Detect whether symbol or type `T` is a function pointer.
 */
enum bool isFunctionPointer(alias T) = is(typeof(*T) == function);

///
@safe unittest
{
    static void foo() {}
    void bar() {}

    auto fpfoo = &foo;
    static assert( isFunctionPointer!fpfoo);
    static assert( isFunctionPointer!(void function()));

    auto dgbar = &bar;
    static assert(!isFunctionPointer!dgbar);
    static assert(!isFunctionPointer!(void delegate()));
    static assert(!isFunctionPointer!foo);
    static assert(!isFunctionPointer!bar);

    static assert( isFunctionPointer!((int a) {}));
}

/**
Detect whether symbol or type `T` is a delegate.
*/
enum bool isDelegate(alias T) = is(typeof(T) == delegate) || is(T == delegate);

///
@safe unittest
{
    static void sfunc() { }
    int x;
    void func() { x++; }

    int delegate() dg;
    assert(isDelegate!dg);
    assert(isDelegate!(int delegate()));
    assert(isDelegate!(typeof(&func)));

    int function() fp;
    assert(!isDelegate!fp);
    assert(!isDelegate!(int function()));
    assert(!isDelegate!(typeof(&sfunc)));
}

/**
Detect whether symbol or type `T` is a function, a function pointer or a delegate.

Params:
    T = The type to check
Returns:
    A `bool`
 */
enum bool isSomeFunction(alias T) =
    is(T == return) ||
    is(typeof(T) == return) ||
    is(typeof(&T) == return); // @property

///
@safe unittest
{
    static real func(ref int) { return 0; }
    static void prop() @property { }
    class C
    {
        real method(ref int) { return 0; }
        real prop() @property { return 0; }
    }
    auto c = new C;
    auto fp = &func;
    auto dg = &c.method;

    static assert( isSomeFunction!func);
    static assert( isSomeFunction!prop);
    static assert( isSomeFunction!(C.method));
    static assert( isSomeFunction!(C.prop));
    static assert( isSomeFunction!(c.prop));
    static assert( isSomeFunction!fp);
    static assert( isSomeFunction!dg);

    real val;
    static assert(!isSomeFunction!int);
    static assert(!isSomeFunction!val);
}

@safe unittest
{
    void nestedFunc() { }
    void nestedProp() @property { }
    static assert(isSomeFunction!nestedFunc);
    static assert(isSomeFunction!nestedProp);
    static assert(isSomeFunction!(real function(ref int)));
    static assert(isSomeFunction!(real delegate(ref int)));
    static assert(isSomeFunction!((int a) { return a; }));
    static assert(!isSomeFunction!isSomeFunction);
}

/**
Detect whether `callable` is a callable object, which can be called with the
function call operator `$(LPAREN)...$(RPAREN)`.

$(NOTE Implicit Function Template Instantiation is *not* attempted - see below.)
 */
template isCallable(alias callable)
{
    static if (is(typeof(&callable.opCall) == delegate))
        // callable is a object which has a member function opCall().
        enum bool isCallable = true;
    else static if (is(typeof(&callable.opCall) V : V*) && is(V == function))
        // callable is a type which has a static member function opCall().
        enum bool isCallable = true;
    else static if (is(typeof(&callable.opCall!()) TemplateInstanceType))
    {
        enum bool isCallable = isCallable!TemplateInstanceType;
    }
    else static if (is(typeof(&callable!()) TemplateInstanceType))
    {
        enum bool isCallable = isCallable!TemplateInstanceType;
    }
    else
    {
        enum bool isCallable = isSomeFunction!callable;
    }
}

/// Functions, function pointers, delegates, non-template function literals.
@safe unittest
{
    void f() { }
    int g(int x) { return x; }

    static assert( isCallable!f);
    static assert( isCallable!g);

    auto fp = &f;
    static assert( isCallable!fp);
    static assert( isCallable!((int x) {}));

    int x;
    static assert(!isCallable!x);
    auto d = () => x;
    static assert( isCallable!d);
}

/// Aggregate types with (static) opCall.
@safe unittest
{
    class C { int opCall(int) { return 0; } }
    auto c = new C;
    struct S { static int opCall(int) { return 0; } }
    interface I { real value() @property; }

    static assert( isCallable!c);
    static assert( isCallable!(c.opCall));
    static assert( isCallable!S);
    static assert( isCallable!(I.value));

    static assert(!isCallable!I);
}

/// Template functions are only detected if they are instantiable with `!()`.
@safe unittest
{
    void f()() { }
    T g(T = int)(T x) { return x; }
    int h(T)();
    struct S1 { static void opCall()() { } }
    struct S2 { static T opCall(T = int)(T x) {return x; } }

    static assert( isCallable!f);
    static assert( isCallable!g);
    static assert(!isCallable!h);
    static assert( isCallable!S1);
    static assert( isCallable!S2);

    static assert(!isCallable!((x) {}));
}

/// Overloaded functions and function templates instantiable with `!()`.
@safe unittest
{
    static struct Wrapper
    {
        void f() { }
        int f(int x) { return x; }

        void g()() { }
        T g(T = int)(T x) { return x; }
    }

    static assert(isCallable!(Wrapper.f));
    static assert(isCallable!(Wrapper.g));
}


/**
Detect whether `S` is an abstract function.

See also: $(DDSUBLINK spec/traits, isAbstractFunction, `__traits(isAbstractFunction, S)`)
Params:
    S = The symbol to check
Returns:
    A `bool`
 */
enum isAbstractFunction(alias S) = __traits(isAbstractFunction, S);

///
@safe unittest
{
    struct S { void foo() { } }
    class C { void foo() { } }
    class AC { abstract void foo(); }
    static assert(!isAbstractFunction!(int));
    static assert(!isAbstractFunction!(S.foo));
    static assert(!isAbstractFunction!(C.foo));
    static assert( isAbstractFunction!(AC.foo));
}

/**
 * Detect whether `S` is a final function.
 *
 * See also: $(DDSUBLINK spec/traits, isFinalFunction, `__traits(isFinalFunction, S)`)
 */
enum isFinalFunction(alias S) = __traits(isFinalFunction, S);

///
@safe unittest
{
    struct S { void bar() { } }
    final class FC { void foo(); }
    class C
    {
        void bar() { }
        final void foo();
    }
    static assert(!isFinalFunction!(int));
    static assert(!isFinalFunction!(S.bar));
    static assert( isFinalFunction!(FC.foo));
    static assert(!isFinalFunction!(C.bar));
    static assert( isFinalFunction!(C.foo));
}

/**
Determines if `f` is a function that requires a context pointer.

Params:
    f = The type to check
Returns
    A `bool`
*/
template isNestedFunction(alias f)
{
    enum isNestedFunction = __traits(isNested, f) && isSomeFunction!(f);
}

///
@safe unittest
{
    static void f() {}
    static void fun()
    {
        int i;
        int f() { return i; }

        static assert(isNestedFunction!(f));
    }

    static assert(!isNestedFunction!f);
}

// https://issues.dlang.org/show_bug.cgi?id=18669
@safe unittest
{
    static class Outer
    {
        class Inner
        {
        }
    }
    int i;
    struct SS
    {
        int bar() { return i; }
    }
    static assert(!isNestedFunction!(Outer.Inner));
    static assert(!isNestedFunction!(SS));
}

/**
 * Detect whether `S` is an abstract class.
 *
 * See also: $(DDSUBLINK spec/traits, isAbstractClass, `__traits(isAbstractClass, S)`)
 */
enum isAbstractClass(alias S) = __traits(isAbstractClass, S);

///
@safe unittest
{
    struct S { }
    class C { }
    abstract class AC { }
    static assert(!isAbstractClass!S);
    static assert(!isAbstractClass!C);
    static assert( isAbstractClass!AC);
    C c;
    static assert(!isAbstractClass!c);
    AC ac;
    static assert( isAbstractClass!ac);
}

/**
 * Detect whether `S` is a final class.
 *
 * See also: $(DDSUBLINK spec/traits, isFinalClass, `__traits(isFinalClass, S)`)
 */
enum isFinalClass(alias S) = __traits(isFinalClass, S);

///
@safe unittest
{
    class C { }
    abstract class AC { }
    final class FC1 : C { }
    final class FC2 { }
    static assert(!isFinalClass!C);
    static assert(!isFinalClass!AC);
    static assert( isFinalClass!FC1);
    static assert( isFinalClass!FC2);
    C c;
    static assert(!isFinalClass!c);
    FC1 fc1;
    static assert( isFinalClass!fc1);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
// General Types
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

version (StdDdoc)
{
    /**
       Removes `const`, `inout` and `immutable` qualifiers, if any, from type `T`.
    */
    template Unconst(T)
    {
        import core.internal.traits : CoreUnconst = Unconst;
        alias Unconst = CoreUnconst!(T);
    }
}
else
{
    import core.internal.traits : CoreUnconst = Unconst;
    alias Unconst = CoreUnconst;
}

///
@safe unittest
{
    static assert(is(Unconst!int == int));
    static assert(is(Unconst!(const int) == int));
    static assert(is(Unconst!(immutable int) == int));
    static assert(is(Unconst!(shared int) == shared int));
    static assert(is(Unconst!(shared(const int)) == shared int));
}

@safe unittest
{
    static assert(is(Unconst!(                   int) == int));
    static assert(is(Unconst!(             const int) == int));
    static assert(is(Unconst!(       inout       int) == int));
    static assert(is(Unconst!(       inout const int) == int));
    static assert(is(Unconst!(shared             int) == shared int));
    static assert(is(Unconst!(shared       const int) == shared int));
    static assert(is(Unconst!(shared inout       int) == shared int));
    static assert(is(Unconst!(shared inout const int) == shared int));
    static assert(is(Unconst!(         immutable int) == int));

    alias ImmIntArr = immutable(int[]);
    static assert(is(Unconst!ImmIntArr == immutable(int)[]));
}

/++
    Removes `shared` qualifier, if any, from type `T`.

    Note that while `immutable` is implicitly `shared`, it is unaffected by
    Unshared. Only explict `shared` is removed.
  +/
template Unshared(T)
{
    static if (is(T == shared U, U))
        alias Unshared = U;
    else
        alias Unshared = T;
}

///
@safe unittest
{
    static assert(is(Unshared!int == int));
    static assert(is(Unshared!(const int) == const int));
    static assert(is(Unshared!(immutable int) == immutable int));

    static assert(is(Unshared!(shared int) == int));
    static assert(is(Unshared!(shared(const int)) == const int));

    static assert(is(Unshared!(shared(int[])) == shared(int)[]));
}

@safe unittest
{
    static assert(is(Unshared!(                   int) == int));
    static assert(is(Unshared!(             const int) == const int));
    static assert(is(Unshared!(       inout       int) == inout int));
    static assert(is(Unshared!(       inout const int) == inout const int));
    static assert(is(Unshared!(shared             int) == int));
    static assert(is(Unshared!(shared       const int) == const int));
    static assert(is(Unshared!(shared inout       int) == inout int));
    static assert(is(Unshared!(shared inout const int) == inout const int));
    static assert(is(Unshared!(         immutable int) == immutable int));
}

version (StdDdoc)
{
    /**
       Removes all qualifiers, if any, from type `T`.
    */
    template Unqual(T)
    {
        import core.internal.traits : CoreUnqual = Unqual;
        alias Unqual = CoreUnqual!(T);
    }
}
else
{
    import core.internal.traits : CoreUnqual = Unqual;
    alias Unqual = CoreUnqual;
}

///
@safe unittest
{
    static assert(is(Unqual!int == int));
    static assert(is(Unqual!(const int) == int));
    static assert(is(Unqual!(immutable int) == int));
    static assert(is(Unqual!(shared int) == int));
    static assert(is(Unqual!(shared(const int)) == int));
}

@safe unittest
{
    static assert(is(Unqual!(                   int) == int));
    static assert(is(Unqual!(             const int) == int));
    static assert(is(Unqual!(       inout       int) == int));
    static assert(is(Unqual!(       inout const int) == int));
    static assert(is(Unqual!(shared             int) == int));
    static assert(is(Unqual!(shared       const int) == int));
    static assert(is(Unqual!(shared inout       int) == int));
    static assert(is(Unqual!(shared inout const int) == int));
    static assert(is(Unqual!(         immutable int) == int));

    alias ImmIntArr = immutable(int[]);
    static assert(is(Unqual!ImmIntArr == immutable(int)[]));
}

// [For internal use]
package template ModifyTypePreservingTQ(alias Modifier, T)
{
    import core.internal.traits : _ModifyTypePreservingTQ = ModifyTypePreservingTQ;
    alias ModifyTypePreservingTQ = _ModifyTypePreservingTQ!(Modifier, T);
}

/**
 * Copies type qualifiers from `FromType` to `ToType`.
 *
 * Supported type qualifiers:
 * $(UL
 *     $(LI `const`)
 *     $(LI `inout`)
 *     $(LI `immutable`)
 *     $(LI `shared`)
 * )
 */
template CopyTypeQualifiers(FromType, ToType)
{
    alias T(U) = ToType;
    alias CopyTypeQualifiers = ModifyTypePreservingTQ!(T, FromType);
}

///
@safe unittest
{
    static assert(is(CopyTypeQualifiers!(inout const real, int) == inout const int));
}

@safe unittest
{
    static assert(is(CopyTypeQualifiers!(                   real, int) ==                    int));
    static assert(is(CopyTypeQualifiers!(             const real, int) ==              const int));
    static assert(is(CopyTypeQualifiers!(       inout       real, int) ==        inout       int));
    static assert(is(CopyTypeQualifiers!(       inout const real, int) ==        inout const int));
    static assert(is(CopyTypeQualifiers!(shared             real, int) == shared             int));
    static assert(is(CopyTypeQualifiers!(shared       const real, int) == shared       const int));
    static assert(is(CopyTypeQualifiers!(shared inout       real, int) == shared inout       int));
    static assert(is(CopyTypeQualifiers!(shared inout const real, int) == shared inout const int));
    static assert(is(CopyTypeQualifiers!(         immutable real, int) ==          immutable int));
}

/**
Returns the type of `ToType` with the "constness" of `FromType`. A type's $(B constness)
refers to whether it is `const`, `immutable`, or `inout`. If `FromType` has no constness, the
returned type will be the same as `ToType`.
*/
template CopyConstness(FromType, ToType)
{
    alias Unshared(T) = T;
    alias Unshared(T: shared U, U) = U;

    alias CopyConstness = Unshared!(CopyTypeQualifiers!(FromType, ToType));
}

///
@safe unittest
{
    const(int) i;
    CopyConstness!(typeof(i), float) f;
    assert( is(typeof(f) == const float));

    CopyConstness!(char, uint) u;
    assert( is(typeof(u) == uint));

    //The 'shared' qualifier will not be copied
    assert(!is(CopyConstness!(shared bool, int) == shared int));

    //But the constness will be
    assert( is(CopyConstness!(shared const real, double) == const double));

    //Careful, const(int)[] is a mutable array of const(int)
    alias MutT = CopyConstness!(const(int)[], int);
    assert(!is(MutT == const(int)));

    //Okay, const(int[]) applies to array and contained ints
    alias CstT = CopyConstness!(const(int[]), int);
    assert( is(CstT == const(int)));
}

@safe unittest
{
    struct Test
    {
        void method1() {}
        void method2() const {}
        void method3() immutable {}
    }

    assert(is(CopyConstness!(typeof(Test.method1), real) == real));

    assert(is(CopyConstness!(typeof(Test.method2), byte) == const(byte)));

    assert(is(CopyConstness!(typeof(Test.method3), string) == immutable(string)));
}

@safe unittest
{
    assert(is(CopyConstness!(inout(int)[], int[]) == int[]));
    assert(is(CopyConstness!(inout(int[]), int[]) == inout(int[])));
}

@safe unittest
{
    static assert(is(CopyConstness!(                   int, real) ==             real));
    static assert(is(CopyConstness!(const              int, real) ==       const real));
    static assert(is(CopyConstness!(inout              int, real) ==       inout real));
    static assert(is(CopyConstness!(inout const        int, real) == inout const real));
    static assert(is(CopyConstness!(shared             int, real) ==             real));
    static assert(is(CopyConstness!(shared const       int, real) ==       const real));
    static assert(is(CopyConstness!(shared inout       int, real) == inout       real));
    static assert(is(CopyConstness!(shared inout const int, real) == inout const real));
    static assert(is(CopyConstness!(immutable          int, real) ==   immutable real));
}

/**
Returns the inferred type of the loop variable when a variable of type T
is iterated over using a `foreach` loop with a single loop variable and
automatically inferred return type.  Note that this may not be the same as
`std.range.ElementType!Range` in the case of narrow strings, or if T
has both opApply and a range interface.
*/
template ForeachType(T)
{
    alias ForeachType = typeof(
    (inout int x = 0)
    {
        foreach (elem; T.init)
        {
            return elem;
        }
        assert(0);
    }());
}

///
@safe unittest
{
    static assert(is(ForeachType!(uint[]) == uint));
    static assert(is(ForeachType!string == immutable(char)));
    static assert(is(ForeachType!(string[string]) == string));
    static assert(is(ForeachType!(inout(int)[]) == inout(int)));
}


/**
 * Strips off all `enum`s from type `T`.
 */
template OriginalType(T)
{
    import core.internal.traits : _OriginalType = OriginalType;
    alias OriginalType = _OriginalType!T;
}

///
@safe unittest
{
    enum E : real { a = 0 } // NOTE: explicit initialization to 0 required during Enum init deprecation cycle
    enum F : E    { a = E.a }
    alias G = const(F);
    static assert(is(OriginalType!E == real));
    static assert(is(OriginalType!F == real));
    static assert(is(OriginalType!G == const real));
}

/**
 * Get the Key type of an Associative Array.
 */
alias KeyType(V : V[K], K) = K;

///
@safe unittest
{
    alias Hash = int[string];
    static assert(is(KeyType!Hash == string));
    static assert(is(ValueType!Hash == int));
    KeyType!Hash str = "a"; // str is declared as string
    ValueType!Hash num = 1; // num is declared as int
}

/**
 * Get the Value type of an Associative Array.
 */
alias ValueType(V : V[K], K) = V;

///
@safe unittest
{
    alias Hash = int[string];
    static assert(is(KeyType!Hash == string));
    static assert(is(ValueType!Hash == int));
    KeyType!Hash str = "a"; // str is declared as string
    ValueType!Hash num = 1; // num is declared as int
}

/**
Params:
    T = A built in integral or vector type.

Returns:
    The corresponding unsigned numeric type for `T` with the
    same type qualifiers.

    If `T` is not a integral or vector, a compile-time error is given.
 */
template Unsigned(T)
{
    template Impl(T)
    {
        static if (is(T : __vector(V[N]), V, size_t N))
            alias Impl = __vector(Impl!V[N]);
        else static if (isUnsigned!T)
            alias Impl = T;
        else static if (isSigned!T && !isFloatingPoint!T)
        {
            static if (is(T == byte )) alias Impl = ubyte;
            static if (is(T == short)) alias Impl = ushort;
            static if (is(T == int  )) alias Impl = uint;
            static if (is(T == long )) alias Impl = ulong;
            static if (is(ucent) && is(T == cent )) alias Impl = ucent;
        }
        else
            static assert(false, "Type " ~ T.stringof ~
                                 " does not have an Unsigned counterpart");
    }

    alias Unsigned = ModifyTypePreservingTQ!(Impl, OriginalType!T);
}

///
@safe unittest
{
    static assert(is(Unsigned!(int) == uint));
    static assert(is(Unsigned!(long) == ulong));
    static assert(is(Unsigned!(const short) == const ushort));
    static assert(is(Unsigned!(immutable byte) == immutable ubyte));
    static assert(is(Unsigned!(inout int) == inout uint));
}


/// Unsigned types are forwarded
@safe unittest
{
    static assert(is(Unsigned!(uint) == uint));
    static assert(is(Unsigned!(const uint) == const uint));

    static assert(is(Unsigned!(ubyte) == ubyte));
    static assert(is(Unsigned!(immutable uint) == immutable uint));
}

@safe unittest
{
    alias U1 = Unsigned!int;
    alias U2 = Unsigned!(const(int));
    alias U3 = Unsigned!(immutable(int));
    static assert(is(U1 == uint));
    static assert(is(U2 == const(uint)));
    static assert(is(U3 == immutable(uint)));
    static if (is(__vector(int[4])) && is(__vector(uint[4])))
    {
        alias UV1 = Unsigned!(__vector(int[4]));
        alias UV2 = Unsigned!(const(__vector(int[4])));
        static assert(is(UV1 == __vector(uint[4])));
        static assert(is(UV2 == const(__vector(uint[4]))));
    }
    //struct S {}
    //alias U2 = Unsigned!S;
    //alias U3 = Unsigned!double;
    static if (is(ucent))
    {
        alias U4 = Unsigned!cent;
        alias U5 = Unsigned!(const(cent));
        alias U6 = Unsigned!(immutable(cent));
        static assert(is(U4 == ucent));
        static assert(is(U5 == const(ucent)));
        static assert(is(U6 == immutable(ucent)));
    }
}

/**
Returns the largest type, i.e. T such that T.sizeof is the largest.  If more
than one type is of the same size, the leftmost argument of these in will be
returned.
*/
template Largest(T...)
if (T.length >= 1)
{
    alias Largest = T[0];
    static foreach (U; T[1 .. $])
        Largest = Select!(U.sizeof > Largest.sizeof, U, Largest);
}

///
@safe unittest
{
    static assert(is(Largest!(uint, ubyte, ushort, real) == real));
    static assert(is(Largest!(ulong, double) == ulong));
    static assert(is(Largest!(double, ulong) == double));
    static assert(is(Largest!(uint, byte, double, short) == double));
    static if (is(ucent))
        static assert(is(Largest!(uint, ubyte, ucent, ushort) == ucent));
}

/**
Returns the corresponding signed type for T. T must be a numeric integral type,
otherwise a compile-time error occurs.
 */
template Signed(T)
{
    template Impl(T)
    {
        static if (is(T : __vector(V[N]), V, size_t N))
            alias Impl = __vector(Impl!V[N]);
        else static if (isSigned!T)
            alias Impl = T;
        else static if (isUnsigned!T)
        {
            static if (is(T == ubyte )) alias Impl = byte;
            static if (is(T == ushort)) alias Impl = short;
            static if (is(T == uint  )) alias Impl = int;
            static if (is(T == ulong )) alias Impl = long;
            static if (is(ucent) && is(T == ucent )) alias Impl = cent;
        }
        else
            static assert(false, "Type " ~ T.stringof ~
                                 " does not have an Signed counterpart");
    }

    alias Signed = ModifyTypePreservingTQ!(Impl, OriginalType!T);
}

///
@safe unittest
{
    alias S1 = Signed!uint;
    static assert(is(S1 == int));
    alias S2 = Signed!(const(uint));
    static assert(is(S2 == const(int)));
    alias S3 = Signed!(immutable(uint));
    static assert(is(S3 == immutable(int)));
    static if (is(ucent))
    {
        alias S4 = Signed!ucent;
        static assert(is(S4 == cent));
    }
}

@safe unittest
{
    static assert(is(Signed!float == float));
    static if (is(__vector(int[4])) && is(__vector(uint[4])))
    {
        alias SV1 = Signed!(__vector(uint[4]));
        alias SV2 = Signed!(const(__vector(uint[4])));
        static assert(is(SV1 == __vector(int[4])));
        static assert(is(SV2 == const(__vector(int[4]))));
    }
}


/**
Returns the most negative value of the numeric type T.
*/
template mostNegative(T)
if (isNumeric!T || isSomeChar!T || isBoolean!T)
{
    static if (is(typeof(T.min_normal)))
        enum mostNegative = -T.max;
    else static if (T.min == 0)
        enum byte mostNegative = 0;
    else
        enum mostNegative = T.min;
}

///
@safe unittest
{
    static assert(mostNegative!float == -float.max);
    static assert(mostNegative!double == -double.max);
    static assert(mostNegative!real == -real.max);
    static assert(mostNegative!bool == false);
}

///
@safe unittest
{
    import std.meta : AliasSeq;

    static foreach (T; AliasSeq!(bool, byte, short, int, long))
        static assert(mostNegative!T == T.min);

    static foreach (T; AliasSeq!(ubyte, ushort, uint, ulong, char, wchar, dchar))
        static assert(mostNegative!T == 0);
}

/**
Get the type that a scalar type `T` will $(LINK2 $(ROOT_DIR)spec/type.html#integer-promotions, promote)
to in multi-term arithmetic expressions.
*/
template Promoted(T)
if (isScalarType!T)
{
    alias Promoted = CopyTypeQualifiers!(T, typeof(T.init + T.init));
}

///
@safe unittest
{
    ubyte a = 3, b = 5;
    static assert(is(typeof(a * b) == Promoted!ubyte));
    static assert(is(Promoted!ubyte == int));

    static assert(is(Promoted!(shared(bool)) == shared(int)));
    static assert(is(Promoted!(const(int)) == const(int)));
    static assert(is(Promoted!double == double));
}

@safe unittest
{
    // promote to int:
    static foreach (T; AliasSeq!(bool, byte, ubyte, short, ushort, char, wchar))
    {
        static assert(is(Promoted!T == int));
        static assert(is(Promoted!(shared(const T)) == shared(const int)));
    }

    // already promoted:
    static foreach (T; AliasSeq!(int, uint, long, ulong, float, double, real))
    {
        static assert(is(Promoted!T == T));
        static assert(is(Promoted!(immutable(T)) == immutable(T)));
    }
}

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
// Misc.
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://

/**
Returns the mangled name of symbol or type `sth`.

`mangledName` is the same as builtin `.mangleof` property, but
might be more convenient in generic code, e.g. as a template argument
when invoking staticMap.
 */
enum mangledName(alias sth) = sth.mangleof;

///
@safe unittest
{
    import std.meta : AliasSeq;
    alias TL = staticMap!(mangledName, int, const int, immutable int);
    static assert(TL == AliasSeq!("i", "xi", "yi"));
}

version (StdUnittest) private void freeFunc(string);

@safe unittest
{
    class C { int value() @property { return 0; } }
    static assert(mangledName!int == int.mangleof);
    static assert(mangledName!C == C.mangleof);
    static assert(mangledName!(C.value) == C.value.mangleof);
    static assert(mangledName!(C.value)[$ - 12 .. $] == "5valueMFNdZi");
    static assert(mangledName!mangledName == "3std6traits11mangledName");
    static assert(mangledName!freeFunc == "_D3std6traits8freeFuncFAyaZv");
    int x;
    // https://issues.dlang.org/show_bug.cgi?id=9148
  static if (is(typeof({ return x; }) : int delegate() pure))
    static assert(mangledName!((int a) { return a+x; }) == "DFNaNbNiNfiZi");  // pure nothrow @safe @nogc
  else
    static assert(mangledName!((int a) { return a+x; }) == "DFNbNiNfiZi");  // nothrow @safe @nnogc
}

@system unittest
{
    // @system due to demangle
    // Test for https://issues.dlang.org/show_bug.cgi?id=5718
    import std.demangle : demangle;
    int foo;
    auto foo_demangled = demangle(mangledName!foo);
    assert(foo_demangled[0 .. 4] == "int " && foo_demangled[$-3 .. $] == "foo",
        foo_demangled);

    void bar();
    auto bar_demangled = demangle(mangledName!bar);
    assert(bar_demangled[0 .. 5] == "void " && bar_demangled[$-5 .. $] == "bar()");
}



// XXX Select & select should go to another module. (functional or algorithm?)

/**
Aliases itself to `T[0]` if the boolean `condition` is `true`
and to `T[1]` otherwise.
 */
template Select(bool condition, T...)
if (T.length == 2)
{
    import std.meta : Alias;
    alias Select = Alias!(T[!condition]);
}

///
@safe unittest
{
    // can select types
    static assert(is(Select!(true, int, long) == int));
    static assert(is(Select!(false, int, long) == long));
    static struct Foo {}
    static assert(is(Select!(false, const(int), const(Foo)) == const(Foo)));

    // can select symbols
    int a = 1;
    int b = 2;
    alias selA = Select!(true, a, b);
    alias selB = Select!(false, a, b);
    assert(selA == 1);
    assert(selB == 2);

    // can select (compile-time) expressions
    enum val = Select!(false, -4, 9 - 6);
    static assert(val == 3);
}

/**
Select one of two functions to run via template parameter.

Params:
    cond = A `bool` which determines which function is run
    a = The first function
    b = The second function

Returns:
    `a` without evaluating `b` if `cond` is `true`.
    Otherwise, returns `b` without evaluating `a`.
 */
A select(bool cond : true, A, B)(A a, lazy B b) { return a; }
/// Ditto
B select(bool cond : false, A, B)(lazy A a, B b) { return b; }

///
@safe unittest
{
    real run() { return 0; }
    int fail() { assert(0); }
    auto a = select!true(run(), fail());
    auto b = select!false(fail(), run());
    static assert(is(typeof(a) == real));
    static assert(is(typeof(b) == real));
}

/++
    Determine if a symbol has a given
    $(DDSUBLINK spec/attribute, uda, user-defined attribute).

    See_Also:
        $(LREF getUDAs)
  +/
enum hasUDA(alias symbol, alias attribute) = getUDAs!(symbol, attribute).length != 0;

///
@safe unittest
{
    enum E;
    struct S {}

    @("alpha") int a;
    static assert(hasUDA!(a, "alpha"));
    static assert(!hasUDA!(a, S));
    static assert(!hasUDA!(a, E));

    @(E) int b;
    static assert(!hasUDA!(b, "alpha"));
    static assert(!hasUDA!(b, S));
    static assert(hasUDA!(b, E));

    @E int c;
    static assert(!hasUDA!(c, "alpha"));
    static assert(!hasUDA!(c, S));
    static assert(hasUDA!(c, E));

    @(S, E) int d;
    static assert(!hasUDA!(d, "alpha"));
    static assert(hasUDA!(d, S));
    static assert(hasUDA!(d, E));

    @S int e;
    static assert(!hasUDA!(e, "alpha"));
    static assert(hasUDA!(e, S));
    static assert(!hasUDA!(e, S()));
    static assert(!hasUDA!(e, E));

    @S() int f;
    static assert(!hasUDA!(f, "alpha"));
    static assert(hasUDA!(f, S));
    static assert(hasUDA!(f, S()));
    static assert(!hasUDA!(f, E));

    @(S, E, "alpha") int g;
    static assert(hasUDA!(g, "alpha"));
    static assert(hasUDA!(g, S));
    static assert(hasUDA!(g, E));

    @(100) int h;
    static assert(hasUDA!(h, 100));

    struct Named { string name; }

    @Named("abc") int i;
    static assert(hasUDA!(i, Named));
    static assert(hasUDA!(i, Named("abc")));
    static assert(!hasUDA!(i, Named("def")));

    struct AttrT(T)
    {
        string name;
        T value;
    }

    @AttrT!int("answer", 42) int j;
    static assert(hasUDA!(j, AttrT));
    static assert(hasUDA!(j, AttrT!int));
    static assert(!hasUDA!(j, AttrT!string));

    @AttrT!string("hello", "world") int k;
    static assert(hasUDA!(k, AttrT));
    static assert(!hasUDA!(k, AttrT!int));
    static assert(hasUDA!(k, AttrT!string));

    struct FuncAttr(alias f) { alias func = f; }
    static int fourtyTwo() { return 42; }
    static size_t getLen(string s) { return s.length; }

    @FuncAttr!getLen int l;
    static assert(hasUDA!(l, FuncAttr));
    static assert(!hasUDA!(l, FuncAttr!fourtyTwo));
    static assert(hasUDA!(l, FuncAttr!getLen));
    static assert(!hasUDA!(l, FuncAttr!fourtyTwo()));
    static assert(!hasUDA!(l, FuncAttr!getLen()));

    @FuncAttr!getLen() int m;
    static assert(hasUDA!(m, FuncAttr));
    static assert(!hasUDA!(m, FuncAttr!fourtyTwo));
    static assert(hasUDA!(m, FuncAttr!getLen));
    static assert(!hasUDA!(m, FuncAttr!fourtyTwo()));
    static assert(hasUDA!(m, FuncAttr!getLen()));
}

/++
    Gets the matching $(DDSUBLINK spec/attribute, uda, user-defined attributes)
    from the given symbol.

    If the UDA is a type, then any UDAs of the same type on the symbol will
    match. If the UDA is a template for a type, then any UDA which is an
    instantiation of that template will match. And if the UDA is a value,
    then any UDAs on the symbol which are equal to that value will match.

    See_Also:
        $(LREF hasUDA)
  +/
template getUDAs(alias symbol, alias attribute)
{
    import std.meta : Filter;

    alias getUDAs = Filter!(isDesiredUDA!attribute, __traits(getAttributes, symbol));
}

///
@safe unittest
{
    struct Attr
    {
        string name;
        int value;
    }

    @Attr("Answer", 42) int a;
    static assert(getUDAs!(a, Attr).length == 1);
    static assert(getUDAs!(a, Attr)[0].name == "Answer");
    static assert(getUDAs!(a, Attr)[0].value == 42);

    @(Attr("Answer", 42), "string", 9999) int b;
    static assert(getUDAs!(b, Attr).length == 1);
    static assert(getUDAs!(b, Attr)[0].name == "Answer");
    static assert(getUDAs!(b, Attr)[0].value == 42);

    @Attr("Answer", 42) @Attr("Pi", 3) int c;
    static assert(getUDAs!(c, Attr).length == 2);
    static assert(getUDAs!(c, Attr)[0].name == "Answer");
    static assert(getUDAs!(c, Attr)[0].value == 42);
    static assert(getUDAs!(c, Attr)[1].name == "Pi");
    static assert(getUDAs!(c, Attr)[1].value == 3);

    static assert(getUDAs!(c, Attr("Answer", 42)).length == 1);
    static assert(getUDAs!(c, Attr("Answer", 42))[0].name == "Answer");
    static assert(getUDAs!(c, Attr("Answer", 42))[0].value == 42);

    static assert(getUDAs!(c, Attr("Answer", 99)).length == 0);

    struct AttrT(T)
    {
        string name;
        T value;
    }

    @AttrT!uint("Answer", 42) @AttrT!int("Pi", 3) @AttrT int d;
    static assert(getUDAs!(d, AttrT).length == 2);
    static assert(getUDAs!(d, AttrT)[0].name == "Answer");
    static assert(getUDAs!(d, AttrT)[0].value == 42);
    static assert(getUDAs!(d, AttrT)[1].name == "Pi");
    static assert(getUDAs!(d, AttrT)[1].value == 3);

    static assert(getUDAs!(d, AttrT!uint).length == 1);
    static assert(getUDAs!(d, AttrT!uint)[0].name == "Answer");
    static assert(getUDAs!(d, AttrT!uint)[0].value == 42);

    static assert(getUDAs!(d, AttrT!int).length == 1);
    static assert(getUDAs!(d, AttrT!int)[0].name == "Pi");
    static assert(getUDAs!(d, AttrT!int)[0].value == 3);

    struct SimpleAttr {}

    @SimpleAttr int e;
    static assert(getUDAs!(e, SimpleAttr).length == 1);
    static assert(is(getUDAs!(e, SimpleAttr)[0] == SimpleAttr));

    @SimpleAttr() int f;
    static assert(getUDAs!(f, SimpleAttr).length == 1);
    static assert(is(typeof(getUDAs!(f, SimpleAttr)[0]) == SimpleAttr));

    struct FuncAttr(alias f) { alias func = f; }
    static int add42(int v) { return v + 42; }
    static string concat(string l, string r) { return l ~ r; }

    @FuncAttr!add42 int g;
    static assert(getUDAs!(g, FuncAttr).length == 1);
    static assert(getUDAs!(g, FuncAttr)[0].func(5) == 47);

    static assert(getUDAs!(g, FuncAttr!add42).length == 1);
    static assert(getUDAs!(g, FuncAttr!add42)[0].func(5) == 47);

    static assert(getUDAs!(g, FuncAttr!add42()).length == 0);

    static assert(getUDAs!(g, FuncAttr!concat).length == 0);
    static assert(getUDAs!(g, FuncAttr!concat()).length == 0);

    @FuncAttr!add42() int h;
    static assert(getUDAs!(h, FuncAttr).length == 1);
    static assert(getUDAs!(h, FuncAttr)[0].func(5) == 47);

    static assert(getUDAs!(h, FuncAttr!add42).length == 1);
    static assert(getUDAs!(h, FuncAttr!add42)[0].func(5) == 47);

    static assert(getUDAs!(h, FuncAttr!add42()).length == 1);
    static assert(getUDAs!(h, FuncAttr!add42())[0].func(5) == 47);

    static assert(getUDAs!(h, FuncAttr!concat).length == 0);
    static assert(getUDAs!(h, FuncAttr!concat()).length == 0);

    @("alpha") @(42) int i;
    static assert(getUDAs!(i, "alpha").length == 1);
    static assert(getUDAs!(i, "alpha")[0] == "alpha");

    static assert(getUDAs!(i, 42).length == 1);
    static assert(getUDAs!(i, 42)[0] == 42);

    static assert(getUDAs!(i, 'c').length == 0);
}

private template isDesiredUDA(alias attribute)
{
    template isDesiredUDA(alias toCheck)
    {
        static if (is(typeof(attribute)) && !__traits(isTemplate, attribute))
        {
            static if (__traits(compiles, toCheck == attribute))
                enum isDesiredUDA = toCheck == attribute;
            else
                enum isDesiredUDA = false;
        }
        else static if (is(typeof(toCheck)))
        {
            static if (__traits(isTemplate, attribute))
                enum isDesiredUDA =  isInstanceOf!(attribute, typeof(toCheck));
            else
                enum isDesiredUDA = is(typeof(toCheck) == attribute);
        }
        else static if (__traits(isTemplate, attribute))
            enum isDesiredUDA = isInstanceOf!(attribute, toCheck);
        else
            enum isDesiredUDA = is(toCheck == attribute);
    }
}

/**
Params:
    symbol = The aggregate type or module to search
    attribute = The user-defined attribute to search for

Returns:
    All symbols within `symbol` that have the given UDA `attribute`.

Note:
    This is not recursive; it will not search for symbols within symbols such as
    nested structs or unions.
 */
template getSymbolsByUDA(alias symbol, alias attribute)
{
    alias membersWithUDA = getSymbolsByUDAImpl!(symbol, attribute, __traits(allMembers, symbol));

    // if the symbol itself has the UDA, tack it on to the front of the list
    static if (hasUDA!(symbol, attribute))
        alias getSymbolsByUDA = AliasSeq!(symbol, membersWithUDA);
    else
        alias getSymbolsByUDA = membersWithUDA;
}

///
@safe unittest
{
    enum Attr;
    struct A
    {
        @Attr int a;
        int b;
    }

    static assert(getSymbolsByUDA!(A, Attr).length == 1);
    static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr));
}

///
@safe unittest
{
    enum Attr;

    static struct A
    {
        @Attr int a;
        int b;
        @Attr void doStuff() {}
        void doOtherStuff() {}
        static struct Inner
        {
            // Not found by getSymbolsByUDA
            @Attr int c;
        }
    }

    // Finds both variables and functions with the attribute, but
    // doesn't include the variables and functions without it.
    static assert(getSymbolsByUDA!(A, Attr).length == 2);
    // Can access attributes on the symbols returned by getSymbolsByUDA.
    static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr));
    static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[1], Attr));
}

/// Finds multiple attributes
@safe unittest
{
    static struct UDA { string name; }

    static struct B
    {
        @UDA("X")
        int x;
        @UDA("Y")
        int y;
        @(100)
        int z;
    }

    // Finds both UDA attributes.
    static assert(getSymbolsByUDA!(B, UDA).length == 2);
    // Finds one `100` attribute.
    static assert(getSymbolsByUDA!(B, 100).length == 1);
    // Can get the value of the UDA from the return value
    static assert(getUDAs!(getSymbolsByUDA!(B, UDA)[0], UDA)[0].name == "X");
}

/// Checks for UDAs on the aggregate symbol itself
@safe unittest
{
    static struct UDA { string name; }

    @UDA("A")
    static struct C
    {
        @UDA("B")
        int d;
    }

    static assert(getSymbolsByUDA!(C, UDA).length == 2);
    static assert(getSymbolsByUDA!(C, UDA)[0].stringof == "C");
    static assert(getSymbolsByUDA!(C, UDA)[1].stringof == "d");
}

/// Finds nothing if there is no member with specific UDA
@safe unittest
{
    static struct UDA { string name; }

    static struct D
    {
        int x;
    }

    static assert(getSymbolsByUDA!(D, UDA).length == 0);
}

// https://issues.dlang.org/show_bug.cgi?id=18314
@safe unittest
{
    enum attr1;
    enum attr2;

    struct A
    {
        @attr1
        int n;
        // Removed due to https://issues.dlang.org/show_bug.cgi?id=16206
        //@attr1
        //void foo()(string){}
        @attr1
        void foo();
        @attr2
        void foo(int a);
    }

    static assert(getSymbolsByUDA!(A, attr1).length == 2);
    static assert(getSymbolsByUDA!(A, attr2).length == 1);
}

// getSymbolsByUDA fails if type has private members
// https://issues.dlang.org/show_bug.cgi?id=15335
@safe unittest
{
    // HasPrivateMembers has, well, private members, one of which has a UDA.
    import std.internal.test.uda : Attr, HasPrivateMembers;
    // Trying access to private member from another file therefore we do not have access
    // for this otherwise we get deprecation warning - not visible from module
    // This line is commented because `__traits(getMember)` should also consider
    // private members; this is not currently the case, but the PR that
    // fixes `__traits(getMember)` is blocked by this specific test.
    //static assert(getSymbolsByUDA!(HasPrivateMembers, Attr).length == 1);
    static assert(hasUDA!(getSymbolsByUDA!(HasPrivateMembers, Attr)[0], Attr));
}

// getSymbolsByUDA works with structs but fails with classes
// https://issues.dlang.org/show_bug.cgi?id=16387
@safe unittest
{
    enum Attr;
    class A
    {
        @Attr uint a;
    }

    alias res = getSymbolsByUDA!(A, Attr);
    static assert(res.length == 1);
    static assert(res[0].stringof == "a");
}

// getSymbolsByUDA fails on AliasSeq members
// https://issues.dlang.org/show_bug.cgi?id=18884
@safe unittest
{
    struct X
    {
        alias A = AliasSeq!(ulong, uint);
    }

    static assert(is(getSymbolsByUDA!(X, X) == AliasSeq!()));
}

// https://issues.dlang.org/show_bug.cgi?id=23776
@safe pure nothrow @nogc unittest
{
    struct T
    {
        struct Tag {}
        @Tag struct MyStructA {}
        @Tag struct MyStructB {}
        @Tag struct MyStructC {}
    }
    alias tcomponents = getSymbolsByUDA!(T, T.Tag);
    static assert(tcomponents.length > 0);

    struct X
    {
        struct Tag {}
        @Tag enum MyEnumA;
        @Tag enum MyEnumB;
        @Tag enum MyEnumC;
    }
    alias xcomponents = getSymbolsByUDA!(X, X.Tag);
    static assert(xcomponents.length > 0);
}

// getSymbolsByUDA produces wrong result if one of the symbols having the UDA is a function
// https://issues.dlang.org/show_bug.cgi?id=18624
@safe unittest
{
    enum Attr;
    struct A
    {
        @Attr void a();
        @Attr void a(int n);
              void b();
        @Attr void c();
    }

    alias ola = __traits(getOverloads, A, "a");
    static assert(__traits(isSame, getSymbolsByUDA!(A, Attr),
        AliasSeq!(ola[0], ola[1], A.c)));
}

// getSymbolsByUDA no longer works on modules
// https://issues.dlang.org/show_bug.cgi?id=20054
version (StdUnittest)
{
    @("Issue20054")
    void issue20054() {}
    static assert(__traits(compiles, getSymbolsByUDA!(mixin(__MODULE__), "Issue20054")));
}

private template isAliasSeq(Args...)
{
    static if (Args.length != 1)
        enum isAliasSeq = true;
    else
        enum isAliasSeq = false;
}

private template getSymbolsByUDAImpl(alias symbol, alias attribute, names...)
{
    import std.meta : Alias, AliasSeq, Filter;
    static if (names.length == 0)
    {
        alias getSymbolsByUDAImpl = AliasSeq!();
    }
    else
    {
        alias tail = getSymbolsByUDAImpl!(symbol, attribute, names[1 .. $]);

        // Filtering inaccessible members.
        static if (!__traits(compiles, __traits(getMember, symbol, names[0])))
        {
            alias getSymbolsByUDAImpl = tail;
        }
        else
        {
            alias member = __traits(getMember, symbol, names[0]);

            // Filtering not compiled members such as alias of basic types.
            static if (isAliasSeq!member ||
                       (isType!member && !isAggregateType!member && !is(member == enum)))
            {
                alias getSymbolsByUDAImpl = tail;
            }
            // If a symbol is overloaded, get UDAs for each overload (including templated overlaods).
            else static if (__traits(getOverloads, symbol, names[0], true).length > 0)
            {
                enum hasSpecificUDA(alias member) = hasUDA!(member, attribute);
                alias overloadsWithUDA = Filter!(hasSpecificUDA, __traits(getOverloads, symbol, names[0]));
                alias getSymbolsByUDAImpl = AliasSeq!(overloadsWithUDA, tail);
            }
            else static if (hasUDA!(member, attribute))
            {
                alias getSymbolsByUDAImpl = AliasSeq!(member, tail);
            }
            else
            {
                alias getSymbolsByUDAImpl = tail;
            }
        }
    }
}

/**
   Returns: `true` iff all types `Ts` are the same.
*/
enum bool allSameType(Ts...) =
{
    static foreach (T; Ts[Ts.length > 1 .. $])
        static if (!is(Ts[0] == T))
            if (__ctfe)  // Dodge the "statement is unreachable" warning
                return false;
    return true;
}();

///
@safe unittest
{
    static assert(allSameType!());
    static assert(allSameType!(int));
    static assert(allSameType!(int, int));
    static assert(allSameType!(int, int, int));
    static assert(allSameType!(float, float, float));
    static assert(!allSameType!(int, double));
    static assert(!allSameType!(int, float, double));
    static assert(!allSameType!(int, float, double, real));
    static assert(!allSameType!(short, int, float, double, real));
}

/**
   Returns: `true` iff the type `T` can be tested in an $(D
   if)-expression, that is if $(D if (pred(T.init)) {}) is compilable.
*/
enum ifTestable(T, alias pred = a => a) = __traits(compiles, { if (pred(T.init)) {} });

///
@safe unittest
{
    class C;
    struct S1;
    struct S2
    {
        T opCast(T)() const;
    }

    static assert( ifTestable!bool);
    static assert( ifTestable!int);
    static assert( ifTestable!(S1*));
    static assert( ifTestable!(typeof(null)));
    static assert( ifTestable!(int[]));
    static assert( ifTestable!(int[string]));
    static assert( ifTestable!S2);
    static assert( ifTestable!C);
    static assert(!ifTestable!S1);
}

@safe unittest
{
    import std.meta : AliasSeq, allSatisfy;
    static assert(allSatisfy!(ifTestable, AliasSeq!(bool, int, float, double, string)));
    struct BoolWrapper { bool value; }
    static assert(!ifTestable!(bool, a => BoolWrapper(a)));
}

/**
 * Detect whether `X` is a type. Analogous to `is(X)`. This is useful when used
 * in conjunction with other templates, e.g. `allSatisfy!(isType, X)`.
 *
 * Returns:
 *      `true` if `X` is a type, `false` otherwise
 */
enum isType(alias X) = is(X);

///
@safe unittest
{
    struct S {
        template Test() {}
    }
    class C {}
    interface I {}
    union U {}
    static assert(isType!int);
    static assert(isType!string);
    static assert(isType!(int[int]));
    static assert(isType!S);
    static assert(isType!C);
    static assert(isType!I);
    static assert(isType!U);

    int n;
    void func(){}
    static assert(!isType!n);
    static assert(!isType!func);
    static assert(!isType!(S.Test));
    static assert(!isType!(S.Test!()));
}

/**
 * Detect whether symbol or type `X` is a function.
 * This is different from finding if a symbol is callable or satisfying `is(X == return)`.
 * It finds specifically if the symbol represents a normal function (or method) declaration, i.e.
 * not a delegate or a function pointer.
 *
 * Returns:
 *     `true` if `X` is a function, `false` otherwise
 *
 * See_Also:
 *     Use $(LREF isFunctionPointer) or $(LREF isDelegate) for detecting those types
 *     respectively.
 */
template isFunction(alias X)
{
    static if (is(typeof(&X) U : U*) && is(U == function) ||
               is(typeof(&X) U == delegate))
    {
        // x is a (nested) function symbol.
        enum isFunction = true;
    }
    else static if (is(X))
    {
        // x is a type
        enum isFunction = is(X == function);
    }
    else
        enum isFunction = false;
}

///
@safe unittest
{
    static void func(){}
    static assert(isFunction!func);
    static assert(isFunction!(typeof(func)));

    auto fp = &func; // function pointer
    static assert(!isFunction!fp);

    int i;
    int f2() => i; // nested function
    static assert(isFunction!f2);

    struct S
    {
        void func(){}
    }
    static assert(isFunction!(S.func));
}

/**
 * Detect whether `X` is a final method or class.
 *
 * Returns:
 *     `true` if `X` is final, `false` otherwise
 */
template isFinal(alias X)
{
    static if (is(X == class))
        enum isFinal = __traits(isFinalClass, X);
    else static if (isFunction!X)
        enum isFinal = __traits(isFinalFunction, X);
    else
        enum isFinal = false;
}

///
@safe unittest
{
    class C
    {
        void nf() {}
        static void sf() {}
        final void ff() {}
    }
    final class FC { }

    static assert(!isFinal!(C));
    static assert( isFinal!(FC));

    static assert(!isFinal!(C.nf));
    static assert(!isFinal!(C.sf));
    static assert( isFinal!(C.ff));
}

/++
 + Determines whether the type `S` can be copied.
 + If a type cannot be copied, then code such as `MyStruct x; auto y = x;` will fail to compile.
 + Copying for structs can be disabled by using `@disable this(this)`.
 +
 + See also: $(DDSUBLINK spec/traits, isCopyable, `__traits(isCopyable, S)`)
 + Params:
 +  S = The type to check.
 +
 + Returns:
 +  `true` if `S` can be copied. `false` otherwise.
 +/
enum isCopyable(S) = __traits(isCopyable, S);

///
@safe unittest
{
    struct S1 {}                        // Fine. Can be copied
    struct S2 {         this(this) {}}  // Fine. Can be copied
    struct S3 {@disable this(this);  }  // Not fine. Copying is disabled.
    struct S4 {S3 s;}                   // Not fine. A field has copying disabled.

    class C1 {}

    static assert( isCopyable!S1);
    static assert( isCopyable!S2);
    static assert(!isCopyable!S3);
    static assert(!isCopyable!S4);

    static assert(isCopyable!C1);
    static assert(isCopyable!int);
    static assert(isCopyable!(int[]));
}

/**
 * The parameter type deduced by IFTI when an expression of type T is passed as
 * an argument to a template function.
 *
 * For all types other than pointer and slice types, `DeducedParameterType!T`
 * is the same as `T`. For pointer and slice types, it is `T` with the
 * outer-most layer of qualifiers dropped.
 */
package(std) alias DeducedParameterType(T) = DeducedParameterTypeImpl!T;
/// ditto
package(std) alias DeducedParameterType(alias T) = DeducedParameterTypeImpl!T;

private template DeducedParameterTypeImpl(T)
{
    static if (is(T == U*, U) || is(T == U[], U))
        alias DeducedParameterTypeImpl = Unqual!T;
    else
        alias DeducedParameterTypeImpl = T;
}

@safe unittest
{
    static assert(is(DeducedParameterType!(const(int)) == const(int)));
    static assert(is(DeducedParameterType!(const(int[2])) == const(int[2])));

    static assert(is(DeducedParameterType!(const(int*)) == const(int)*));
    static assert(is(DeducedParameterType!(const(int[])) == const(int)[]));
}

@safe unittest
{
    static struct NoCopy
    {
        @disable this(this);
    }

    static assert(is(DeducedParameterType!NoCopy == NoCopy));
    static assert(is(DeducedParameterType!(inout(NoCopy)) == inout(NoCopy)));
}

@safe unittest
{
    static assert(is(DeducedParameterType!(inout(int[])) == inout(int)[]));
}

private auto dip1000Test(int x) {return *&x;}
// We don't use isSafe, because betterC client code needs to instantiate
// core.internal.array.comparison.__cmp in the client side. isSafe uses
// __cmp of two strings, so using it would instantate that here instead. That
// won't do because betterC compilations do not link the Phobos binary in.
package(std) enum dip1000Enabled
    = is(typeof(&dip1000Test) : int function(int) @safe);
