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>
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
{};
27 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
29 #endif // !TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
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>
40 static int constructed
;
41 static int value_constructed
;
42 static int default_constructed
;
43 static int copy_constructed
;
44 static int move_constructed
;
46 static int value_assigned
;
47 static int copy_assigned
;
48 static int move_assigned
;
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
{
93 ++assigned
; ++value_assigned
;
96 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
98 #endif // !TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
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
;
112 TestBase
& operator=(TestBase
const& o
) noexcept
{
113 assert(o
.value
!= -1); assert(o
.value
!= -999);
114 ++assigned
; ++copy_assigned
;
118 TestBase
& operator=(TestBase
&& o
) noexcept
{
119 assert(o
.value
!= -1); assert(o
.value
!= -999);
120 ++assigned
; ++move_assigned
;
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>
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
{
159 //~ValueBase() { assert(value != -999); value = -999; }
161 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
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
;
168 assert(val
!= -1); assert(val
!= 999);
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
);
176 assert(val
!= -1); assert(val
!= 999);
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);
192 TEST_CONSTEXPR_CXX14 ValueBase
& operator=(ValueBase
&& o
) noexcept
{
193 assert(o
.value
!= -1); assert(o
.value
!= -999);
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())) {}
216 #ifndef TEST_WORKAROUND_MSVC_BROKEN_ZA_CTOR_CHECK
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
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 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
301 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
302 return L
.value
== R
.value
;
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
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 } // 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
345 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
346 return L
.value
== R
.value
;
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
367 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
368 return L
.value
== R
.value
;
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
389 constexpr bool operator==(Tp
const& L
, Tp
const& R
) noexcept
{
390 return L
.value
== R
.value
;
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