[OpenACC] Implement 'collapse' for combined constructs.
[llvm-project.git] / libcxx / test / support / archetypes.h
blob259346e90a510588de6774e7a302f6336bead07c
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef TEST_SUPPORT_ARCHETYPES_H
10 #define TEST_SUPPORT_ARCHETYPES_H
12 #include <type_traits>
13 #include <cassert>
14 #include <initializer_list>
16 #include "test_macros.h"
17 #include "test_workarounds.h"
19 #if TEST_STD_VER >= 11
21 namespace ArchetypeBases {
23 template <bool, class T>
24 struct DepType : T {};
26 struct NullBase {
27 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
28 protected:
29 #endif // !TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
30 NullBase() = default;
31 NullBase(NullBase const&) = default;
32 NullBase& operator=(NullBase const&) = default;
33 NullBase(NullBase &&) = default;
34 NullBase& operator=(NullBase &&) = default;
37 template <class Derived, bool Explicit = false>
38 struct TestBase {
39 static int alive;
40 static int constructed;
41 static int value_constructed;
42 static int default_constructed;
43 static int copy_constructed;
44 static int move_constructed;
45 static int assigned;
46 static int value_assigned;
47 static int copy_assigned;
48 static int move_assigned;
49 static int destroyed;
51 static void reset() {
52 assert(alive == 0);
53 alive = 0;
54 reset_constructors();
57 static void reset_constructors() {
58 constructed = value_constructed = default_constructed =
59 copy_constructed = move_constructed = 0;
60 assigned = value_assigned = copy_assigned = move_assigned = destroyed = 0;
63 TestBase() noexcept : value(0) {
64 ++alive; ++constructed; ++default_constructed;
66 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
67 explicit TestBase(int x) noexcept : value(x) {
68 ++alive; ++constructed; ++value_constructed;
70 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
71 TestBase(int x) noexcept : value(x) {
72 ++alive; ++constructed; ++value_constructed;
74 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
75 explicit TestBase(int, int y) noexcept : value(y) {
76 ++alive; ++constructed; ++value_constructed;
78 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
79 TestBase(int, int y) noexcept : value(y) {
80 ++alive; ++constructed; ++value_constructed;
82 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
83 explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept
84 : value(static_cast<int>(il.size())) {
85 ++alive; ++constructed; ++value_constructed;
87 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
88 explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept : value(static_cast<int>(il.size())) {
89 ++alive; ++constructed; ++value_constructed;
91 TestBase& operator=(int xvalue) noexcept {
92 value = xvalue;
93 ++assigned; ++value_assigned;
94 return *this;
96 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
97 protected:
98 #endif // !TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
99 ~TestBase() {
100 assert(value != -999); assert(alive > 0);
101 --alive; ++destroyed; value = -999;
103 explicit TestBase(TestBase const& o) noexcept : value(o.value) {
104 assert(o.value != -1); assert(o.value != -999);
105 ++alive; ++constructed; ++copy_constructed;
107 explicit TestBase(TestBase && o) noexcept : value(o.value) {
108 assert(o.value != -1); assert(o.value != -999);
109 ++alive; ++constructed; ++move_constructed;
110 o.value = -1;
112 TestBase& operator=(TestBase const& o) noexcept {
113 assert(o.value != -1); assert(o.value != -999);
114 ++assigned; ++copy_assigned;
115 value = o.value;
116 return *this;
118 TestBase& operator=(TestBase&& o) noexcept {
119 assert(o.value != -1); assert(o.value != -999);
120 ++assigned; ++move_assigned;
121 value = o.value;
122 o.value = -1;
123 return *this;
125 public:
126 int value;
129 template <class D, bool E> int TestBase<D, E>::alive = 0;
130 template <class D, bool E> int TestBase<D, E>::constructed = 0;
131 template <class D, bool E> int TestBase<D, E>::value_constructed = 0;
132 template <class D, bool E> int TestBase<D, E>::default_constructed = 0;
133 template <class D, bool E> int TestBase<D, E>::copy_constructed = 0;
134 template <class D, bool E> int TestBase<D, E>::move_constructed = 0;
135 template <class D, bool E> int TestBase<D, E>::assigned = 0;
136 template <class D, bool E> int TestBase<D, E>::value_assigned = 0;
137 template <class D, bool E> int TestBase<D, E>::copy_assigned = 0;
138 template <class D, bool E> int TestBase<D, E>::move_assigned = 0;
139 template <class D, bool E> int TestBase<D, E>::destroyed = 0;
141 template <bool Explicit = false>
142 struct ValueBase {
143 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
144 explicit constexpr ValueBase(int x) : value(x) {}
145 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
146 constexpr ValueBase(int x) : value(x) {}
147 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
148 explicit constexpr ValueBase(int, int y) : value(y) {}
149 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
150 constexpr ValueBase(int, int y) : value(y) {}
151 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
152 explicit constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
153 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
154 constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
155 TEST_CONSTEXPR_CXX14 ValueBase& operator=(int xvalue) noexcept {
156 value = xvalue;
157 return *this;
159 //~ValueBase() { assert(value != -999); value = -999; }
160 int value;
161 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
162 protected:
163 #endif // !TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
164 constexpr static int check_value(int const& val) {
165 #if TEST_STD_VER < 14
166 return val == -1 || val == 999 ? (TEST_THROW(42), 0) : val;
167 #else
168 assert(val != -1); assert(val != 999);
169 return val;
170 #endif
172 constexpr static int check_value(int& val, int val_cp = 0) {
173 #if TEST_STD_VER < 14
174 return val_cp = val, val = -1, (val_cp == -1 || val_cp == 999 ? (TEST_THROW(42), 0) : val_cp);
175 #else
176 assert(val != -1); assert(val != 999);
177 val_cp = val;
178 val = -1;
179 return val_cp;
180 #endif
182 constexpr ValueBase() noexcept : value(0) {}
183 constexpr ValueBase(ValueBase const& o) noexcept : value(check_value(o.value)) {
185 constexpr ValueBase(ValueBase && o) noexcept : value(check_value(o.value)) {
187 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase const& o) noexcept {
188 assert(o.value != -1); assert(o.value != -999);
189 value = o.value;
190 return *this;
192 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase&& o) noexcept {
193 assert(o.value != -1); assert(o.value != -999);
194 value = o.value;
195 o.value = -1;
196 return *this;
201 template <bool Explicit = false>
202 struct TrivialValueBase {
203 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
204 explicit constexpr TrivialValueBase(int x) : value(x) {}
205 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
206 constexpr TrivialValueBase(int x) : value(x) {}
207 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
208 explicit constexpr TrivialValueBase(int, int y) : value(y) {}
209 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
210 constexpr TrivialValueBase(int, int y) : value(y) {}
211 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
212 explicit constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
213 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
214 constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
215 int value;
216 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
217 protected:
218 #endif // !TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
219 constexpr TrivialValueBase() noexcept : value(0) {}
224 //============================================================================//
225 // Trivial Implicit Test Types
226 namespace ImplicitTypes {
227 #include "archetypes.ipp"
230 //============================================================================//
231 // Trivial Explicit Test Types
232 namespace ExplicitTypes {
233 #define DEFINE_EXPLICIT explicit
234 #include "archetypes.ipp"
237 //============================================================================//
239 namespace NonConstexprTypes {
240 #define DEFINE_CONSTEXPR
241 #include "archetypes.ipp"
244 //============================================================================//
245 // Non-literal implicit test types
246 namespace NonLiteralTypes {
247 #define DEFINE_ASSIGN_CONSTEXPR
248 #define DEFINE_DTOR(Name) ~Name() {}
249 #include "archetypes.ipp"
252 //============================================================================//
253 // Non-throwing implicit test types
254 namespace NonThrowingTypes {
255 #define DEFINE_NOEXCEPT noexcept
256 #include "archetypes.ipp"
259 //============================================================================//
260 // Non-Trivially Copyable Implicit Test Types
261 namespace NonTrivialTypes {
262 #define DEFINE_CTOR {}
263 #define DEFINE_ASSIGN { return *this; }
264 #include "archetypes.ipp"
267 //============================================================================//
268 // Implicit counting types
269 namespace TestTypes {
270 #define DEFINE_CONSTEXPR
271 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
272 #include "archetypes.ipp"
274 using TestType = AllCtors;
276 // Add equality operators
277 template <class Tp>
278 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
279 return L.value == R.value;
282 template <class Tp>
283 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
284 return L.value != R.value;
289 //============================================================================//
290 // Implicit counting types
291 namespace ExplicitTestTypes {
292 #define DEFINE_CONSTEXPR
293 #define DEFINE_EXPLICIT explicit
294 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
295 #include "archetypes.ipp"
297 using TestType = AllCtors;
299 // Add equality operators
300 template <class Tp>
301 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
302 return L.value == R.value;
305 template <class Tp>
306 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
307 return L.value != R.value;
312 //============================================================================//
313 // Implicit value types
314 namespace ConstexprTestTypes {
315 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
316 #include "archetypes.ipp"
318 using TestType = AllCtors;
320 // Add equality operators
321 template <class Tp>
322 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
323 return L.value == R.value;
326 template <class Tp>
327 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
328 return L.value != R.value;
331 } // namespace ConstexprTestTypes
334 //============================================================================//
336 namespace ExplicitConstexprTestTypes {
337 #define DEFINE_EXPLICIT explicit
338 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
339 #include "archetypes.ipp"
341 using TestType = AllCtors;
343 // Add equality operators
344 template <class Tp>
345 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
346 return L.value == R.value;
349 template <class Tp>
350 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
351 return L.value != R.value;
354 } // namespace ExplicitConstexprTestTypes
357 //============================================================================//
359 namespace TrivialTestTypes {
360 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
361 #include "archetypes.ipp"
363 using TestType = AllCtors;
365 // Add equality operators
366 template <class Tp>
367 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
368 return L.value == R.value;
371 template <class Tp>
372 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
373 return L.value != R.value;
376 } // namespace TrivialTestTypes
378 //============================================================================//
380 namespace ExplicitTrivialTestTypes {
381 #define DEFINE_EXPLICIT explicit
382 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
383 #include "archetypes.ipp"
385 using TestType = AllCtors;
387 // Add equality operators
388 template <class Tp>
389 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
390 return L.value == R.value;
393 template <class Tp>
394 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
395 return L.value != R.value;
398 } // namespace ExplicitTrivialTestTypes
400 #endif // TEST_STD_VER >= 11
402 #endif // TEST_SUPPORT_ARCHETYPES_H