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 #include "test_workarounds.h"
9
10 #if TEST_STD_VER >= 11
11
12 namespace ArchetypeBases {
13
14 template <bool, class T>
15 struct DepType : T {};
16
17 struct NullBase {
18 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
19 protected:
20 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
21 NullBase() = default;
22 NullBase(NullBase const&) = default;
23 NullBase& operator=(NullBase const&) = default;
24 NullBase(NullBase &&) = default;
25 NullBase& operator=(NullBase &&) = default;
26 };
27
28 template <class Derived, bool Explicit = false>
29 struct TestBase {
30 static int alive;
31 static int constructed;
32 static int value_constructed;
33 static int default_constructed;
34 static int copy_constructed;
35 static int move_constructed;
36 static int assigned;
37 static int value_assigned;
38 static int copy_assigned;
39 static int move_assigned;
40 static int destroyed;
41
resetArchetypeBases::TestBase42 static void reset() {
43 assert(alive == 0);
44 alive = 0;
45 reset_constructors();
46 }
47
reset_constructorsArchetypeBases::TestBase48 static void reset_constructors() {
49 constructed = value_constructed = default_constructed =
50 copy_constructed = move_constructed = 0;
51 assigned = value_assigned = copy_assigned = move_assigned = destroyed = 0;
52 }
53
TestBaseArchetypeBases::TestBase54 TestBase() noexcept : value(0) {
55 ++alive; ++constructed; ++default_constructed;
56 }
57 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TestBaseArchetypeBases::TestBase58 explicit TestBase(int x) noexcept : value(x) {
59 ++alive; ++constructed; ++value_constructed;
60 }
61 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TestBaseArchetypeBases::TestBase62 TestBase(int x) noexcept : value(x) {
63 ++alive; ++constructed; ++value_constructed;
64 }
65 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TestBaseArchetypeBases::TestBase66 explicit TestBase(int, int y) noexcept : value(y) {
67 ++alive; ++constructed; ++value_constructed;
68 }
69 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TestBaseArchetypeBases::TestBase70 TestBase(int, int y) noexcept : value(y) {
71 ++alive; ++constructed; ++value_constructed;
72 }
73 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TestBaseArchetypeBases::TestBase74 explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept
75 : value(static_cast<int>(il.size())) {
76 ++alive; ++constructed; ++value_constructed;
77 }
78 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TestBaseArchetypeBases::TestBase79 explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept : value(static_cast<int>(il.size())) {
80 ++alive; ++constructed; ++value_constructed;
81 }
operator =ArchetypeBases::TestBase82 TestBase& operator=(int xvalue) noexcept {
83 value = xvalue;
84 ++assigned; ++value_assigned;
85 return *this;
86 }
87 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
88 protected:
89 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
~TestBaseArchetypeBases::TestBase90 ~TestBase() {
91 assert(value != -999); assert(alive > 0);
92 --alive; ++destroyed; value = -999;
93 }
TestBaseArchetypeBases::TestBase94 explicit TestBase(TestBase const& o) noexcept : value(o.value) {
95 assert(o.value != -1); assert(o.value != -999);
96 ++alive; ++constructed; ++copy_constructed;
97 }
TestBaseArchetypeBases::TestBase98 explicit TestBase(TestBase && o) noexcept : value(o.value) {
99 assert(o.value != -1); assert(o.value != -999);
100 ++alive; ++constructed; ++move_constructed;
101 o.value = -1;
102 }
operator =ArchetypeBases::TestBase103 TestBase& operator=(TestBase const& o) noexcept {
104 assert(o.value != -1); assert(o.value != -999);
105 ++assigned; ++copy_assigned;
106 value = o.value;
107 return *this;
108 }
operator =ArchetypeBases::TestBase109 TestBase& operator=(TestBase&& o) noexcept {
110 assert(o.value != -1); assert(o.value != -999);
111 ++assigned; ++move_assigned;
112 value = o.value;
113 o.value = -1;
114 return *this;
115 }
116 public:
117 int value;
118 };
119
120 template <class D, bool E> int TestBase<D, E>::alive = 0;
121 template <class D, bool E> int TestBase<D, E>::constructed = 0;
122 template <class D, bool E> int TestBase<D, E>::value_constructed = 0;
123 template <class D, bool E> int TestBase<D, E>::default_constructed = 0;
124 template <class D, bool E> int TestBase<D, E>::copy_constructed = 0;
125 template <class D, bool E> int TestBase<D, E>::move_constructed = 0;
126 template <class D, bool E> int TestBase<D, E>::assigned = 0;
127 template <class D, bool E> int TestBase<D, E>::value_assigned = 0;
128 template <class D, bool E> int TestBase<D, E>::copy_assigned = 0;
129 template <class D, bool E> int TestBase<D, E>::move_assigned = 0;
130 template <class D, bool E> int TestBase<D, E>::destroyed = 0;
131
132 template <bool Explicit = false>
133 struct ValueBase {
134 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase135 explicit constexpr ValueBase(int x) : value(x) {}
136 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase137 constexpr ValueBase(int x) : value(x) {}
138 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase139 explicit constexpr ValueBase(int, int y) : value(y) {}
140 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase141 constexpr ValueBase(int, int y) : value(y) {}
142 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase143 explicit constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
144 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase145 constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
operator =ArchetypeBases::ValueBase146 TEST_CONSTEXPR_CXX14 ValueBase& operator=(int xvalue) noexcept {
147 value = xvalue;
148 return *this;
149 }
150 //~ValueBase() { assert(value != -999); value = -999; }
151 int value;
152 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
153 protected:
154 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
check_valueArchetypeBases::ValueBase155 constexpr static int check_value(int const& val) {
156 #if TEST_STD_VER < 14
157 return val == -1 || val == 999 ? (TEST_THROW(42), 0) : val;
158 #else
159 assert(val != -1); assert(val != 999);
160 return val;
161 #endif
162 }
check_valueArchetypeBases::ValueBase163 constexpr static int check_value(int& val, int val_cp = 0) {
164 #if TEST_STD_VER < 14
165 return val_cp = val, val = -1, (val_cp == -1 || val_cp == 999 ? (TEST_THROW(42), 0) : val_cp);
166 #else
167 assert(val != -1); assert(val != 999);
168 val_cp = val;
169 val = -1;
170 return val_cp;
171 #endif
172 }
ValueBaseArchetypeBases::ValueBase173 constexpr ValueBase() noexcept : value(0) {}
ValueBaseArchetypeBases::ValueBase174 constexpr ValueBase(ValueBase const& o) noexcept : value(check_value(o.value)) {
175 }
ValueBaseArchetypeBases::ValueBase176 constexpr ValueBase(ValueBase && o) noexcept : value(check_value(o.value)) {
177 }
operator =ArchetypeBases::ValueBase178 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase const& o) noexcept {
179 assert(o.value != -1); assert(o.value != -999);
180 value = o.value;
181 return *this;
182 }
operator =ArchetypeBases::ValueBase183 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase&& o) noexcept {
184 assert(o.value != -1); assert(o.value != -999);
185 value = o.value;
186 o.value = -1;
187 return *this;
188 }
189 };
190
191
192 template <bool Explicit = false>
193 struct TrivialValueBase {
194 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase195 explicit constexpr TrivialValueBase(int x) : value(x) {}
196 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase197 constexpr TrivialValueBase(int x) : value(x) {}
198 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase199 explicit constexpr TrivialValueBase(int, int y) : value(y) {}
200 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase201 constexpr TrivialValueBase(int, int y) : value(y) {}
202 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase203 explicit constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
204 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase205 constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
206 int value;
207 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
208 protected:
209 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
TrivialValueBaseArchetypeBases::TrivialValueBase210 constexpr TrivialValueBase() noexcept : value(0) {}
211 };
212
213 }
214
215 //============================================================================//
216 // Trivial Implicit Test Types
217 namespace ImplicitTypes {
218 #include "archetypes.ipp"
219 }
220
221 //============================================================================//
222 // Trivial Explicit Test Types
223 namespace ExplicitTypes {
224 #define DEFINE_EXPLICIT explicit
225 #include "archetypes.ipp"
226 }
227
228 //============================================================================//
229 //
230 namespace NonConstexprTypes {
231 #define DEFINE_CONSTEXPR
232 #include "archetypes.ipp"
233 }
234
235 //============================================================================//
236 // Non-literal implicit test types
237 namespace NonLiteralTypes {
238 #define DEFINE_ASSIGN_CONSTEXPR
239 #define DEFINE_DTOR(Name) ~Name() {}
240 #include "archetypes.ipp"
241 }
242
243 //============================================================================//
244 // Non-throwing implicit test types
245 namespace NonThrowingTypes {
246 #define DEFINE_NOEXCEPT noexcept
247 #include "archetypes.ipp"
248 }
249
250 //============================================================================//
251 // Non-Trivially Copyable Implicit Test Types
252 namespace NonTrivialTypes {
253 #define DEFINE_CTOR {}
254 #define DEFINE_ASSIGN { return *this; }
255 #include "archetypes.ipp"
256 }
257
258 //============================================================================//
259 // Implicit counting types
260 namespace TestTypes {
261 #define DEFINE_CONSTEXPR
262 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
263 #include "archetypes.ipp"
264
265 using TestType = AllCtors;
266
267 // Add equality operators
268 template <class Tp>
operator ==(Tp const & L,Tp const & R)269 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
270 return L.value == R.value;
271 }
272
273 template <class Tp>
operator !=(Tp const & L,Tp const & R)274 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
275 return L.value != R.value;
276 }
277
278 }
279
280 //============================================================================//
281 // Implicit counting types
282 namespace ExplicitTestTypes {
283 #define DEFINE_CONSTEXPR
284 #define DEFINE_EXPLICIT explicit
285 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
286 #include "archetypes.ipp"
287
288 using TestType = AllCtors;
289
290 // Add equality operators
291 template <class Tp>
operator ==(Tp const & L,Tp const & R)292 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
293 return L.value == R.value;
294 }
295
296 template <class Tp>
operator !=(Tp const & L,Tp const & R)297 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
298 return L.value != R.value;
299 }
300
301 }
302
303 //============================================================================//
304 // Implicit value types
305 namespace ConstexprTestTypes {
306 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
307 #include "archetypes.ipp"
308
309 using TestType = AllCtors;
310
311 // Add equality operators
312 template <class Tp>
operator ==(Tp const & L,Tp const & R)313 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
314 return L.value == R.value;
315 }
316
317 template <class Tp>
operator !=(Tp const & L,Tp const & R)318 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
319 return L.value != R.value;
320 }
321
322 } // end namespace ConstexprTestTypes
323
324
325 //============================================================================//
326 //
327 namespace ExplicitConstexprTestTypes {
328 #define DEFINE_EXPLICIT explicit
329 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
330 #include "archetypes.ipp"
331
332 using TestType = AllCtors;
333
334 // Add equality operators
335 template <class Tp>
operator ==(Tp const & L,Tp const & R)336 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
337 return L.value == R.value;
338 }
339
340 template <class Tp>
operator !=(Tp const & L,Tp const & R)341 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
342 return L.value != R.value;
343 }
344
345 } // end namespace ExplicitConstexprTestTypes
346
347
348 //============================================================================//
349 //
350 namespace TrivialTestTypes {
351 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
352 #include "archetypes.ipp"
353
354 using TestType = AllCtors;
355
356 // Add equality operators
357 template <class Tp>
operator ==(Tp const & L,Tp const & R)358 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
359 return L.value == R.value;
360 }
361
362 template <class Tp>
operator !=(Tp const & L,Tp const & R)363 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
364 return L.value != R.value;
365 }
366
367 } // end namespace TrivialTestTypes
368
369 //============================================================================//
370 //
371 namespace ExplicitTrivialTestTypes {
372 #define DEFINE_EXPLICIT explicit
373 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
374 #include "archetypes.ipp"
375
376 using TestType = AllCtors;
377
378 // Add equality operators
379 template <class Tp>
operator ==(Tp const & L,Tp const & R)380 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
381 return L.value == R.value;
382 }
383
384 template <class Tp>
operator !=(Tp const & L,Tp const & R)385 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
386 return L.value != R.value;
387 }
388
389 } // end namespace ExplicitTrivialTestTypes
390
391 #endif // TEST_STD_VER >= 11
392
393 #endif // TEST_SUPPORT_ARCHETYPES_HPP
394