124 lines
3.0 KiB
D

module core.internal.traits;
alias AliasSeq(T...) = T;
template allSatisfy(alias F, T...)
{
static foreach (Ti; T)
{
static if (!is(typeof(allSatisfy) == bool) && // not yet defined
!F!(Ti))
{
enum allSatisfy = false;
}
}
static if (!is(typeof(allSatisfy) == bool)) // if not yet defined
{
enum allSatisfy = true;
}
}
template Unqual(T : const U, U)
{
static if (is(U == shared V, V))
alias Unqual = V;
else
alias Unqual = U;
}
alias Unconst(T : const U, U) = U;
template hasElaborateMove(S)
{
static if (__traits(isStaticArray, S))
{
enum bool hasElaborateMove = S.sizeof && hasElaborateMove!(BaseElemOf!S);
}
else static if (is(S == struct))
{
enum hasElaborateMove = (is(typeof(S.init.opPostMove(lvalueOf!S))) &&
!is(typeof(S.init.opPostMove(rvalueOf!S)))) ||
anySatisfy!(.hasElaborateMove, Fields!S);
}
else
{
enum bool hasElaborateMove = false;
}
}
template substInout(T)
{
static if (is(T == immutable))
{
alias substInout = T;
}
else static if (is(T : shared const U, U) || is(T : const U, U))
{
// U is top-unqualified
mixin("alias substInout = "
~ (is(T == shared) ? "shared " : "")
~ (is(T == const) || is(T == inout) ? "const " : "") // substitute inout to const
~ "substInoutForm!U;");
}
else
static assert(0);
}
template anySatisfy(alias F, Ts...)
{
static foreach (T; Ts)
{
static if (!is(typeof(anySatisfy) == bool) && // not yet defined
F!T)
{
enum anySatisfy = true;
}
}
static if (!is(typeof(anySatisfy) == bool)) // if not yet defined
{
enum anySatisfy = false;
}
}
template hasElaborateCopyConstructor(S)
{
static if (__traits(isStaticArray, S))
{
enum bool hasElaborateCopyConstructor = S.sizeof && hasElaborateCopyConstructor!(BaseElemOf!S);
}
else static if (is(S == struct))
{
enum hasElaborateCopyConstructor = __traits(hasCopyConstructor, S) || __traits(hasPostblit, S);
}
else
{
enum bool hasElaborateCopyConstructor = false;
}
}
template hasElaborateDestructor(S)
{
static if (__traits(isStaticArray, S))
{
enum bool hasElaborateDestructor = S.sizeof && hasElaborateDestructor!(BaseElemOf!S);
}
else static if (is(S == struct))
{
// Once https://issues.dlang.org/show_bug.cgi?id=24865 is fixed, then
// this should be the implementation, but until that's fixed, we need the
// uncommented code.
// enum hasElaborateDestructor = __traits(hasMember, S, "__xdtor");
enum hasElaborateDestructor = hasDtor([__traits(allMembers, S)]);
}
else
{
enum bool hasElaborateDestructor = false;
}
}
enum bool isAggregateType(T) = is(T == struct) || is(T == union) ||
is(T == class) || is(T == interface);
enum bool isPointer(T) = is(T == U*, U) && !isAggregateType!T;