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 //
    231 namespace NonConstexprTypes {
    232 #define DEFINE_CONSTEXPR
    233 #include "archetypes.ipp"
    234 }
    235 
    236 //============================================================================//
    237 // Non-literal implicit test types
    238 namespace NonLiteralTypes {
    239 #define DEFINE_ASSIGN_CONSTEXPR
    240 #define DEFINE_DTOR(Name) ~Name() {}
    241 #include "archetypes.ipp"
    242 }
    243 
    244 //============================================================================//
    245 // Non-Trivially Copyable Implicit Test Types
    246 namespace NonTrivialTypes {
    247 #define DEFINE_CTOR {}
    248 #define DEFINE_ASSIGN { return *this; }
    249 #define DEFINE_DEFAULT_CTOR = default
    250 #include "archetypes.ipp"
    251 }
    252 
    253 //============================================================================//
    254 // Implicit counting types
    255 namespace TestTypes {
    256 #define DEFINE_CONSTEXPR
    257 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
    258 #include "archetypes.ipp"
    259 
    260 using TestType = AllCtors;
    261 
    262 // Add equality operators
    263 template <class Tp>
    264 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
    265   return L.value == R.value;
    266 }
    267 
    268 template <class Tp>
    269 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
    270   return L.value != R.value;
    271 }
    272 
    273 }
    274 
    275 //============================================================================//
    276 // Implicit counting types
    277 namespace ExplicitTestTypes {
    278 #define DEFINE_CONSTEXPR
    279 #define DEFINE_EXPLICIT explicit
    280 #define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
    281 #include "archetypes.ipp"
    282 
    283 using TestType = AllCtors;
    284 
    285 // Add equality operators
    286 template <class Tp>
    287 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
    288   return L.value == R.value;
    289 }
    290 
    291 template <class Tp>
    292 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
    293   return L.value != R.value;
    294 }
    295 
    296 }
    297 
    298 //============================================================================//
    299 // Implicit value types
    300 namespace ConstexprTestTypes {
    301 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
    302 #include "archetypes.ipp"
    303 
    304 using TestType = AllCtors;
    305 
    306 // Add equality operators
    307 template <class Tp>
    308 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
    309   return L.value == R.value;
    310 }
    311 
    312 template <class Tp>
    313 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
    314   return L.value != R.value;
    315 }
    316 
    317 } // end namespace ValueTypes
    318 
    319 
    320 //============================================================================//
    321 //
    322 namespace ExplicitConstexprTestTypes {
    323 #define DEFINE_EXPLICIT explicit
    324 #define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
    325 #include "archetypes.ipp"
    326 
    327 using TestType = AllCtors;
    328 
    329 // Add equality operators
    330 template <class Tp>
    331 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
    332   return L.value == R.value;
    333 }
    334 
    335 template <class Tp>
    336 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
    337   return L.value != R.value;
    338 }
    339 
    340 } // end namespace ValueTypes
    341 
    342 
    343 //============================================================================//
    344 //
    345 namespace TrivialTestTypes {
    346 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
    347 #include "archetypes.ipp"
    348 
    349 using TestType = AllCtors;
    350 
    351 // Add equality operators
    352 template <class Tp>
    353 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
    354   return L.value == R.value;
    355 }
    356 
    357 template <class Tp>
    358 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
    359   return L.value != R.value;
    360 }
    361 
    362 } // end namespace TrivialValueTypes
    363 
    364 //============================================================================//
    365 //
    366 namespace ExplicitTrivialTestTypes {
    367 #define DEFINE_EXPLICIT explicit
    368 #define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
    369 #include "archetypes.ipp"
    370 
    371 using TestType = AllCtors;
    372 
    373 // Add equality operators
    374 template <class Tp>
    375 constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
    376   return L.value == R.value;
    377 }
    378 
    379 template <class Tp>
    380 constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
    381   return L.value != R.value;
    382 }
    383 
    384 } // end namespace ExplicitTrivialTestTypes
    385 
    386 #endif // TEST_STD_VER >= 11
    387 
    388 #endif // TEST_SUPPORT_ARCHETYPES_HPP
    389