• 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 //
231 namespace NonConstexprTypes {
232 #define DEFINE_CONSTEXPR
233 #include "archetypes.ipp"
234 }
235 
236 //============================================================================//
237 // Non-literal implicit test types
238 namespace NonLiteralTypes {
239 #define DEFINE_ASSIGN_CONSTEXPR
240 #define DEFINE_DTOR(Name) ~Name() {}
241 #include "archetypes.ipp"
242 }
243 
244 //============================================================================//
245 // Non-Trivially Copyable Implicit Test Types
246 namespace NonTrivialTypes {
247 #define DEFINE_CTOR {}
248 #define DEFINE_ASSIGN { return *this; }
249 #define DEFINE_DEFAULT_CTOR = default
250 #include "archetypes.ipp"
251 }
252 
253 //============================================================================//
254 // Implicit counting types
255 namespace TestTypes {
256 #define DEFINE_CONSTEXPR
257 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
258 #include "archetypes.ipp"
259 
260 using TestType = AllCtors;
261 
262 // Add equality operators
263 template <class Tp>
operator ==(Tp const & L,Tp const & R)264 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
265   return L.value == R.value;
266 }
267 
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 }
274 
275 //============================================================================//
276 // Implicit counting types
277 namespace ExplicitTestTypes {
278 #define DEFINE_CONSTEXPR
279 #define DEFINE_EXPLICIT explicit
280 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
281 #include "archetypes.ipp"
282 
283 using TestType = AllCtors;
284 
285 // Add equality operators
286 template <class Tp>
operator ==(Tp const & L,Tp const & R)287 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
288   return L.value == R.value;
289 }
290 
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 }
297 
298 //============================================================================//
299 // Implicit value types
300 namespace ConstexprTestTypes {
301 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
302 #include "archetypes.ipp"
303 
304 using TestType = AllCtors;
305 
306 // Add equality operators
307 template <class Tp>
operator ==(Tp const & L,Tp const & R)308 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
309   return L.value == R.value;
310 }
311 
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 } // end namespace ValueTypes
318 
319 
320 //============================================================================//
321 //
322 namespace ExplicitConstexprTestTypes {
323 #define DEFINE_EXPLICIT explicit
324 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
325 #include "archetypes.ipp"
326 
327 using TestType = AllCtors;
328 
329 // Add equality operators
330 template <class Tp>
operator ==(Tp const & L,Tp const & R)331 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
332   return L.value == R.value;
333 }
334 
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 } // end namespace ValueTypes
341 
342 
343 //============================================================================//
344 //
345 namespace TrivialTestTypes {
346 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
347 #include "archetypes.ipp"
348 
349 using TestType = AllCtors;
350 
351 // Add equality operators
352 template <class Tp>
operator ==(Tp const & L,Tp const & R)353 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
354   return L.value == R.value;
355 }
356 
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 } // end namespace TrivialValueTypes
363 
364 //============================================================================//
365 //
366 namespace ExplicitTrivialTestTypes {
367 #define DEFINE_EXPLICIT explicit
368 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
369 #include "archetypes.ipp"
370 
371 using TestType = AllCtors;
372 
373 // Add equality operators
374 template <class Tp>
operator ==(Tp const & L,Tp const & R)375 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
376   return L.value == R.value;
377 }
378 
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 } // end namespace ExplicitTrivialTestTypes
385 
386 #endif // TEST_STD_VER >= 11
387 
388 #endif // TEST_SUPPORT_ARCHETYPES_HPP
389