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 #include "test_workarounds.h" 9 10 #if TEST_STD_VER >= 11 11 12 namespace ArchetypeBases { 13 14 template <bool, class T> 15 struct DepType : T {}; 16 17 struct NullBase { 18 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 19 protected: 20 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 21 NullBase() = default; 22 NullBase(NullBase const&) = default; 23 NullBase& operator=(NullBase const&) = default; 24 NullBase(NullBase &&) = default; 25 NullBase& operator=(NullBase &&) = default; 26 }; 27 28 template <class Derived, bool Explicit = false> 29 struct TestBase { 30 static int alive; 31 static int constructed; 32 static int value_constructed; 33 static int default_constructed; 34 static int copy_constructed; 35 static int move_constructed; 36 static int assigned; 37 static int value_assigned; 38 static int copy_assigned; 39 static int move_assigned; 40 static int destroyed; 41 42 static void reset() { 43 assert(alive == 0); 44 alive = 0; 45 reset_constructors(); 46 } 47 48 static void reset_constructors() { 49 constructed = value_constructed = default_constructed = 50 copy_constructed = move_constructed = 0; 51 assigned = value_assigned = copy_assigned = move_assigned = destroyed = 0; 52 } 53 54 TestBase() noexcept : value(0) { 55 ++alive; ++constructed; ++default_constructed; 56 } 57 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 58 explicit TestBase(int x) noexcept : value(x) { 59 ++alive; ++constructed; ++value_constructed; 60 } 61 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 62 TestBase(int x) noexcept : value(x) { 63 ++alive; ++constructed; ++value_constructed; 64 } 65 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 66 explicit TestBase(int, int y) noexcept : value(y) { 67 ++alive; ++constructed; ++value_constructed; 68 } 69 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 70 TestBase(int, int y) noexcept : value(y) { 71 ++alive; ++constructed; ++value_constructed; 72 } 73 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 74 explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept 75 : value(static_cast<int>(il.size())) { 76 ++alive; ++constructed; ++value_constructed; 77 } 78 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 79 explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept : value(static_cast<int>(il.size())) { 80 ++alive; ++constructed; ++value_constructed; 81 } 82 TestBase& operator=(int xvalue) noexcept { 83 value = xvalue; 84 ++assigned; ++value_assigned; 85 return *this; 86 } 87 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 88 protected: 89 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 90 ~TestBase() { 91 assert(value != -999); assert(alive > 0); 92 --alive; ++destroyed; value = -999; 93 } 94 explicit TestBase(TestBase const& o) noexcept : value(o.value) { 95 assert(o.value != -1); assert(o.value != -999); 96 ++alive; ++constructed; ++copy_constructed; 97 } 98 explicit TestBase(TestBase && o) noexcept : value(o.value) { 99 assert(o.value != -1); assert(o.value != -999); 100 ++alive; ++constructed; ++move_constructed; 101 o.value = -1; 102 } 103 TestBase& operator=(TestBase const& o) noexcept { 104 assert(o.value != -1); assert(o.value != -999); 105 ++assigned; ++copy_assigned; 106 value = o.value; 107 return *this; 108 } 109 TestBase& operator=(TestBase&& o) noexcept { 110 assert(o.value != -1); assert(o.value != -999); 111 ++assigned; ++move_assigned; 112 value = o.value; 113 o.value = -1; 114 return *this; 115 } 116 public: 117 int value; 118 }; 119 120 template <class D, bool E> int TestBase<D, E>::alive = 0; 121 template <class D, bool E> int TestBase<D, E>::constructed = 0; 122 template <class D, bool E> int TestBase<D, E>::value_constructed = 0; 123 template <class D, bool E> int TestBase<D, E>::default_constructed = 0; 124 template <class D, bool E> int TestBase<D, E>::copy_constructed = 0; 125 template <class D, bool E> int TestBase<D, E>::move_constructed = 0; 126 template <class D, bool E> int TestBase<D, E>::assigned = 0; 127 template <class D, bool E> int TestBase<D, E>::value_assigned = 0; 128 template <class D, bool E> int TestBase<D, E>::copy_assigned = 0; 129 template <class D, bool E> int TestBase<D, E>::move_assigned = 0; 130 template <class D, bool E> int TestBase<D, E>::destroyed = 0; 131 132 template <bool Explicit = false> 133 struct ValueBase { 134 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 135 explicit constexpr ValueBase(int x) : value(x) {} 136 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 137 constexpr ValueBase(int x) : value(x) {} 138 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 139 explicit constexpr ValueBase(int, int y) : value(y) {} 140 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 141 constexpr ValueBase(int, int y) : value(y) {} 142 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 143 explicit constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {} 144 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 145 constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {} 146 TEST_CONSTEXPR_CXX14 ValueBase& operator=(int xvalue) noexcept { 147 value = xvalue; 148 return *this; 149 } 150 //~ValueBase() { assert(value != -999); value = -999; } 151 int value; 152 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 153 protected: 154 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 155 constexpr static int check_value(int const& val) { 156 #if TEST_STD_VER < 14 157 return val == -1 || val == 999 ? (TEST_THROW(42), 0) : val; 158 #else 159 assert(val != -1); assert(val != 999); 160 return val; 161 #endif 162 } 163 constexpr static int check_value(int& val, int val_cp = 0) { 164 #if TEST_STD_VER < 14 165 return val_cp = val, val = -1, (val_cp == -1 || val_cp == 999 ? (TEST_THROW(42), 0) : val_cp); 166 #else 167 assert(val != -1); assert(val != 999); 168 val_cp = val; 169 val = -1; 170 return val_cp; 171 #endif 172 } 173 constexpr ValueBase() noexcept : value(0) {} 174 constexpr ValueBase(ValueBase const& o) noexcept : value(check_value(o.value)) { 175 } 176 constexpr ValueBase(ValueBase && o) noexcept : value(check_value(o.value)) { 177 } 178 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase const& o) noexcept { 179 assert(o.value != -1); assert(o.value != -999); 180 value = o.value; 181 return *this; 182 } 183 TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase&& o) noexcept { 184 assert(o.value != -1); assert(o.value != -999); 185 value = o.value; 186 o.value = -1; 187 return *this; 188 } 189 }; 190 191 192 template <bool Explicit = false> 193 struct TrivialValueBase { 194 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 195 explicit constexpr TrivialValueBase(int x) : value(x) {} 196 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 197 constexpr TrivialValueBase(int x) : value(x) {} 198 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 199 explicit constexpr TrivialValueBase(int, int y) : value(y) {} 200 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 201 constexpr TrivialValueBase(int, int y) : value(y) {} 202 template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true> 203 explicit constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {} 204 template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> 205 constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {} 206 int value; 207 #ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 208 protected: 209 #endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK 210 constexpr TrivialValueBase() noexcept : value(0) {} 211 }; 212 213 } 214 215 //============================================================================// 216 // Trivial Implicit Test Types 217 namespace ImplicitTypes { 218 #include "archetypes.ipp" 219 } 220 221 //============================================================================// 222 // Trivial Explicit Test Types 223 namespace ExplicitTypes { 224 #define DEFINE_EXPLICIT explicit 225 #include "archetypes.ipp" 226 } 227 228 //============================================================================// 229 // 230 namespace NonConstexprTypes { 231 #define DEFINE_CONSTEXPR 232 #include "archetypes.ipp" 233 } 234 235 //============================================================================// 236 // Non-literal implicit test types 237 namespace NonLiteralTypes { 238 #define DEFINE_ASSIGN_CONSTEXPR 239 #define DEFINE_DTOR(Name) ~Name() {} 240 #include "archetypes.ipp" 241 } 242 243 //============================================================================// 244 // Non-throwing implicit test types 245 namespace NonThrowingTypes { 246 #define DEFINE_NOEXCEPT noexcept 247 #include "archetypes.ipp" 248 } 249 250 //============================================================================// 251 // Non-Trivially Copyable Implicit Test Types 252 namespace NonTrivialTypes { 253 #define DEFINE_CTOR {} 254 #define DEFINE_ASSIGN { return *this; } 255 #include "archetypes.ipp" 256 } 257 258 //============================================================================// 259 // Implicit counting types 260 namespace TestTypes { 261 #define DEFINE_CONSTEXPR 262 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name> 263 #include "archetypes.ipp" 264 265 using TestType = AllCtors; 266 267 // Add equality operators 268 template <class Tp> 269 constexpr bool operator==(Tp const& L, Tp const& R) noexcept { 270 return L.value == R.value; 271 } 272 273 template <class Tp> 274 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept { 275 return L.value != R.value; 276 } 277 278 } 279 280 //============================================================================// 281 // Implicit counting types 282 namespace ExplicitTestTypes { 283 #define DEFINE_CONSTEXPR 284 #define DEFINE_EXPLICIT explicit 285 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true> 286 #include "archetypes.ipp" 287 288 using TestType = AllCtors; 289 290 // Add equality operators 291 template <class Tp> 292 constexpr bool operator==(Tp const& L, Tp const& R) noexcept { 293 return L.value == R.value; 294 } 295 296 template <class Tp> 297 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept { 298 return L.value != R.value; 299 } 300 301 } 302 303 //============================================================================// 304 // Implicit value types 305 namespace ConstexprTestTypes { 306 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<> 307 #include "archetypes.ipp" 308 309 using TestType = AllCtors; 310 311 // Add equality operators 312 template <class Tp> 313 constexpr bool operator==(Tp const& L, Tp const& R) noexcept { 314 return L.value == R.value; 315 } 316 317 template <class Tp> 318 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept { 319 return L.value != R.value; 320 } 321 322 } // end namespace ConstexprTestTypes 323 324 325 //============================================================================// 326 // 327 namespace ExplicitConstexprTestTypes { 328 #define DEFINE_EXPLICIT explicit 329 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true> 330 #include "archetypes.ipp" 331 332 using TestType = AllCtors; 333 334 // Add equality operators 335 template <class Tp> 336 constexpr bool operator==(Tp const& L, Tp const& R) noexcept { 337 return L.value == R.value; 338 } 339 340 template <class Tp> 341 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept { 342 return L.value != R.value; 343 } 344 345 } // end namespace ExplicitConstexprTestTypes 346 347 348 //============================================================================// 349 // 350 namespace TrivialTestTypes { 351 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false> 352 #include "archetypes.ipp" 353 354 using TestType = AllCtors; 355 356 // Add equality operators 357 template <class Tp> 358 constexpr bool operator==(Tp const& L, Tp const& R) noexcept { 359 return L.value == R.value; 360 } 361 362 template <class Tp> 363 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept { 364 return L.value != R.value; 365 } 366 367 } // end namespace TrivialTestTypes 368 369 //============================================================================// 370 // 371 namespace ExplicitTrivialTestTypes { 372 #define DEFINE_EXPLICIT explicit 373 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true> 374 #include "archetypes.ipp" 375 376 using TestType = AllCtors; 377 378 // Add equality operators 379 template <class Tp> 380 constexpr bool operator==(Tp const& L, Tp const& R) noexcept { 381 return L.value == R.value; 382 } 383 384 template <class Tp> 385 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept { 386 return L.value != R.value; 387 } 388 389 } // end namespace ExplicitTrivialTestTypes 390 391 #endif // TEST_STD_VER >= 11 392 393 #endif // TEST_SUPPORT_ARCHETYPES_HPP 394