diff --git a/test/Jamfile b/test/Jamfile index 588291b..2f2c42a 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -109,3 +109,4 @@ run variant_subset.cpp throw_exception.cpp : : : $(NX) : variant_subset_nx ; run variant_hash.cpp ; run variant_trivial.cpp ; +run variant_special.cpp ; diff --git a/test/variant_special.cpp b/test/variant_special.cpp new file mode 100644 index 0000000..4c012bc --- /dev/null +++ b/test/variant_special.cpp @@ -0,0 +1,116 @@ +// Copyright 2020 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(_MSC_VER) && _MSC_VER < 1910 +# pragma warning(disable: 4503) // decorated name length exceeded +#endif + +#include +#include +#include + +#include +using namespace boost::mp11; + +// mp_power_set + +template struct mp_power_set_impl; + +template using mp_power_set = typename mp_power_set_impl::type; + +template class L> struct mp_power_set_impl< L<> > +{ + using type = L< L<> >; +}; + +template class L, class T1, class... T> struct mp_power_set_impl< L > +{ + using S1 = mp_power_set< L >; + + template using _f = mp_push_front; + + using S2 = mp_transform<_f, S1>; + + using type = mp_append< S1, S2 >; +}; + +// + +using namespace boost::variant2; + +struct D +{ + ~D() noexcept {} +}; + +struct CC1 +{ + CC1( CC1 const& ) {} +}; + +struct CC2 +{ + CC2( CC2 const& ) = delete; +}; + +struct MC1 +{ + MC1( MC1 && ) {} +}; + +struct MC2 +{ + MC2( MC2 && ) = delete; +}; + +struct CA1 +{ + CA1& operator=( CA1 const& ) { return *this; } +}; + +struct CA2 +{ + CA2& operator=( CA2 const& ) = delete; +}; + +struct MA1 +{ + MA1& operator=( MA1 && ) { return *this; } +}; + +struct MA2 +{ + MA2& operator=( MA2 && ) = delete; +}; + +struct test +{ + template void operator()( mp_list ) const noexcept + { + using U = mp_inherit; + + BOOST_TEST_EQ( std::is_copy_constructible>::value, std::is_copy_constructible::value ); + BOOST_TEST_EQ( std::is_nothrow_copy_constructible>::value, std::is_nothrow_copy_constructible::value ); + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + BOOST_TEST_EQ( std::is_move_constructible>::value, std::is_move_constructible::value ); +#else + BOOST_TEST_GE( std::is_move_constructible>::value, std::is_move_constructible::value ); +#endif + + BOOST_TEST_EQ( std::is_nothrow_move_constructible>::value, std::is_nothrow_move_constructible::value ); + + BOOST_TEST_EQ( std::is_copy_assignable>::value, std::is_copy_constructible::value && std::is_copy_assignable::value ); + BOOST_TEST_EQ( std::is_nothrow_copy_assignable>::value, std::is_nothrow_copy_constructible::value && std::is_copy_assignable::value ); + + BOOST_TEST_EQ( std::is_move_assignable>::value, std::is_move_constructible::value && std::is_move_assignable::value ); + BOOST_TEST_EQ( std::is_nothrow_move_assignable>::value, std::is_nothrow_move_constructible::value && std::is_move_assignable::value ); + } +}; + +int main() +{ + mp_for_each< mp_power_set< mp_list > >( test() ); + return boost::report_errors(); +}