]> git.ipfire.org Git - thirdparty/gcc.git/blob - libphobos/libdruntime/core/internal/traits.d
Add D front-end, libphobos library, and D2 testsuite.
[thirdparty/gcc.git] / libphobos / libdruntime / core / internal / traits.d
1 /**
2 * Contains traits for runtime internal usage.
3 *
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)
8 */
9 module core.internal.traits;
10
11 /// taken from std.typetuple.TypeTuple
12 template TypeTuple(TList...)
13 {
14 alias TypeTuple = TList;
15 }
16
17 T trustedCast(T, U)(auto ref U u) @trusted pure nothrow
18 {
19 return cast(T)u;
20 }
21
22 template Unconst(T)
23 {
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;
29 }
30
31 /// taken from std.traits.Unqual
32 template Unqual(T)
33 {
34 version (none) // Error: recursive alias declaration @@@BUG1308@@@
35 {
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;
41 }
42 else // workaround
43 {
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;
53 }
54 }
55
56 // Substitute all `inout` qualifiers that appears in T to `const`
57 template substInout(T)
58 {
59 static if (is(T == immutable))
60 {
61 alias substInout = T;
62 }
63 else static if (is(T : shared const U, U) || is(T : const U, U))
64 {
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;");
70 }
71 else
72 static assert(0);
73 }
74
75 private template substInoutForm(T)
76 {
77 static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface))
78 {
79 alias substInoutForm = T; // prevent matching to the form of alias-this-ed type
80 }
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;
86 }
87
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))
90 {
91 static if (is(FT RT == return) && is(FT Args == function))
92 {
93 import core.demangle : mangleFunc;
94 enum decl = {
95 string s = "extern(D) RT externDFunc(Args)";
96 foreach (attr; __traits(getFunctionAttributes, FT))
97 s ~= " " ~ attr;
98 return s ~ ";";
99 }();
100 pragma(mangle, mangleFunc!T(fqn)) mixin(decl);
101 }
102 else
103 static assert(0);
104 }
105
106 template staticIota(int beg, int end)
107 {
108 static if (beg + 1 >= end)
109 {
110 static if (beg >= end)
111 {
112 alias staticIota = TypeTuple!();
113 }
114 else
115 {
116 alias staticIota = TypeTuple!(+beg);
117 }
118 }
119 else
120 {
121 enum mid = beg + (end - beg) / 2;
122 alias staticIota = TypeTuple!(staticIota!(beg, mid), staticIota!(mid, end));
123 }
124 }
125
126 template dtorIsNothrow(T)
127 {
128 enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow);
129 }
130
131 template anySatisfy(alias F, T...)
132 {
133 static if (T.length == 0)
134 {
135 enum anySatisfy = false;
136 }
137 else static if (T.length == 1)
138 {
139 enum anySatisfy = F!(T[0]);
140 }
141 else
142 {
143 enum anySatisfy =
144 anySatisfy!(F, T[ 0 .. $/2]) ||
145 anySatisfy!(F, T[$/2 .. $ ]);
146 }
147 }
148
149 // Somehow fails for non-static nested structs without support for aliases
150 template hasElaborateDestructor(T...)
151 {
152 static if (is(T[0]))
153 alias S = T[0];
154 else
155 alias S = typeof(T[0]);
156
157 static if (is(S : E[n], E, size_t n) && S.length)
158 {
159 enum bool hasElaborateDestructor = hasElaborateDestructor!E;
160 }
161 else static if (is(S == struct))
162 {
163 enum hasElaborateDestructor = __traits(hasMember, S, "__dtor")
164 || anySatisfy!(.hasElaborateDestructor, S.tupleof);
165 }
166 else
167 enum bool hasElaborateDestructor = false;
168 }
169
170 // Somehow fails for non-static nested structs without support for aliases
171 template hasElaborateCopyConstructor(T...)
172 {
173 static if (is(T[0]))
174 alias S = T[0];
175 else
176 alias S = typeof(T[0]);
177
178 static if (is(S : E[n], E, size_t n) && S.length)
179 {
180 enum bool hasElaborateCopyConstructor = hasElaborateCopyConstructor!E;
181 }
182 else static if (is(S == struct))
183 {
184 enum hasElaborateCopyConstructor = __traits(hasMember, S, "__postblit")
185 || anySatisfy!(.hasElaborateCopyConstructor, S.tupleof);
186 }
187 else
188 enum bool hasElaborateCopyConstructor = false;
189 }
190
191 // std.meta.Filter
192 template Filter(alias pred, TList...)
193 {
194 static if (TList.length == 0)
195 {
196 alias Filter = TypeTuple!();
197 }
198 else static if (TList.length == 1)
199 {
200 static if (pred!(TList[0]))
201 alias Filter = TypeTuple!(TList[0]);
202 else
203 alias Filter = TypeTuple!();
204 }
205 else
206 {
207 alias Filter =
208 TypeTuple!(
209 Filter!(pred, TList[ 0 .. $/2]),
210 Filter!(pred, TList[$/2 .. $ ]));
211 }
212 }