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
resetArchetypeBases::TestBase39 static void reset() {
40 assert(alive == 0);
41 alive = 0;
42 reset_constructors();
43 }
44
reset_constructorsArchetypeBases::TestBase45 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
TestBaseArchetypeBases::TestBase51 TestBase() noexcept : value(0) {
52 ++alive; ++constructed; ++default_constructed;
53 }
54 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TestBaseArchetypeBases::TestBase55 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>
TestBaseArchetypeBases::TestBase59 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>
TestBaseArchetypeBases::TestBase63 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>
TestBaseArchetypeBases::TestBase67 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>
TestBaseArchetypeBases::TestBase71 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>
TestBaseArchetypeBases::TestBase76 explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept : value(static_cast<int>(il.size())) {
77 ++alive; ++constructed; ++value_constructed;
78 }
operator =ArchetypeBases::TestBase79 TestBase& operator=(int xvalue) noexcept {
80 value = xvalue;
81 ++assigned; ++value_assigned;
82 return *this;
83 }
84 protected:
~TestBaseArchetypeBases::TestBase85 ~TestBase() {
86 assert(value != -999); assert(alive > 0);
87 --alive; ++destroyed; value = -999;
88 }
TestBaseArchetypeBases::TestBase89 explicit TestBase(TestBase const& o) noexcept : value(o.value) {
90 assert(o.value != -1); assert(o.value != -999);
91 ++alive; ++constructed; ++copy_constructed;
92 }
TestBaseArchetypeBases::TestBase93 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 }
operator =ArchetypeBases::TestBase98 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 }
operator =ArchetypeBases::TestBase104 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>
ValueBaseArchetypeBases::ValueBase130 explicit constexpr ValueBase(int x) : value(x) {}
131 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase132 constexpr ValueBase(int x) : value(x) {}
133 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase134 explicit constexpr ValueBase(int, int y) : value(y) {}
135 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase136 constexpr ValueBase(int, int y) : value(y) {}
137 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
ValueBaseArchetypeBases::ValueBase138 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>
ValueBaseArchetypeBases::ValueBase140 constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
operator =ArchetypeBases::ValueBase141 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:
check_valueArchetypeBases::ValueBase148 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 }
check_valueArchetypeBases::ValueBase156 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 }
ValueBaseArchetypeBases::ValueBase166 constexpr ValueBase() noexcept : value(0) {}
ValueBaseArchetypeBases::ValueBase167 constexpr ValueBase(ValueBase const& o) noexcept : value(check_value(o.value)) {
168 }
ValueBaseArchetypeBases::ValueBase169 constexpr ValueBase(ValueBase && o) noexcept : value(check_value(o.value)) {
170 }
operator =ArchetypeBases::ValueBase171 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 }
operator =ArchetypeBases::ValueBase176 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>
TrivialValueBaseArchetypeBases::TrivialValueBase188 explicit constexpr TrivialValueBase(int x) : value(x) {}
189 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase190 constexpr TrivialValueBase(int x) : value(x) {}
191 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase192 explicit constexpr TrivialValueBase(int, int y) : value(y) {}
193 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase194 constexpr TrivialValueBase(int, int y) : value(y) {}
195 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
TrivialValueBaseArchetypeBases::TrivialValueBase196 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>
TrivialValueBaseArchetypeBases::TrivialValueBase198 constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
199 int value;
200 protected:
TrivialValueBaseArchetypeBases::TrivialValueBase201 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>
operator ==(Tp const & L,Tp const & R)255 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
256 return L.value == R.value;
257 }
258
259 template <class Tp>
operator !=(Tp const & L,Tp const & R)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>
operator ==(Tp const & L,Tp const & R)278 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
279 return L.value == R.value;
280 }
281
282 template <class Tp>
operator !=(Tp const & L,Tp const & R)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>
operator ==(Tp const & L,Tp const & R)299 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
300 return L.value == R.value;
301 }
302
303 template <class Tp>
operator !=(Tp const & L,Tp const & R)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>
operator ==(Tp const & L,Tp const & R)322 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
323 return L.value == R.value;
324 }
325
326 template <class Tp>
operator !=(Tp const & L,Tp const & R)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>
operator ==(Tp const & L,Tp const & R)344 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
345 return L.value == R.value;
346 }
347
348 template <class Tp>
operator !=(Tp const & L,Tp const & R)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>
operator ==(Tp const & L,Tp const & R)366 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
367 return L.value == R.value;
368 }
369
370 template <class Tp>
operator !=(Tp const & L,Tp const & R)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
380