124 lines
3.0 KiB
D
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;
|