]> git.ipfire.org Git - thirdparty/gcc.git/blob - libphobos/libdruntime/rt/util/typeinfo.d
Add D front-end, libphobos library, and D2 testsuite.
[thirdparty/gcc.git] / libphobos / libdruntime / rt / util / typeinfo.d
1 /**
2 * This module contains utilities for TypeInfo implementation.
3 *
4 * Copyright: Copyright Kenji Hara 2014-.
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
6 * Authors: Kenji Hara
7 */
8 module rt.util.typeinfo;
9
10 template Floating(T)
11 if (is(T == float) || is(T == double) || is(T == real))
12 {
13 pure nothrow @safe:
14
15 bool equals(T f1, T f2)
16 {
17 return f1 == f2;
18 }
19
20 int compare(T d1, T d2)
21 {
22 if (d1 != d1 || d2 != d2) // if either are NaN
23 {
24 if (d1 != d1)
25 {
26 if (d2 != d2)
27 return 0;
28 return -1;
29 }
30 return 1;
31 }
32 return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
33 }
34
35 size_t hashOf(T value) @trusted
36 {
37 if (value == 0) // +0.0 and -0.0
38 value = 0;
39
40 static if (is(T == float)) // special case?
41 return *cast(uint*)&value;
42 else
43 {
44 import rt.util.hash;
45 return rt.util.hash.hashOf((&value)[0 .. 1], 0);
46 }
47 }
48 }
49 template Floating(T)
50 if (is(T == cfloat) || is(T == cdouble) || is(T == creal))
51 {
52 pure nothrow @safe:
53
54 bool equals(T f1, T f2)
55 {
56 return f1 == f2;
57 }
58
59 int compare(T f1, T f2)
60 {
61 int result;
62
63 if (f1.re < f2.re)
64 result = -1;
65 else if (f1.re > f2.re)
66 result = 1;
67 else if (f1.im < f2.im)
68 result = -1;
69 else if (f1.im > f2.im)
70 result = 1;
71 else
72 result = 0;
73 return result;
74 }
75
76 size_t hashOf(T value) @trusted
77 {
78 if (value == 0 + 0i)
79 value = 0 + 0i;
80 import rt.util.hash;
81 return rt.util.hash.hashOf((&value)[0 .. 1], 0);
82 }
83 }
84
85 template Array(T)
86 if (is(T == float) || is(T == double) || is(T == real) ||
87 is(T == cfloat) || is(T == cdouble) || is(T == creal))
88 {
89 pure nothrow @safe:
90
91 bool equals(T[] s1, T[] s2)
92 {
93 size_t len = s1.length;
94 if (len != s2.length)
95 return false;
96 for (size_t u = 0; u < len; u++)
97 {
98 if (!Floating!T.equals(s1[u], s2[u]))
99 return false;
100 }
101 return true;
102 }
103
104 int compare(T[] s1, T[] s2)
105 {
106 size_t len = s1.length;
107 if (s2.length < len)
108 len = s2.length;
109 for (size_t u = 0; u < len; u++)
110 {
111 if (int c = Floating!T.compare(s1[u], s2[u]))
112 return c;
113 }
114 if (s1.length < s2.length)
115 return -1;
116 else if (s1.length > s2.length)
117 return 1;
118 return 0;
119 }
120
121 size_t hashOf(T[] value)
122 {
123 size_t h = 0;
124 foreach (e; value)
125 h += Floating!T.hashOf(e);
126 return h;
127 }
128 }
129
130 version (unittest)
131 {
132 alias TypeTuple(T...) = T;
133 }
134 unittest
135 {
136 // Bugzilla 13052
137
138 static struct SX(F) { F f; }
139 TypeInfo ti;
140
141 // real types
142 foreach (F; TypeTuple!(float, double, real))
143 (){ // workaround #2396
144 alias S = SX!F;
145 F f1 = +0.0,
146 f2 = -0.0;
147
148 assert(f1 == f2);
149 assert(f1 !is f2);
150 ti = typeid(F);
151 assert(ti.getHash(&f1) == ti.getHash(&f2));
152
153 F[] a1 = [f1, f1, f1];
154 F[] a2 = [f2, f2, f2];
155 assert(a1 == a2);
156 assert(a1 !is a2);
157 ti = typeid(F[]);
158 assert(ti.getHash(&a1) == ti.getHash(&a2));
159
160 F[][] aa1 = [a1, a1, a1];
161 F[][] aa2 = [a2, a2, a2];
162 assert(aa1 == aa2);
163 assert(aa1 !is aa2);
164 ti = typeid(F[][]);
165 assert(ti.getHash(&aa1) == ti.getHash(&aa2));
166
167 S s1 = {f1},
168 s2 = {f2};
169 assert(s1 == s2);
170 assert(s1 !is s2);
171 ti = typeid(S);
172 assert(ti.getHash(&s1) == ti.getHash(&s2));
173
174 S[] da1 = [S(f1), S(f1), S(f1)],
175 da2 = [S(f2), S(f2), S(f2)];
176 assert(da1 == da2);
177 assert(da1 !is da2);
178 ti = typeid(S[]);
179 assert(ti.getHash(&da1) == ti.getHash(&da2));
180
181 S[3] sa1 = {f1},
182 sa2 = {f2};
183 assert(sa1 == sa2);
184 assert(sa1[] !is sa2[]);
185 ti = typeid(S[3]);
186 assert(ti.getHash(&sa1) == ti.getHash(&sa2));
187 }();
188
189 // imaginary types
190 foreach (F; TypeTuple!(ifloat, idouble, ireal))
191 (){ // workaround #2396
192 alias S = SX!F;
193 F f1 = +0.0i,
194 f2 = -0.0i;
195
196 assert(f1 == f2);
197 assert(f1 !is f2);
198 ti = typeid(F);
199 assert(ti.getHash(&f1) == ti.getHash(&f2));
200
201 F[] a1 = [f1, f1, f1];
202 F[] a2 = [f2, f2, f2];
203 assert(a1 == a2);
204 assert(a1 !is a2);
205 ti = typeid(F[]);
206 assert(ti.getHash(&a1) == ti.getHash(&a2));
207
208 F[][] aa1 = [a1, a1, a1];
209 F[][] aa2 = [a2, a2, a2];
210 assert(aa1 == aa2);
211 assert(aa1 !is aa2);
212 ti = typeid(F[][]);
213 assert(ti.getHash(&aa1) == ti.getHash(&aa2));
214
215 S s1 = {f1},
216 s2 = {f2};
217 assert(s1 == s2);
218 assert(s1 !is s2);
219 ti = typeid(S);
220 assert(ti.getHash(&s1) == ti.getHash(&s2));
221
222 S[] da1 = [S(f1), S(f1), S(f1)],
223 da2 = [S(f2), S(f2), S(f2)];
224 assert(da1 == da2);
225 assert(da1 !is da2);
226 ti = typeid(S[]);
227 assert(ti.getHash(&da1) == ti.getHash(&da2));
228
229 S[3] sa1 = {f1},
230 sa2 = {f2};
231 assert(sa1 == sa2);
232 assert(sa1[] !is sa2[]);
233 ti = typeid(S[3]);
234 assert(ti.getHash(&sa1) == ti.getHash(&sa2));
235 }();
236
237 // complex types
238 foreach (F; TypeTuple!(cfloat, cdouble, creal))
239 (){ // workaround #2396
240 alias S = SX!F;
241 F[4] f = [+0.0 + 0.0i,
242 +0.0 - 0.0i,
243 -0.0 + 0.0i,
244 -0.0 - 0.0i];
245
246 foreach (i, f1; f) foreach (j, f2; f) if (i != j)
247 {
248 assert(f1 == 0 + 0i);
249
250 assert(f1 == f2);
251 assert(f1 !is f2);
252 ti = typeid(F);
253 assert(ti.getHash(&f1) == ti.getHash(&f2));
254
255 F[] a1 = [f1, f1, f1];
256 F[] a2 = [f2, f2, f2];
257 assert(a1 == a2);
258 assert(a1 !is a2);
259 ti = typeid(F[]);
260 assert(ti.getHash(&a1) == ti.getHash(&a2));
261
262 F[][] aa1 = [a1, a1, a1];
263 F[][] aa2 = [a2, a2, a2];
264 assert(aa1 == aa2);
265 assert(aa1 !is aa2);
266 ti = typeid(F[][]);
267 assert(ti.getHash(&aa1) == ti.getHash(&aa2));
268
269 S s1 = {f1},
270 s2 = {f2};
271 assert(s1 == s2);
272 assert(s1 !is s2);
273 ti = typeid(S);
274 assert(ti.getHash(&s1) == ti.getHash(&s2));
275
276 S[] da1 = [S(f1), S(f1), S(f1)],
277 da2 = [S(f2), S(f2), S(f2)];
278 assert(da1 == da2);
279 assert(da1 !is da2);
280 ti = typeid(S[]);
281 assert(ti.getHash(&da1) == ti.getHash(&da2));
282
283 S[3] sa1 = {f1},
284 sa2 = {f2};
285 assert(sa1 == sa2);
286 assert(sa1[] !is sa2[]);
287 ti = typeid(S[3]);
288 assert(ti.getHash(&sa1) == ti.getHash(&sa2));
289 }
290 }();
291 }