]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/support/archetypes.hpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / support / archetypes.hpp
1 #ifndef TEST_SUPPORT_ARCHETYPES_HPP
2 #define TEST_SUPPORT_ARCHETYPES_HPP
3
4 #include <type_traits>
5 #include <cassert>
6
7 #include "test_macros.h"
8
9 #if TEST_STD_VER >= 11
10
11 namespace ArchetypeBases {
12
13 template <bool, class T>
14 struct DepType : T {};
15
16 struct NullBase {
17 protected:
18   NullBase() = default;
19   NullBase(NullBase const&) = default;
20   NullBase& operator=(NullBase const&) = default;
21   NullBase(NullBase &&) = default;
22   NullBase& operator=(NullBase &&) = default;
23 };
24
25 template <class Derived, bool Explicit = false>
26 struct TestBase {
27     static int alive;
28     static int constructed;
29     static int value_constructed;
30     static int default_constructed;
31     static int copy_constructed;
32     static int move_constructed;
33     static int assigned;
34     static int value_assigned;
35     static int copy_assigned;
36     static int move_assigned;
37     static int destroyed;
38
39     static void reset() {
40         assert(alive == 0);
41         alive = 0;
42         reset_constructors();
43     }
44
45     static void reset_constructors() {
46       constructed = value_constructed = default_constructed =
47         copy_constructed = move_constructed = 0;
48       assigned = value_assigned = copy_assigned = move_assigned = destroyed = 0;
49     }
50
51     TestBase() noexcept : value(0) {
52         ++alive; ++constructed; ++default_constructed;
53     }
54     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
55     explicit TestBase(int x) noexcept : value(x) {
56         ++alive; ++constructed; ++value_constructed;
57     }
58     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
59     TestBase(int x) noexcept : value(x) {
60         ++alive; ++constructed; ++value_constructed;
61     }
62     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
63     explicit TestBase(int, int y) noexcept : value(y) {
64         ++alive; ++constructed; ++value_constructed;
65     }
66     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
67     TestBase(int, int y) noexcept : value(y) {
68         ++alive; ++constructed; ++value_constructed;
69     }
70     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
71     explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept
72       : value(static_cast<int>(il.size())) {
73         ++alive; ++constructed; ++value_constructed;
74     }
75     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
76     explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept : value(static_cast<int>(il.size())) {
77         ++alive; ++constructed; ++value_constructed;
78     }
79     TestBase& operator=(int xvalue) noexcept {
80       value = xvalue;
81       ++assigned; ++value_assigned;
82       return *this;
83     }
84 protected:
85     ~TestBase() {
86       assert(value != -999); assert(alive > 0);
87       --alive; ++destroyed; value = -999;
88     }
89     explicit TestBase(TestBase const& o) noexcept : value(o.value) {
90         assert(o.value != -1); assert(o.value != -999);
91         ++alive; ++constructed; ++copy_constructed;
92     }
93     explicit TestBase(TestBase && o) noexcept : value(o.value) {
94         assert(o.value != -1); assert(o.value != -999);
95         ++alive; ++constructed; ++move_constructed;
96         o.value = -1;
97     }
98     TestBase& operator=(TestBase const& o) noexcept {
99       assert(o.value != -1); assert(o.value != -999);
100       ++assigned; ++copy_assigned;
101       value = o.value;
102       return *this;
103     }
104     TestBase& operator=(TestBase&& o) noexcept {
105         assert(o.value != -1); assert(o.value != -999);
106         ++assigned; ++move_assigned;
107         value = o.value;
108         o.value = -1;
109         return *this;
110     }
111 public:
112     int value;
113 };
114
115 template <class D, bool E> int TestBase<D, E>::alive = 0;
116 template <class D, bool E> int TestBase<D, E>::constructed = 0;
117 template <class D, bool E> int TestBase<D, E>::value_constructed = 0;
118 template <class D, bool E> int TestBase<D, E>::default_constructed = 0;
119 template <class D, bool E> int TestBase<D, E>::copy_constructed = 0;
120 template <class D, bool E> int TestBase<D, E>::move_constructed = 0;
121 template <class D, bool E> int TestBase<D, E>::assigned = 0;
122 template <class D, bool E> int TestBase<D, E>::value_assigned = 0;
123 template <class D, bool E> int TestBase<D, E>::copy_assigned = 0;
124 template <class D, bool E> int TestBase<D, E>::move_assigned = 0;
125 template <class D, bool E> int TestBase<D, E>::destroyed = 0;
126
127 template <bool Explicit = false>
128 struct ValueBase {
129     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
130     explicit constexpr ValueBase(int x) : value(x) {}
131     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
132     constexpr ValueBase(int x) : value(x) {}
133     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
134     explicit constexpr ValueBase(int, int y) : value(y) {}
135     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
136     constexpr ValueBase(int, int y) : value(y) {}
137     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
138     explicit constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
139     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
140     constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
141     TEST_CONSTEXPR_CXX14 ValueBase& operator=(int xvalue) noexcept {
142         value = xvalue;
143         return *this;
144     }
145     //~ValueBase() { assert(value != -999); value = -999; }
146     int value;
147 protected:
148     constexpr static int check_value(int const& val) {
149 #if TEST_STD_VER < 14
150       return val == -1 || val == 999 ? (TEST_THROW(42), 0) : val;
151 #else
152       assert(val != -1); assert(val != 999);
153       return val;
154 #endif
155     }
156     constexpr static int check_value(int& val, int val_cp = 0) {
157 #if TEST_STD_VER < 14
158       return val_cp = val, val = -1, (val_cp == -1 || val_cp == 999 ? (TEST_THROW(42), 0) : val_cp);
159 #else
160       assert(val != -1); assert(val != 999);
161       val_cp = val;
162       val = -1;
163       return val_cp;
164 #endif
165     }
166     constexpr ValueBase() noexcept : value(0) {}
167     constexpr ValueBase(ValueBase const& o) noexcept : value(check_value(o.value)) {
168     }
169     constexpr ValueBase(ValueBase && o) noexcept : value(check_value(o.value)) {
170     }
171     TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase const& o) noexcept {
172         assert(o.value != -1); assert(o.value != -999);
173         value = o.value;
174         return *this;
175     }
176     TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase&& o) noexcept {
177         assert(o.value != -1); assert(o.value != -999);
178         value = o.value;
179         o.value = -1;
180         return *this;
181     }
182 };
183
184
185 template <bool Explicit = false>
186 struct TrivialValueBase {
187     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
188     explicit constexpr TrivialValueBase(int x) : value(x) {}
189     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
190     constexpr TrivialValueBase(int x) : value(x) {}
191     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
192     explicit constexpr TrivialValueBase(int, int y) : value(y) {}
193     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
194     constexpr TrivialValueBase(int, int y) : value(y) {}
195     template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
196     explicit constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
197     template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
198     constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
199     int value;
200 protected:
201     constexpr TrivialValueBase() noexcept : value(0) {}
202 };
203
204 }
205
206 //============================================================================//
207 // Trivial Implicit Test Types
208 namespace ImplicitTypes {
209 #include "archetypes.ipp"
210 }
211
212 //============================================================================//
213 // Trivial Explicit Test Types
214 namespace ExplicitTypes {
215 #define DEFINE_EXPLICIT explicit
216 #include "archetypes.ipp"
217 }
218
219
220 //============================================================================//
221 //
222 namespace NonConstexprTypes {
223 #define DEFINE_CONSTEXPR
224 #include "archetypes.ipp"
225 }
226
227 //============================================================================//
228 // Non-literal implicit test types
229 namespace NonLiteralTypes {
230 #define DEFINE_ASSIGN_CONSTEXPR
231 #define DEFINE_DTOR(Name) ~Name() {}
232 #include "archetypes.ipp"
233 }
234
235 //============================================================================//
236 // Non-Trivially Copyable Implicit Test Types
237 namespace NonTrivialTypes {
238 #define DEFINE_CTOR {}
239 #define DEFINE_ASSIGN { return *this; }
240 #define DEFINE_DEFAULT_CTOR = default
241 #include "archetypes.ipp"
242 }
243
244 //============================================================================//
245 // Implicit counting types
246 namespace TestTypes {
247 #define DEFINE_CONSTEXPR
248 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
249 #include "archetypes.ipp"
250
251 using TestType = AllCtors;
252
253 // Add equality operators
254 template <class Tp>
255 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
256   return L.value == R.value;
257 }
258
259 template <class Tp>
260 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
261   return L.value != R.value;
262 }
263
264 }
265
266 //============================================================================//
267 // Implicit counting types
268 namespace ExplicitTestTypes {
269 #define DEFINE_CONSTEXPR
270 #define DEFINE_EXPLICIT explicit
271 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
272 #include "archetypes.ipp"
273
274 using TestType = AllCtors;
275
276 // Add equality operators
277 template <class Tp>
278 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
279   return L.value == R.value;
280 }
281
282 template <class Tp>
283 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
284   return L.value != R.value;
285 }
286
287 }
288
289 //============================================================================//
290 // Implicit value types
291 namespace ConstexprTestTypes {
292 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
293 #include "archetypes.ipp"
294
295 using TestType = AllCtors;
296
297 // Add equality operators
298 template <class Tp>
299 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
300   return L.value == R.value;
301 }
302
303 template <class Tp>
304 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
305   return L.value != R.value;
306 }
307
308 } // end namespace ValueTypes
309
310
311 //============================================================================//
312 //
313 namespace ExplicitConstexprTestTypes {
314 #define DEFINE_EXPLICIT explicit
315 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
316 #include "archetypes.ipp"
317
318 using TestType = AllCtors;
319
320 // Add equality operators
321 template <class Tp>
322 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
323   return L.value == R.value;
324 }
325
326 template <class Tp>
327 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
328   return L.value != R.value;
329 }
330
331 } // end namespace ValueTypes
332
333
334 //============================================================================//
335 //
336 namespace TrivialTestTypes {
337 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
338 #include "archetypes.ipp"
339
340 using TestType = AllCtors;
341
342 // Add equality operators
343 template <class Tp>
344 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
345   return L.value == R.value;
346 }
347
348 template <class Tp>
349 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
350   return L.value != R.value;
351 }
352
353 } // end namespace TrivialValueTypes
354
355 //============================================================================//
356 //
357 namespace ExplicitTrivialTestTypes {
358 #define DEFINE_EXPLICIT explicit
359 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
360 #include "archetypes.ipp"
361
362 using TestType = AllCtors;
363
364 // Add equality operators
365 template <class Tp>
366 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
367   return L.value == R.value;
368 }
369
370 template <class Tp>
371 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
372   return L.value != R.value;
373 }
374
375 } // end namespace ExplicitTrivialTestTypes
376
377 #endif // TEST_STD_VER >= 11
378
379 #endif // TEST_SUPPORT_ARCHETYPES_HPP