From 260b1312229c39e6a1a47e5850c7aeb760dccbb2 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 24 Aug 2025 13:01:12 +0200 Subject: [PATCH] Remove meta.transform duplicating Phobos --- meta/tanya/meta/metafunction.d | 142 +--- meta/tanya/meta/package.d | 1 - meta/tanya/meta/trait.d | 1158 +--------------------------- meta/tanya/meta/transform.d | 504 ------------ middle/tanya/memory/allocator.d | 1 + middle/tanya/memory/lifetime.d | 3 +- source/tanya/algorithm/iteration.d | 2 +- source/tanya/algorithm/mutation.d | 2 +- source/tanya/container/array.d | 2 +- source/tanya/container/entry.d | 2 +- source/tanya/container/hashtable.d | 2 +- source/tanya/container/list.d | 2 +- source/tanya/container/set.d | 2 +- source/tanya/container/string.d | 2 +- source/tanya/conv.d | 3 +- source/tanya/format.d | 2 +- source/tanya/math/package.d | 2 +- source/tanya/net/iface.d | 2 +- source/tanya/net/inet.d | 2 +- source/tanya/net/ip.d | 2 +- source/tanya/range/primitive.d | 2 +- test/tanya/test/stub.d | 8 +- tests/tanya/meta/tests/trait.d | 81 -- 23 files changed, 25 insertions(+), 1904 deletions(-) delete mode 100644 meta/tanya/meta/transform.d diff --git a/meta/tanya/meta/metafunction.d b/meta/tanya/meta/metafunction.d index eeb0d56..248cd0e 100644 --- a/meta/tanya/meta/metafunction.d +++ b/meta/tanya/meta/metafunction.d @@ -18,8 +18,9 @@ */ module tanya.meta.metafunction; +import std.traits : Unqual; +import std.meta : NoDuplicates; import tanya.meta.trait; -import tanya.meta.transform; /** * Finds the minimum value in $(D_PARAM Args) according to $(D_PARAM pred). @@ -1601,145 +1602,6 @@ if (__traits(isTemplate, pred)) static assert(is(Filter!(isIntegral, Given) == AliasSeq!(int, uint))); } -/** - * Removes all duplicates from the alias sequence $(D_PARAM L). - * - * Params: - * L = Alias sequence. - * - * Returns: $(D_PARAM L) containing only unique items. - */ -template NoDuplicates(L...) -{ - static if (L.length == 0) - { - alias NoDuplicates = AliasSeq!(); - } - else - { - private alias Rest = NoDuplicates!(EraseAll!(L[0], L[1 .. $])); - alias NoDuplicates = AliasSeq!(L[0], Rest); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - alias Given = AliasSeq!(int, uint, int, short, short, uint); - static assert(is(NoDuplicates!Given == AliasSeq!(int, uint, short))); -} - -/** - * Converts an input range $(D_PARAM range) into an alias sequence. - * - * Params: - * range = Input range. - * - * Returns: Alias sequence with items from $(D_PARAM range). - */ -template aliasSeqOf(alias range) -{ - static if (isArray!(typeof(range))) - { - static if (range.length == 0) - { - alias aliasSeqOf = AliasSeq!(); - } - else - { - alias aliasSeqOf = AliasSeq!(range[0], aliasSeqOf!(range[1 .. $])); - } - } - else - { - ReturnType!(typeof(&range.front))[] toArray(typeof(range) range) - { - typeof(return) result; - foreach (r; range) - { - result ~= r; - } - return result; - } - alias aliasSeqOf = aliasSeqOf!(toArray(range)); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(aliasSeqOf!([0, 1, 2, 3]) == AliasSeq!(0, 1, 2, 3)); -} - -/** - * Produces a alias sequence consisting of every $(D_PARAM n)th element of - * $(D_PARAM Args), starting with the first. - * - * Params: - * n = Step. - * Args = The items to stride. - * - * Returns: Alias sequence of every $(D_PARAM n)th element of $(D_PARAM Args). - */ -template Stride(size_t n, Args...) -if (n > 0) -{ - static if (Args.length > n) - { - alias Stride = AliasSeq!(Args[0], Stride!(n, Args[n .. $])); - } - else static if (Args.length > 0) - { - alias Stride = AliasSeq!(Args[0]); - } - else - { - alias Stride = AliasSeq!(); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(Stride!(3, 1, 2, 3, 4, 5, 6, 7, 8) == AliasSeq!(1, 4, 7)); - static assert(Stride!(2, 1, 2, 3) == AliasSeq!(1, 3)); - static assert(Stride!(2, 1, 2) == AliasSeq!(1)); - static assert(Stride!(2, 1) == AliasSeq!(1)); - static assert(Stride!(1, 1, 2, 3) == AliasSeq!(1, 2, 3)); - static assert(is(Stride!3 == AliasSeq!())); -} - -/** - * Aliases itself to $(D_INLINECODE T[0]) if $(D_PARAM cond) is $(D_KEYWORD true), - * to $(D_INLINECODE T[1]) if $(D_KEYWORD false). - * - * Params: - * cond = Template predicate. - * T = Two arguments. - * - * Returns: $(D_INLINECODE T[0]) if $(D_PARAM cond) is $(D_KEYWORD true), - * $(D_INLINECODE T[1]) otherwise. - */ -template Select(bool cond, T...) -if (T.length == 2) -{ - static if (cond) - { - alias Select = T[0]; - } - else - { - alias Select = T[1]; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(Select!(true, int, float) == int)); - static assert(is(Select!(false, int, float) == float)); -} - /** * Attaches a numeric index to each element from $(D_PARAM Args). * diff --git a/meta/tanya/meta/package.d b/meta/tanya/meta/package.d index d962b12..daf8d9e 100644 --- a/meta/tanya/meta/package.d +++ b/meta/tanya/meta/package.d @@ -20,4 +20,3 @@ module tanya.meta; public import tanya.meta.metafunction; public import tanya.meta.trait; -public import tanya.meta.transform; diff --git a/meta/tanya/meta/trait.d b/meta/tanya/meta/trait.d index b91d673..537952f 100644 --- a/meta/tanya/meta/trait.d +++ b/meta/tanya/meta/trait.d @@ -17,8 +17,8 @@ */ module tanya.meta.trait; +import std.traits : OriginalType, Unqual; import tanya.meta.metafunction; -import tanya.meta.transform; /** * Determines whether $(D_PARAM T) is a wide string, i.e. consists of @@ -1576,199 +1576,6 @@ enum bool isImplicitlyConvertible(From, To) = is(From : To); static assert(isImplicitlyConvertible!(string, const(char)[])); } -/** - * Returns a tuple of base classes and interfaces of $(D_PARAM T). - * - * $(D_PSYMBOL BaseTypeTuple) returns only classes and interfaces $(D_PARAM T) - * directly inherits from, but not the base classes and interfaces of its parents. - * - * Params: - * T = Class or interface type. - * - * Returns: A tuple of base classes or interfaces of ($D_PARAM T). - * - * See_Also: $(D_PSYMBOL TransitiveBaseTypeTuple). - */ -template BaseTypeTuple(T) -if (is(T == class) || (is(T == interface))) -{ - static if (is(T Tuple == super)) - { - alias BaseTypeTuple = Tuple; - } - else - { - static assert(false, "Argument isn't a class or interface"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - interface I1 - { - } - interface I2 - { - } - interface I3 : I1, I2 - { - } - interface I4 - { - } - class A : I3, I4 - { - } - static assert(is(BaseTypeTuple!A == AliasSeq!(Object, I3, I4))); - static assert(BaseTypeTuple!Object.length == 0); -} - -/** - * Returns a tuple of all base classes and interfaces of $(D_PARAM T). - * - * $(D_PSYMBOL TransitiveBaseTypeTuple) returns first the parent class, then - * grandparent and so on. The last class is $(D_PSYMBOL Object). Then the interfaces - * follow. - * - * Params: - * T = Class or interface type. - * - * Returns: A tuple of all base classes and interfaces of ($D_PARAM T). - * - * See_Also: $(D_PSYMBOL BaseTypeTuple). - */ -template TransitiveBaseTypeTuple(T) -if (is(T == class) || is(T == interface)) -{ - private template Impl(T...) - { - static if (T.length == 0) - { - alias Impl = AliasSeq!(); - } - else - { - alias Impl = AliasSeq!(BaseTypeTuple!(T[0]), - Map!(ImplCopy, BaseTypeTuple!(T[0]))); - } - } - private alias ImplCopy = Impl; // To avoid recursive template expansion. - private enum bool cmp(A, B) = is(B == interface) && is(A == class); - - alias TransitiveBaseTypeTuple = NoDuplicates!(Sort!(cmp, Impl!T)); -} - -/// -@nogc nothrow pure @safe unittest -{ - interface I1 - { - } - interface I2 : I1 - { - } - class A : I2 - { - } - class B : A, I1 - { - } - class C : B, I2 - { - } - alias Expected = AliasSeq!(B, A, Object, I2, I1); - static assert(is(TransitiveBaseTypeTuple!C == Expected)); - - static assert(is(TransitiveBaseTypeTuple!Object == AliasSeq!())); - static assert(is(TransitiveBaseTypeTuple!I2 == AliasSeq!(I1))); -} - -/** - * Returns all the base classes of $(D_PARAM T), the direct parent class comes - * first, $(D_PSYMBOL Object) ist the last one. - * - * The only type that doesn't have any base class is $(D_PSYMBOL Object). - * - * Params: - * T = Class type. - * - * Returns: Base classes of $(D_PARAM T). - */ -template BaseClassesTuple(T) -if (is(T == class)) -{ - static if (is(T == Object)) - { - alias BaseClassesTuple = AliasSeq!(); - } - else - { - private alias Parents = BaseTypeTuple!T; - alias BaseClassesTuple = AliasSeq!(Parents[0], BaseClassesTuple!(Parents[0])); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - interface I1 - { - } - interface I2 - { - } - class A : I1, I2 - { - } - class B : A, I1 - { - } - class C : B, I2 - { - } - static assert(is(BaseClassesTuple!C == AliasSeq!(B, A, Object))); - static assert(BaseClassesTuple!Object.length == 0); -} - -/** - * Returns all the interfaces $(D_PARAM T) inherits from. - * - * Params: - * T = Class or interface type. - * - * Returns: Interfaces $(D_PARAM T) inherits from. - */ -template InterfacesTuple(T) -if (is(T == class) || is(T == interface)) -{ - alias InterfacesTuple = Filter!(isInterface, TransitiveBaseTypeTuple!T); -} - -/// -@nogc nothrow pure @safe unittest -{ - interface I1 - { - } - interface I2 : I1 - { - } - class A : I2 - { - } - class B : A, I1 - { - } - class C : B, I2 - { - } - static assert(is(InterfacesTuple!C == AliasSeq!(I2, I1))); - - static assert(is(InterfacesTuple!Object == AliasSeq!())); - static assert(is(InterfacesTuple!I1 == AliasSeq!())); -} - /** * Tests whether a value of type $(D_PARAM Rhs) can be assigned to a variable * of type $(D_PARAM Lhs). @@ -1825,589 +1632,6 @@ template isAssignable(Lhs, Rhs = Lhs) static assert(!isAssignable!(const int, int)); } -/** - * Returns template parameters of $(D_PARAM T). - * - * Params: - * T = Template instance. - * - * Returns: Template parameters of $(D_PARAM T). - */ -alias TemplateArgsOf(alias T : Base!Args, alias Base, Args...) = Args; - -/// -@nogc nothrow pure @safe unittest -{ - template T(A, B) - { - } - static assert(is(TemplateArgsOf!(T!(int, uint)) == AliasSeq!(int, uint))); -} - -/** - * Returns a tuple with parameter types of a function. - * - * Params: - * F = A function. - * - * Returns: Tuple with parameter types of a function. - */ -template Parameters(F...) -if (isCallable!F) -{ - static if (is(FunctionTypeOf!F T == function)) - { - alias Parameters = T; - } - else - { - static assert(false, "Function has no parameters"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - int func(Object, uint[]); - static assert(is(Parameters!func == AliasSeq!(Object, uint[]))); -} - -/** - * Returns a string array with all parameter names of a function. - * - * If a parameter has no name, an empty string is placed into array. - * - * Params: - * F = A function. - * - * Returns: Function parameter names. - */ -template ParameterIdentifierTuple(F...) -if (isCallable!F) -{ - static if (is(FunctionTypeOf!F Params == __parameters)) - { - string[] Impl() - { - string[] tuple; - - foreach (k, P; Params) - { - static if (is(typeof(__traits(identifier, Params[k .. $])))) - { - tuple ~= __traits(identifier, Params[k .. $]); - } - else - { - tuple ~= ""; - } - } - - return tuple; - } - enum string[] ParameterIdentifierTuple = Impl(); - } - else - { - static assert(false, "Function has no parameters"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - int func(ref Object stuff, uint[] = null, scope uint k = 1); - alias P = ParameterIdentifierTuple!func; - static assert(P[0] == "stuff"); - static assert(P[1] == ""); - static assert(P[2] == "k"); -} - -/// Attributes can be attached to a function. -enum FunctionAttribute : uint -{ - none = 0x0000, - pure_ = 0x0001, - nothrow_ = 0x0002, - ref_ = 0x0004, - property = 0x0008, - trusted = 0x0010, - safe = 0x0020, - nogc = 0x0040, - system = 0x0080, - const_ = 0x0100, - immutable_ = 0x0200, - inout_ = 0x0400, - shared_ = 0x0800, - return_ = 0x1000, - scope_ = 0x2000, -} - -/** - * Retrieves the attributes of the function $(D_PARAM F). - * - * The attributes are returned as a bit-mask of - * $(D_PSYMBOL FunctionAttribute) values. - * - * Params: A function. - * - * Returns: Attributes of the function $(D_PARAM F). - * - * See_Also: $(D_PSYMBOL FunctionAttribute). - */ -template functionAttributes(F...) -if (isCallable!F) -{ - uint Impl() - { - uint attrs = FunctionAttribute.none; - foreach (a; __traits(getFunctionAttributes, F[0])) - { - static if (a == "const") - { - attrs |= FunctionAttribute.const_; - } - else static if (a == "immutable") - { - attrs |= FunctionAttribute.immutable_; - } - else static if (a == "inout") - { - attrs |= FunctionAttribute.inout_; - } - else static if (a == "@nogc") - { - attrs |= FunctionAttribute.nogc; - } - else static if (a == "nothrow") - { - attrs |= FunctionAttribute.nothrow_; - } - else static if (a == "@property") - { - attrs |= FunctionAttribute.property; - } - else static if (a == "pure") - { - attrs |= FunctionAttribute.pure_; - } - else static if (a == "ref") - { - attrs |= FunctionAttribute.ref_; - } - else static if (a == "return") - { - attrs |= FunctionAttribute.return_; - } - else static if (a == "@safe") - { - attrs |= FunctionAttribute.safe; - } - else static if (a == "scope") - { - attrs |= FunctionAttribute.scope_; - } - else static if (a == "shared") - { - attrs |= FunctionAttribute.shared_; - } - else static if (a == "@system") - { - attrs |= FunctionAttribute.system; - } - else static if (a == "@trusted") - { - attrs |= FunctionAttribute.trusted; - } - } - return attrs; - } - enum uint functionAttributes = Impl(); -} - -/// -@nogc nothrow pure @safe unittest -{ - @property ref int func1() pure nothrow @safe @nogc shared scope; - static assert((functionAttributes!func1 & FunctionAttribute.pure_) - == FunctionAttribute.pure_); - static assert((functionAttributes!func1 & FunctionAttribute.nothrow_) - == FunctionAttribute.nothrow_); - static assert((functionAttributes!func1 & FunctionAttribute.safe) - == FunctionAttribute.safe); - static assert((functionAttributes!func1 & FunctionAttribute.nogc) - == FunctionAttribute.nogc); - static assert((functionAttributes!func1 & FunctionAttribute.shared_) - == FunctionAttribute.shared_); - static assert((functionAttributes!func1 & FunctionAttribute.ref_) - == FunctionAttribute.ref_); - static assert((functionAttributes!func1 & FunctionAttribute.property) - == FunctionAttribute.property); - static assert((functionAttributes!func1 & FunctionAttribute.scope_) - == FunctionAttribute.scope_); - static assert((functionAttributes!func1 & FunctionAttribute.system) == 0); - static assert((functionAttributes!func1 & FunctionAttribute.trusted) == 0); - static assert((functionAttributes!func1 & FunctionAttribute.return_) == 0); -} - -/** - * Determines whether a function has attribute. - * - * This template should get at least two arguments: the function itself and the - * attributes it should be tested for. If more than one attribute is given, - * $(D_PSYMBOL hasFunctionAttributes) evaluates to $(D_KEYWORD true) if all of - * them are present. The attributes should be $(D_PSYMBOL FunctionAttribute) - * members. - * - * Params: - * Args = The function and attributes. - * - * Returns: - * - * See_Also: $(D_PSYMBOL FunctionAttribute). - */ -template hasFunctionAttributes(Args...) -if (Args.length > 1 - && is(typeof(Args[1]) == FunctionAttribute) - && isCallable!(Args[0]) - && allSameType!(Map!(TypeOf, Args[1 .. $]))) -{ - enum uint pred(Args_...) = Args_[0] | Args_[1]; - - template Reduce(Args_...) - { - static if (Args_.length == 1) - { - enum uint Reduce = Args_[0]; - } - else - { - enum uint Reduce = Reduce!(pred!(Args_[0], Args_[1]), Args_[2 .. $]); - } - } - enum uint field = Reduce!(0, Args[1 .. $]); - enum hasFunctionAttributes = (functionAttributes!(Args[0]) & field) == field; -} - -/// -@nogc nothrow pure @safe unittest -{ - static struct Range - { - @property auto front() inout - { - return 8; - } - } - static assert(hasFunctionAttributes!(Range.init.front, FunctionAttribute.inout_)); - static assert(!hasFunctionAttributes!(Range.init.front, FunctionAttribute.const_)); - static assert(!hasFunctionAttributes!(Range.init.front, - FunctionAttribute.inout_, FunctionAttribute.const_)); -} - -/** - * Returns a tuple with default values of the parameters to $(D_PARAM F). - * - * If a parameter doesn't have a default value, $(D_KEYWORD void) is returned. - * - * Params: - * F = A function. - * - * Returns: Default values of the parameters to $(D_PARAM F). - */ -template ParameterDefaults(F...) -if (isCallable!F) -{ - static if (is(FunctionTypeOf!F T == __parameters)) - { - private template GetDefault(size_t i) - { - static if (i == T.length) - { - alias GetDefault = AliasSeq!(); - } - else - { - auto getDefault(T[i .. i + 1] name) - { - return name[0]; - } - static if (is(typeof(getDefault()))) - { - alias Default = Alias!(getDefault()); - } - else - { - alias Default = void; - } - alias GetDefault = AliasSeq!(Default, GetDefault!(i + 1)); - } - } - - alias ParameterDefaults = GetDefault!0; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - void func1(int k, uint b = 5, int[] = [1, 2]); - alias Defaults = ParameterDefaults!func1; - static assert(is(Defaults[0] == void)); - static assert(Defaults[1 .. 3] == AliasSeq!(5, [1, 2])); -} - -/** - * Determines whether $(D_PARAM T) has an elaborate destructor. - * - * Only $(D_KEYWORD struct)s and static arrays of $(D_KEYWORD struct)s with the - * length greater than`0` can have elaborate destructors, for all other types - * $(D_PSYMBOL hasElaborateDestructor) evaluates to $(D_KEYWORD false). - * - * An elaborate destructor is an explicitly defined destructor or one generated - * by the compiler. The compiler generates a destructor for a - * $(D_KEYWORD struct) if it has members with an elaborate destructor. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) has an elaborate destructor, - * $(D_KEYWORD false) otherwise. - */ -template hasElaborateDestructor(T) -{ - static if (is(T E : E[L], size_t L)) - { - enum bool hasElaborateDestructor = L > 0 && hasElaborateDestructor!E; - } - else - { - enum bool hasElaborateDestructor = is(T == struct) - && hasMember!(T, "__xdtor"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - class C - { - ~this() - { - } - } - static assert(!hasElaborateDestructor!C); - - static struct S - { - ~this() - { - } - } - static struct S1 - { - S s; - } - static struct S2 - { - } - static assert(hasElaborateDestructor!S); // Explicit destructor. - static assert(hasElaborateDestructor!S1); // Compiler-generated destructor. - static assert(!hasElaborateDestructor!S2); // No destructor. - - static assert(hasElaborateDestructor!(S[1])); - static assert(!hasElaborateDestructor!(S[0])); -} - -/** - * Determines whether $(D_PARAM T) has an elaborate postblit constructor. - * - * Only $(D_KEYWORD struct)s and static arrays of $(D_KEYWORD struct)s with the - * length greater than`0` can have elaborate postblit constructors, for all - * other types $(D_PSYMBOL hasElaborateCopyConstructor) evaluates to - * $(D_KEYWORD false). - * - * An elaborate postblit constructor is an explicitly defined postblit - * constructor or one generated by the compiler. The compiler generates a - * postblit constructor for a - * $(D_KEYWORD struct) if it has members with an elaborate postblit - * constructor. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) has an elaborate postblit - * constructor, $(D_KEYWORD false) otherwise. - */ -template hasElaborateCopyConstructor(T) -{ - static if (is(T E : E[L], size_t L)) - { - enum bool hasElaborateCopyConstructor = L > 0 - && hasElaborateCopyConstructor!E; - } - else - { - enum bool hasElaborateCopyConstructor = is(T == struct) - && hasMember!(T, "__xpostblit"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(!hasElaborateCopyConstructor!int); - - static struct S - { - this(this) - { - } - } - static struct S1 - { - S s; - } - static struct S2 - { - } - static assert(hasElaborateCopyConstructor!S); // Explicit destructor. - static assert(hasElaborateCopyConstructor!S1); // Compiler-generated destructor. - static assert(!hasElaborateCopyConstructor!S2); // No destructor. - static assert(hasElaborateCopyConstructor!(S[1])); - static assert(!hasElaborateCopyConstructor!(S[0])); -} - -/** - * Determines whether $(D_PARAM T) has an elaborate assign. - * - * Only $(D_KEYWORD struct)s and static arrays of $(D_KEYWORD struct)s with the - * length greater than`0` can have an elaborate assign, for all - * other types $(D_PSYMBOL hasElaborateAssign) evaluates to $(D_KEYWORD false). - * - * An elaborate assign is defined with $(D_INLINECODE opAssign(typeof(this))) - * or $(D_INLINECODE opAssign(ref typeof(this))). An elaborate assign can be - * generated for a $(D_KEYWORD struct) by the compiler if one of the members of - * this $(D_KEYWORD struct) has an elaborate assign. - * - * Params: - * T = A type. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) has an elaborate assign, - * $(D_KEYWORD false) otherwise. - */ -template hasElaborateAssign(T) -{ - static if (is(T E : E[L], size_t L)) - { - enum bool hasElaborateAssign = L > 0 && hasElaborateAssign!E; - } - else static if (is(T == struct)) - { - private enum bool valueAssign = is(typeof({ T.init.opAssign(T()); })); - enum bool hasElaborateAssign = valueAssign || is(typeof({ - T s; - s.opAssign(s); - })); - } - else - { - enum bool hasElaborateAssign = false; - } -} - -/** - * Returns all members of $(D_KEYWORD enum) $(D_PARAM T). - * - * The members of $(D_PARAM T) are typed as $(D_PARAM T), not as a base type - * of the enum. - * - * $(D_PARAM EnumMembers) returns all members of $(D_PARAM T), also if there - * are some duplicates. - * - * Params: - * T = A $(D_KEYWORD enum). - * - * Returns: All members of $(D_PARAM T). - */ -template EnumMembers(T) -if (is(T == enum)) -{ - private template getEnumMembers(Args...) - { - static if (Args.length == 1) - { - enum T getEnumMembers = __traits(getMember, T, Args[0]); - } - else - { - alias getEnumMembers = AliasSeq!(__traits(getMember, T, Args[0]), - getEnumMembers!(Args[1 .. $])); - } - } - private alias allMembers = AliasSeq!(__traits(allMembers, T)); - static if (allMembers.length == 1) - { - alias EnumMembers = AliasSeq!(__traits(getMember, T, allMembers)); - } - else - { - alias EnumMembers = getEnumMembers!allMembers; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - enum E : int - { - one, - two, - three, - } - static assert([EnumMembers!E] == [E.one, E.two, E.three]); -} - -/** - * Different than $(D_INLINECODE T.alignof), which is the same for all class - * types, $(D_PSYMBOL classInstanceOf) determines the alignment of the class - * instance and not of its reference. - * - * Params: - * T = A class. - * - * Returns: Alignment of an instance of the class $(D_PARAM T). - */ -template classInstanceAlignment(T) -if (is(T == class)) -{ - private enum ptrdiff_t pred(U1, U2) = U1.alignof - U2.alignof; - private alias Fields = typeof(T.tupleof); - enum size_t classInstanceAlignment = Max!(pred, T, Fields).alignof; -} - -/// -@nogc nothrow pure @safe unittest -{ - class C1 - { - } - static assert(classInstanceAlignment!C1 == C1.alignof); - - static struct S - { - align(8) - uint s; - - int i; - } - class C2 - { - S s; - } - static assert(classInstanceAlignment!C2 == S.alignof); -} - /** * Returns the size in bytes of the state that needs to be allocated to hold an * object of type $(D_PARAM T). @@ -2459,383 +1683,3 @@ template stateSize(T) static assert(stateSize!Empty == 1); static assert(stateSize!void == 1); } - -/** - * Tests whether $(D_INLINECODE pred(T)) can be used as condition in an - * $(D_KEYWORD if)-statement or a ternary operator. - * - * $(D_PARAM pred) is an optional parameter. By default $(D_PSYMBOL ifTestable) - * tests whether $(D_PARAM T) itself is usable as condition in an - * $(D_KEYWORD if)-statement or a ternary operator, i.e. if it a value of type - * $(D_PARAM T) can be converted to a boolean. - * - * Params: - * T = A type. - * pred = Function with one argument. - * - * Returns: $(D_KEYWORD true) if $(D_INLINECODE pred(T)) can be used as - * condition in an $(D_KEYWORD if)-statement or a ternary operator. - */ -template ifTestable(T, alias pred = a => a) -{ - enum bool ifTestable = is(typeof(pred(T.init) ? true : false)); -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(ifTestable!int); - - static struct S1 - { - } - static assert(!ifTestable!S1); - - static struct S2 - { - bool opCast(T : bool)() - { - return true; - } - } - static assert(ifTestable!S2); -} - -/** - * Returns a compile-time tuple of user-defined attributes (UDA) attached to - * $(D_PARAM symbol). - * - * $(D_PARAM symbol) can be: - * - * $(DL - * $(DT Template) - * $(DD The attribute is matched if it is an instance of the template - * $(D_PARAM attr).) - * $(DT Type) - * $(DD The attribute is matched if it its type is $(D_PARAM attr).) - * $(DT Expression) - * $(DD The attribute is matched if it equals to $(D_PARAM attr).) - * ) - * - * If $(D_PARAM attr) isn't given, all user-defined attributes of - * $(D_PARAM symbol) are returned. - * - * Params: - * symbol = A symbol. - * attr = User-defined attribute. - * - * Returns: A tuple of user-defined attributes attached to $(D_PARAM symbol) - * and matching $(D_PARAM attr). - * - * See_Also: $(LINK2 https://dlang.org/spec/attribute.html#uda, - * User Defined Attributes). - */ -template getUDAs(alias symbol, alias attr) -{ - private template FindUDA(T...) - { - static if (T.length == 0) - { - alias FindUDA = AliasSeq!(); - } - else static if ((isTypeTuple!attr && is(TypeOf!(T[0]) == attr)) - || (is(typeof(T[0] == attr)) && (T[0] == attr)) - || isInstanceOf!(attr, TypeOf!(T[0]))) - { - alias FindUDA = AliasSeq!(T[0], FindUDA!(T[1 .. $])); - } - else - { - alias FindUDA = FindUDA!(T[1 .. $]); - } - } - alias getUDAs = FindUDA!(__traits(getAttributes, symbol)); -} - -/// -alias getUDAs(alias symbol) = AliasSeq!(__traits(getAttributes, symbol)); - -/// -@nogc nothrow pure @safe unittest -{ - static struct Attr - { - int i; - } - @Attr int a; - static assert(getUDAs!(a, Attr).length == 1); - - @Attr(8) int b; - static assert(getUDAs!(b, Attr).length == 1); - static assert(getUDAs!(b, Attr)[0].i == 8); - static assert(getUDAs!(b, Attr(8)).length == 1); - static assert(getUDAs!(b, Attr(7)).length == 0); - - @("string", 5) int c; - static assert(getUDAs!(c, "string").length == 1); - static assert(getUDAs!(c, 5).length == 1); - static assert(getUDAs!(c, "String").length == 0); - static assert(getUDAs!(c, 4).length == 0); - - static struct T(U) - { - enum U s = 7; - U i; - } - @T!int @T!int(8) int d; - static assert(getUDAs!(d, T).length == 2); - static assert(getUDAs!(d, T)[0].s == 7); - static assert(getUDAs!(d, T)[1].i == 8); - - @T int e; - static assert(getUDAs!(e, T).length == 0); -} - -/** - * Determines whether $(D_PARAM symbol) has user-defined attribute - * $(D_PARAM attr) attached to it. - * - * Params: - * symbol = A symbol. - * attr = User-defined attribute. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM symbol) has user-defined attribute - * $(D_PARAM attr), $(D_KEYWORD false) otherwise. - * - * See_Also: $(LINK2 https://dlang.org/spec/attribute.html#uda, - * User Defined Attributes). - */ -template hasUDA(alias symbol, alias attr) -{ - enum bool hasUDA = getUDAs!(symbol, attr).length != 0; -} - -/// -@nogc nothrow pure @safe unittest -{ - static struct Attr1 - { - } - static struct Attr2 - { - } - @Attr1 int a; - static assert(hasUDA!(a, Attr1)); - static assert(!hasUDA!(a, Attr2)); -} - -/** - * If $(D_PARAM T) is a type, constructs its default value, otherwise - * $(D_PSYMBOL evalUDA) aliases itself to $(D_PARAM T). - * - * This template is useful when working with UDAs with default parameters, - * i.e. if an attribute can be given as `@Attr` or `@Attr("param")`, - * $(D_PSYMBOL evalUDA) makes `@Attr()` from `@Attr`, but returns - * `@Attr("param")` as is. - * - * $(D_PARAM T) (or its type if it isn't a type already) should have a default - * constructor. - * - * Params: - * T = User Defined Attribute. - */ -alias evalUDA(alias T) = T; - -/// ditto -alias evalUDA(T) = Alias!(T()); - -/// -@nogc nothrow pure @safe unittest -{ - static struct Length - { - size_t length = 8; - } - @Length @Length(0) int i; - alias uda = AliasSeq!(__traits(getAttributes, i)); - - alias attr1 = evalUDA!(uda[0]); - alias attr2 = evalUDA!(uda[1]); - - static assert(is(typeof(attr1) == Length)); - static assert(is(typeof(attr2) == Length)); - - static assert(attr1.length == 8); - static assert(attr2.length == 0); -} - -/** - * Tests whether $(D_PARAM T) is an inner class, i.e. a class nested inside - * another class. - * - * All inner classes get `outer` propery automatically generated, which points - * to its parent class, though it can be explicitly defined to be something - * different. If $(D_PARAM T) does this, $(D_PSYMBOL isInnerClass) - * evaluates to $(D_KEYWORD false). - * - * Params: - * T = Class to be tested. - * - * Returns $(D_KEYWORD true) if $(D_PARAM T) is an inner class, - * $(D_KEYWORD false) otherwise. - */ -template isInnerClass(T) -{ - static if (is(T == class) && is(typeof(T.outer) == class)) - { - enum bool isInnerClass = !canFind!("outer", __traits(allMembers, T)); - } - else - { - enum bool isInnerClass = false; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - class A - { - } - class O - { - class I - { - } - class Fake - { - bool outer; - } - } - static assert(!isInnerClass!(O)); - static assert(isInnerClass!(O.I)); - static assert(!isInnerClass!(O.Fake)); -} - -/** - * Returns the types of all members of $(D_PARAM T). - * - * If $(D_PARAM T) is a $(D_KEYWORD struct) or $(D_KEYWORD union) or - * $(D_KEYWORD class), returns the types of all its fields. It is actually the - * same as `T.tupleof`, but the content pointer for the nested type isn't - * included. - * - * If $(D_PARAM T) is neither a $(D_KEYWORD struct) nor $(D_KEYWORD union) nor - * $(D_KEYWORD class), $(D_PSYMBOL Fields) returns an $(D_PSYMBOL AliasSeq) - * with the single element $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_PARAM T)'s fields. - */ -template Fields(T) -{ - static if ((is(T == struct) || is(T == union)) && isNested!T) - { - // The last element of .tupleof of a nested struct or union is "this", - // the context pointer, type "void*". - alias Fields = typeof(T.tupleof[0 .. $ - 1]); - } - else static if (is(T == class) || is(T == struct) || is(T == union)) - { - alias Fields = typeof(T.tupleof); - } - else - { - alias Fields = AliasSeq!T; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - struct Nested - { - int i; - - void func() - { - } - } - static assert(is(Fields!Nested == AliasSeq!int)); - - class C - { - uint u; - } - static assert(is(Fields!C == AliasSeq!uint)); - - static assert(is(Fields!short == AliasSeq!short)); -} - -/** - * Determines whether all $(D_PARAM Types) are the same. - * - * If $(D_PARAM Types) is empty, returns $(D_KEYWORD true). - * - * Params: - * Types = Type sequence. - * - * Returns: $(D_KEYWORD true) if all $(D_PARAM Types) are the same, - * $(D_KEYWORD false) otherwise. - */ -template allSameType(Types...) -{ - static if (Types.length == 0) - { - enum bool allSameType = true; - } - else - { - private enum bool sameType(T) = is(T == Types[0]); - - enum bool allSameType = allSatisfy!(sameType, Types[1 .. $]); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(allSameType!()); - static assert(allSameType!int); - static assert(allSameType!(int, int, int)); - static assert(!allSameType!(int, uint, int)); - static assert(!allSameType!(int, uint, short)); -} - -/** - * Determines whether values of type $(D_PARAM T) can be compared for equality, - * i.e. using `==` or `!=` binary operators. - * - * Params: - * T = Type to test. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) can be compared for equality, - * $(D_KEYWORD false) otherwise. - */ -enum bool isEqualityComparable(T) = ifTestable!(T, a => a == a); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isEqualityComparable!int); -} - -/** - * Determines whether values of type $(D_PARAM T) can be compared for ordering, - * i.e. using `>`, `>=`, `<` or `<=` binary operators. - * - * Params: - * T = Type to test. - * - * Returns: $(D_KEYWORD true) if $(D_PARAM T) can be compared for ordering, - * $(D_KEYWORD false) otherwise. - */ -enum bool isOrderingComparable(T) = ifTestable!(T, a => a > a); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(isOrderingComparable!int); -} diff --git a/meta/tanya/meta/transform.d b/meta/tanya/meta/transform.d deleted file mode 100644 index 2bef67f..0000000 --- a/meta/tanya/meta/transform.d +++ /dev/null @@ -1,504 +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/. */ - -/** - * Type transformations. - * - * Templates in this module can be used to modify type qualifiers or transform - * types. They take some type as argument and return a different type after - * perfoming the specified transformation. - * - * Copyright: Eugene Wissner 2017-2025. - * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, - * Mozilla Public License, v. 2.0). - * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) - * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/meta/tanya/meta/transform.d, - * tanya/meta/transform.d) - */ -module tanya.meta.transform; - -import tanya.meta.metafunction; -import tanya.meta.trait; - -/** - * Removes any type qualifiers from $(D_PARAM T). - * - * Removed qualifiers are: - * $(UL - * $(LI const) - * $(LI immutable) - * $(LI inout) - * $(LI shared) - * ) - * and combinations of these. - * - * If the type $(D_PARAM T) doesn't have any qualifieres, - * $(D_INLINECODE Unqual!T) becomes an alias for $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_PARAM T) without any type qualifiers. - */ -template Unqual(T) -{ - static if (is(T U == shared const U) - || is(T U == shared inout U) - || is(T U == shared inout const U) - || is(T U == inout const U) - || is(T U == const U) - || is(T U == immutable U) - || is(T U == inout U) - || is(T U == shared U)) - { - alias Unqual = U; - } - else - { - alias Unqual = T; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(Unqual!bool == bool)); - static assert(is(Unqual!(immutable bool) == bool)); - static assert(is(Unqual!(inout bool) == bool)); - static assert(is(Unqual!(inout const bool) == bool)); - static assert(is(Unqual!(shared bool) == bool)); - static assert(is(Unqual!(shared const bool) == bool)); - static assert(is(Unqual!(shared inout const bool) == bool)); -} - -/** - * If $(D_PARAM T) is an $(D_KEYWORD enum), $(D_INLINECODE OriginalType!T) - * evaluates to the most base type of that $(D_KEYWORD enum) and to - * $(D_PARAM T) otherwise. - * - * Params: - * T = A type. - * - * Returns: Base type of the $(D_KEYWORD enum) $(D_PARAM T) or $(D_PARAM T) - * itself. - */ -template OriginalType(T) -{ - static if (is(T U == enum)) - { - alias OriginalType = OriginalType!U; - } - else - { - alias OriginalType = T; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - enum E1 : const(int) - { - n = 0, - } - enum E2 : bool - { - t = true, - } - enum E3 : E2 - { - t = E2.t, - } - enum E4 : const(E2) - { - t = E2.t, - } - - static assert(is(OriginalType!E1 == const int)); - static assert(is(OriginalType!E2 == bool)); - static assert(is(OriginalType!E3 == bool)); - static assert(is(OriginalType!E4 == bool)); - static assert(is(OriginalType!(const E4) == bool)); -} - -/** - * Copies constness of $(D_PARAM From) to $(D_PARAM To). - * - * The following type qualifiers affect the constness and hence are copied: - * $(UL - * $(LI const) - * $(LI immutable) - * $(LI inout) - * $(LI inout const) - * ) - * - * Params: - * From = Source type. - * To = Target type. - * - * Returns: $(D_PARAM To) with the constness of $(D_PARAM From). - */ -template CopyConstness(From, To) -{ - static if (is(From T == immutable T)) - { - alias CopyConstness = immutable To; - } - else static if (is(From T == const T) || is(From T == shared const T)) - { - alias CopyConstness = const To; - } - else static if (is(From T == inout T) || is(From T == shared inout T)) - { - alias CopyConstness = inout To; - } - else static if (is(From T == inout const T) - || is(From T == shared inout const T)) - { - alias CopyConstness = inout const To; - } - else - { - alias CopyConstness = To; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(CopyConstness!(int, char) == char)); - static assert(is(CopyConstness!(const int, char) == const char)); - static assert(is(CopyConstness!(immutable int, char) == immutable char)); - static assert(is(CopyConstness!(inout int, char) == inout char)); - static assert(is(CopyConstness!(inout const int, char) == inout const char)); - - static assert(is(CopyConstness!(shared int, char) == char)); - static assert(is(CopyConstness!(shared const int, char) == const char)); - static assert(is(CopyConstness!(shared inout int, char) == inout char)); - static assert(is(CopyConstness!(shared inout const int, char) == inout const char)); - - static assert(is(CopyConstness!(const int, shared char) == shared const char)); - static assert(is(CopyConstness!(const int, immutable char) == immutable char)); - static assert(is(CopyConstness!(immutable int, const char) == immutable char)); -} - -/** - * Retrieves the target type `U` of a pointer `U*`. - * - * Params: - * T = Pointer type. - * - * Returns: Pointer target type. - */ -template PointerTarget(T) -{ - static if (is(T U : U*)) - { - alias PointerTarget = U; - } - else - { - static assert(T.stringof ~ " isn't a pointer type"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(PointerTarget!(bool*) == bool)); - static assert(is(PointerTarget!(const bool*) == const bool)); - static assert(is(PointerTarget!(const shared bool*) == const shared bool)); - static assert(!is(PointerTarget!bool)); -} - -/** - * Params: - * T = The type of the associative array. - * - * Returns: The key type of the associative array $(D_PARAM T). - */ -template KeyType(T) -{ - static if (is(T V : V[K], K)) - { - alias KeyType = K; - } - else - { - static assert(false, T.stringof ~ " isn't an associative array"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(KeyType!(int[string]) == string)); - static assert(!is(KeyType!(int[15]))); -} - -/** - * Params: - * T = The type of the associative array. - * - * Returns: The value type of the associative array $(D_PARAM T). - */ -template ValueType(T) -{ - static if (is(T V : V[K], K)) - { - alias ValueType = V; - } - else - { - static assert(false, T.stringof ~ " isn't an associative array"); - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(ValueType!(int[string]) == int)); - static assert(!is(ValueType!(int[15]))); -} - -/** - * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE inout(T)). - */ -alias InoutOf(T) = inout(T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(InoutOf!int == inout int)); -} - -/** - * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE inout(T)). - */ -alias ConstOf(T) = const(T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(ConstOf!int == const int)); -} - -/** - * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE inout(T)). - */ -alias SharedOf(T) = shared(T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(SharedOf!int == shared int)); -} - -/** - * Adds $(D_KEYWORD inout) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE inout(T)). - */ -alias SharedInoutOf(T) = shared(inout T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(SharedInoutOf!int == shared inout int)); -} - -/** - * Adds $(D_KEYWORD shared const) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE shared(const T)). - */ -alias SharedConstOf(T) = shared(const T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(SharedConstOf!int == shared const int)); -} - -/** - * Adds $(D_KEYWORD immutable) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE immutable(T)). - */ -alias ImmutableOf(T) = immutable(T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(ImmutableOf!int == immutable int)); -} - -/** - * Adds $(D_KEYWORD inout const) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE inout(const T)). - */ -alias InoutConstOf(T) = inout(const T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(InoutConstOf!int == inout const int)); -} - -/** - * Adds $(D_KEYWORD shared inout const) qualifier to the type $(D_PARAM T). - * - * Params: - * T = A type. - * - * Returns: $(D_INLINECODE shared(inout const T)). - */ -alias SharedInoutConstOf(T) = shared(inout const T); - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(SharedInoutConstOf!int == shared inout const int)); -} - -/** - * Determines the type of $(D_PARAM T). If $(D_PARAM T) is already a type, - * $(D_PSYMBOL TypeOf) aliases itself to $(D_PARAM T). - * - * $(D_PSYMBOL TypeOf) evaluates to $(D_KEYWORD void) for template arguments. - * - * The symbols that don't have a type and aren't types cannot be used as - * arguments to $(D_PSYMBOL TypeOf). - * - * Params: - * T = Expression, type or template. - * - * Returns: The type of $(D_PARAM T). - */ -alias TypeOf(T) = T; - -/// ditto -template TypeOf(alias T) -if (isExpressions!T || __traits(isTemplate, T)) -{ - alias TypeOf = typeof(T); -} - -/// -@nogc nothrow pure @safe unittest -{ - struct S(T) - { - } - static assert(is(TypeOf!S == void)); - static assert(is(TypeOf!int == int)); - static assert(is(TypeOf!true == bool)); - static assert(!is(TypeOf!(tanya.meta))); -} - -/** - * Finds the type with the smallest size in the $(D_PARAM Args) list. If - * several types have the same type, the leftmost is returned. - * - * Params: - * Args = Type list. - * - * Returns: The smallest type. - * - * See_Also: $(D_PSYMBOL Largest). - */ -template Smallest(Args...) -if (Args.length >= 1) -{ - static assert(is(Args[0]), T.stringof ~ " doesn't have .sizeof property"); - - static if (Args.length == 1) - { - alias Smallest = Args[0]; - } - else static if (Smallest!(Args[1 .. $]).sizeof < Args[0].sizeof) - { - alias Smallest = Smallest!(Args[1 .. $]); - } - else - { - alias Smallest = Args[0]; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(Smallest!(int, ushort, uint, short) == ushort)); - static assert(is(Smallest!(short) == short)); - static assert(is(Smallest!(ubyte[8], ubyte[5]) == ubyte[5])); - static assert(!is(Smallest!(short, 5))); -} - -/** - * Finds the type with the largest size in the $(D_PARAM Args) list. If several - * types have the same type, the leftmost is returned. - * - * Params: - * Args = Type list. - * - * Returns: The largest type. - * - * See_Also: $(D_PSYMBOL Smallest). - */ -template Largest(Args...) -if (Args.length >= 1) -{ - static assert(is(Args[0]), T.stringof ~ " doesn't have .sizeof property"); - - static if (Args.length == 1) - { - alias Largest = Args[0]; - } - else static if (Largest!(Args[1 .. $]).sizeof > Args[0].sizeof) - { - alias Largest = Largest!(Args[1 .. $]); - } - else - { - alias Largest = Args[0]; - } -} - -/// -@nogc nothrow pure @safe unittest -{ - static assert(is(Largest!(int, short, uint) == int)); - static assert(is(Largest!(short) == short)); - static assert(is(Largest!(ubyte[8], ubyte[5]) == ubyte[8])); - static assert(!is(Largest!(short, 5))); -} diff --git a/middle/tanya/memory/allocator.d b/middle/tanya/memory/allocator.d index 188eff9..a5a10f4 100644 --- a/middle/tanya/memory/allocator.d +++ b/middle/tanya/memory/allocator.d @@ -17,6 +17,7 @@ */ module tanya.memory.allocator; +import std.traits : hasElaborateDestructor; import tanya.memory.lifetime; import tanya.meta.trait; diff --git a/middle/tanya/memory/lifetime.d b/middle/tanya/memory/lifetime.d index 606086f..caae384 100644 --- a/middle/tanya/memory/lifetime.d +++ b/middle/tanya/memory/lifetime.d @@ -14,6 +14,7 @@ */ module tanya.memory.lifetime; +import std.traits : isInnerClass, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor; import tanya.memory.allocator; import tanya.meta.metafunction; import tanya.meta.trait; @@ -60,7 +61,7 @@ package(tanya) void destroyAllImpl(R, E)(R p) * Postcondition: $(D_PARAM memory) and the result point to the same memory. */ T emplace(T, U, Args...)(void[] memory, U outer, auto ref Args args) -if (!isAbstractClass!T && isInnerClass!T && is(typeof(T.outer) == U)) +if (is(T == class) && !isAbstractClass!T && isInnerClass!T && is(typeof(T.outer) == U)) in { assert(memory.length >= stateSize!T); diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d index 469699c..9eb339a 100644 --- a/source/tanya/algorithm/iteration.d +++ b/source/tanya/algorithm/iteration.d @@ -20,10 +20,10 @@ */ module tanya.algorithm.iteration; +import std.traits : Unqual; import std.typecons; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range; private struct SingletonByValue(E) diff --git a/source/tanya/algorithm/mutation.d b/source/tanya/algorithm/mutation.d index da5ed96..7b8fc60 100644 --- a/source/tanya/algorithm/mutation.d +++ b/source/tanya/algorithm/mutation.d @@ -14,10 +14,10 @@ */ module tanya.algorithm.mutation; +import std.traits : Unqual, hasElaborateAssign, hasElaborateCopyConstructor, hasElaborateDestructor; static import tanya.memory.lifetime; static import tanya.memory.op; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range; /** diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d index 7027641..7fa9855 100644 --- a/source/tanya/container/array.d +++ b/source/tanya/container/array.d @@ -18,11 +18,11 @@ import core.checkedint; import std.algorithm.comparison; import std.algorithm.iteration; import std.algorithm.mutation : bringToFront; +import std.traits : PointerTarget, Unqual, hasElaborateDestructor; import tanya.algorithm.mutation; import tanya.memory.allocator; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range; /** diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d index f8414e0..52b3e6a 100644 --- a/source/tanya/container/entry.d +++ b/source/tanya/container/entry.d @@ -14,11 +14,11 @@ */ module tanya.container.entry; +import std.traits : Unqual, hasElaborateDestructor; import tanya.container.array; import tanya.memory.allocator; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; package struct SEntry(T) { diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d index 119cc3c..00d8584 100644 --- a/source/tanya/container/hashtable.d +++ b/source/tanya/container/hashtable.d @@ -15,6 +15,7 @@ module tanya.container.hashtable; import std.algorithm.iteration; +import std.traits : CopyConstness, Unqual, ifTestable; import tanya.algorithm.mutation; import tanya.container.array; import tanya.container.entry; @@ -22,7 +23,6 @@ import tanya.hash.lookup; import tanya.memory.allocator; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range.primitive; /** diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d index 0c924ec..8489056 100644 --- a/source/tanya/container/list.d +++ b/source/tanya/container/list.d @@ -17,11 +17,11 @@ module tanya.container.list; import std.algorithm.comparison; import std.algorithm.iteration; +import std.traits : Unqual; import tanya.container.entry; import tanya.memory.allocator; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range.array; import tanya.range.primitive; diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d index 1b7c1db..89a04e1 100644 --- a/source/tanya/container/set.d +++ b/source/tanya/container/set.d @@ -15,13 +15,13 @@ */ module tanya.container.set; +import std.traits : CopyConstness, Unqual, ifTestable; import tanya.container.array; import tanya.container.entry; import tanya.hash.lookup; import tanya.memory.allocator; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range.primitive; /** diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d index a2cd2f2..25e203c 100644 --- a/source/tanya/container/string.d +++ b/source/tanya/container/string.d @@ -28,12 +28,12 @@ module tanya.container.string; import std.algorithm.comparison; import std.algorithm.mutation : bringToFront; +import std.traits : CopyConstness, Unqual; import tanya.algorithm.mutation; import tanya.hash.lookup; import tanya.memory.allocator; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range.array; import tanya.range.primitive; diff --git a/source/tanya/conv.d b/source/tanya/conv.d index 7d5a264..eb6e2e4 100644 --- a/source/tanya/conv.d +++ b/source/tanya/conv.d @@ -14,11 +14,10 @@ */ module tanya.conv; -import std.traits : Unsigned, isNumeric; +import std.traits : Unsigned, isNumeric, Largest, Unqual, EnumMembers; import tanya.container.string; import tanya.memory.allocator; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range; /** diff --git a/source/tanya/format.d b/source/tanya/format.d index ebe3354..a2b4569 100644 --- a/source/tanya/format.d +++ b/source/tanya/format.d @@ -49,12 +49,12 @@ module tanya.format; import std.algorithm.comparison; import std.ascii; +import std.traits : Unqual; import tanya.container.string; import tanya.math; static import tanya.memory.op; import tanya.meta.metafunction; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range; // Returns the last part of buffer with converted number. diff --git a/source/tanya/math/package.d b/source/tanya/math/package.d index 0d10238..4552f75 100644 --- a/source/tanya/math/package.d +++ b/source/tanya/math/package.d @@ -22,8 +22,8 @@ module tanya.math; import std.math; +import std.traits : Unqual; import tanya.meta.trait; -import tanya.meta.transform; /// Floating-point number precisions according to IEEE-754. enum IEEEPrecision : ubyte diff --git a/source/tanya/net/iface.d b/source/tanya/net/iface.d index 699d09d..8443cb4 100644 --- a/source/tanya/net/iface.d +++ b/source/tanya/net/iface.d @@ -14,10 +14,10 @@ */ module tanya.net.iface; +import std.traits : Unqual; import tanya.algorithm.mutation; import tanya.container.string; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range; version (Windows) diff --git a/source/tanya/net/inet.d b/source/tanya/net/inet.d index 7199a3c..564aa1b 100644 --- a/source/tanya/net/inet.d +++ b/source/tanya/net/inet.d @@ -14,8 +14,8 @@ */ module tanya.net.inet; +import std.traits : Unqual; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range; /** diff --git a/source/tanya/net/ip.d b/source/tanya/net/ip.d index 4b6d2f7..73ef23d 100644 --- a/source/tanya/net/ip.d +++ b/source/tanya/net/ip.d @@ -18,6 +18,7 @@ import std.algorithm.comparison; import std.ascii; import std.sumtype; import std.typecons; +import std.traits : Unqual; import tanya.algorithm.iteration; import tanya.algorithm.mutation; import tanya.container.string; @@ -25,7 +26,6 @@ import tanya.conv; import tanya.format; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.net.iface; import tanya.net.inet; import tanya.range; diff --git a/source/tanya/range/primitive.d b/source/tanya/range/primitive.d index 3cc45e0..c9bf419 100644 --- a/source/tanya/range/primitive.d +++ b/source/tanya/range/primitive.d @@ -15,9 +15,9 @@ module tanya.range.primitive; import std.algorithm.comparison; +import std.traits : FunctionAttribute, hasElaborateCopyConstructor, functionAttributes; import tanya.memory.lifetime; import tanya.meta.trait; -import tanya.meta.transform; import tanya.range.array; /** diff --git a/test/tanya/test/stub.d b/test/tanya/test/stub.d index a83cf01..fca2d96 100644 --- a/test/tanya/test/stub.d +++ b/test/tanya/test/stub.d @@ -90,8 +90,8 @@ struct WithLvalueElements */ mixin template InputRangeStub(E = int) { + import std.traits : hasUDA, getUDAs; import tanya.meta.metafunction : Alias; - import tanya.meta.trait : evalUDA, getUDAs, hasUDA; /* * Aliases for the attribute lookups to access them faster @@ -113,7 +113,7 @@ mixin template InputRangeStub(E = int) } else static if (Length.length != 0) { - private enum size_t count = evalUDA!(Length[0]).length; + private enum size_t count = Length[0]().length; static assert (!infinite, "Range cannot have length and be infinite at the same time"); @@ -372,7 +372,7 @@ struct Hashable */ mixin template StructStub() { - import tanya.meta.trait : evalUDA, getUDAs, hasUDA; + import std.traits : hasUDA, getUDAs; static if (hasUDA!(typeof(this), NonCopyable)) { @@ -384,7 +384,7 @@ mixin template StructStub() { size_t toHash() const @nogc nothrow pure @safe { - return evalUDA!(Hashable[0]).hash; + return Hashable[0]().hash; } } diff --git a/tests/tanya/meta/tests/trait.d b/tests/tanya/meta/tests/trait.d index 4df2f18..3440fa0 100644 --- a/tests/tanya/meta/tests/trait.d +++ b/tests/tanya/meta/tests/trait.d @@ -89,84 +89,3 @@ import tanya.meta.trait; static assert(is(FunctionTypeOf!S2 == function)); static assert(is(FunctionTypeOf!s2 == function)); } - -@nogc nothrow pure @safe unittest -{ - static assert(!hasElaborateAssign!int); - - static struct S1 - { - void opAssign(S1) - { - } - } - static struct S2 - { - void opAssign(int) - { - } - } - static struct S3 - { - S1 s; - alias s this; - } - static assert(hasElaborateAssign!S1); - static assert(!hasElaborateAssign!(const S1)); - static assert(hasElaborateAssign!(S1[1])); - static assert(!hasElaborateAssign!(S1[0])); - static assert(!hasElaborateAssign!S2); - static assert(hasElaborateAssign!S3); - - static struct S4 - { - void opAssign(S4) - { - } - @disable this(this); - } - static assert(hasElaborateAssign!S4); -} - -// Produces a tuple for an enum with only one member -@nogc nothrow pure @safe unittest -{ - enum E : int - { - one = 0, - } - static assert(EnumMembers!E == AliasSeq!0); -} - -@nogc nothrow pure @safe unittest -{ - class RefCountedStore(T) - { - } - static assert(!isInnerClass!(RefCountedStore!int)); -} - -@nogc nothrow pure @safe unittest -{ - static struct DisabledOpEquals - { - @disable bool opEquals(typeof(this)) @nogc nothrow pure @safe; - - int opCmp(typeof(this)) @nogc nothrow pure @safe - { - return 0; - } - } - static assert(!isEqualityComparable!DisabledOpEquals); - static assert(isOrderingComparable!DisabledOpEquals); - - static struct OpEquals - { - bool opEquals(typeof(this)) @nogc nothrow pure @safe - { - return true; - } - } - static assert(isEqualityComparable!OpEquals); - static assert(!isOrderingComparable!OpEquals); -}