diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-10-12 07:46:20 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-10-12 07:46:20 +0000 |
commit | a9e659619f592c49b352af16253ec0b79c207956 (patch) | |
tree | afba7c02efb5a36d4fb797262d8b0db50da64c49 /libcxx/test/support | |
parent | 90d990e034f05f4d9e0354f54205fd3b471f6507 (diff) | |
download | bcm5719-llvm-a9e659619f592c49b352af16253ec0b79c207956.tar.gz bcm5719-llvm-a9e659619f592c49b352af16253ec0b79c207956.zip |
Implement N4606 optional
Summary:
Adapt implementation of Library Fundamentals TS optional into an implementation of N4606 optional.
- Update relational operators per http://wg21.link/P0307
- Update to requirements of http://wg21.link/P0032
- Extension: Implement trivial copy/move construction/assignment for `optional<T>` when `T` is trivially copyable.
Audit P/Rs for optional LWG issues:
- 2756 "C++ WP optional<T> should 'forward' T's implicit conversions" Implemented, which also resolves 2753 "Optional's constructors and assignments need constraints" (modulo my refusal to explicitly delete the move operations, which is a design error that I'm working on correcting in the 2756 P/R).
- 2736 "nullopt_t insufficiently constrained" Already conforming. I've added a test ensuring that `nullopt_t` is not copy-initializable from an empty braced-init-list, which I believe is the root intent of the issue, to avoid regression.
- 2740 "constexpr optional<T>::operator->" Already conforming.
- 2746 "Inconsistency between requirements for emplace between optional and variant" No P/R, but note that the author's '"suggested resolution" is already implemented.
- 2748 "swappable traits for optionals" Already conforming.
- 2753 "Optional's constructors and assignments need constraints" Implemented.
Most of the work for this patch was done by Casey Carter @ Microsoft. Thank you Casey!
Reviewers: mclow.lists, CaseyCarter, EricWF
Differential Revision: https://reviews.llvm.org/D22741
llvm-svn: 283980
Diffstat (limited to 'libcxx/test/support')
-rw-r--r-- | libcxx/test/support/archetypes.hpp | 322 | ||||
-rw-r--r-- | libcxx/test/support/archetypes.ipp | 141 |
2 files changed, 420 insertions, 43 deletions
diff --git a/libcxx/test/support/archetypes.hpp b/libcxx/test/support/archetypes.hpp index 5b294049658..c09aa7085ff 100644 --- a/libcxx/test/support/archetypes.hpp +++ b/libcxx/test/support/archetypes.hpp @@ -1,10 +1,186 @@ #ifndef TEST_SUPPORT_ARCHETYPES_HPP #define TEST_SUPPORT_ARCHETYPES_HPP +#include <type_traits> +#include <cassert> + #include "test_macros.h" #if TEST_STD_VER >= 11 +namespace ArchetypeBases { + +template <bool, class T> +struct DepType : T {}; + +struct NullBase {}; + +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 x, int y) noexcept : value(y) { + ++alive; ++constructed; ++value_constructed; + } + template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> + TestBase(int x, 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 y = 0) noexcept + : value(il.size()) { + ++alive; ++constructed; ++value_constructed; + } + template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> + TestBase(std::initializer_list<int>& il, int y = 0) noexcept : value(il.size()) { + ++alive; ++constructed; ++value_constructed; + } + TestBase& operator=(int xvalue) noexcept { + value = xvalue; + ++assigned; ++value_assigned; + return *this; + } +protected: + ~TestBase() { + assert(value != -999); assert(alive > 0); + --alive; ++destroyed; value = -999; + } + TestBase(TestBase const& o) noexcept : value(o.value) { + assert(o.value != -1); assert(o.value != -999); + ++alive; ++constructed; ++copy_constructed; + } + 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 x, int y) : value(y) {} + template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> + constexpr ValueBase(int x, 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 y = 0) : value(il.size()) {} + template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> + constexpr ValueBase(std::initializer_list<int>& il, int y = 0) : value(il.size()) {} + constexpr ValueBase& operator=(int xvalue) noexcept { + value = xvalue; + return *this; + } + //~ValueBase() { assert(value != -999); value = -999; } + int value; +protected: + constexpr ValueBase() noexcept : value(0) {} + constexpr ValueBase(ValueBase const& o) noexcept : value(o.value) { + assert(o.value != -1); assert(o.value != -999); + } + constexpr ValueBase(ValueBase && o) noexcept : value(o.value) { + assert(o.value != -1); assert(o.value != -999); + o.value = -1; + } + constexpr ValueBase& operator=(ValueBase const& o) noexcept { + assert(o.value != -1); assert(o.value != -999); + value = o.value; + return *this; + } + constexpr 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 x, int y) : value(y) {} + template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> + constexpr TrivialValueBase(int x, 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 y = 0) : value(il.size()) {} + template <bool Dummy = true, typename std::enable_if<Dummy && !Explicit, bool>::type = true> + constexpr TrivialValueBase(std::initializer_list<int>& il, int y = 0) : value(il.size()) {}; + int value; +protected: + constexpr TrivialValueBase() noexcept : value(0) {} +}; + +} + //============================================================================// // Trivial Implicit Test Types namespace ImplicitTypes { @@ -18,9 +194,18 @@ namespace ExplicitTypes { #include "archetypes.ipp" } + +//============================================================================// +// +namespace NonConstexprTypes { +#define DEFINE_CONSTEXPR +#include "archetypes.ipp" +} + //============================================================================// -// Non-Trivial Implicit Test Types +// Non-literal implicit test types namespace NonLiteralTypes { +#define DEFINE_ASSIGN_CONSTEXPR #define DEFINE_DTOR(Name) ~Name() {} #include "archetypes.ipp" } @@ -29,9 +214,144 @@ namespace NonLiteralTypes { // Non-Trivially Copyable Implicit Test Types namespace NonTrivialTypes { #define DEFINE_CTOR {} +#define DEFINE_ASSIGN { return *this; } +#define DEFINE_DEFAULT_CTOR = default +#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 ValueTypes + + +//============================================================================// +// +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 ValueTypes + + +//============================================================================// +// +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 TrivialValueTypes + +//============================================================================// +// +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 diff --git a/libcxx/test/support/archetypes.ipp b/libcxx/test/support/archetypes.ipp index 094440a9783..1f94ddcf0c8 100644 --- a/libcxx/test/support/archetypes.ipp +++ b/libcxx/test/support/archetypes.ipp @@ -1,10 +1,22 @@ +#ifndef DEFINE_BASE +#define DEFINE_BASE(Name) ::ArchetypeBases::NullBase +#endif #ifndef DEFINE_EXPLICIT #define DEFINE_EXPLICIT #endif +#ifndef DEFINE_CONSTEXPR +#define DEFINE_CONSTEXPR constexpr +#endif +#ifndef DEFINE_ASSIGN_CONSTEXPR +#define DEFINE_ASSIGN_CONSTEXPR DEFINE_CONSTEXPR +#endif #ifndef DEFINE_CTOR #define DEFINE_CTOR = default #endif +#ifndef DEFINE_DEFAULT_CTOR +#define DEFINE_DEFAULT_CTOR DEFINE_CTOR +#endif #ifndef DEFINE_ASSIGN #define DEFINE_ASSIGN = default #endif @@ -12,78 +24,117 @@ #define DEFINE_DTOR(Name) #endif -struct NoDefault { - DEFINE_EXPLICIT NoDefault() = delete; +struct AllCtors : DEFINE_BASE(AllCtors) { + using Base = DEFINE_BASE(AllCtors); + using Base::Base; + using Base::operator=; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN; + DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN; + DEFINE_DTOR(AllCtors) +}; + +struct NoCtors : DEFINE_BASE(NoCtors) { + using Base = DEFINE_BASE(NoCtors); + using Base::Base; + DEFINE_EXPLICIT NoCtors() = delete; + DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete; + NoCtors& operator=(NoCtors const&) = delete; + DEFINE_DTOR(NoCtors) +}; + +struct NoDefault : DEFINE_BASE(NoDefault) { + using Base = DEFINE_BASE(NoDefault); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete; DEFINE_DTOR(NoDefault) }; -struct AllCtors { - DEFINE_EXPLICIT AllCtors() DEFINE_CTOR; - DEFINE_EXPLICIT AllCtors(AllCtors const&) DEFINE_CTOR; - DEFINE_EXPLICIT AllCtors(AllCtors &&) DEFINE_CTOR; - AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN; - AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN; - DEFINE_DTOR(AllCtors) +struct DefaultOnly : DEFINE_BASE(DefaultOnly) { + using Base = DEFINE_BASE(DefaultOnly); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR; + DefaultOnly(DefaultOnly const&) = delete; + DefaultOnly& operator=(DefaultOnly const&) = delete; + DEFINE_DTOR(DefaultOnly) }; -struct Copyable { - DEFINE_EXPLICIT Copyable() DEFINE_CTOR; - DEFINE_EXPLICIT Copyable(Copyable const &) DEFINE_CTOR; +struct Copyable : DEFINE_BASE(Copyable) { + using Base = DEFINE_BASE(Copyable); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR; Copyable &operator=(Copyable const &) DEFINE_ASSIGN; DEFINE_DTOR(Copyable) }; -struct CopyOnly { - DEFINE_EXPLICIT CopyOnly() DEFINE_CTOR; - DEFINE_EXPLICIT CopyOnly(CopyOnly const &) DEFINE_CTOR; - DEFINE_EXPLICIT CopyOnly(CopyOnly &&) = delete; +struct CopyOnly : DEFINE_BASE(CopyOnly) { + using Base = DEFINE_BASE(CopyOnly); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete; CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN; CopyOnly &operator=(CopyOnly &&) = delete; DEFINE_DTOR(CopyOnly) }; -struct NonCopyable { - DEFINE_EXPLICIT NonCopyable() DEFINE_CTOR; - DEFINE_EXPLICIT NonCopyable(NonCopyable const &) = delete; +struct NonCopyable : DEFINE_BASE(NonCopyable) { + using Base = DEFINE_BASE(NonCopyable); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) = delete; NonCopyable &operator=(NonCopyable const &) = delete; DEFINE_DTOR(NonCopyable) }; -struct MoveOnly { - DEFINE_EXPLICIT MoveOnly() DEFINE_CTOR; - DEFINE_EXPLICIT MoveOnly(MoveOnly &&) DEFINE_CTOR; +struct MoveOnly : DEFINE_BASE(MoveOnly) { + using Base = DEFINE_BASE(MoveOnly); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR; MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN; DEFINE_DTOR(MoveOnly) }; -struct CopyAssignable { - DEFINE_EXPLICIT CopyAssignable() = delete; - CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN; - DEFINE_DTOR(CopyAssignable) +struct CopyAssignable : DEFINE_BASE(CopyAssignable) { + using Base = DEFINE_BASE(CopyAssignable); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete; + CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN; + DEFINE_DTOR(CopyAssignable) }; -struct CopyAssignOnly { - DEFINE_EXPLICIT CopyAssignOnly() = delete; - CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN; - CopyAssignOnly& operator=(CopyAssignOnly &&) = delete; - DEFINE_DTOR(CopyAssignOnly) +struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) { + using Base = DEFINE_BASE(CopyAssignOnly); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete; + CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN; + CopyAssignOnly& operator=(CopyAssignOnly &&) = delete; + DEFINE_DTOR(CopyAssignOnly) }; -struct MoveAssignOnly { - DEFINE_EXPLICIT MoveAssignOnly() = delete; - MoveAssignOnly& operator=(MoveAssignOnly const&) = delete; - MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN; - DEFINE_DTOR(MoveAssignOnly) +struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) { + using Base = DEFINE_BASE(MoveAssignOnly); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete; + MoveAssignOnly& operator=(MoveAssignOnly const&) = delete; + MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN; + DEFINE_DTOR(MoveAssignOnly) }; -struct ConvertingType { - DEFINE_EXPLICIT ConvertingType() DEFINE_CTOR; - DEFINE_EXPLICIT ConvertingType(ConvertingType const&) DEFINE_CTOR; - DEFINE_EXPLICIT ConvertingType(ConvertingType &&) DEFINE_CTOR; +struct ConvertingType : DEFINE_BASE(ConvertingType) { + using Base = DEFINE_BASE(ConvertingType); + using Base::Base; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_CTOR; + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_CTOR; ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN; ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN; template <class ...Args> - DEFINE_EXPLICIT ConvertingType(Args&&...) {} + DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {} template <class Arg> ConvertingType& operator=(Arg&&) { return *this; } DEFINE_DTOR(ConvertingType) @@ -91,8 +142,10 @@ struct ConvertingType { template <template <class...> class List> using ApplyTypes = List< - NoDefault, AllCtors, + NoCtors, + NoDefault, + DefaultOnly, Copyable, CopyOnly, NonCopyable, @@ -103,7 +156,11 @@ using ApplyTypes = List< ConvertingType >; +#undef DEFINE_BASE #undef DEFINE_EXPLICIT +#undef DEFINE_CONSTEXPR +#undef DEFINE_ASSIGN_CONSTEXPR #undef DEFINE_CTOR +#undef DEFINE_DEFAULT_CTOR #undef DEFINE_ASSIGN #undef DEFINE_DTOR |