2 * Contains traits for runtime internal usage.
4 * Copyright: Copyright Digital Mars 2014 -.
5 * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Martin Nowak
7 * Source: $(DRUNTIMESRC core/internal/_traits.d)
9 module core.internal.traits;
11 /// taken from std.typetuple.TypeTuple
12 template TypeTuple(TList...)
14 alias TypeTuple = TList;
17 T trustedCast(T, U)(auto ref U u) @trusted pure nothrow
24 static if (is(T U == immutable U)) alias Unconst = U;
25 else static if (is(T U == inout const U)) alias Unconst = U;
26 else static if (is(T U == inout U)) alias Unconst = U;
27 else static if (is(T U == const U)) alias Unconst = U;
28 else alias Unconst = T;
31 /// taken from std.traits.Unqual
34 version (none) // Error: recursive alias declaration @@@BUG1308@@@
36 static if (is(T U == const U)) alias Unqual = Unqual!U;
37 else static if (is(T U == immutable U)) alias Unqual = Unqual!U;
38 else static if (is(T U == inout U)) alias Unqual = Unqual!U;
39 else static if (is(T U == shared U)) alias Unqual = Unqual!U;
40 else alias Unqual = T;
44 static if (is(T U == immutable U)) alias Unqual = U;
45 else static if (is(T U == shared inout const U)) alias Unqual = U;
46 else static if (is(T U == shared inout U)) alias Unqual = U;
47 else static if (is(T U == shared const U)) alias Unqual = U;
48 else static if (is(T U == shared U)) alias Unqual = U;
49 else static if (is(T U == inout const U)) alias Unqual = U;
50 else static if (is(T U == inout U)) alias Unqual = U;
51 else static if (is(T U == const U)) alias Unqual = U;
52 else alias Unqual = T;
56 // Substitute all `inout` qualifiers that appears in T to `const`
57 template substInout(T)
59 static if (is(T == immutable))
63 else static if (is(T : shared const U, U) || is(T : const U, U))
65 // U is top-unqualified
66 mixin("alias substInout = "
67 ~ (is(T == shared) ? "shared " : "")
68 ~ (is(T == const) || is(T == inout) ? "const " : "") // substitute inout to const
69 ~ "substInoutForm!U;");
75 private template substInoutForm(T)
77 static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface))
79 alias substInoutForm = T; // prevent matching to the form of alias-this-ed type
81 else static if (is(T : V[K], K, V)) alias substInoutForm = substInout!V[substInout!K];
82 else static if (is(T : U[n], U, size_t n)) alias substInoutForm = substInout!U[n];
83 else static if (is(T : U[], U)) alias substInoutForm = substInout!U[];
84 else static if (is(T : U*, U)) alias substInoutForm = substInout!U*;
85 else alias substInoutForm = T;
88 /// used to declare an extern(D) function that is defined in a different module
89 template externDFunc(string fqn, T:FT*, FT) if (is(FT == function))
91 static if (is(FT RT == return) && is(FT Args == function))
93 import core.demangle : mangleFunc;
95 string s = "extern(D) RT externDFunc(Args)";
96 foreach (attr; __traits(getFunctionAttributes, FT))
100 pragma(mangle, mangleFunc!T(fqn)) mixin(decl);
106 template staticIota(int beg, int end)
108 static if (beg + 1 >= end)
110 static if (beg >= end)
112 alias staticIota = TypeTuple!();
116 alias staticIota = TypeTuple!(+beg);
121 enum mid = beg + (end - beg) / 2;
122 alias staticIota = TypeTuple!(staticIota!(beg, mid), staticIota!(mid, end));
126 template dtorIsNothrow(T)
128 enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow);
131 template anySatisfy(alias F, T...)
133 static if (T.length == 0)
135 enum anySatisfy = false;
137 else static if (T.length == 1)
139 enum anySatisfy = F!(T[0]);
144 anySatisfy!(F, T[ 0 .. $/2]) ||
145 anySatisfy!(F, T[$/2 .. $ ]);
149 // Somehow fails for non-static nested structs without support for aliases
150 template hasElaborateDestructor(T...)
155 alias S = typeof(T[0]);
157 static if (is(S : E[n], E, size_t n) && S.length)
159 enum bool hasElaborateDestructor = hasElaborateDestructor!E;
161 else static if (is(S == struct))
163 enum hasElaborateDestructor = __traits(hasMember, S, "__dtor")
164 || anySatisfy!(.hasElaborateDestructor, S.tupleof);
167 enum bool hasElaborateDestructor = false;
170 // Somehow fails for non-static nested structs without support for aliases
171 template hasElaborateCopyConstructor(T...)
176 alias S = typeof(T[0]);
178 static if (is(S : E[n], E, size_t n) && S.length)
180 enum bool hasElaborateCopyConstructor = hasElaborateCopyConstructor!E;
182 else static if (is(S == struct))
184 enum hasElaborateCopyConstructor = __traits(hasMember, S, "__postblit")
185 || anySatisfy!(.hasElaborateCopyConstructor, S.tupleof);
188 enum bool hasElaborateCopyConstructor = false;
192 template Filter(alias pred, TList...)
194 static if (TList.length == 0)
196 alias Filter = TypeTuple!();
198 else static if (TList.length == 1)
200 static if (pred!(TList[0]))
201 alias Filter = TypeTuple!(TList[0]);
203 alias Filter = TypeTuple!();
209 Filter!(pred, TList[ 0 .. $/2]),
210 Filter!(pred, TList[$/2 .. $ ]));