• 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 
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