diff --git a/meta/tanya/meta/metafunction.d b/meta/tanya/meta/metafunction.d index 248cd0e..ef4acfb 100644 --- a/meta/tanya/meta/metafunction.d +++ b/meta/tanya/meta/metafunction.d @@ -18,7 +18,7 @@ */ module tanya.meta.metafunction; -import std.traits : Unqual; +import std.traits : Unqual, isInstanceOf, isMutable, isTypeTuple, isUnsigned, isSigned, isIntegral; import std.meta : NoDuplicates; import tanya.meta.trait; diff --git a/meta/tanya/meta/trait.d b/meta/tanya/meta/trait.d index 537952f..243c123 100644 --- a/meta/tanya/meta/trait.d +++ b/meta/tanya/meta/trait.d @@ -17,32 +17,25 @@ */ module tanya.meta.trait; -import std.traits : OriginalType, Unqual; +import std.traits : OriginalType, Unqual, isStaticArray, isUnsigned; import tanya.meta.metafunction; /** * Determines whether $(D_PARAM T) is a wide string, i.e. consists of * $(D_KEYWORD dchar). * - * The character type of the string can be qualified with $(D_KEYWORD const), - * $(D_KEYWORD immutable) or $(D_KEYWORD inout), but an occurrence of - * $(D_KEYWORD shared) in the character type results in returning - * $(D_KEYWORD false). - * The string itself (in contrast to its character type) can have any type + * The character type of the string and the string itself can have any type * qualifiers. * - * Static $(D_KEYWORD char) and $(D_KEYWORD wchar) arrays are not considered - * strings. + * Static $(D_KEYWORD dchar) arrays are not considered strings. * * Params: - * T = A Type. + * T = A type. * * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a wide string, * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isNarrowString). */ -enum bool isWideString(T) = is(T : const dchar[]) && !isStaticArray!T; +enum bool isWideString(T) = is(immutable T == immutable dchar[]); /// @nogc nothrow pure @safe unittest @@ -65,8 +58,8 @@ enum bool isWideString(T) = is(T : const dchar[]) && !isStaticArray!T; static assert(isWideString!(const(dchar)[])); static assert(isWideString!(inout(dchar)[])); - static assert(!isWideString!(shared(const(dchar))[])); - static assert(!isWideString!(shared(dchar)[])); + static assert(isWideString!(shared(const(dchar))[])); + static assert(isWideString!(shared(dchar)[])); static assert(!isWideString!(dchar[10])); } @@ -104,1534 +97,6 @@ enum bool isPolymorphicType(T) = is(T == class) || is(T == interface); static assert(!isPolymorphicType!short); } -/** - * Determines whether the type $(D_PARAM T) has a static method - * named $(D_PARAM member). - * - * Params: - * T = Aggregate type. - * member = Symbol name. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM member) is a static method of - * $(D_PARAM T), $(D_KEYWORD false) otherwise. - */ -template hasStaticMember(T, string member) -{ - static if (hasMember!(T, member)) - { - alias Member = Alias!(__traits(getMember, T, member)); - - static if (__traits(isStaticFunction, Member) - || (!isFunction!Member && is(typeof(&Member)))) - { - enum bool hasStaticMember = true; - } - else - { - enum bool hasStaticMember = false; - } - } - else - { - enum bool hasStaticMember = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static struct S - { - int member1; - void member2() - { - } - static int member3; - static void member4() - { - } - static void function() member5; - } - static assert(!hasStaticMember!(S, "member1")); - static assert(!hasStaticMember!(S, "member2")); - static assert(hasStaticMember!(S, "member3")); - static assert(hasStaticMember!(S, "member4")); - static assert(hasStaticMember!(S, "member5")); -} - -/** - * Determines whether $(D_PARAM T) is a floating point type. - * - * Floating point types are: - * $(UL - * $(LI float) - * $(LI double) - * $(LI real) - * ) - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a floating point type, - * $(D_KEYWORD false) otherwise. - */ -enum bool isFloatingPoint(T) = is(Unqual!(OriginalType!T) == double) - || is(Unqual!(OriginalType!T) == float) - || is(Unqual!(OriginalType!T) == real); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isFloatingPoint!float); - static assert(isFloatingPoint!double); - static assert(isFloatingPoint!real); - static assert(isFloatingPoint!(const float)); - static assert(isFloatingPoint!(shared float)); - static assert(isFloatingPoint!(shared const float)); - static assert(!isFloatingPoint!int); -} - -/** - * Determines whether $(D_PARAM T) is a signed numeric type. - * - * Signed numeric types are: - * $(UL - * $(LI byte) - * $(LI short) - * $(LI int) - * $(LI long) - * $(LI float) - * $(LI double) - * $(LI real) - * ) - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a signed numeric type, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isUnsigned). - */ -enum bool isSigned(T) = is(Unqual!(OriginalType!T) == byte) - || is(Unqual!(OriginalType!T) == short) - || is(Unqual!(OriginalType!T) == int) - || is(Unqual!(OriginalType!T) == long) - || isFloatingPoint!T; - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isSigned!byte); - static assert(isSigned!short); - static assert(isSigned!int); - static assert(isSigned!long); - static assert(isSigned!float); - static assert(isSigned!double); - static assert(isSigned!real); - - static assert(!isSigned!ubyte); - static assert(!isSigned!ushort); - static assert(!isSigned!uint); - static assert(!isSigned!ulong); -} - -/** - * Determines whether $(D_PARAM T) is an unsigned numeric type. - * - * Unsigned numeric types are: - * $(UL - * $(LI ubyte) - * $(LI ushort) - * $(LI uint) - * $(LI ulong) - * ) - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is an unsigned numeric type, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isSigned). - */ -enum bool isUnsigned(T) = is(Unqual!(OriginalType!T) == ubyte) - || is(Unqual!(OriginalType!T) == ushort) - || is(Unqual!(OriginalType!T) == uint) - || is(Unqual!(OriginalType!T) == ulong); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isUnsigned!ubyte); - static assert(isUnsigned!ushort); - static assert(isUnsigned!uint); - static assert(isUnsigned!ulong); - - static assert(!isUnsigned!byte); - static assert(!isUnsigned!short); - static assert(!isUnsigned!int); - static assert(!isUnsigned!long); - static assert(!isUnsigned!float); - static assert(!isUnsigned!double); - static assert(!isUnsigned!real); -} - -/** - * Determines whether $(D_PARAM T) is an integral type. - * - * Integral types are: - * $(UL - * $(LI ubyte) - * $(LI ushort) - * $(LI uint) - * $(LI ulong) - * $(LI byte) - * $(LI short) - * $(LI int) - * $(LI long) - * ) - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is an integral type, - * $(D_KEYWORD false) otherwise. - */ -enum bool isIntegral(T) = isUnsigned!T - || is(Unqual!(OriginalType!T) == byte) - || is(Unqual!(OriginalType!T) == short) - || is(Unqual!(OriginalType!T) == int) - || is(Unqual!(OriginalType!T) == long); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isIntegral!ubyte); - static assert(isIntegral!byte); - static assert(!isIntegral!float); -} - -/** - * Determines whether $(D_PARAM T) is a boolean type, i.e. $(D_KEYWORD bool). - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a boolean type, - * $(D_KEYWORD false) otherwise. - */ -enum bool isBoolean(T) = is(Unqual!(OriginalType!T) == bool); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isBoolean!bool); - static assert(isBoolean!(shared const bool)); - static assert(!isBoolean!(ubyte)); - static assert(!isBoolean!(byte)); - - enum E : bool - { - t = true, - f = false, - } - static assert(isBoolean!E); - - static struct S1 - { - bool b; - alias b this; - } - static assert(!isBoolean!S1); - - static struct S2 - { - bool opCast(T : bool)() - { - return true; - } - } - static assert(!isBoolean!S2); -} - -/** - * Determines whether $(D_PARAM T) is a character type. - * - * Character types are: - * - * $(UL - * $(LI char) - * $(LI wchar) - * $(LI dchar) - * ) - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a character type, - * $(D_KEYWORD false) otherwise. - */ -enum bool isSomeChar(T) = is(Unqual!(OriginalType!T) == char) - || is(Unqual!(OriginalType!T) == wchar) - || is(Unqual!(OriginalType!T) == dchar); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isSomeChar!char); - static assert(isSomeChar!wchar); - static assert(isSomeChar!dchar); - - static assert(!isSomeChar!byte); - static assert(!isSomeChar!ubyte); - static assert(!isSomeChar!short); - static assert(!isSomeChar!ushort); - static assert(!isSomeChar!int); - static assert(!isSomeChar!uint); -} - -/** - * Determines whether $(D_PARAM T) is a pointer type. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a pointer type, - * $(D_KEYWORD false) otherwise. - */ -template isPointer(T) -{ - static if (is(T U : U*)) - { - enum bool isPointer = !is(Unqual!(OriginalType!T) == typeof(null)); - } - else - { - enum bool isPointer = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isPointer!(bool*)); - static assert(isPointer!(const bool*)); - static assert(isPointer!(const shared bool*)); - static assert(!isPointer!bool); -} - -/** - * Determines whether $(D_PARAM T) is an array type (dynamic or static, but - * not an associative one). - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is an array type, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isAssociativeArray). - */ -template isArray(T) -{ - static if (is(T U : U[])) - { - enum bool isArray = true; - } - else - { - enum bool isArray = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isArray!(bool[])); - static assert(isArray!(const bool[])); - static assert(isArray!(shared bool[])); - static assert(isArray!(bool[8])); - static assert(!isArray!bool); - static assert(!isArray!(bool[string])); -} - -/** - * Determines whether $(D_PARAM T) is a static array type. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a static array type, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isArray). - */ -template isStaticArray(T) -{ - static if (is(T U : U[L], size_t L)) - { - enum bool isStaticArray = true; - } - else - { - enum bool isStaticArray = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isStaticArray!(bool[8])); - static assert(isStaticArray!(const bool[8])); - static assert(isStaticArray!(shared bool[8])); - static assert(!isStaticArray!(bool[])); - static assert(!isStaticArray!bool); - static assert(!isStaticArray!(bool[string])); -} - -/** - * Determines whether $(D_PARAM T) is a dynamic array type. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a dynamic array type, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isArray). - */ -enum bool isDynamicArray(T) = isArray!T && !isStaticArray!T; - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isDynamicArray!(bool[])); - static assert(isDynamicArray!(const bool[])); - static assert(isDynamicArray!(shared bool[])); - static assert(!isDynamicArray!(bool[8])); - static assert(!isDynamicArray!bool); - static assert(!isDynamicArray!(bool[string])); -} - -/** - * Determines whether $(D_PARAM T) is an associative array type. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is an associative array type, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isArray). - */ -template isAssociativeArray(T) -{ - static if (is(T U : U[L], L)) - { - enum bool isAssociativeArray = true; - } - else - { - enum bool isAssociativeArray = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isAssociativeArray!(bool[string])); - static assert(isAssociativeArray!(const bool[string])); - static assert(isAssociativeArray!(shared const bool[string])); - static assert(!isAssociativeArray!(bool[])); - static assert(!isAssociativeArray!(bool[8])); - static assert(!isAssociativeArray!bool); -} - -/** - * Determines whether $(D_PARAM T) is an aggregate type. - * - * Aggregate types are: - * - * $(UL - * $(LI $(D_KEYWORD struct)s) - * $(LI $(D_KEYWORD class)es) - * $(LI $(D_KEYWORD interface)s) - * $(LI $(D_KEYWORD union)s) - * ) - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is an aggregate type, - * $(D_KEYWORD false) otherwise. - */ -enum bool isAggregateType(T) = is(T == struct) - || is(T == class) - || is(T == interface) - || is(T == union); - -/// -@nogc nothrow pure @safe unittest -{ - static struct S; - class C; - interface I; - union U; - enum E; - - static assert(isAggregateType!S); - static assert(isAggregateType!C); - static assert(isAggregateType!I); - static assert(isAggregateType!U); - static assert(!isAggregateType!E); - static assert(!isAggregateType!void); -} - -/** - * Determines whether $(D_PARAM T) is a narrow string, i.e. consists of - * $(D_KEYWORD char) or $(D_KEYWORD wchar). - * - * The character type of the string can be qualified with $(D_KEYWORD const), - * $(D_KEYWORD immutable) or $(D_KEYWORD inout), but an occurrence of - * $(D_KEYWORD shared) in the character type results in returning - * $(D_KEYWORD false). - * The string itself (in contrast to its character type) can have any type - * qualifiers. - * - * Static $(D_KEYWORD char) and $(D_KEYWORD wchar) arrays are not considered - * strings. - * - * Params: - * T = A Type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a narrow string, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isWideString). - */ -enum bool isNarrowString(T) = (is(T : const char[]) || is (T : const wchar[])) - && !isStaticArray!T; - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isNarrowString!(char[])); - static assert(isNarrowString!(wchar[])); - static assert(!isNarrowString!(dchar[])); - - static assert(isNarrowString!string); - static assert(isNarrowString!wstring); - static assert(!isNarrowString!dstring); - - static assert(isNarrowString!(const string)); - static assert(isNarrowString!(const wstring)); - static assert(!isNarrowString!(const dstring)); - - static assert(isNarrowString!(shared string)); - static assert(isNarrowString!(shared wstring)); - static assert(!isNarrowString!(shared dstring)); - - static assert(isNarrowString!(const(char)[])); - static assert(isNarrowString!(inout(char)[])); - static assert(!isNarrowString!(shared(const(char))[])); - static assert(!isNarrowString!(shared(char)[])); - static assert(!isNarrowString!(char[10])); -} - -/** - * Determines whether $(D_PARAM T) is a string, i.e. consists of - * $(D_KEYWORD char), $(D_KEYWORD wchar) or $(D_KEYWORD dchar). - * - * The character type of the string can be qualified with $(D_KEYWORD const), - * $(D_KEYWORD immutable) or $(D_KEYWORD inout), but an occurrence of - * $(D_KEYWORD shared) in the character type results in returning - * $(D_KEYWORD false). - * The string itself (in contrast to its character type) can have any type - * qualifiers. - * - * Static character arrays are not considered strings. - * - * Params: - * T = A Type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a string, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isNarrowString), $(D_PSYMBOL isWideString). - */ -enum bool isSomeString(T) = isNarrowString!T || isWideString!T; - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isSomeString!(dchar[])); - static assert(isSomeString!(char[])); - static assert(isSomeString!(wchar[])); - - static assert(isSomeString!dstring); - static assert(isSomeString!string); - static assert(isSomeString!wstring); - - static assert(isSomeString!(const dstring)); - static assert(isSomeString!(const string)); - static assert(isSomeString!(const wstring)); - - static assert(isSomeString!(shared dstring)); - static assert(isSomeString!(shared string)); - static assert(isSomeString!(shared wstring)); - - static assert(isSomeString!(const(char)[])); - static assert(isSomeString!(inout(char)[])); - static assert(!isSomeString!(shared(const(char))[])); - static assert(!isSomeString!(shared(char)[])); - static assert(!isSomeString!(char[10])); -} - -/** - * Determines whether the type $(D_PARAM T) is copyable. - * - * Only structs can be not copyable if their postblit constructor or the - * postblit constructor of one of its fields is disabled, i.e. annotated with - * $(D_KEYWORD @disable). - * - * Params: - * T = A type. - * - * Returns: $(D_PARAM true) if $(D_PARAM T) can be copied, - * $(D_PARAM false) otherwise. - */ -enum bool isCopyable(T) = is(typeof({ T s1 = T.init; T s2 = s1; })); - -/// -@nogc nothrow pure @safe unittest -{ - static struct S1 - { - } - static struct S2 - { - this(this) - { - } - } - static struct S3 - { - @disable this(this); - } - static struct S4 - { - S3 s; - } - class C - { - } - - static assert(isCopyable!S1); - static assert(isCopyable!S2); - static assert(!isCopyable!S3); - static assert(!isCopyable!S4); - - static assert(isCopyable!C); - static assert(isCopyable!bool); -} - -/** - * Determines whether $(D_PARAM T) is an abstract class. - * - * Abstract class is a class marked as such or a class that has any abstract - * methods or doesn't implement all methods of abstract base classes. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is an abstract class, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isAbstractFunction). - */ -enum bool isAbstractClass(T) = __traits(isAbstractClass, T); - -/// -@nogc nothrow pure @safe unittest -{ - class A - { - } - abstract class B - { - } - class C - { - abstract void func(); - } - class D : C - { - } - class E : C - { - override void func() - { - } - } - static assert(!isAbstractClass!A); - static assert(isAbstractClass!B); - static assert(isAbstractClass!C); - static assert(isAbstractClass!D); - static assert(!isAbstractClass!E); -} - -/** - * Checks whether $(D_PARAM T) is a type, same as `is(T)` does. - * - * Params: - * T = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a type, $(D_KEYWORD false) - * otherwise. - */ -enum bool isType(alias T) = is(T); - -/// ditto -enum bool isType(T) = true; - -/** - * Determines whether $(D_PARAM Args) contains only types. - * - * Params: - * Args = Alias sequence. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM Args) consists only of types, - * $(D_KEYWORD false) otherwise. - */ -enum bool isTypeTuple(Args...) = allSatisfy!(isType, Args); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isTypeTuple!(int, uint, Object)); - static assert(isTypeTuple!()); - static assert(!isTypeTuple!(int, 8, Object)); - static assert(!isTypeTuple!(5, 8, 2)); - - class C - { - } - enum E : bool - { - t, - f, - } - union U - { - } - static struct T() - { - } - - static assert(isTypeTuple!C); - static assert(isTypeTuple!E); - static assert(isTypeTuple!U); - static assert(isTypeTuple!void); - static assert(isTypeTuple!int); - static assert(!isTypeTuple!T); - static assert(isTypeTuple!(T!())); - static assert(!isTypeTuple!5); - static assert(!isTypeTuple!(tanya.meta.trait)); -} - -/** - * Tells whether $(D_PARAM Args) contains only expressions. - * - * An expression is determined by applying $(D_KEYWORD typeof) to an argument: - * - * --- - * static if (is(typeof(Args[i]))) - * { - * // Args[i] is an expression. - * } - * else - * { - * // Args[i] is not an expression. - * } - * --- - * - * Params: - * Args = Alias sequence. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM Args) consists only of expressions, - * $(D_KEYWORD false) otherwise. - */ -template isExpressions(Args...) -{ - static if (Args.length == 0) - { - enum bool isExpressions = true; - } - else static if (is(typeof(Args[0]) U)) - { - enum bool isExpressions = !is(U == void) - && isExpressions!(Args[1 .. $]); - } - else - { - enum bool isExpressions = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isExpressions!(5, 8, 2)); - static assert(isExpressions!()); - static assert(!isExpressions!(int, uint, Object)); - static assert(!isExpressions!(int, 8, Object)); - - template T(U) - { - } - static assert(!isExpressions!T); -} - -/** - * Determines whether $(D_PARAM T) is a final class. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a final class, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isFinalFunction). - */ -enum bool isFinalClass(T) = __traits(isFinalClass, T); - -/// -@nogc nothrow pure @safe unittest -{ - final class A - { - } - class B - { - } - - static assert(isFinalClass!A); - static assert(!isFinalClass!B); -} - -/** - * Determines whether $(D_PARAM T) is an abstract method. - * - * Params: - * F = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM F) is an abstract method, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isAbstractClass). - */ -enum bool isAbstractFunction(alias F) = __traits(isAbstractFunction, F); - -/// -@nogc nothrow pure @safe unittest -{ - class A - { - void func() - { - } - } - class B - { - abstract void func(); - } - class C : B - { - override void func() - { - } - } - static assert(!isAbstractFunction!(A.func)); - static assert(isAbstractFunction!(B.func)); - static assert(!isAbstractFunction!(C.func)); -} - -/** - * Determines whether $(D_PARAM T) is a final method. - * - * Params: - * F = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM F) is a final method, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isFinalClass). - */ -enum bool isFinalFunction(alias F) = __traits(isFinalFunction, F); - -/// -@nogc nothrow pure @safe unittest -{ - class A - { - void virtualFunc() - { - } - final void finalFunc() - { - } - } - - static assert(isFinalFunction!(A.finalFunc)); - static assert(!isFinalFunction!(A.virtualFunc)); -} - -/** - * Function pointer is a pointer to a function. So a simple function is not - * a function pointer, but getting the address of such function returns a - * function pointer. - * - * A function pointer doesn't save the context pointer, thus cannot have access - * to its outer scope. - * - * Params: - * F = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM F) is a function pointer, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(LINK2 http://dlang.org/spec/function.html#closures, - * Delegates, Function Pointers, and Closures). - */ -template isFunctionPointer(F...) -if (F.length == 1) -{ - static if ((is(typeof(F[0]) T : T*) && is(T == function)) - || (is(F[0] T : T*) && is(T == function))) - { - enum bool isFunctionPointer = true; - } - else - { - enum bool isFunctionPointer = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isFunctionPointer!(void function())); - static assert(!isFunctionPointer!(void delegate())); - - static assert(isFunctionPointer!(() {})); - - void func() - { - } - static void staticFunc() - { - } - interface I - { - @property int prop(); - } - - static assert(!isFunctionPointer!func); - static assert(!isFunctionPointer!staticFunc); - - auto functionPointer = &staticFunc; - auto dg = &func; - - static assert(isFunctionPointer!functionPointer); - static assert(!isFunctionPointer!dg); - - static assert(!isFunctionPointer!(I.prop)); -} - -/** - * Delegate stores the function pointer and function context. - * - * Params: - * F = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM F) is a delegate, - * $(D_KEYWORD false) delegate. - * - * See_Also: $(LINK2 http://dlang.org/spec/function.html#closures, - * Delegates, Function Pointers, and Closures). - */ -template isDelegate(F...) -if (F.length == 1) -{ - static if (is(F[0] == delegate) - || is(typeof(F[0]) == delegate)) - { - enum bool isDelegate = true; - } - else - { - enum bool isDelegate = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isDelegate!(void delegate())); - static assert(!isDelegate!(void function())); - - static assert(!isDelegate!(() {})); - - void func() - { - } - static void staticFunc() - { - } - interface I - { - @property int prop(); - } - - static assert(!isDelegate!func); - static assert(!isDelegate!staticFunc); - - auto functionPointer = &staticFunc; - auto dg = &func; - - static assert(!isDelegate!functionPointer); - static assert(isDelegate!dg); - - static assert(!isDelegate!(I.prop)); -} - -/** - * $(D_PSYMBOL isFunction) returns $(D_KEYWORD true) only for plain functions, - * not function pointers or delegates. Use $(D_PSYMBOL isFunctionPointer) or - * $(D_PSYMBOL isDelegate) to detect them or $(D_PSYMBOL isSomeFunction) - * for detecting a function of any type. - * - * Params: - * F = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM F) is a function, - * $(D_KEYWORD false) otherwise. - * - * See_Also: $(LINK2 http://dlang.org/spec/function.html#closures, - * Delegates, Function Pointers, and Closures). - */ -template isFunction(F...) -if (F.length == 1) -{ - static if (is(F[0] == function) - || is(typeof(&F[0]) T == delegate) - || (is(typeof(&F[0]) T : T*) && is(T == function))) - { - enum bool isFunction = true; - } - else - { - enum bool isFunction = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(!isFunction!(void function())); - static assert(!isFunction!(() {})); - static assert(!isFunction!(void delegate())); - - void func() - { - } - static void staticFunc() - { - } - interface I - { - @property int prop(); - } - - static assert(isFunction!func); - static assert(isFunction!staticFunc); - - auto functionPointer = &staticFunc; - auto dg = &func; - - static assert(!isFunction!functionPointer); - static assert(!isFunction!dg); - - static assert(isFunction!(I.prop)); -} - -/** - * Params: - * F = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM F) is a function, function pointer - * or delegate, $(D_KEYWORD false) otherwise. - * - * See_Also: $(D_PSYMBOL isFunction), - * $(D_PSYMBOL isDelegate), - * $(D_PSYMBOL isFunctionPointer). - */ -template isSomeFunction(F...) -if (F.length == 1) -{ - enum bool isSomeFunction = isFunctionPointer!F - || isFunction!F - || isDelegate!F; -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isSomeFunction!(void function())); - static assert(isSomeFunction!(() {})); - static assert(isSomeFunction!(void delegate())); - - void func() - { - } - static void staticFunc() - { - } - - static assert(isSomeFunction!func); - static assert(isSomeFunction!staticFunc); - - auto functionPointer = &staticFunc; - auto dg = &func; - - static assert(isSomeFunction!functionPointer); - static assert(isSomeFunction!dg); - - static assert(!isSomeFunction!int); -} - -/** - * Params: - * F = A symbol. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM F) is callable, - * $(D_KEYWORD false) otherwise. - */ -template isCallable(F...) -if (F.length == 1) -{ - static if (isSomeFunction!F - || (is(typeof(F[0].opCall)) && isFunction!(F[0].opCall))) - { - enum bool isCallable = true; - } - else - { - enum bool isCallable = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static struct S - { - void opCall() - { - } - } - class C - { - static void opCall() - { - } - } - interface I - { - } - S s; - - static assert(isCallable!s); - static assert(isCallable!C); - static assert(isCallable!S); - static assert(!isCallable!I); -} - -/** - * Determines whether $(D_PARAM T) defines a symbol $(D_PARAM member). - * - * Params: - * T = Aggregate type. - * member = Symbol name. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) defines a symbol - * $(D_PARAM member), $(D_KEYWORD false) otherwise. - */ -enum bool hasMember(T, string member) = __traits(hasMember, T, member); - -/// -@nogc nothrow pure @safe unittest -{ - static struct S - { - int member1; - void member2() - { - } - static int member3; - static void member4() - { - } - } - static assert(hasMember!(S, "member1")); - static assert(hasMember!(S, "member2")); - static assert(hasMember!(S, "member3")); - static assert(hasMember!(S, "member4")); - static assert(!hasMember!(S, "member6")); -} - -/** - * Determines whether $(D_PARAM T) is mutable, i.e. has one of the following - * qualifiers or a combination of them: - * - * $(UL - * $(LI $(D_KEYWORD const)) - * $(LI $(D_KEYWORD immutable)) - * $(LI $(D_KEYWORD const)) - * ) - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) is mutable, - * $(D_KEYWORD false) otherwise. - */ -template isMutable(T) -{ - static if (is(T U == const U) - || is(T U == inout U) - || is(T U == inout const U) - || is(T U == immutable U) - || is(T U == shared const U) - || is(T U == shared inout U) - || is(T U == shared inout const U)) - { - enum bool isMutable = false; - } - else - { - enum bool isMutable = true; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static struct S - { - void method() - { - static assert(isMutable!(typeof(this))); - } - - void method() inout - { - static assert(!isMutable!(typeof(this))); - } - - void immMethod() const - { - static assert(!isMutable!(typeof(this))); - } - void immMethod() immutable - { - static assert(!isMutable!(typeof(this))); - } - } -} - -/** - * Determines whether $(D_PARAM T) is a nested type, i.e. $(D_KEYWORD class), - * $(D_KEYWORD struct) or $(D_KEYWORD union), which internally stores a context - * pointer. - * - * Params: - * T = $(D_KEYWORD class), $(D_KEYWORD struct) or $(D_KEYWORD union) type. - * - * Returns: $(D_KEYWORD true) if the argument is a nested type which internally - * stores a context pointer, $(D_KEYWORD false) otherwise. - */ -template isNested(T) -if (is(T == class) || is(T == struct) || is(T == union)) -{ - enum bool isNested = __traits(isNested, T); -} - -/// -@nogc pure nothrow @safe unittest -{ - static struct S - { - } - static assert(!isNested!S); - - class C - { - void method() - { - } - } - static assert(isNested!C); -} - -/** - * Determines whether $(D_PARAM T) is a nested function. - * - * Params: - * F = A function. - * - * Returns $(D_KEYWORD true) if the $(D_PARAM T) is a nested function, - * $(D_KEYWORD false) otherwise. - */ -enum bool isNestedFunction(alias F) = __traits(isNested, F); - -/// -@nogc nothrow pure @safe unittest -{ - void func() - { - void nestedFunc() - { - } - static assert(isNestedFunction!nestedFunc); - } -} - -/** - * Determines the type of the callable $(D_PARAM F). - * - * Params: - * F = A function. - * - * Returns: Type of the function $(D_PARAM F). - */ -template FunctionTypeOf(F...) -if (isCallable!F) -{ - static if ((is(typeof(F[0]) T : T*) && is(T == function)) - || (is(F[0] T : T*) && is(T == function)) - || is(F[0] T == delegate) - || is(typeof(F[0]) T == delegate) - || is(F[0] T == function) - || is(typeof(&F[0]) T == delegate) - || (is(typeof(&F[0]) T : T*) && is(T == function))) - { - alias FunctionTypeOf = T; - } - else - { - alias FunctionTypeOf = FunctionTypeOf!(F[0].opCall); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(FunctionTypeOf!(void function()) == function)); - static assert(is(FunctionTypeOf!(() {}) == function)); -} - -/** - * Determines the return type of the callable $(D_PARAM F). - * - * Params: - * F = A callable object. - * - * Returns: Return type of $(D_PARAM F). - */ -template ReturnType(F...) -if (isCallable!F) -{ - static if (is(FunctionTypeOf!(F[0]) T == return)) - { - alias ReturnType = T; - } - else - { - static assert(false, "Argument is not a callable"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(ReturnType!(int delegate()) == int)); - static assert(is(ReturnType!(bool function()) == bool)); -} - -/** - * Determines the template $(D_PARAM T) is an instance of. - * - * Params: - * T = Template instance. - * - * Returns: Template $(D_PARAM T) is an instance of. - */ -alias TemplateOf(alias T : Base!Args, alias Base, Args...) = Base; - -/// -@nogc nothrow pure @safe unittest -{ - static struct S(T) - { - } - static assert(__traits(isSame, TemplateOf!(S!int), S)); - - static void func(T)() - { - } - static assert(__traits(isSame, TemplateOf!(func!int), func)); - - template T(U) - { - } - static assert(__traits(isSame, TemplateOf!(T!int), T)); -} - -/** - * Returns the mangled name of the symbol $(D_PARAM T). - * - * Params: - * T = A symbol. - * - * Returns: Mangled name of $(D_PARAM T). - */ -enum string mangledName(T) = T.mangleof; - -/// -enum string mangledName(alias T) = T.mangleof; - -/** - * Tests whether $(D_PARAM I) is an instance of template $(D_PARAM T). - * - * Params: - * T = Template. - * I = Template instance. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM I) is an instance of $(D_PARAM T), - * $(D_KEYWORD false) otherwise. - */ -enum bool isInstanceOf(alias T, I) = is(I == T!Args, Args...); - -template isInstanceOf(alias T, alias I) -{ - static if (is(typeof(TemplateOf!I))) - { - enum bool isInstanceOf = __traits(isSame, TemplateOf!I, T); - } - else - { - enum bool isInstanceOf = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static struct S(T) - { - } - static assert(isInstanceOf!(S, S!int)); - - static void func(T)(); - static assert(isInstanceOf!(func, func!int)); - - template T(U) - { - } - static assert(isInstanceOf!(T, T!int)); -} - -/** - * Checks whether $(D_PARAM From) is implicitly (without explicit - * $(D_KEYWORD cast)) to $(D_PARAM To). - * - * Params: - * From = Source type. - * To = Conversion target type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM From) is implicitly convertible to - * $(D_PARAM To), $(D_KEYWORD false) if not. - */ -enum bool isImplicitlyConvertible(From, To) = is(From : To); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isImplicitlyConvertible!(const(byte), byte)); - static assert(isImplicitlyConvertible!(byte, char)); - static assert(isImplicitlyConvertible!(byte, short)); - static assert(!isImplicitlyConvertible!(short, byte)); - static assert(isImplicitlyConvertible!(string, const(char)[])); -} - -/** - * Tests whether a value of type $(D_PARAM Rhs) can be assigned to a variable - * of type $(D_PARAM Lhs). - * - * If $(D_PARAM Rhs) isn't specified, $(D_PSYMBOL isAssignable) tests whether a - * value of type $(D_PARAM Lhs) can be assigned to a variable of the same type. - * - * $(D_PSYMBOL isAssignable) tells whether $(D_PARAM Rhs) can be assigned by - * value as well by reference. - * - * Params: - * Lhs = Variable type. - * Rhs = Expression type. - * - * Returns: $(D_KEYWORD true) if a value of type $(D_PARAM Rhs) can be assigned - * to a variable of type $(D_PARAM Lhs), $(D_KEYWORD false) otherwise. - */ -template isAssignable(Lhs, Rhs = Lhs) -{ - enum bool isAssignable = is(typeof({ - Lhs lhs = Lhs.init; - Rhs rhs = Rhs.init; - lhs = ((inout ref Rhs) => Rhs.init)(rhs); - })); -} - -/// -@nogc nothrow pure @safe unittest -{ - static struct S1 - { - @disable this(); - @disable this(this); - } - static struct S2 - { - void opAssign(S1 s) pure nothrow @safe @nogc - { - } - } - static struct S3 - { - void opAssign(ref S1 s) pure nothrow @safe @nogc - { - } - } - static assert(isAssignable!(S2, S1)); - static assert(!isAssignable!(S3, S1)); - - static assert(isAssignable!(const(char)[], string)); - static assert(!isAssignable!(string, char[])); - - static assert(isAssignable!int); - static assert(!isAssignable!(const int, int)); -} - /** * Returns the size in bytes of the state that needs to be allocated to hold an * object of type $(D_PARAM T). diff --git a/middle/tanya/memory/allocator.d b/middle/tanya/memory/allocator.d index a5a10f4..2acd044 100644 --- a/middle/tanya/memory/allocator.d +++ b/middle/tanya/memory/allocator.d @@ -17,7 +17,7 @@ */ module tanya.memory.allocator; -import std.traits : hasElaborateDestructor; +import std.traits : hasElaborateDestructor, isAssociativeArray, isArray; import tanya.memory.lifetime; import tanya.meta.trait; diff --git a/middle/tanya/memory/lifetime.d b/middle/tanya/memory/lifetime.d index caae384..a5b98cd 100644 --- a/middle/tanya/memory/lifetime.d +++ b/middle/tanya/memory/lifetime.d @@ -14,7 +14,8 @@ */ module tanya.memory.lifetime; -import std.traits : isInnerClass, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor; +import std.traits : isInnerClass, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor, + isAssignable, isNested, isAbstractClass, isAggregateType, isStaticArray; import tanya.memory.allocator; import tanya.meta.metafunction; import tanya.meta.trait; diff --git a/middle/tanya/memory/smartref.d b/middle/tanya/memory/smartref.d index 01a90e1..59ac3af 100644 --- a/middle/tanya/memory/smartref.d +++ b/middle/tanya/memory/smartref.d @@ -23,6 +23,7 @@ */ module tanya.memory.smartref; +import std.traits : isPointer, isAbstractClass, isAssociativeArray, isDynamicArray, isArray; import tanya.memory.allocator; import tanya.memory.lifetime; import tanya.meta.trait; diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d index 9eb339a..41c5f8b 100644 --- a/source/tanya/algorithm/iteration.d +++ b/source/tanya/algorithm/iteration.d @@ -20,7 +20,7 @@ */ module tanya.algorithm.iteration; -import std.traits : Unqual; +import std.traits : Unqual, isMutable; import std.typecons; import tanya.memory.lifetime; import tanya.meta.trait; diff --git a/source/tanya/algorithm/mutation.d b/source/tanya/algorithm/mutation.d index 7b8fc60..e1e7c22 100644 --- a/source/tanya/algorithm/mutation.d +++ b/source/tanya/algorithm/mutation.d @@ -14,7 +14,8 @@ */ module tanya.algorithm.mutation; -import std.traits : Unqual, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor; +import std.traits : Unqual, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor, isAssignable, + isDynamicArray; static import tanya.memory.lifetime; static import tanya.memory.op; import tanya.meta.trait; diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d index 7fa9855..b3b3455 100644 --- a/source/tanya/container/array.d +++ b/source/tanya/container/array.d @@ -18,7 +18,7 @@ import core.checkedint; import std.algorithm.comparison; import std.algorithm.iteration; import std.algorithm.mutation : bringToFront; -import std.traits : PointerTarget, Unqual, hasElaborateDestructor; +import std.traits : PointerTarget, Unqual, hasElaborateDestructor, isImplicitlyConvertible, isCopyable; import tanya.algorithm.mutation; import tanya.memory.allocator; import tanya.memory.lifetime; diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d index 00d8584..d74783c 100644 --- a/source/tanya/container/hashtable.d +++ b/source/tanya/container/hashtable.d @@ -15,7 +15,7 @@ module tanya.container.hashtable; import std.algorithm.iteration; -import std.traits : CopyConstness, Unqual, ifTestable; +import std.traits : CopyConstness, Unqual, ifTestable, isMutable; import tanya.algorithm.mutation; import tanya.container.array; import tanya.container.entry; diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d index 8489056..23af88d 100644 --- a/source/tanya/container/list.d +++ b/source/tanya/container/list.d @@ -17,7 +17,7 @@ module tanya.container.list; import std.algorithm.comparison; import std.algorithm.iteration; -import std.traits : Unqual; +import std.traits : Unqual, isImplicitlyConvertible, isCopyable; import tanya.container.entry; import tanya.memory.allocator; import tanya.memory.lifetime; diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d index 89a04e1..67fc66a 100644 --- a/source/tanya/container/set.d +++ b/source/tanya/container/set.d @@ -15,7 +15,7 @@ */ module tanya.container.set; -import std.traits : CopyConstness, Unqual, ifTestable; +import std.traits : CopyConstness, Unqual, ifTestable, isImplicitlyConvertible, isMutable; import tanya.container.array; import tanya.container.entry; import tanya.hash.lookup; diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d index 25e203c..71328f2 100644 --- a/source/tanya/container/string.d +++ b/source/tanya/container/string.d @@ -28,7 +28,7 @@ module tanya.container.string; import std.algorithm.comparison; import std.algorithm.mutation : bringToFront; -import std.traits : CopyConstness, Unqual; +import std.traits : CopyConstness, Unqual, isInstanceOf, isSomeChar, isNarrowString; import tanya.algorithm.mutation; import tanya.hash.lookup; import tanya.memory.allocator; diff --git a/source/tanya/conv.d b/source/tanya/conv.d index eb6e2e4..8f46bd3 100644 --- a/source/tanya/conv.d +++ b/source/tanya/conv.d @@ -14,7 +14,8 @@ */ module tanya.conv; -import std.traits : Unsigned, isNumeric, Largest, Unqual, EnumMembers; +import std.traits : Unsigned, isNumeric, Largest, Unqual, EnumMembers, isFloatingPoint, isSomeChar, isSigned, + isUnsigned, isIntegral, isSomeString; import tanya.container.string; import tanya.memory.allocator; import tanya.meta.trait; diff --git a/source/tanya/format.d b/source/tanya/format.d index a2b4569..0b031d1 100644 --- a/source/tanya/format.d +++ b/source/tanya/format.d @@ -49,7 +49,7 @@ module tanya.format; import std.algorithm.comparison; import std.ascii; -import std.traits : Unqual; +import std.traits : Unqual, isPointer, isSomeChar, isFloatingPoint, isSomeFunction, isIntegral, isSomeString; import tanya.container.string; import tanya.math; static import tanya.memory.op; diff --git a/source/tanya/hash/lookup.d b/source/tanya/hash/lookup.d index 62faf89..706cca5 100644 --- a/source/tanya/hash/lookup.d +++ b/source/tanya/hash/lookup.d @@ -14,7 +14,7 @@ */ module tanya.hash.lookup; -import std.traits : isScalarType; +import std.traits : isScalarType, isPointer, isSomeChar, isArray, isIntegral, isBoolean; import tanya.meta.trait; import tanya.range.primitive; diff --git a/source/tanya/math/package.d b/source/tanya/math/package.d index 4552f75..ef0592e 100644 --- a/source/tanya/math/package.d +++ b/source/tanya/math/package.d @@ -22,7 +22,7 @@ module tanya.math; import std.math; -import std.traits : Unqual; +import std.traits : Unqual, isFloatingPoint; import tanya.meta.trait; /// Floating-point number precisions according to IEEE-754. diff --git a/source/tanya/net/inet.d b/source/tanya/net/inet.d index 564aa1b..314a90c 100644 --- a/source/tanya/net/inet.d +++ b/source/tanya/net/inet.d @@ -14,7 +14,7 @@ */ module tanya.net.inet; -import std.traits : Unqual; +import std.traits : Unqual, isUnsigned; import tanya.meta.trait; import tanya.range; diff --git a/source/tanya/range/adapter.d b/source/tanya/range/adapter.d index 9dfe2f2..d30b24c 100644 --- a/source/tanya/range/adapter.d +++ b/source/tanya/range/adapter.d @@ -14,6 +14,7 @@ */ module tanya.range.adapter; +import std.traits : hasMember, isArray; import tanya.algorithm.mutation; import tanya.memory.lifetime; import tanya.meta.trait; diff --git a/source/tanya/range/primitive.d b/source/tanya/range/primitive.d index c9bf419..aa8c0cf 100644 --- a/source/tanya/range/primitive.d +++ b/source/tanya/range/primitive.d @@ -15,7 +15,7 @@ module tanya.range.primitive; import std.algorithm.comparison; -import std.traits : FunctionAttribute, hasElaborateCopyConstructor, functionAttributes; +import std.traits : FunctionAttribute, ReturnType, hasElaborateCopyConstructor, functionAttributes; import tanya.memory.lifetime; import tanya.meta.trait; import tanya.range.array; diff --git a/test/tanya/test/assertion.d b/test/tanya/test/assertion.d index 5fd9831..919194f 100644 --- a/test/tanya/test/assertion.d +++ b/test/tanya/test/assertion.d @@ -22,6 +22,7 @@ */ module tanya.test.assertion; +import std.traits : isSomeFunction; import tanya.memory.allocator; import tanya.meta.trait; diff --git a/tests/tanya/memory/tests/smartref.d b/tests/tanya/memory/tests/smartref.d index 63308d8..25d7d8f 100644 --- a/tests/tanya/memory/tests/smartref.d +++ b/tests/tanya/memory/tests/smartref.d @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ module tanya.memory.tests.smartref; +import std.traits : ReturnType; import tanya.memory.allocator; import tanya.memory.smartref; import tanya.meta.trait; diff --git a/tests/tanya/meta/tests/trait.d b/tests/tanya/meta/tests/trait.d deleted file mode 100644 index 3440fa0..0000000 --- a/tests/tanya/meta/tests/trait.d +++ /dev/null @@ -1,91 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -module tanya.meta.tests.trait; - -import tanya.meta.metafunction; -import tanya.meta.trait; - -// typeof(null) is not a pointer. -@nogc nothrow pure @safe unittest -{ - static assert(!isPointer!(typeof(null))); - static assert(!isPointer!(const shared typeof(null))); - - enum typeOfNull : typeof(null) - { - null_ = null, - } - static assert(!isPointer!typeOfNull); -} - -@nogc nothrow pure @safe unittest -{ - static struct S - { - @property int opCall() - { - return 0; - } - } - S s; - static assert(isCallable!S); - static assert(isCallable!s); -} - -@nogc nothrow pure @safe unittest -{ - static assert(is(FunctionTypeOf!(void delegate()) == function)); - - static void staticFunc() - { - } - auto functionPointer = &staticFunc; - static assert(is(FunctionTypeOf!staticFunc == function)); - static assert(is(FunctionTypeOf!functionPointer == function)); - - void func() - { - } - auto dg = &func; - static assert(is(FunctionTypeOf!func == function)); - static assert(is(FunctionTypeOf!dg == function)); - - interface I - { - @property int prop(); - } - static assert(is(FunctionTypeOf!(I.prop) == function)); - - static struct S - { - void opCall() - { - } - } - class C - { - static void opCall() - { - } - } - S s; - - static assert(is(FunctionTypeOf!s == function)); - static assert(is(FunctionTypeOf!C == function)); - static assert(is(FunctionTypeOf!S == function)); -} - -@nogc nothrow pure @safe unittest -{ - static struct S2 - { - @property int opCall() - { - return 0; - } - } - S2 s2; - static assert(is(FunctionTypeOf!S2 == function)); - static assert(is(FunctionTypeOf!s2 == function)); -}