#ifndef TEST_SUPPORT_ARCHETYPES_HPP
|
#define TEST_SUPPORT_ARCHETYPES_HPP
|
|
#include <type_traits>
|
#include <cassert>
|
|
#include "test_macros.h"
|
#include "test_workarounds.h"
|
|
#if TEST_STD_VER >= 11
|
|
namespace ArchetypeBases {
|
|
template <bool, class T>
|
struct DepType : T {};
|
|
struct NullBase {
|
#ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
protected:
|
#endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
NullBase() = default;
|
NullBase(NullBase const&) = default;
|
NullBase& operator=(NullBase const&) = default;
|
NullBase(NullBase &&) = default;
|
NullBase& operator=(NullBase &&) = default;
|
};
|
|
template <class Derived, bool Explicit = false>
|
struct TestBase {
|
static int alive;
|
static int constructed;
|
static int value_constructed;
|
static int default_constructed;
|
static int copy_constructed;
|
static int move_constructed;
|
static int assigned;
|
static int value_assigned;
|
static int copy_assigned;
|
static int move_assigned;
|
static int destroyed;
|
|
static void reset() {
|
assert(alive == 0);
|
alive = 0;
|
reset_constructors();
|
}
|
|
static void reset_constructors() {
|
constructed = value_constructed = default_constructed =
|
copy_constructed = move_constructed = 0;
|
assigned = value_assigned = copy_assigned = move_assigned = destroyed = 0;
|
}
|
|
TestBase() noexcept : value(0) {
|
++alive; ++constructed; ++default_constructed;
|
}
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit TestBase(int x) noexcept : value(x) {
|
++alive; ++constructed; ++value_constructed;
|
}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
TestBase(int x) noexcept : value(x) {
|
++alive; ++constructed; ++value_constructed;
|
}
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit TestBase(int, int y) noexcept : value(y) {
|
++alive; ++constructed; ++value_constructed;
|
}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
TestBase(int, int y) noexcept : value(y) {
|
++alive; ++constructed; ++value_constructed;
|
}
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept
|
: value(static_cast<int>(il.size())) {
|
++alive; ++constructed; ++value_constructed;
|
}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
explicit TestBase(std::initializer_list<int>& il, int = 0) noexcept : value(static_cast<int>(il.size())) {
|
++alive; ++constructed; ++value_constructed;
|
}
|
TestBase& operator=(int xvalue) noexcept {
|
value = xvalue;
|
++assigned; ++value_assigned;
|
return *this;
|
}
|
#ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
protected:
|
#endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
~TestBase() {
|
assert(value != -999); assert(alive > 0);
|
--alive; ++destroyed; value = -999;
|
}
|
explicit TestBase(TestBase const& o) noexcept : value(o.value) {
|
assert(o.value != -1); assert(o.value != -999);
|
++alive; ++constructed; ++copy_constructed;
|
}
|
explicit TestBase(TestBase && o) noexcept : value(o.value) {
|
assert(o.value != -1); assert(o.value != -999);
|
++alive; ++constructed; ++move_constructed;
|
o.value = -1;
|
}
|
TestBase& operator=(TestBase const& o) noexcept {
|
assert(o.value != -1); assert(o.value != -999);
|
++assigned; ++copy_assigned;
|
value = o.value;
|
return *this;
|
}
|
TestBase& operator=(TestBase&& o) noexcept {
|
assert(o.value != -1); assert(o.value != -999);
|
++assigned; ++move_assigned;
|
value = o.value;
|
o.value = -1;
|
return *this;
|
}
|
public:
|
int value;
|
};
|
|
template <class D, bool E> int TestBase<D, E>::alive = 0;
|
template <class D, bool E> int TestBase<D, E>::constructed = 0;
|
template <class D, bool E> int TestBase<D, E>::value_constructed = 0;
|
template <class D, bool E> int TestBase<D, E>::default_constructed = 0;
|
template <class D, bool E> int TestBase<D, E>::copy_constructed = 0;
|
template <class D, bool E> int TestBase<D, E>::move_constructed = 0;
|
template <class D, bool E> int TestBase<D, E>::assigned = 0;
|
template <class D, bool E> int TestBase<D, E>::value_assigned = 0;
|
template <class D, bool E> int TestBase<D, E>::copy_assigned = 0;
|
template <class D, bool E> int TestBase<D, E>::move_assigned = 0;
|
template <class D, bool E> int TestBase<D, E>::destroyed = 0;
|
|
template <bool Explicit = false>
|
struct ValueBase {
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit constexpr ValueBase(int x) : value(x) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
constexpr ValueBase(int x) : value(x) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit constexpr ValueBase(int, int y) : value(y) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
constexpr ValueBase(int, int y) : value(y) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
constexpr ValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
|
TEST_CONSTEXPR_CXX14 ValueBase& operator=(int xvalue) noexcept {
|
value = xvalue;
|
return *this;
|
}
|
//~ValueBase() { assert(value != -999); value = -999; }
|
int value;
|
#ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
protected:
|
#endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
constexpr static int check_value(int const& val) {
|
#if TEST_STD_VER < 14
|
return val == -1 || val == 999 ? (TEST_THROW(42), 0) : val;
|
#else
|
assert(val != -1); assert(val != 999);
|
return val;
|
#endif
|
}
|
constexpr static int check_value(int& val, int val_cp = 0) {
|
#if TEST_STD_VER < 14
|
return val_cp = val, val = -1, (val_cp == -1 || val_cp == 999 ? (TEST_THROW(42), 0) : val_cp);
|
#else
|
assert(val != -1); assert(val != 999);
|
val_cp = val;
|
val = -1;
|
return val_cp;
|
#endif
|
}
|
constexpr ValueBase() noexcept : value(0) {}
|
constexpr ValueBase(ValueBase const& o) noexcept : value(check_value(o.value)) {
|
}
|
constexpr ValueBase(ValueBase && o) noexcept : value(check_value(o.value)) {
|
}
|
TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase const& o) noexcept {
|
assert(o.value != -1); assert(o.value != -999);
|
value = o.value;
|
return *this;
|
}
|
TEST_CONSTEXPR_CXX14 ValueBase& operator=(ValueBase&& o) noexcept {
|
assert(o.value != -1); assert(o.value != -999);
|
value = o.value;
|
o.value = -1;
|
return *this;
|
}
|
};
|
|
|
template <bool Explicit = false>
|
struct TrivialValueBase {
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit constexpr TrivialValueBase(int x) : value(x) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
constexpr TrivialValueBase(int x) : value(x) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit constexpr TrivialValueBase(int, int y) : value(y) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
constexpr TrivialValueBase(int, int y) : value(y) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && Explicit, bool>::type = true>
|
explicit constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
|
template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true>
|
constexpr TrivialValueBase(std::initializer_list<int>& il, int = 0) : value(static_cast<int>(il.size())) {}
|
int value;
|
#ifndef TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
protected:
|
#endif // !TEST_WORKAROUND_C1XX_BROKEN_ZA_CTOR_CHECK
|
constexpr TrivialValueBase() noexcept : value(0) {}
|
};
|
|
}
|
|
//============================================================================//
|
// Trivial Implicit Test Types
|
namespace ImplicitTypes {
|
#include "archetypes.ipp"
|
}
|
|
//============================================================================//
|
// Trivial Explicit Test Types
|
namespace ExplicitTypes {
|
#define DEFINE_EXPLICIT explicit
|
#include "archetypes.ipp"
|
}
|
|
//============================================================================//
|
//
|
namespace NonConstexprTypes {
|
#define DEFINE_CONSTEXPR
|
#include "archetypes.ipp"
|
}
|
|
//============================================================================//
|
// Non-literal implicit test types
|
namespace NonLiteralTypes {
|
#define DEFINE_ASSIGN_CONSTEXPR
|
#define DEFINE_DTOR(Name) ~Name() {}
|
#include "archetypes.ipp"
|
}
|
|
//============================================================================//
|
// Non-throwing implicit test types
|
namespace NonThrowingTypes {
|
#define DEFINE_NOEXCEPT noexcept
|
#include "archetypes.ipp"
|
}
|
|
//============================================================================//
|
// Non-Trivially Copyable Implicit Test Types
|
namespace NonTrivialTypes {
|
#define DEFINE_CTOR {}
|
#define DEFINE_ASSIGN { return *this; }
|
#include "archetypes.ipp"
|
}
|
|
//============================================================================//
|
// Implicit counting types
|
namespace TestTypes {
|
#define DEFINE_CONSTEXPR
|
#define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name>
|
#include "archetypes.ipp"
|
|
using TestType = AllCtors;
|
|
// Add equality operators
|
template <class Tp>
|
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
return L.value == R.value;
|
}
|
|
template <class Tp>
|
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
return L.value != R.value;
|
}
|
|
}
|
|
//============================================================================//
|
// Implicit counting types
|
namespace ExplicitTestTypes {
|
#define DEFINE_CONSTEXPR
|
#define DEFINE_EXPLICIT explicit
|
#define DEFINE_BASE(Name) ::ArchetypeBases::TestBase<Name, true>
|
#include "archetypes.ipp"
|
|
using TestType = AllCtors;
|
|
// Add equality operators
|
template <class Tp>
|
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
return L.value == R.value;
|
}
|
|
template <class Tp>
|
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
return L.value != R.value;
|
}
|
|
}
|
|
//============================================================================//
|
// Implicit value types
|
namespace ConstexprTestTypes {
|
#define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<>
|
#include "archetypes.ipp"
|
|
using TestType = AllCtors;
|
|
// Add equality operators
|
template <class Tp>
|
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
return L.value == R.value;
|
}
|
|
template <class Tp>
|
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
return L.value != R.value;
|
}
|
|
} // end namespace ConstexprTestTypes
|
|
|
//============================================================================//
|
//
|
namespace ExplicitConstexprTestTypes {
|
#define DEFINE_EXPLICIT explicit
|
#define DEFINE_BASE(Name) ::ArchetypeBases::ValueBase<true>
|
#include "archetypes.ipp"
|
|
using TestType = AllCtors;
|
|
// Add equality operators
|
template <class Tp>
|
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
return L.value == R.value;
|
}
|
|
template <class Tp>
|
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
return L.value != R.value;
|
}
|
|
} // end namespace ExplicitConstexprTestTypes
|
|
|
//============================================================================//
|
//
|
namespace TrivialTestTypes {
|
#define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<false>
|
#include "archetypes.ipp"
|
|
using TestType = AllCtors;
|
|
// Add equality operators
|
template <class Tp>
|
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
return L.value == R.value;
|
}
|
|
template <class Tp>
|
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
return L.value != R.value;
|
}
|
|
} // end namespace TrivialTestTypes
|
|
//============================================================================//
|
//
|
namespace ExplicitTrivialTestTypes {
|
#define DEFINE_EXPLICIT explicit
|
#define DEFINE_BASE(Name) ::ArchetypeBases::TrivialValueBase<true>
|
#include "archetypes.ipp"
|
|
using TestType = AllCtors;
|
|
// Add equality operators
|
template <class Tp>
|
constexpr bool operator==(Tp const& L, Tp const& R) noexcept {
|
return L.value == R.value;
|
}
|
|
template <class Tp>
|
constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
|
return L.value != R.value;
|
}
|
|
} // end namespace ExplicitTrivialTestTypes
|
|
#endif // TEST_STD_VER >= 11
|
|
#endif // TEST_SUPPORT_ARCHETYPES_HPP
|