Home | History | Annotate | Download | only in support
      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