95 lines
3.0 KiB
D
95 lines
3.0 KiB
D
module std.traits;
|
|
|
|
public import core.internal.traits;
|
|
|
|
enum bool isFloatingPoint(T) = __traits(isFloating, T) && is(T : real);
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
enum bool isSigned(T) = __traits(isArithmetic, T) && !__traits(isUnsigned, T)
|
|
&& is(T : real);
|
|
|
|
enum hasMember(T, string name) = __traits(hasMember, T, name);
|
|
|
|
enum bool isArray(T) = isStaticArray!T || isDynamicArray!T;
|
|
|
|
enum bool isStaticArray(T) = __traits(isStaticArray, T);
|
|
|
|
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;
|
|
}
|
|
|
|
enum isAssignable(Lhs, Rhs = Lhs) = isRvalueAssignable!(Lhs, Rhs) && isLvalueAssignable!(Lhs, Rhs);
|
|
|
|
enum isRvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, { lvalueOf!Lhs = rvalueOf!Rhs; });
|
|
|
|
enum isLvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, { lvalueOf!Lhs = lvalueOf!Rhs; });
|
|
|
|
enum bool isInstanceOf(alias S, T) = is(T == S!Args, Args...);
|
|
|
|
template isInstanceOf(alias S, alias T)
|
|
{
|
|
enum impl(alias T : S!Args, Args...) = true;
|
|
enum impl(alias T) = false;
|
|
enum isInstanceOf = impl!T;
|
|
}
|
|
|
|
import core.internal.traits : CoreUnqual = Unqual;
|
|
alias Unqual = CoreUnqual;
|
|
|
|
@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
|
|
|
|
@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
|
|
|
|
enum bool isIterable(T) = is(typeof({ foreach (elem; T.init) {} }));
|
|
|
|
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);
|
|
}
|
|
|
|
enum bool isSomeString(T) = is(immutable T == immutable C[], C) && (is(C == char) || is(C == wchar) || is(C == dchar));
|
|
|
|
template Select(bool condition, T...)
|
|
if (T.length == 2)
|
|
{
|
|
import std.meta : Alias;
|
|
alias Select = Alias!(T[!condition]);
|
|
}
|
|
|