1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef TEST_SUPPORT_ARCHETYPES_H
10 #define TEST_SUPPORT_ARCHETYPES_H
12 #include <type_traits>
15 #include "test_macros.h"
16 #include "test_workarounds.h"
18 #if TEST_STD_VER >= 11
20 namespace ArchetypeBases
{
22 template <bool, class T
>
23 struct DepType
: T
{};
26 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
28 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
30 NullBase(NullBase
const&) = default;
31 NullBase
& operator=(NullBase
const&) = default;
32 NullBase(NullBase
&&) = default;
33 NullBase
& operator=(NullBase
&&) = default;
36 template <class Derived
, bool Explicit
= false>
39 static int constructed
;
40 static int value_constructed
;
41 static int default_constructed
;
42 static int copy_constructed
;
43 static int move_constructed
;
45 static int value_assigned
;
46 static int copy_assigned
;
47 static int move_assigned
;
56 static void reset_constructors() {
57 constructed
= value_constructed
= default_constructed
=
58 copy_constructed
= move_constructed
= 0;
59 assigned
= value_assigned
= copy_assigned
= move_assigned
= destroyed
= 0;
62 TestBase() noexcept
: value(0) {
63 ++alive
; ++constructed
; ++default_constructed
;
65 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
66 explicit TestBase(int x
) noexcept
: value(x
) {
67 ++alive
; ++constructed
; ++value_constructed
;
69 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
70 TestBase(int x
) noexcept
: value(x
) {
71 ++alive
; ++constructed
; ++value_constructed
;
73 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
74 explicit TestBase(int, int y
) noexcept
: value(y
) {
75 ++alive
; ++constructed
; ++value_constructed
;
77 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
78 TestBase(int, int y
) noexcept
: value(y
) {
79 ++alive
; ++constructed
; ++value_constructed
;
81 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
82 explicit TestBase(std::initializer_list
<int>& il
, int = 0) noexcept
83 : value(static_cast<int>(il
.size())) {
84 ++alive
; ++constructed
; ++value_constructed
;
86 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
87 explicit TestBase(std::initializer_list
<int>& il
, int = 0) noexcept
: value(static_cast<int>(il
.size())) {
88 ++alive
; ++constructed
; ++value_constructed
;
90 TestBase
& operator=(int xvalue
) noexcept
{
92 ++assigned
; ++value_assigned
;
95 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
97 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
99 assert(value
!= -999); assert(alive
> 0);
100 --alive
; ++destroyed
; value
= -999;
102 explicit TestBase(TestBase
const& o
) noexcept
: value(o
.value
) {
103 assert(o
.value
!= -1); assert(o
.value
!= -999);
104 ++alive
; ++constructed
; ++copy_constructed
;
106 explicit TestBase(TestBase
&& o
) noexcept
: value(o
.value
) {
107 assert(o
.value
!= -1); assert(o
.value
!= -999);
108 ++alive
; ++constructed
; ++move_constructed
;
111 TestBase
& operator=(TestBase
const& o
) noexcept
{
112 assert(o
.value
!= -1); assert(o
.value
!= -999);
113 ++assigned
; ++copy_assigned
;
117 TestBase
& operator=(TestBase
&& o
) noexcept
{
118 assert(o
.value
!= -1); assert(o
.value
!= -999);
119 ++assigned
; ++move_assigned
;
128 template <class D
, bool E
> int TestBase
<D
, E
>::alive
= 0;
129 template <class D
, bool E
> int TestBase
<D
, E
>::constructed
= 0;
130 template <class D
, bool E
> int TestBase
<D
, E
>::value_constructed
= 0;
131 template <class D
, bool E
> int TestBase
<D
, E
>::default_constructed
= 0;
132 template <class D
, bool E
> int TestBase
<D
, E
>::copy_constructed
= 0;
133 template <class D
, bool E
> int TestBase
<D
, E
>::move_constructed
= 0;
134 template <class D
, bool E
> int TestBase
<D
, E
>::assigned
= 0;
135 template <class D
, bool E
> int TestBase
<D
, E
>::value_assigned
= 0;
136 template <class D
, bool E
> int TestBase
<D
, E
>::copy_assigned
= 0;
137 template <class D
, bool E
> int TestBase
<D
, E
>::move_assigned
= 0;
138 template <class D
, bool E
> int TestBase
<D
, E
>::destroyed
= 0;
140 template <bool Explicit
= false>
142 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
143 explicit constexpr ValueBase(int x
) : value(x
) {}
144 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
145 constexpr ValueBase(int x
) : value(x
) {}
146 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
147 explicit constexpr ValueBase(int, int y
) : value(y
) {}
148 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
149 constexpr ValueBase(int, int y
) : value(y
) {}
150 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
151 explicit constexpr ValueBase(std::initializer_list
<int>& il
, int = 0) : value(static_cast<int>(il
.size())) {}
152 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
153 constexpr ValueBase(std::initializer_list
<int>& il
, int = 0) : value(static_cast<int>(il
.size())) {}
154 TEST_CONSTEXPR_CXX14 ValueBase
& operator=(int xvalue
) noexcept
{
158 //~ValueBase() { assert(value != -999); value = -999; }
160 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
162 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
163 constexpr static int check_value(int const& val
) {
164 #if TEST_STD_VER < 14
165 return val
== -1 || val
== 999 ? (TEST_THROW(42), 0) : val
;
167 assert(val
!= -1); assert(val
!= 999);
171 constexpr static int check_value(int& val
, int val_cp
= 0) {
172 #if TEST_STD_VER < 14
173 return val_cp
= val
, val
= -1, (val_cp
== -1 || val_cp
== 999 ? (TEST_THROW(42), 0) : val_cp
);
175 assert(val
!= -1); assert(val
!= 999);
181 constexpr ValueBase() noexcept
: value(0) {}
182 constexpr ValueBase(ValueBase
const& o
) noexcept
: value(check_value(o
.value
)) {
184 constexpr ValueBase(ValueBase
&& o
) noexcept
: value(check_value(o
.value
)) {
186 TEST_CONSTEXPR_CXX14 ValueBase
& operator=(ValueBase
const& o
) noexcept
{
187 assert(o
.value
!= -1); assert(o
.value
!= -999);
191 TEST_CONSTEXPR_CXX14 ValueBase
& operator=(ValueBase
&& o
) noexcept
{
192 assert(o
.value
!= -1); assert(o
.value
!= -999);
200 template <bool Explicit
= false>
201 struct TrivialValueBase
{
202 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
203 explicit constexpr TrivialValueBase(int x
) : value(x
) {}
204 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
205 constexpr TrivialValueBase(int x
) : value(x
) {}
206 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
207 explicit constexpr TrivialValueBase(int, int y
) : value(y
) {}
208 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
209 constexpr TrivialValueBase(int, int y
) : value(y
) {}
210 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& Explicit
, bool>::type
= true>
211 explicit constexpr TrivialValueBase(std::initializer_list
<int>& il
, int = 0) : value(static_cast<int>(il
.size())) {}
212 template <bool Dummy
= true, typename
std::enable_if
<Dummy
&& !Explicit
, bool>::type
= true>
213 constexpr TrivialValueBase(std::initializer_list
<int>& il
, int = 0) : value(static_cast<int>(il
.size())) {}
215 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
217 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
218 constexpr TrivialValueBase() noexcept
: value(0) {}
223 //============================================================================//
224 // Trivial Implicit Test Types
225 namespace ImplicitTypes
{
226 #include "archetypes.ipp"
229 //============================================================================//
230 // Trivial Explicit Test Types
231 namespace ExplicitTypes
{
232 #define DEFINE_EXPLICIT explicit
233 #include "archetypes.ipp"
236 //============================================================================//
238 namespace NonConstexprTypes
{
239 #define DEFINE_CONSTEXPR
240 #include "archetypes.ipp"
243 //============================================================================//
244 // Non-literal implicit test types
245 namespace NonLiteralTypes
{
246 #define DEFINE_ASSIGN_CONSTEXPR
247 #define DEFINE_DTOR(Name) ~Name() {}
248 #include "archetypes.ipp"
251 //============================================================================//
252 // Non-throwing implicit test types
253 namespace NonThrowingTypes
{
254 #define DEFINE_NOEXCEPT noexcept
255 #include "archetypes.ipp"
258 //============================================================================//
259 // Non-Trivially Copyable Implicit Test Types
260 namespace NonTrivialTypes
{
261 #define DEFINE_CTOR {}
262 #define DEFINE_ASSIGN { return *this; }
263 #include "archetypes.ipp"
266 //============================================================================//
267 // Implicit counting types
268 namespace TestTypes
{
269 #define DEFINE_CONSTEXPR
270 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
271 #include "archetypes.ipp"
273 using TestType
= AllCtors
;
275 // Add equality operators
277 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
278 return L
.value
== R
.value
;
282 constexpr bool operator!=(Tp
const& L
, Tp
const& R
) noexcept
{
283 return L
.value
!= R
.value
;
288 //============================================================================//
289 // Implicit counting types
290 namespace ExplicitTestTypes
{
291 #define DEFINE_CONSTEXPR
292 #define DEFINE_EXPLICIT explicit
293 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
294 #include "archetypes.ipp"
296 using TestType
= AllCtors
;
298 // Add equality operators
300 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
301 return L
.value
== R
.value
;
305 constexpr bool operator!=(Tp
const& L
, Tp
const& R
) noexcept
{
306 return L
.value
!= R
.value
;
311 //============================================================================//
312 // Implicit value types
313 namespace ConstexprTestTypes
{
314 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
315 #include "archetypes.ipp"
317 using TestType
= AllCtors
;
319 // Add equality operators
321 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
322 return L
.value
== R
.value
;
326 constexpr bool operator!=(Tp
const& L
, Tp
const& R
) noexcept
{
327 return L
.value
!= R
.value
;
330 } // end namespace ConstexprTestTypes
333 //============================================================================//
335 namespace ExplicitConstexprTestTypes
{
336 #define DEFINE_EXPLICIT explicit
337 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
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 ExplicitConstexprTestTypes
356 //============================================================================//
358 namespace TrivialTestTypes
{
359 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
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 TrivialTestTypes
377 //============================================================================//
379 namespace ExplicitTrivialTestTypes
{
380 #define DEFINE_EXPLICIT explicit
381 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
382 #include "archetypes.ipp"
384 using TestType
= AllCtors
;
386 // Add equality operators
388 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
389 return L
.value
== R
.value
;
393 constexpr bool operator!=(Tp
const& L
, Tp
const& R
) noexcept
{
394 return L
.value
!= R
.value
;
397 } // end namespace ExplicitTrivialTestTypes
399 #endif // TEST_STD_VER >= 11
401 #endif // TEST_SUPPORT_ARCHETYPES_H