• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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