diff --git a/include/boost/any.hpp b/include/boost/any.hpp index e77d189..b09e88d 100644 --- a/include/boost/any.hpp +++ b/include/boost/any.hpp @@ -58,7 +58,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \throws std::bad_alloc or any exceptions arising from the copy /// constructor of the contained type. template - any(const ValueType & value) + BOOST_ANY_IMPL_CONSTEXPR any(const ValueType & value) : content(new holder< typename std::remove_cv::type>::type >(value)) @@ -77,7 +77,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \throws May fail with a `std::bad_alloc` /// exception or any exceptions arising from the copy /// constructor of the contained type. - any(const any & other) + BOOST_ANY_IMPL_CONSTEXPR any(const any & other) : content(other.content ? other.content->clone() : 0) { } @@ -87,7 +87,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// /// \post other->empty() is true /// \throws Nothing. - any(any&& other) noexcept + BOOST_ANY_IMPL_CONSTEXPR any(any&& other) noexcept : content(other.content) { other.content = 0; @@ -100,7 +100,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \throws std::bad_alloc or any exceptions arising from the move or /// copy constructor of the contained type. template - any(ValueType&& value + BOOST_ANY_IMPL_CONSTEXPR any(ValueType&& value , typename std::enable_if::value >::type* = 0 // disable if value has type `any&` , typename std::enable_if::value >::type* = 0) // disable if value has type `const ValueType&&` : content(new holder< typename std::decay::type >(std::forward(value))) @@ -114,7 +114,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// Releases any and all resources used in management of instance. /// /// \throws Nothing. - ~any() noexcept + BOOST_ANY_IMPL_CONSTEXPR ~any() noexcept { delete content; } @@ -125,7 +125,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// /// \returns `*this` /// \throws Nothing. - any & swap(any & rhs) noexcept + BOOST_ANY_IMPL_CONSTEXPR any & swap(any & rhs) noexcept { placeholder* tmp = content; content = rhs.content; @@ -142,7 +142,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// or any exceptions arising from the copy constructor of the /// contained type. Assignment satisfies the strong guarantee /// of exception safety. - any & operator=(const any& rhs) + BOOST_ANY_IMPL_CONSTEXPR any & operator=(const any& rhs) { any(rhs).swap(*this); return *this; @@ -156,7 +156,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// /// \post `rhs->empty()` is true /// \throws Nothing. - any & operator=(any&& rhs) noexcept + BOOST_ANY_IMPL_CONSTEXPR any & operator=(any&& rhs) noexcept { rhs.swap(*this); any().swap(rhs); @@ -173,7 +173,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// contained type. Assignment satisfies the strong guarantee /// of exception safety. template - any & operator=(ValueType&& rhs) + BOOST_ANY_IMPL_CONSTEXPR any & operator=(ValueType&& rhs) { static_assert( !anys::detail::is_basic_any::type>::value, @@ -187,13 +187,13 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \returns `true` if instance is empty, otherwise `false`. /// \throws Nothing. - bool empty() const noexcept + BOOST_ANY_IMPL_CONSTEXPR bool empty() const noexcept { return !content; } /// \post this->empty() is true - void clear() noexcept + BOOST_ANY_IMPL_CONSTEXPR void clear() noexcept { any().swap(*this); } @@ -204,7 +204,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// /// Useful for querying against types known either at compile time or /// only at runtime. - const boost::typeindex::type_info& type() const noexcept + BOOST_ANY_IMPL_CONSTEXPR const boost::typeindex::type_info& type() const noexcept { return content ? content->type() : boost::typeindex::type_id().type_info(); } @@ -223,24 +223,24 @@ BOOST_ANY_BEGIN_MODULE_EXPORT { public: // structors - holder(const ValueType & value) + BOOST_ANY_IMPL_CONSTEXPR holder(const ValueType & value) : held(value) { } - holder(ValueType&& value) + BOOST_ANY_IMPL_CONSTEXPR holder(ValueType&& value) : held(static_cast< ValueType&& >(value)) { } public: // queries - const boost::typeindex::type_info& type() const noexcept override + BOOST_ANY_IMPL_CONSTEXPR const boost::typeindex::type_info& type() const noexcept override { return boost::typeindex::type_id().type_info(); } - placeholder * clone() const BOOST_OVERRIDE + BOOST_ANY_IMPL_CONSTEXPR placeholder * clone() const BOOST_OVERRIDE { return new holder(held); } @@ -255,7 +255,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT private: // representation template - friend ValueType * unsafe_any_cast(any *) noexcept; + friend BOOST_ANY_IMPL_CONSTEXPR ValueType * unsafe_any_cast(any *) noexcept; friend class boost::anys::unique_any; @@ -265,7 +265,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// Exchange of the contents of `lhs` and `rhs`. /// \throws Nothing. - inline void swap(any & lhs, any & rhs) noexcept + BOOST_ANY_IMPL_CONSTEXPR inline void swap(any & lhs, any & rhs) noexcept { lhs.swap(rhs); } @@ -278,7 +278,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT // use typeid() comparison, e.g., when our types may travel across // different shared libraries. template - inline ValueType * unsafe_any_cast(any * operand) noexcept + BOOST_ANY_IMPL_CONSTEXPR inline ValueType * unsafe_any_cast(any * operand) noexcept { return std::addressof( static_cast *>(operand->content)->held @@ -286,7 +286,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT } template - inline const ValueType * unsafe_any_cast(const any * operand) noexcept + BOOST_ANY_IMPL_CONSTEXPR inline const ValueType * unsafe_any_cast(const any * operand) noexcept { return boost::unsafe_any_cast(const_cast(operand)); } @@ -295,7 +295,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \returns Pointer to a ValueType stored in `operand`, nullptr if /// `operand` does not contain specified `ValueType`. template - ValueType * any_cast(any * operand) noexcept + BOOST_ANY_IMPL_CONSTEXPR ValueType * any_cast(any * operand) noexcept { return operand && operand->type() == boost::typeindex::type_id() ? boost::unsafe_any_cast::type>(operand) @@ -305,7 +305,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \returns Const pointer to a ValueType stored in `operand`, nullptr if /// `operand` does not contain specified `ValueType`. template - inline const ValueType * any_cast(const any * operand) noexcept + BOOST_ANY_IMPL_CONSTEXPR inline const ValueType * any_cast(const any * operand) noexcept { return boost::any_cast(const_cast(operand)); } @@ -314,7 +314,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \throws boost::bad_any_cast if `operand` does not contain /// specified ValueType. template - ValueType any_cast(any & operand) + BOOST_ANY_IMPL_CONSTEXPR ValueType any_cast(any & operand) { using nonref = typename std::remove_reference::type; @@ -346,7 +346,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \throws boost::bad_any_cast if `operand` does not contain /// specified `ValueType`. template - inline ValueType any_cast(const any & operand) + BOOST_ANY_IMPL_CONSTEXPR inline ValueType any_cast(const any & operand) { using nonref = typename std::remove_reference::type; return boost::any_cast(const_cast(operand)); @@ -356,7 +356,7 @@ BOOST_ANY_BEGIN_MODULE_EXPORT /// \throws boost::bad_any_cast if `operand` does not contain /// specified `ValueType`. template - inline ValueType any_cast(any&& operand) + BOOST_ANY_IMPL_CONSTEXPR inline ValueType any_cast(any&& operand) { static_assert( std::is_rvalue_reference::value /*true if ValueType is rvalue or just a value*/ diff --git a/include/boost/any/detail/config.hpp b/include/boost/any/detail/config.hpp index 728ce7f..fe07854 100644 --- a/include/boost/any/detail/config.hpp +++ b/include/boost/any/detail/config.hpp @@ -7,6 +7,18 @@ #ifndef BOOST_ANY_ANYS_DETAIL_CONFIG_HPP #define BOOST_ANY_ANYS_DETAIL_CONFIG_HPP +#if defined __has_include +# if __has_include () +# include +# endif +#endif + +#if defined(__cpp_lib_constexpr_new) || defined(BOOST_ANY_DOXYGEN_INVOKED) +#define BOOST_ANY_IMPL_CONSTEXPR constexpr +#else +#define BOOST_ANY_IMPL_CONSTEXPR +#endif + #ifdef BOOST_ANY_INTERFACE_UNIT # define BOOST_ANY_BEGIN_MODULE_EXPORT export { # define BOOST_ANY_END_MODULE_EXPORT } diff --git a/include/boost/any/detail/placeholder.hpp b/include/boost/any/detail/placeholder.hpp index 1a5776d..88ae874 100644 --- a/include/boost/any/detail/placeholder.hpp +++ b/include/boost/any/detail/placeholder.hpp @@ -27,8 +27,8 @@ namespace detail { class BOOST_SYMBOL_VISIBLE placeholder { public: - virtual ~placeholder() {} - virtual const boost::typeindex::type_info& type() const noexcept = 0; + BOOST_ANY_IMPL_CONSTEXPR virtual ~placeholder() {} + BOOST_ANY_IMPL_CONSTEXPR virtual const boost::typeindex::type_info& type() const noexcept = 0; }; } // namespace detail diff --git a/include/boost/any/unique_any.hpp b/include/boost/any/unique_any.hpp index 99099fd..a0921a6 100644 --- a/include/boost/any/unique_any.hpp +++ b/include/boost/any/unique_any.hpp @@ -61,7 +61,7 @@ class unique_any { /// /// \post other->has_value() is false. /// \throws Nothing. - unique_any(unique_any&& other) noexcept = default; + BOOST_ANY_IMPL_CONSTEXPR unique_any(unique_any&& other) noexcept = default; /// Forwards `value`, so /// that the content of the new instance has type `std::decay_t` @@ -70,7 +70,7 @@ class unique_any { /// \throws std::bad_alloc or any exceptions arising from the move or /// copy constructor of the contained type. template - unique_any(T&& value, typename std::enable_if::value>::type* = nullptr) + BOOST_ANY_IMPL_CONSTEXPR unique_any(T&& value, typename std::enable_if::value>::type* = nullptr) : content(new holder< typename std::decay::type >(std::forward(value))) { static_assert( @@ -108,7 +108,7 @@ class unique_any { /// \throws std::bad_alloc or any exceptions arising from the move or /// copy constructor of the contained type. template - explicit unique_any(in_place_type_t, Args&&... args) + BOOST_ANY_IMPL_CONSTEXPR explicit unique_any(in_place_type_t, Args&&... args) : content(new holder::type>(std::forward(args)...)) { } @@ -120,7 +120,7 @@ class unique_any { /// \throws std::bad_alloc or any exceptions arising from the move or /// copy constructor of the contained type. template - explicit unique_any(in_place_type_t, std::initializer_list il, Args&&... args) + BOOST_ANY_IMPL_CONSTEXPR explicit unique_any(in_place_type_t, std::initializer_list il, Args&&... args) : content(new holder::type>(il, std::forward(args)...)) { } @@ -137,7 +137,7 @@ class unique_any { /// /// \post `rhs->empty()` is true /// \throws Nothing. - unique_any & operator=(unique_any&& rhs) noexcept = default; + BOOST_ANY_IMPL_CONSTEXPR unique_any & operator=(unique_any&& rhs) noexcept = default; /// Forwards `rhs`, /// discarding previous content, so that the new content of is @@ -148,7 +148,7 @@ class unique_any { /// contained type. Assignment satisfies the strong guarantee /// of exception safety. template - unique_any & operator=(T&& rhs) + BOOST_ANY_IMPL_CONSTEXPR unique_any & operator=(T&& rhs) { unique_any(std::forward(rhs)).swap(*this); return *this; @@ -162,7 +162,7 @@ class unique_any { /// \throws std::bad_alloc or any exceptions arising from the move or /// copy constructor of the contained type. template - typename std::decay::type& emplace(Args&&... args) { + BOOST_ANY_IMPL_CONSTEXPR typename std::decay::type& emplace(Args&&... args) { auto* raw_ptr = new holder::type>(std::forward(args)...); content = std::unique_ptr(raw_ptr); return raw_ptr->held; @@ -176,14 +176,14 @@ class unique_any { /// \throws std::bad_alloc or any exceptions arising from the move or /// copy constructor of the contained type. template - typename std::decay::type& emplace(std::initializer_list il, Args&&... args) { + BOOST_ANY_IMPL_CONSTEXPR typename std::decay::type& emplace(std::initializer_list il, Args&&... args) { auto* raw_ptr = new holder::type>(il, std::forward(args)...); content = std::unique_ptr(raw_ptr); return raw_ptr->held; } /// \post this->has_value() is false. - void reset() noexcept + BOOST_ANY_IMPL_CONSTEXPR void reset() noexcept { content.reset(); } @@ -192,14 +192,14 @@ class unique_any { /// /// \returns `*this` /// \throws Nothing. - void swap(unique_any& rhs) noexcept + BOOST_ANY_IMPL_CONSTEXPR void swap(unique_any& rhs) noexcept { content.swap(rhs.content); } /// \returns `true` if instance is not empty, otherwise `false`. /// \throws Nothing. - bool has_value() const noexcept + BOOST_ANY_IMPL_CONSTEXPR bool has_value() const noexcept { return !!content; } @@ -210,7 +210,7 @@ class unique_any { /// /// Useful for querying against types known either at compile time or /// only at runtime. - const boost::typeindex::type_info& type() const noexcept + BOOST_ANY_IMPL_CONSTEXPR const boost::typeindex::type_info& type() const noexcept { return content ? content->type() : boost::typeindex::type_id().type_info(); } @@ -222,18 +222,18 @@ class unique_any { { public: template - holder(Args&&... args) + BOOST_ANY_IMPL_CONSTEXPR holder(Args&&... args) : held(std::forward(args)...) { } template - holder(std::initializer_list il, Args&&... args) + BOOST_ANY_IMPL_CONSTEXPR holder(std::initializer_list il, Args&&... args) : held(il, std::forward(args)...) { } - const boost::typeindex::type_info& type() const noexcept override + BOOST_ANY_IMPL_CONSTEXPR const boost::typeindex::type_info& type() const noexcept override { return boost::typeindex::type_id().type_info(); } @@ -244,7 +244,7 @@ class unique_any { private: // representation template - friend T * unsafe_any_cast(unique_any *) noexcept; + friend BOOST_ANY_IMPL_CONSTEXPR T * unsafe_any_cast(unique_any *) noexcept; std::unique_ptr content; /// @endcond @@ -252,7 +252,7 @@ class unique_any { /// Exchange of the contents of `lhs` and `rhs`. /// \throws Nothing. -inline void swap(unique_any & lhs, unique_any & rhs) noexcept +BOOST_ANY_IMPL_CONSTEXPR inline void swap(unique_any & lhs, unique_any & rhs) noexcept { lhs.swap(rhs); } @@ -265,7 +265,7 @@ inline void swap(unique_any & lhs, unique_any & rhs) noexcept // use typeid() comparison, e.g., when our types may travel across // different shared libraries. template -inline T * unsafe_any_cast(unique_any * operand) noexcept +BOOST_ANY_IMPL_CONSTEXPR inline T * unsafe_any_cast(unique_any * operand) noexcept { return std::addressof( static_cast&>(*operand->content).held @@ -273,7 +273,7 @@ inline T * unsafe_any_cast(unique_any * operand) noexcept } template -inline const T * unsafe_any_cast(const unique_any * operand) noexcept +BOOST_ANY_IMPL_CONSTEXPR inline const T * unsafe_any_cast(const unique_any * operand) noexcept { return anys::unsafe_any_cast(const_cast(operand)); } @@ -282,7 +282,7 @@ inline const T * unsafe_any_cast(const unique_any * operand) noexcept /// \returns Pointer to a `T` stored in `operand`, nullptr if /// `operand` does not contain specified `T`. template -T * any_cast(unique_any * operand) noexcept +BOOST_ANY_IMPL_CONSTEXPR T * any_cast(unique_any * operand) noexcept { return operand && operand->type() == boost::typeindex::type_id() ? anys::unsafe_any_cast::type>(operand) @@ -292,7 +292,7 @@ T * any_cast(unique_any * operand) noexcept /// \returns Const pointer to a `T` stored in `operand`, nullptr if /// `operand` does not contain specified `T`. template -inline const T * any_cast(const unique_any * operand) noexcept +BOOST_ANY_IMPL_CONSTEXPR inline const T * any_cast(const unique_any * operand) noexcept { return anys::any_cast(const_cast(operand)); } @@ -300,7 +300,7 @@ inline const T * any_cast(const unique_any * operand) noexcept /// \returns `T` stored in `operand` /// \throws boost::bad_any_cast if `operand` does not contain specified `T`. template -T any_cast(unique_any & operand) +BOOST_ANY_IMPL_CONSTEXPR T any_cast(unique_any & operand) { using nonref = typename std::remove_reference::type; @@ -331,7 +331,7 @@ T any_cast(unique_any & operand) /// \returns `T` stored in `operand` /// \throws boost::bad_any_cast if `operand` does not contain specified `T`. template -inline T any_cast(const unique_any & operand) +BOOST_ANY_IMPL_CONSTEXPR inline T any_cast(const unique_any & operand) { using nonref = typename std::remove_reference::type; return anys::any_cast(const_cast(operand)); @@ -340,7 +340,7 @@ inline T any_cast(const unique_any & operand) /// \returns `T` stored in `operand` /// \throws boost::bad_any_cast if `operand` does not contain specified `T`. template -inline T any_cast(unique_any&& operand) +BOOST_ANY_IMPL_CONSTEXPR inline T any_cast(unique_any&& operand) { static_assert( std::is_rvalue_reference::value /*true if T is rvalue or just a value*/ diff --git a/test/any_test.cpp b/test/any_test.cpp index 2c0b38b..8ea5f2b 100644 --- a/test/any_test.cpp +++ b/test/any_test.cpp @@ -55,9 +55,77 @@ static void test_with_func() s = boost::any_cast(returning_string2()); } + + +#ifdef __cpp_lib_constexpr_new + +#define BOOST_ANY_IMPL_CONSTEXPR_ASSERT(X) \ + if (!(X)) throw std::runtime_error(#X " is false at " + std::to_string(__LINE__)) + +constexpr int test_constexpr() { + boost::any a; + + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.empty()); + + a = 42; + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.empty()); + + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 42); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(*boost::unsafe_any_cast(&a) == 42); + + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(&a) == nullptr); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 42); + + boost::any b = std::move(a); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!b.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(b) == 42); + + a = std::move(b); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(b.empty()); + + a.clear(); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(b.empty()); + + a = 43; + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 43); + + a.swap(b); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!b.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(b) == 43); + + a.swap(b); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(b.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 43); + + b = a; + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!b.empty()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 43); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(b) == 43); + + const boost::any ca = 44; + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(ca) == 44); + + return 0; +} + +#undef BOOST_ANY_IMPL_CONSTEXPR_ASSERT + +#endif + int main() { test_with_func(); +#ifdef __cpp_lib_constexpr_new + static_assert(test_constexpr() == 0); +#endif + return any_tests::basic_tests::run_tests(); } diff --git a/test/unique_any/base.cpp b/test/unique_any/base.cpp index c615301..5bfa261 100644 --- a/test/unique_any/base.cpp +++ b/test/unique_any/base.cpp @@ -125,6 +125,69 @@ void test_swap() { BOOST_TEST_EQ(boost::any_cast&>(a).data(), vec_data); } +#ifdef __cpp_lib_constexpr_new + +#define BOOST_ANY_IMPL_CONSTEXPR_ASSERT(X) \ + if (!(X)) throw std::runtime_error(#X " is false at " + std::to_string(__LINE__)) + +constexpr int test_constexpr() { + boost::anys::unique_any a; + + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.has_value()); + + auto& i = a.emplace(42); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(i == 42); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.has_value()); + + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 42); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(*boost::unsafe_any_cast(&a) == 42); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::anys::any_cast(a) == 42); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(*boost::anys::unsafe_any_cast(&a) == 42); + + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(&a) == nullptr); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::anys::any_cast(&a) == nullptr); + + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 42); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::anys::any_cast(a) == 42); + + boost::anys::unique_any b = std::move(a); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(b.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::anys::any_cast(b) == 42); + + a = std::move(b); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!b.has_value()); + + a.reset(); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!b.has_value()); + + a = 43; + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 43); + + a.swap(b); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!a.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(b.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(b) == 43); + + a.swap(b); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(a.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(!b.has_value()); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(a) == 43); + + const boost::anys::unique_any ca = 44; + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::any_cast(ca) == 44); + BOOST_ANY_IMPL_CONSTEXPR_ASSERT(boost::anys::any_cast(ca) == 44); + + return 0; +} + +#undef BOOST_ANY_IMPL_CONSTEXPR_ASSERT + +#endif + int main() { test_basic(); test_const(); @@ -132,6 +195,10 @@ int main() { test_destructor(); test_swap(); +#ifdef __cpp_lib_constexpr_new + static_assert(test_constexpr() == 0); +#endif + return boost::report_errors(); }