1 #ifndef TEST_SUPPORT_ARCHETYPES_HPP
2 #define TEST_SUPPORT_ARCHETYPES_HPP
7 #include "test_macros.h"
11 namespace ArchetypeBases {
13 template <bool, class T>
14 struct DepType : T {};
19 NullBase(NullBase const&) = default;
20 NullBase& operator=(NullBase const&) = default;
21 NullBase(NullBase &&) = default;
22 NullBase& operator=(NullBase &&) = default;
25 template <class Derived, bool Explicit = false>
28 static int constructed;
29 static int value_constructed;
30 static int default_constructed;
31 static int copy_constructed;
32 static int move_constructed;
34 static int value_assigned;
35 static int copy_assigned;
36 static int move_assigned;
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;
51 TestBase() noexcept : value(0) {
52 ++alive; ++constructed; ++default_constructed;
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;
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;
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;
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;
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;
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;
79 TestBase& operator=(int xvalue) noexcept {
81 ++assigned; ++value_assigned;
86 assert(value != -999); assert(alive > 0);
87 --alive; ++destroyed; value = -999;
89 explicit TestBase(TestBase const& o) noexcept : value(o.value) {
90 assert(o.value != -1); assert(o.value != -999);
91 ++alive; ++constructed; ++copy_constructed;
93 explicit TestBase(TestBase && o) noexcept : value(o.value) {
94 assert(o.value != -1); assert(o.value != -999);
95 ++alive; ++constructed; ++move_constructed;
98 TestBase& operator=(TestBase const& o) noexcept {
99 assert(o.value != -1); assert(o.value != -999);
100 ++assigned; ++copy_assigned;
104 TestBase& operator=(TestBase&& o) noexcept {
105 assert(o.value != -1); assert(o.value != -999);
106 ++assigned; ++move_assigned;
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;
127 template <bool Explicit = false>
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 {
145 //~ValueBase() { assert(value != -999); value = -999; }
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;
152 assert(val != -1); assert(val != 999);
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);
160 assert(val != -1); assert(val != 999);
166 constexpr ValueBase() noexcept : value(0) {}
167 constexpr ValueBase(ValueBase const& o) noexcept : value(check_value(o.value)) {
169 constexpr ValueBase(ValueBase && o) noexcept : value(check_value(o.value)) {
171 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase const& o) noexcept {
172 assert(o.value != -1); assert(o.value != -999);
176 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase&& o) noexcept {
177 assert(o.value != -1); assert(o.value != -999);
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())) {}
201 constexpr TrivialValueBase() noexcept : value(0) {}
206 //============================================================================//
207 // Trivial Implicit Test Types
208 namespace ImplicitTypes {
209 #include "archetypes.ipp"
212 //============================================================================//
213 // Trivial Explicit Test Types
214 namespace ExplicitTypes {
215 #define DEFINE_EXPLICIT explicit
216 #include "archetypes.ipp"
220 //============================================================================//
222 namespace NonConstexprTypes {
223 #define DEFINE_CONSTEXPR
224 #include "archetypes.ipp"
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"
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"
244 //============================================================================//
245 // Implicit counting types
246 namespace TestTypes {
247 #define DEFINE_CONSTEXPR
248 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
249 #include "archetypes.ipp"
251 using TestType = AllCtors;
253 // Add equality operators
255 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
256 return L.value == R.value;
260 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
261 return L.value != R.value;
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"
274 using TestType = AllCtors;
276 // Add equality operators
278 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
279 return L.value == R.value;
283 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
284 return L.value != R.value;
289 //============================================================================//
290 // Implicit value types
291 namespace ConstexprTestTypes {
292 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
293 #include "archetypes.ipp"
295 using TestType = AllCtors;
297 // Add equality operators
299 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
300 return L.value == R.value;
304 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
305 return L.value != R.value;
308 } // end namespace ValueTypes
311 //============================================================================//
313 namespace ExplicitConstexprTestTypes {
314 #define DEFINE_EXPLICIT explicit
315 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
316 #include "archetypes.ipp"
318 using TestType = AllCtors;
320 // Add equality operators
322 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
323 return L.value == R.value;
327 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
328 return L.value != R.value;
331 } // end namespace ValueTypes
334 //============================================================================//
336 namespace TrivialTestTypes {
337 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
338 #include "archetypes.ipp"
340 using TestType = AllCtors;
342 // Add equality operators
344 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
345 return L.value == R.value;
349 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
350 return L.value != R.value;
353 } // end namespace TrivialValueTypes
355 //============================================================================//
357 namespace ExplicitTrivialTestTypes {
358 #define DEFINE_EXPLICIT explicit
359 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
360 #include "archetypes.ipp"
362 using TestType = AllCtors;
364 // Add equality operators
366 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
367 return L.value == R.value;
371 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
372 return L.value != R.value;
375 } // end namespace ExplicitTrivialTestTypes
377 #endif // TEST_STD_VER >= 11
379 #endif // TEST_SUPPORT_ARCHETYPES_HPP