From 90cc6b7374c7713324fa3790a00957350340f54e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 18 Oct 2018 07:19:45 +0300 Subject: [PATCH] Port to C++11 --- include/boost/variant2/variant.hpp | 722 +++++++++++-------- test/Jamfile | 12 +- test/variant_copy_assign.cpp | 8 +- test/variant_eq_ne.cpp | 2 +- test/variant_in_place_index_construct.cpp | 32 +- test/variant_in_place_index_construct_cx.cpp | 26 +- test/variant_in_place_type_construct.cpp | 24 +- test/variant_in_place_type_construct_cx.cpp | 20 +- test/variant_lt_gt.cpp | 2 +- test/variant_move_assign.cpp | 8 +- test/variant_swap.cpp | 8 +- test/variant_visit.cpp | 42 +- 12 files changed, 508 insertions(+), 398 deletions(-) diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 4c5f5a9..01655cb 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -80,8 +80,12 @@ template struct variant_size: variant_size { }; +#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) + template /*inline*/ constexpr std::size_t variant_size_v = variant_size::value; +#endif + template struct variant_size>: mp_size> { }; @@ -101,15 +105,15 @@ template struct variant_alternative { }; -template struct variant_alternative: mp_defer< variant2::detail::var_alt_impl, mp_size_t, T, mp_quote> +template struct variant_alternative: mp_defer< variant2::detail::var_alt_impl, mp_size_t, T, mp_quote_trait> { }; -template struct variant_alternative: mp_defer< variant2::detail::var_alt_impl, mp_size_t, T, mp_quote> +template struct variant_alternative: mp_defer< variant2::detail::var_alt_impl, mp_size_t, T, mp_quote_trait> { }; -template struct variant_alternative: mp_defer< variant2::detail::var_alt_impl, mp_size_t, T, mp_quote> +template struct variant_alternative: mp_defer< variant2::detail::var_alt_impl, mp_size_t, T, mp_quote_trait> { }; @@ -130,65 +134,25 @@ template constexpr bool holds_alternative( variant co template constexpr variant_alternative_t>& get(variant& v) { static_assert( I < sizeof...(T), "Index out of bounds" ); - -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) - return (void)( v.index() != I? throw bad_variant_access(): 0 ), v._get_impl( mp_size_t() ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return v._get_impl( mp_size_t() ); - -#endif } template constexpr variant_alternative_t>&& get(variant&& v) { static_assert( I < sizeof...(T), "Index out of bounds" ); - -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) - return (void)( v.index() != I? throw bad_variant_access(): 0 ), std::move( v._get_impl( mp_size_t() ) ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return std::move( v._get_impl( mp_size_t() ) ); - -#endif } template constexpr variant_alternative_t> const& get(variant const& v) { static_assert( I < sizeof...(T), "Index out of bounds" ); - -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) - return (void)( v.index() != I? throw bad_variant_access(): 0 ), v._get_impl( mp_size_t() ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return v._get_impl( mp_size_t() ); - -#endif } template constexpr variant_alternative_t> const&& get(variant const&& v) { static_assert( I < sizeof...(T), "Index out of bounds" ); - -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) - return (void)( v.index() != I? throw bad_variant_access(): 0 ), std::move( v._get_impl( mp_size_t() ) ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return std::move( v._get_impl( mp_size_t() ) ); - -#endif } // get (type) @@ -196,99 +160,69 @@ template constexpr variant_alternative_t constexpr U& get(variant& v) { static_assert( mp_count, U>::value == 1, "The type must occur exactly once in the list of variant alternatives" ); - constexpr auto I = mp_find, U>::value; -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) + using I = mp_find, U>; - return (void)( v.index() != I? throw bad_variant_access(): 0 ), v._get_impl( mp_size_t() ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return v._get_impl( mp_size_t() ); - -#endif + return (void)( v.index() != I::value? throw bad_variant_access(): 0 ), v._get_impl( I() ); } template constexpr U&& get(variant&& v) { static_assert( mp_count, U>::value == 1, "The type must occur exactly once in the list of variant alternatives" ); - constexpr auto I = mp_find, U>::value; -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) + using I = mp_find, U>; - return (void)( v.index() != I? throw bad_variant_access(): 0 ), std::move( v._get_impl( mp_size_t() ) ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return std::move( v._get_impl( mp_size_t() ) ); - -#endif + return (void)( v.index() != I::value? throw bad_variant_access(): 0 ), std::move( v._get_impl( I() ) ); } template constexpr U const& get(variant const& v) { static_assert( mp_count, U>::value == 1, "The type must occur exactly once in the list of variant alternatives" ); - constexpr auto I = mp_find, U>::value; -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) + using I = mp_find, U>; - return (void)( v.index() != I? throw bad_variant_access(): 0 ), v._get_impl( mp_size_t() ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return v._get_impl( mp_size_t() ); - -#endif + return (void)( v.index() != I::value? throw bad_variant_access(): 0 ), v._get_impl( I() ); } template constexpr U const&& get(variant const&& v) { static_assert( mp_count, U>::value == 1, "The type must occur exactly once in the list of variant alternatives" ); - constexpr auto I = mp_find, U>::value; -#if BOOST_WORKAROUND( BOOST_GCC, < 60000 ) + using I = mp_find, U>; - return (void)( v.index() != I? throw bad_variant_access(): 0 ), std::move( v._get_impl( mp_size_t() ) ); - -#else - - if( v.index() != I ) throw bad_variant_access(); - return std::move( v._get_impl( mp_size_t() ) ); - -#endif + return (void)( v.index() != I::value? throw bad_variant_access(): 0 ), std::move( v._get_impl( I() ) ); } // get_if -template constexpr std::add_pointer_t>> get_if(variant* v) noexcept +template constexpr typename std::add_pointer>>::type get_if(variant* v) noexcept { static_assert( I < sizeof...(T), "Index out of bounds" ); return v && v->index() == I? &v->_get_impl( mp_size_t() ): 0; } -template constexpr std::add_pointer_t>> get_if(variant const * v) noexcept +template constexpr typename std::add_pointer>>::type get_if(variant const * v) noexcept { static_assert( I < sizeof...(T), "Index out of bounds" ); return v && v->index() == I? &v->_get_impl( mp_size_t() ): 0; } -template constexpr std::add_pointer_t get_if(variant* v) noexcept +template constexpr typename std::add_pointer::type get_if(variant* v) noexcept { static_assert( mp_count, U>::value == 1, "The type must occur exactly once in the list of variant alternatives" ); - constexpr auto I = mp_find, U>::value; - return v && v->index() == I? &v->_get_impl( mp_size_t() ): 0; + using I = mp_find, U>; + + return v && v->index() == I::value? &v->_get_impl( I() ): 0; } -template constexpr std::add_pointer_t get_if(variant const * v) noexcept +template constexpr typename std::add_pointer::type get_if(variant const * v) noexcept { static_assert( mp_count, U>::value == 1, "The type must occur exactly once in the list of variant alternatives" ); - constexpr auto I = mp_find, U>::value; - return v && v->index() == I? &v->_get_impl( mp_size_t() ): 0; + using I = mp_find, U>; + + return v && v->index() == I::value? &v->_get_impl( I() ): 0; } // @@ -363,10 +297,10 @@ template union variant_storage_impl rest_.emplace( mp_size_t(), std::forward(a)... ); } - constexpr T1& get( mp_size_t<0> ) noexcept { return first_; } + BOOST_CXX14_CONSTEXPR T1& get( mp_size_t<0> ) noexcept { return first_; } constexpr T1 const& get( mp_size_t<0> ) const noexcept { return first_; } - template constexpr mp_at_c, I-1>& get( mp_size_t ) noexcept { return rest_.get( mp_size_t() ); } + template BOOST_CXX14_CONSTEXPR mp_at_c, I-1>& get( mp_size_t ) noexcept { return rest_.get( mp_size_t() ); } template constexpr mp_at_c, I-1> const& get( mp_size_t ) const noexcept { return rest_.get( mp_size_t() ); } }; @@ -389,25 +323,25 @@ template union variant_storage_impl ::new( &first_ ) T1( std::forward(a)... ); } - template constexpr void emplace_impl( mp_false, mp_size_t, A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace_impl( mp_false, mp_size_t, A&&... a ) { rest_.emplace( mp_size_t(), std::forward(a)... ); } - template constexpr void emplace_impl( mp_true, mp_size_t, A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace_impl( mp_true, mp_size_t, A&&... a ) { *this = variant_storage_impl( mp_size_t(), std::forward(a)... ); } - template constexpr void emplace( mp_size_t, A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace( mp_size_t, A&&... a ) { this->emplace_impl( mp_all, variant2::detail::is_trivially_move_assignable...>(), mp_size_t(), std::forward(a)... ); } - constexpr T1& get( mp_size_t<0> ) noexcept { return first_; } + BOOST_CXX14_CONSTEXPR T1& get( mp_size_t<0> ) noexcept { return first_; } constexpr T1 const& get( mp_size_t<0> ) const noexcept { return first_; } - template constexpr mp_at_c, I-1>& get( mp_size_t ) noexcept { return rest_.get( mp_size_t() ); } + template BOOST_CXX14_CONSTEXPR mp_at_c, I-1>& get( mp_size_t ) noexcept { return rest_.get( mp_size_t() ); } template constexpr mp_at_c, I-1> const& get( mp_size_t ) const noexcept { return rest_.get( mp_size_t() ); } }; @@ -473,7 +407,7 @@ template struct variant_base_impl return ix_ - 1; } - template constexpr mp_at_c, I>& _get_impl( mp_size_t ) noexcept + template BOOST_CXX14_CONSTEXPR mp_at_c, I>& _get_impl( mp_size_t ) noexcept { size_t const J = I+1; @@ -484,20 +418,19 @@ template struct variant_base_impl template constexpr mp_at_c, I> const& _get_impl( mp_size_t ) const noexcept { - size_t const J = I+1; + // size_t const J = I+1; + // assert( ix_ == I+1 ); - assert( ix_ == J ); - - return st1_.get( mp_size_t() ); + return st1_.get( mp_size_t() ); } - template constexpr void emplace_impl( mp_true, mp_bool, A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace_impl( mp_true, mp_bool, A&&... a ) { st1_.emplace( mp_size_t(), std::forward(a)... ); ix_ = J; } - template constexpr void emplace_impl( mp_false, mp_true, A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace_impl( mp_false, mp_true, A&&... a ) { U tmp( std::forward(a)... ); @@ -537,7 +470,7 @@ template struct variant_base_impl } } - template constexpr void emplace( A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace( A&&... a ) { std::size_t const J = I+1; using U = mp_at_c, I>; @@ -566,7 +499,7 @@ template struct variant_base_impl return ix_ >= 0? ix_ - 1: -ix_ - 1; } - template constexpr mp_at_c, I>& _get_impl( mp_size_t ) noexcept + template BOOST_CXX14_CONSTEXPR mp_at_c, I>& _get_impl( mp_size_t ) noexcept { size_t const J = I+1; @@ -578,15 +511,14 @@ template struct variant_base_impl template constexpr mp_at_c, I> const& _get_impl( mp_size_t ) const noexcept { - size_t const J = I+1; + // size_t const J = I+1; + // assert( ix_ == J || -ix_ == J ); + // constexpr mp_size_t j{}; - assert( ix_ == J || -ix_ == J ); - - constexpr mp_size_t j{}; - return ix_ >= 0? st1_.get( j ): st2_.get( j ); + return ix_ >= 0? st1_.get( mp_size_t() ): st2_.get( mp_size_t() ); } - template constexpr void emplace( A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace( A&&... a ) { size_t const J = I+1; @@ -617,16 +549,27 @@ template struct variant_base_impl { } + //[&]( auto I ){ + // using U = mp_at_c, I>; + // st1_.get( I ).~U(); + //} + + struct _destroy_L1 + { + variant_base_impl * this_; + + template void operator()( I ) const noexcept + { + using U = mp_at, I>; + this_->st1_.get( I() ).~U(); + } + }; + void _destroy() noexcept { if( ix_ > 0 ) { - mp_with_index<1 + sizeof...(T)>( ix_, [&]( auto I ){ - - using U = mp_at_c, I>; - st1_.get( I ).~U(); - - }); + mp_with_index<1 + sizeof...(T)>( ix_, _destroy_L1{ this } ); } } @@ -640,7 +583,7 @@ template struct variant_base_impl return ix_ - 1; } - template constexpr mp_at_c, I>& _get_impl( mp_size_t ) noexcept + template BOOST_CXX14_CONSTEXPR mp_at_c, I>& _get_impl( mp_size_t ) noexcept { size_t const J = I+1; @@ -651,11 +594,10 @@ template struct variant_base_impl template constexpr mp_at_c, I> const& _get_impl( mp_size_t ) const noexcept { - size_t const J = I+1; + // size_t const J = I+1; + // assert( ix_ == J ); - assert( ix_ == J ); - - return st1_.get( mp_size_t() ); + return st1_.get( mp_size_t() ); } template void emplace( A&&... a ) @@ -721,25 +663,42 @@ template struct variant_base_impl { } + //[&]( auto I ){ + // using U = mp_at_c, I>; + // st1_.get( I ).~U(); + //} + + struct _destroy_L1 + { + variant_base_impl * this_; + + template void operator()( I ) const noexcept + { + using U = mp_at, I>; + this_->st1_.get( I() ).~U(); + } + }; + + struct _destroy_L2 + { + variant_base_impl * this_; + + template void operator()( I ) const noexcept + { + using U = mp_at, I>; + this_->st2_.get( I() ).~U(); + } + }; + void _destroy() noexcept { if( ix_ > 0 ) { - mp_with_index<1 + sizeof...(T)>( ix_, [&]( auto I ){ - - using U = mp_at_c, I>; - st1_.get( I ).~U(); - - }); + mp_with_index<1 + sizeof...(T)>( ix_, _destroy_L1{ this } ); } else if( ix_ < 0 ) { - mp_with_index<1 + sizeof...(T)>( -ix_, [&]( auto I ){ - - using U = mp_at_c, I>; - st2_.get( I ).~U(); - - }); + mp_with_index<1 + sizeof...(T)>( -ix_, _destroy_L2{ this } ); } } @@ -753,7 +712,7 @@ template struct variant_base_impl return ix_ >= 0? ix_ - 1: -ix_ - 1; } - template constexpr mp_at_c, I>& _get_impl( mp_size_t ) noexcept + template BOOST_CXX14_CONSTEXPR mp_at_c, I>& _get_impl( mp_size_t ) noexcept { size_t const J = I+1; @@ -765,12 +724,11 @@ template struct variant_base_impl template constexpr mp_at_c, I> const& _get_impl( mp_size_t ) const noexcept { - size_t const J = I+1; + // size_t const J = I+1; + // assert( ix_ == J || -ix_ == J ); + // constexpr mp_size_t j{}; - assert( ix_ == J || -ix_ == J ); - - constexpr mp_size_t j{}; - return ix_ >= 0? st1_.get( j ): st2_.get( j ); + return ix_ >= 0? st1_.get( mp_size_t() ): st2_.get( mp_size_t() ); } template void emplace( A&&... a ) @@ -802,8 +760,12 @@ template struct in_place_type_t { }; +#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) + template constexpr in_place_type_t in_place_type{}; +#endif + namespace detail { @@ -818,8 +780,12 @@ template struct in_place_index_t { }; +#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) + template constexpr in_place_index_t in_place_index{}; +#endif + namespace detail { @@ -851,7 +817,7 @@ template using is_nothrow_swappable_impl = mp_bool< is_nothrow_swappabl #else -template using is_nothrow_swappable_impl = std::enable_if_t(), std::declval()))>; +template using is_nothrow_swappable_impl = typename std::enable_if(), std::declval()))>::type; #endif @@ -909,6 +875,21 @@ public: { } +private: + + struct L1 + { + variant_base * this_; + variant const & r; + + template void operator()( I i ) const + { + ::new( static_cast( this_ ) ) variant_base( i, r._get_impl( i ) ); + } + }; + +public: + template...>>, E1>, class E3 = mp_if...>, E1> @@ -916,11 +897,7 @@ public: variant( variant const& r ) noexcept( mp_all...>::value ) { - mp_with_index( r.index(), [&]( auto I ){ - - ::new( static_cast(this) ) variant_base( I, r._get_impl( I ) ); - - }); + mp_with_index( r.index(), L1{ this, r } ); } template void operator()( I i ) const + { + ::new( static_cast( this_ ) ) variant_base( i, std::move( r._get_impl( i ) ) ); + } + }; + +public: + template...>>, E1>, class E3 = mp_if...>, E1> @@ -938,18 +930,14 @@ public: variant( variant && r ) noexcept( mp_all...>::value ) { - mp_with_index( r.index(), [&]( auto I ){ - - ::new( static_cast(this) ) variant_base( I, std::move( r._get_impl( I ) ) ); - - }); + mp_with_index( r.index(), L2{ this, r } ); } template, - class E1 = std::enable_if_t< !std::is_same::value && !variant2::detail::is_in_place_index::value && !variant2::detail::is_in_place_type::value >, + class Ud = typename std::decay::type, + class E1 = typename std::enable_if< !std::is_same::value && !variant2::detail::is_in_place_index::value && !variant2::detail::is_in_place_type::value >::type, class V = variant2::detail::resolve_overload_type, - class E2 = std::enable_if_t::value> + class E2 = typename std::enable_if::value>::type > constexpr variant( U&& u ) noexcept( std::is_nothrow_constructible::value ) @@ -957,22 +945,22 @@ public: { } - template, U>, class E = std::enable_if_t::value>> + template, U>, class E = typename std::enable_if::value>::type> constexpr explicit variant( in_place_type_t, A&&... a ): variant_base( I(), std::forward(a)... ) { } - template, U>, class E = std::enable_if_t&, A...>::value>> + template, U>, class E = typename std::enable_if&, A...>::value>::type> constexpr explicit variant( in_place_type_t, std::initializer_list il, A&&... a ): variant_base( I(), il, std::forward(a)... ) { } - template, I>, A...>::value>> + template, I>, A...>::value>::type> constexpr explicit variant( in_place_index_t, A&&... a ): variant_base( mp_size_t(), std::forward(a)... ) { } - template, I>, std::initializer_list&, A...>::value>> + template, I>, std::initializer_list&, A...>::value>::type> constexpr explicit variant( in_place_index_t, std::initializer_list il, A&&... a ): variant_base( mp_size_t(), il, std::forward(a)... ) { } @@ -981,44 +969,76 @@ public: template..., variant2::detail::is_trivially_copy_assignable...>, E1> > - constexpr variant& operator=( variant const & r ) noexcept + BOOST_CXX14_CONSTEXPR variant& operator=( variant const & r ) noexcept { static_cast( *this ) = static_cast( r ); return *this; } +private: + + struct L3 + { + variant * this_; + variant const & r; + + template void operator()( I i ) const + { + if( this_->index() == i ) + { + this_->_get_impl( i ) = r._get_impl( i ); + } + else + { + this_->variant_base::template emplace( r._get_impl( i ) ); + } + } + }; + +public: + template..., variant2::detail::is_trivially_copy_assignable...>>, E1>, class E3 = mp_if..., std::is_copy_assignable...>, E1> > - constexpr variant& operator=( variant const & r ) + BOOST_CXX14_CONSTEXPR variant& operator=( variant const & r ) noexcept( mp_all..., std::is_nothrow_copy_assignable...>::value ) { - mp_with_index( r.index(), [&]( auto I ){ - - if( this->index() == I ) - { - this->_get_impl( I ) = r._get_impl( I ); - } - else - { - this->variant_base::template emplace( r._get_impl( I ) ); - } - - }); - + mp_with_index( r.index(), L3{ this, r } ); return *this; } template..., variant2::detail::is_trivially_move_assignable...>, E1> > - constexpr variant& operator=( variant && r ) noexcept + BOOST_CXX14_CONSTEXPR variant& operator=( variant && r ) noexcept { static_cast( *this ) = static_cast( r ); return *this; } +private: + + struct L4 + { + variant * this_; + variant & r; + + template void operator()( I i ) const + { + if( this_->index() == i ) + { + this_->_get_impl( i ) = std::move( r._get_impl( i ) ); + } + else + { + this_->variant_base::template emplace( std::move( r._get_impl( i ) ) ); + } + } + }; + +public: + template..., variant2::detail::is_trivially_move_assignable...>>, E1>, class E3 = mp_if..., std::is_move_assignable...>, E1> @@ -1026,28 +1046,16 @@ public: variant& operator=( variant && r ) noexcept( mp_all..., std::is_nothrow_move_assignable...>::value ) { - mp_with_index( r.index(), [&]( auto I ){ - - if( this->index() == I ) - { - this->_get_impl( I ) = std::move( r._get_impl( I ) ); - } - else - { - this->variant_base::template emplace( std::move( r._get_impl( I ) ) ); - } - - }); - + mp_with_index( r.index(), L4{ this, r } ); return *this; } template, variant>::value>, + class E1 = typename std::enable_if::type, variant>::value>::type, class V = variant2::detail::resolve_overload_type, - class E2 = std::enable_if_t::value && std::is_constructible::value> + class E2 = typename std::enable_if::value && std::is_constructible::value>::type > - constexpr variant& operator=( U&& u ) + BOOST_CXX14_CONSTEXPR variant& operator=( U&& u ) noexcept( std::is_nothrow_assignable::value && std::is_nothrow_constructible::value ) { std::size_t const I = variant2::detail::resolve_overload_index::value; @@ -1066,29 +1074,29 @@ public: // modifiers - template, U>, class E = std::enable_if_t::value>> - constexpr U& emplace( A&&... a ) + template, U>, class E = typename std::enable_if::value>::type> + BOOST_CXX14_CONSTEXPR U& emplace( A&&... a ) { variant_base::template emplace( std::forward(a)... ); return _get_impl( I() ); } - template, U>, class E = std::enable_if_t&, A...>::value>> - constexpr U& emplace( std::initializer_list il, A&&... a ) + template, U>, class E = typename std::enable_if&, A...>::value>::type> + BOOST_CXX14_CONSTEXPR U& emplace( std::initializer_list il, A&&... a ) { variant_base::template emplace( il, std::forward(a)... ); return _get_impl( I() ); } - template, I>, A...>::value>> - constexpr variant_alternative_t>& emplace( A&&... a ) + template, I>, A...>::value>::type> + BOOST_CXX14_CONSTEXPR variant_alternative_t>& emplace( A&&... a ) { variant_base::template emplace( std::forward(a)... ); return _get_impl( mp_size_t() ); } - template, I>, std::initializer_list&, A...>::value>> - constexpr variant_alternative_t>& emplace( std::initializer_list il, A&&... a ) + template, I>, std::initializer_list&, A...>::value>::type> + BOOST_CXX14_CONSTEXPR variant_alternative_t>& emplace( std::initializer_list il, A&&... a ) { variant_base::template emplace( il, std::forward(a)... ); return _get_impl( mp_size_t() ); @@ -1100,16 +1108,27 @@ public: // swap +private: + + struct L5 + { + variant * this_; + variant & r; + + template void operator()( I i ) const + { + using std::swap; + swap( this_->_get_impl( i ), r._get_impl( i ) ); + } + }; + +public: + void swap( variant& r ) noexcept( mp_all..., variant2::detail::is_nothrow_swappable...>::value ) { if( index() == r.index() ) { - mp_with_index( index(), [&]( auto I ){ - - using std::swap; - swap( this->_get_impl( I ), r._get_impl( I ) ); - - }); + mp_with_index( index(), L5{ this, r } ); } else { @@ -1130,41 +1149,61 @@ public: // converting constructors (extension) +private: + + template struct L6 + { + variant_base * this_; + variant const & r; + + template void operator()( I i ) const + { + using J = mp_find, mp_at, I>>; + ::new( static_cast(this_) ) variant_base( J{}, r._get_impl( i ) ); + } + }; + +public: + template..., mp_contains, U>...>, void> > variant( variant const& r ) noexcept( mp_all...>::value ) { - mp_with_index( r.index(), [&]( auto I ){ - - using J = mp_find, mp_at_c, I>>; - - ::new( static_cast(this) ) variant_base( J{}, r._get_impl( I ) ); - - }); + mp_with_index( r.index(), L6{ this, r } ); } +private: + + template struct L7 + { + variant_base * this_; + variant & r; + + template void operator()( I i ) const + { + using J = mp_find, mp_at, I>>; + ::new( static_cast(this_) ) variant_base( J{}, std::move( r._get_impl( i ) ) ); + } + }; + +public: + template..., mp_contains, U>...>, void> > variant( variant && r ) noexcept( mp_all...>::value ) { - mp_with_index( r.index(), [&]( auto I ){ - - using J = mp_find, mp_at_c, I>>; - - ::new( static_cast(this) ) variant_base( J{}, std::move( r._get_impl( I ) ) ); - - }); + mp_with_index( r.index(), L7{ this, r } ); } // subset (extension) private: - template> static constexpr variant _subset_impl( mp_size_t, V && v ) + template::type> static constexpr variant _subset_impl( mp_size_t, V && v ) { - return variant( in_place_index, std::forward(v) ); + return variant( in_place_index_t(), std::forward(v) ); } template static variant _subset_impl( mp_size_t, V && /*v*/ ) @@ -1172,130 +1211,189 @@ private: throw bad_variant_access(); } +private: + + template struct L8 + { + variant * this_; + + template variant operator()( I i ) const + { + using J = mp_find, mp_at, I>>; + return this_->_subset_impl( J{}, this_->_get_impl( i ) ); + } + }; + public: template..., mp_contains, U>...>, void> > - constexpr variant subset() & + BOOST_CXX14_CONSTEXPR variant subset() & { - return mp_with_index( index(), [&]( auto I ){ - - using J = mp_find, mp_at_c, I>>; - - return this->_subset_impl( J{}, this->_get_impl( I ) ); - - }); + return mp_with_index( index(), L8{ this } ); } +private: + + template struct L9 + { + variant const * this_; + + template variant operator()( I i ) const + { + using J = mp_find, mp_at, I>>; + return this_->_subset_impl( J{}, this_->_get_impl( i ) ); + } + }; + +public: + template..., mp_contains, U>...>, void> > constexpr variant subset() const& { - return mp_with_index( index(), [&]( auto I ){ - - using J = mp_find, mp_at_c, I>>; - - return this->_subset_impl( J{}, this->_get_impl( I ) ); - - }); + return mp_with_index( index(), L9{ this } ); } +private: + + template struct L10 + { + variant * this_; + + template variant operator()( I i ) const + { + using J = mp_find, mp_at, I>>; + return this_->_subset_impl( J{}, std::move( this_->_get_impl( i ) ) ); + } + }; + +public: + template..., mp_contains, U>...>, void> > - constexpr variant subset() && + BOOST_CXX14_CONSTEXPR variant subset() && { - return mp_with_index( index(), [&]( auto I ){ - - using J = mp_find, mp_at_c, I>>; - - return this->_subset_impl( J{}, std::move( this->_get_impl( I ) ) ); - - }); + return mp_with_index( index(), L10{ this } ); } +private: + + template struct L11 + { + variant const * this_; + + template variant operator()( I i ) const + { + using J = mp_find, mp_at, I>>; + return this_->_subset_impl( J{}, std::move( this_->_get_impl( i ) ) ); + } + }; + +public: + template..., mp_contains, U>...>, void> > constexpr variant subset() const&& { - return mp_with_index( index(), [&]( auto I ){ - - using J = mp_find, mp_at_c, I>>; - - return this->_subset_impl( J{}, std::move( this->_get_impl( I ) ) ); - - }); + return mp_with_index( index(), L11{ this } ); } }; // relational operators + +namespace detail +{ + +template struct eq_L +{ + variant const & v; + variant const & w; + + template bool operator()( I i ) const + { + return v._get_impl( i ) == w._get_impl( i ); + } +}; + +} // namespace detail + template constexpr bool operator==( variant const & v, variant const & w ) { - if( v.index() != w.index() ) return false; - - return mp_with_index( v.index(), [&]( auto I ){ - - return v._get_impl( I ) == w._get_impl( I ); - - }); + return v.index() == w.index() && mp_with_index( v.index(), detail::eq_L{ v, w } ); } +namespace detail +{ + +template struct ne_L +{ + variant const & v; + variant const & w; + + template bool operator()( I i ) const + { + return v._get_impl( i ) != w._get_impl( i ); + } +}; + +} // namespace detail + template constexpr bool operator!=( variant const & v, variant const & w ) { - if( v.index() != w.index() ) return true; - - return mp_with_index( v.index(), [&]( auto I ){ - - return v._get_impl( I ) != w._get_impl( I ); - - }); + return v.index() != w.index() || mp_with_index( v.index(), detail::ne_L{ v, w } ); } +namespace detail +{ + +template struct lt_L +{ + variant const & v; + variant const & w; + + template bool operator()( I i ) const + { + return v._get_impl( i ) < w._get_impl( i ); + } +}; + +} // namespace detail + template constexpr bool operator<( variant const & v, variant const & w ) { - if( v.index() < w.index() ) return true; - if( v.index() > w.index() ) return false; - - return mp_with_index( v.index(), [&]( auto I ){ - - return v._get_impl( I ) < w._get_impl( I ); - - }); + return v.index() < w.index() || ( v.index() == w.index() && mp_with_index( v.index(), detail::lt_L{ v, w } ) ); } template constexpr bool operator>( variant const & v, variant const & w ) { - if( v.index() > w.index() ) return true; - if( v.index() < w.index() ) return false; - - return mp_with_index( v.index(), [&]( auto I ){ - - return v._get_impl( I ) > w._get_impl( I ); - - }); + return w < v; } +namespace detail +{ + +template struct le_L +{ + variant const & v; + variant const & w; + + template bool operator()( I i ) const + { + return v._get_impl( i ) <= w._get_impl( i ); + } +}; + +} // namespace detail + template constexpr bool operator<=( variant const & v, variant const & w ) { - if( v.index() < w.index() ) return true; - if( v.index() > w.index() ) return false; - - return mp_with_index( v.index(), [&]( auto I ){ - - return v._get_impl( I ) <= w._get_impl( I ); - - }); + return v.index() < w.index() || ( v.index() == w.index() && mp_with_index( v.index(), detail::le_L{ v, w } ) ); } template constexpr bool operator>=( variant const & v, variant const & w ) { - if( v.index() > w.index() ) return true; - if( v.index() < w.index() ) return false; - - return mp_with_index( v.index(), [&]( auto I ){ - - return v._get_impl( I ) >= w._get_impl( I ); - - }); + return w <= v; } // visitation @@ -1309,9 +1407,9 @@ template struct Qret template using front_if_same = mp_if, mp_front>; -template using var_size = variant_size>; +template using var_size = variant_size::type>; -template>> using apply_cv_ref_ = mp_if, T&, T>; +template::type>> using apply_cv_ref_ = mp_if, T&, T>; #if BOOST_WORKAROUND( BOOST_MSVC, < 1920 ) @@ -1341,13 +1439,25 @@ template constexpr auto visit( F&& f ) -> decltype(std::forward(f)() return std::forward(f)(); } +namespace detail +{ + +template struct visit_L1 +{ + F&& f; + V1&& v1; + + template auto operator()( I i ) const -> Vret + { + return std::forward(f)( get( std::forward(v1) ) ); + } +}; + +} // namespace detail + template constexpr auto visit( F&& f, V1&& v1 ) -> variant2::detail::Vret { - return mp_with_index>( v1.index(), [&]( auto I ){ - - return std::forward(f)( get( std::forward(v1) ) ); - - }); + return mp_with_index>( v1.index(), detail::visit_L1{ std::forward(f), std::forward(v1) } ); } #if BOOST_WORKAROUND( BOOST_MSVC, < 1920 ) @@ -1398,7 +1508,7 @@ template constexpr auto visit( F&& f, V // specialized algorithms template..., variant2::detail::is_swappable...>::value>> + class E = typename std::enable_if..., variant2::detail::is_swappable...>::value>::type> void swap( variant & v, variant & w ) noexcept( noexcept(v.swap(w)) ) { diff --git a/test/Jamfile b/test/Jamfile index b4fdd6f..6e0bc33 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -9,7 +9,7 @@ import testing ; import ../../config/checks/config : requires ; -project : requirements [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_hdr_type_traits cxx14_constexpr ] ; +project : requirements [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_hdr_type_traits cxx11_constexpr ] ; run variant_size.cpp ; run variant_alternative.cpp ; @@ -42,19 +42,19 @@ run variant_in_place_type_construct.cpp ; compile variant_in_place_type_construct_cx.cpp ; run variant_copy_assign.cpp ; -compile variant_copy_assign_cx.cpp ; +compile variant_copy_assign_cx.cpp : [ requires cxx14_constexpr ] ; run variant_move_assign.cpp ; -compile variant_move_assign_cx.cpp ; +compile variant_move_assign_cx.cpp : [ requires cxx14_constexpr ] ; run variant_value_assign.cpp ; -compile variant_value_assign_cx.cpp ; +compile variant_value_assign_cx.cpp : [ requires cxx14_constexpr ] ; run variant_emplace_index.cpp ; -compile variant_emplace_index_cx.cpp ; +compile variant_emplace_index_cx.cpp : [ requires cxx14_constexpr ] ; run variant_emplace_type.cpp ; -compile variant_emplace_type_cx.cpp ; +compile variant_emplace_type_cx.cpp : [ requires cxx14_constexpr ] ; run variant_swap.cpp ; run variant_eq_ne.cpp ; diff --git a/test/variant_copy_assign.cpp b/test/variant_copy_assign.cpp index c4ae80f..3211ecc 100644 --- a/test/variant_copy_assign.cpp +++ b/test/variant_copy_assign.cpp @@ -108,7 +108,7 @@ int main() BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 0 ); - variant v2( in_place_index<1>, 1 ); + variant v2( in_place_index_t<1>{}, 1 ); v = v2; BOOST_TEST_EQ( v.index(), 1 ); @@ -150,19 +150,19 @@ int main() BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v).v, 1 ); - variant v3( in_place_index<1>, 2 ); + variant v3( in_place_index_t<1>{}, 2 ); v = v3; BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v).v, 2 ); - variant const v4( in_place_index<1>, 3 ); + variant const v4( in_place_index_t<1>{}, 3 ); v = v4; BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v).v, 3 ); - variant const v5( in_place_index<0>, 4 ); + variant const v5( in_place_index_t<0>{}, 4 ); v = v5; BOOST_TEST_EQ( v.index(), 0 ); diff --git a/test/variant_eq_ne.cpp b/test/variant_eq_ne.cpp index 47b3873..d92f4f5 100644 --- a/test/variant_eq_ne.cpp +++ b/test/variant_eq_ne.cpp @@ -60,7 +60,7 @@ int main() } { - variant v1, v2, v3( in_place_index<1> ), v4( in_place_index<1> ), v5( 3.14f ), v6( 3.14f ); + variant v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f ); BOOST_TEST( v1 == v2 ); BOOST_TEST_NOT( v1 != v2 ); diff --git a/test/variant_in_place_index_construct.cpp b/test/variant_in_place_index_construct.cpp index 4e87b3f..d555b71 100644 --- a/test/variant_in_place_index_construct.cpp +++ b/test/variant_in_place_index_construct.cpp @@ -24,111 +24,111 @@ struct X int main() { { - variant v( in_place_index<0> ); + variant v( in_place_index_t<0>{} ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 0 ); } { - variant v( in_place_index<0> ); + variant v( in_place_index_t<0>{} ); BOOST_TEST_EQ( v.index(), 0 ); } { - variant v( in_place_index<0>, 1 ); + variant v( in_place_index_t<0>{}, 1 ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 1 ); } { - variant v( in_place_index<0> ); + variant v( in_place_index_t<0>{} ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 0 ); } { - variant v( in_place_index<0>, 1 ); + variant v( in_place_index_t<0>{}, 1 ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 1 ); } { - variant v( in_place_index<1> ); + variant v( in_place_index_t<1>{} ); BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v), 0 ); } { - variant v( in_place_index<1>, 3.14f ); + variant v( in_place_index_t<1>{}, 3.14f ); BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v), 3.14f ); } { - variant v( in_place_index<0>, 1 ); + variant v( in_place_index_t<0>{}, 1 ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 1 ); } { - variant v( in_place_index<1>, 1 ); + variant v( in_place_index_t<1>{}, 1 ); BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v), 1 ); } { - variant v( in_place_index<2>, 3.14f ); + variant v( in_place_index_t<2>{}, 3.14f ); BOOST_TEST_EQ( v.index(), 2 ); BOOST_TEST_EQ( get<2>(v), 3.14f ); } { - variant v( in_place_index<3>, 3.14f ); + variant v( in_place_index_t<3>{}, 3.14f ); BOOST_TEST_EQ( v.index(), 3 ); BOOST_TEST_EQ( get<3>(v), 3.14f ); } { - variant v( in_place_index<4>, "text" ); + variant v( in_place_index_t<4>{}, "text" ); BOOST_TEST_EQ( v.index(), 4 ); BOOST_TEST_EQ( get<4>(v), std::string("text") ); } { - variant v( in_place_index<5>, "text" ); + variant v( in_place_index_t<5>{}, "text" ); BOOST_TEST_EQ( v.index(), 5 ); BOOST_TEST_EQ( get<5>(v), std::string("text") ); } { - variant v( in_place_index<5>, 4, 'a' ); + variant v( in_place_index_t<5>{}, 4, 'a' ); BOOST_TEST_EQ( v.index(), 5 ); BOOST_TEST_EQ( get<5>(v), std::string( 4, 'a' ) ); } { - variant v( in_place_index<4>, { 'a', 'b', 'c' } ); + variant v( in_place_index_t<4>{}, { 'a', 'b', 'c' } ); BOOST_TEST_EQ( v.index(), 4 ); BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) ); } { - variant v( in_place_index<5>, { 'a', 'b', 'c' }, std::allocator() ); + variant v( in_place_index_t<5>{}, { 'a', 'b', 'c' }, std::allocator() ); BOOST_TEST_EQ( v.index(), 5 ); BOOST_TEST_EQ( get<5>(v), (std::string{ 'a', 'b', 'c' }) ); diff --git a/test/variant_in_place_index_construct_cx.cpp b/test/variant_in_place_index_construct_cx.cpp index e9c771f..24f93a4 100644 --- a/test/variant_in_place_index_construct_cx.cpp +++ b/test/variant_in_place_index_construct_cx.cpp @@ -27,89 +27,89 @@ struct X int main() { { - constexpr variant v( in_place_index<0> ); + constexpr variant v( in_place_index_t<0>{} ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 0 ); } { - constexpr variant v( in_place_index<0> ); + constexpr variant v( in_place_index_t<0>{} ); STATIC_ASSERT( v.index() == 0 ); } { - constexpr variant v( in_place_index<0>, 1 ); + constexpr variant v( in_place_index_t<0>{}, 1 ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 1 ); } { - constexpr variant v( in_place_index<0> ); + constexpr variant v( in_place_index_t<0>{} ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 0 ); } { - constexpr variant v( in_place_index<0>, 1 ); + constexpr variant v( in_place_index_t<0>{}, 1 ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 1 ); } { - constexpr variant v( in_place_index<1> ); + constexpr variant v( in_place_index_t<1>{} ); STATIC_ASSERT( v.index() == 1 ); STATIC_ASSERT( get<1>(v) == 0 ); } { - constexpr variant v( in_place_index<1>, 3.14f ); + constexpr variant v( in_place_index_t<1>{}, 3.14f ); STATIC_ASSERT( v.index() == 1 ); STATIC_ASSERT( get<1>(v) == 3.14f ); } { - constexpr variant v( in_place_index<0>, 1 ); + constexpr variant v( in_place_index_t<0>{}, 1 ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 1 ); } { - constexpr variant v( in_place_index<1>, 1 ); + constexpr variant v( in_place_index_t<1>{}, 1 ); STATIC_ASSERT( v.index() == 1 ); STATIC_ASSERT( get<1>(v) == 1 ); } { - constexpr variant v( in_place_index<2>, 3.14f ); + constexpr variant v( in_place_index_t<2>{}, 3.14f ); STATIC_ASSERT( v.index() == 2 ); STATIC_ASSERT( get<2>(v) == 3.14f ); } { - constexpr variant v( in_place_index<3>, 3.14f ); + constexpr variant v( in_place_index_t<3>{}, 3.14f ); STATIC_ASSERT( v.index() == 3 ); STATIC_ASSERT( get<3>(v) == 3.14f ); } { - constexpr variant v( in_place_index<4> ); + constexpr variant v( in_place_index_t<4>{} ); STATIC_ASSERT( v.index() == 4 ); } { - constexpr variant v( in_place_index<5>, 0, 0 ); + constexpr variant v( in_place_index_t<5>{}, 0, 0 ); STATIC_ASSERT( v.index() == 5 ); } diff --git a/test/variant_in_place_type_construct.cpp b/test/variant_in_place_type_construct.cpp index dc956eb..6ba38c7 100644 --- a/test/variant_in_place_type_construct.cpp +++ b/test/variant_in_place_type_construct.cpp @@ -24,7 +24,7 @@ struct X int main() { { - variant v( in_place_type ); + variant v( in_place_type_t{} ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 0 ); @@ -33,7 +33,7 @@ int main() } { - variant v( in_place_type ); + variant v( in_place_type_t{} ); BOOST_TEST_EQ( v.index(), 0 ); @@ -41,7 +41,7 @@ int main() } { - variant v( in_place_type, 1 ); + variant v( in_place_type_t{}, 1 ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 1 ); @@ -50,7 +50,7 @@ int main() } { - variant v( in_place_type ); + variant v( in_place_type_t{} ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 0 ); @@ -59,7 +59,7 @@ int main() } { - variant v( in_place_type, 1 ); + variant v( in_place_type_t{}, 1 ); BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 1 ); @@ -68,7 +68,7 @@ int main() } { - variant v( in_place_type ); + variant v( in_place_type_t{} ); BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v), 0 ); @@ -77,7 +77,7 @@ int main() } { - variant v( in_place_type, 3.14f ); + variant v( in_place_type_t{}, 3.14f ); BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v), 3.14f ); @@ -86,7 +86,7 @@ int main() } { - variant v( in_place_type, 3.14f ); + variant v( in_place_type_t{}, 3.14f ); BOOST_TEST_EQ( v.index(), 2 ); BOOST_TEST_EQ( get<2>(v), 3.14f ); @@ -95,7 +95,7 @@ int main() } { - variant v( in_place_type, "text" ); + variant v( in_place_type_t{}, "text" ); BOOST_TEST_EQ( v.index(), 4 ); BOOST_TEST_EQ( get<4>(v), std::string("text") ); @@ -104,7 +104,7 @@ int main() } { - variant v( in_place_type, 4, 'a' ); + variant v( in_place_type_t{}, 4, 'a' ); BOOST_TEST_EQ( v.index(), 4 ); BOOST_TEST_EQ( get<4>(v), std::string( 4, 'a' ) ); @@ -113,7 +113,7 @@ int main() } { - variant v( in_place_type, { 'a', 'b', 'c' } ); + variant v( in_place_type_t{}, { 'a', 'b', 'c' } ); BOOST_TEST_EQ( v.index(), 4 ); BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) ); @@ -122,7 +122,7 @@ int main() } { - variant v( in_place_type, { 'a', 'b', 'c' }, std::allocator() ); + variant v( in_place_type_t{}, { 'a', 'b', 'c' }, std::allocator() ); BOOST_TEST_EQ( v.index(), 4 ); BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) ); diff --git a/test/variant_in_place_type_construct_cx.cpp b/test/variant_in_place_type_construct_cx.cpp index 054159b..219abc6 100644 --- a/test/variant_in_place_type_construct_cx.cpp +++ b/test/variant_in_place_type_construct_cx.cpp @@ -22,7 +22,7 @@ struct X int main() { { - constexpr variant v( in_place_type ); + constexpr variant v( in_place_type_t{} ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 0 ); @@ -31,7 +31,7 @@ int main() } { - constexpr variant v( in_place_type ); + constexpr variant v( in_place_type_t{} ); STATIC_ASSERT( v.index() == 0 ); @@ -39,7 +39,7 @@ int main() } { - constexpr variant v( in_place_type, 1 ); + constexpr variant v( in_place_type_t{}, 1 ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 1 ); @@ -48,7 +48,7 @@ int main() } { - constexpr variant v( in_place_type ); + constexpr variant v( in_place_type_t{} ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 0 ); @@ -57,7 +57,7 @@ int main() } { - constexpr variant v( in_place_type, 1 ); + constexpr variant v( in_place_type_t{}, 1 ); STATIC_ASSERT( v.index() == 0 ); STATIC_ASSERT( get<0>(v) == 1 ); @@ -66,7 +66,7 @@ int main() } { - constexpr variant v( in_place_type ); + constexpr variant v( in_place_type_t{} ); STATIC_ASSERT( v.index() == 1 ); STATIC_ASSERT( get<1>(v) == 0 ); @@ -75,7 +75,7 @@ int main() } { - constexpr variant v( in_place_type, 3.14f ); + constexpr variant v( in_place_type_t{}, 3.14f ); STATIC_ASSERT( v.index() == 1 ); STATIC_ASSERT( get<1>(v) == 3.14f ); @@ -84,7 +84,7 @@ int main() } { - constexpr variant v( in_place_type, 3.14f ); + constexpr variant v( in_place_type_t{}, 3.14f ); STATIC_ASSERT( v.index() == 2 ); STATIC_ASSERT( get<2>(v) == 3.14f ); @@ -93,7 +93,7 @@ int main() } { - constexpr variant v( in_place_type ); + constexpr variant v( in_place_type_t{} ); STATIC_ASSERT( v.index() == 4 ); @@ -101,7 +101,7 @@ int main() } { - constexpr variant v( in_place_type, 0, 0 ); + constexpr variant v( in_place_type_t{}, 0, 0 ); STATIC_ASSERT( v.index() == 4 ); diff --git a/test/variant_lt_gt.cpp b/test/variant_lt_gt.cpp index 558052c..61ff8cc 100644 --- a/test/variant_lt_gt.cpp +++ b/test/variant_lt_gt.cpp @@ -62,7 +62,7 @@ int main() } { - variant v1, v2, v3( in_place_index<1> ), v4( in_place_index<1> ), v5( 3.14f ), v6( 3.14f ); + variant v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f ); TEST_EQ( v1, v2 ) TEST_LE( v1, v3 ) diff --git a/test/variant_move_assign.cpp b/test/variant_move_assign.cpp index 9c87718..9d78a03 100644 --- a/test/variant_move_assign.cpp +++ b/test/variant_move_assign.cpp @@ -108,7 +108,7 @@ int main() BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 0 ); - variant v2( in_place_index<1>, 1 ); + variant v2( in_place_index_t<1>{}, 1 ); v = std::move(v2); BOOST_TEST_EQ( v.index(), 1 ); @@ -150,19 +150,19 @@ int main() BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v).v, 1 ); - variant v3( in_place_index<1>, 2 ); + variant v3( in_place_index_t<1>{}, 2 ); v = std::move(v3); BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v).v, 2 ); - variant v4( in_place_index<1>, 3 ); + variant v4( in_place_index_t<1>{}, 3 ); v = std::move(v4); BOOST_TEST_EQ( v.index(), 1 ); BOOST_TEST_EQ( get<1>(v).v, 3 ); - variant v5( in_place_index<0>, 4 ); + variant v5( in_place_index_t<0>{}, 4 ); v = std::move(v5); BOOST_TEST_EQ( v.index(), 0 ); diff --git a/test/variant_swap.cpp b/test/variant_swap.cpp index 679f5f8..560ca69 100644 --- a/test/variant_swap.cpp +++ b/test/variant_swap.cpp @@ -130,7 +130,7 @@ int main() BOOST_TEST_EQ( v.index(), 0 ); BOOST_TEST_EQ( get<0>(v), 0 ); - variant v2( in_place_index<1>, 1 ); + variant v2( in_place_index_t<1>{}, 1 ); BOOST_TEST_EQ( v2.index(), 1 ); BOOST_TEST_EQ( get<1>(v2), 1 ); @@ -215,7 +215,7 @@ int main() BOOST_TEST_EQ( v2.index(), 0 ); BOOST_TEST_EQ( get<0>(v2).v, 0 ); - variant v3( in_place_index<1>, 2 ); + variant v3( in_place_index_t<1>{}, 2 ); BOOST_TEST_EQ( v3.index(), 1 ); BOOST_TEST_EQ( get<1>(v3).v, 2 ); @@ -228,7 +228,7 @@ int main() BOOST_TEST_EQ( v3.index(), 0 ); BOOST_TEST_EQ( get<0>(v3).v, 1 ); - variant v4( in_place_index<1>, 3 ); + variant v4( in_place_index_t<1>{}, 3 ); BOOST_TEST_EQ( v4.index(), 1 ); BOOST_TEST_EQ( get<1>(v4).v, 3 ); @@ -241,7 +241,7 @@ int main() BOOST_TEST_EQ( v4.index(), 1 ); BOOST_TEST_EQ( get<1>(v4).v, 2 ); - variant v5( in_place_index<0>, 4 ); + variant v5( in_place_index_t<0>{}, 4 ); BOOST_TEST_EQ( v5.index(), 0 ); BOOST_TEST_EQ( get<0>(v5).v, 4 ); diff --git a/test/variant_visit.cpp b/test/variant_visit.cpp index 98fdb29..0dde501 100644 --- a/test/variant_visit.cpp +++ b/test/variant_visit.cpp @@ -35,47 +35,47 @@ int main() { variant v( 1 ); - BOOST_TEST_EQ( (visit( []( auto x ){ return x; }, v )), 1 ); + BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 1 ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 1 ); }, v ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 1 ); }, std::move(v) ); + visit( []( int x ){ BOOST_TEST_EQ( x, 1 ); }, v ); + visit( []( int x ){ BOOST_TEST_EQ( x, 1 ); }, std::move(v) ); } { variant const v( 2 ); - BOOST_TEST_EQ( (visit( []( auto x ){ return x; }, v )), 2 ); + BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 2 ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 2 ); }, v ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 2 ); }, std::move(v) ); + visit( []( int x ){ BOOST_TEST_EQ( x, 2 ); }, v ); + visit( []( int x ){ BOOST_TEST_EQ( x, 2 ); }, std::move(v) ); } { variant v( 3 ); - BOOST_TEST_EQ( (visit( []( auto x ){ return x; }, v )), 3 ); + BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 3 ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 3 ); }, v ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 3 ); }, std::move(v) ); + visit( []( int x ){ BOOST_TEST_EQ( x, 3 ); }, v ); + visit( []( int x ){ BOOST_TEST_EQ( x, 3 ); }, std::move(v) ); } { variant const v( 4 ); - BOOST_TEST_EQ( (visit( []( auto x ){ return x; }, v )), 4 ); + BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 4 ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 4 ); }, v ); - visit( []( auto x ){ BOOST_TEST_EQ( x, 4 ); }, std::move(v) ); + visit( []( int x ){ BOOST_TEST_EQ( x, 4 ); }, v ); + visit( []( int x ){ BOOST_TEST_EQ( x, 4 ); }, std::move(v) ); } { variant v1( 1 ); variant const v2( 3.14f ); - BOOST_TEST_EQ( (visit( []( auto x1, auto x2 ){ return (int)(x1 * 1000) + (int)(x2 * 100); }, v1, v2 )), 1314 ); + BOOST_TEST_EQ( (visit( []( int x1, float x2 ){ return (int)(x1 * 1000) + (int)(x2 * 100); }, v1, v2 )), 1314 ); - visit( []( auto x1, auto x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, v1, v2 ); - visit( []( auto x1, auto x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, std::move(v1), std::move(v2) ); + visit( []( int x1, float x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, v1, v2 ); + visit( []( int x1, float x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, std::move(v1), std::move(v2) ); } { @@ -83,10 +83,10 @@ int main() variant const v2( 3.14f ); variant v3( 6.28 ); - BOOST_TEST_EQ( (visit( []( auto x1, auto x2, auto x3 ){ return (int)(x1 * 100) * 1000000 + (int)(x2 * 100) * 1000 + (int)(x3 * 100); }, v1, v2, v3 )), 100314628 ); + BOOST_TEST_EQ( (visit( []( int x1, float x2, double x3 ){ return (int)(x1 * 100) * 1000000 + (int)(x2 * 100) * 1000 + (int)(x3 * 100); }, v1, v2, v3 )), 100314628 ); - visit( []( auto x1, auto x2, auto x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, v1, v2, v3 ); - visit( []( auto x1, auto x2, auto x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, std::move(v1), std::move(v2), std::move(v3) ); + visit( []( int x1, float x2, double x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, v1, v2, v3 ); + visit( []( int x1, float x2, double x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, std::move(v1), std::move(v2), std::move(v3) ); } { @@ -95,10 +95,10 @@ int main() variant v3( 6.28 ); variant const v4( 'A' ); - BOOST_TEST_EQ( (visit( []( auto x1, auto x2, auto x3, auto x4 ){ return (long long)(x1 * 100) * 100000000 + (long long)(x2 * 100) * 100000 + (long long)(x3 * 10000) + (int)x4; }, v1, v2, v3, v4 )), 10031462800 + 'A' ); + BOOST_TEST_EQ( (visit( []( int x1, float x2, double x3, char x4 ){ return (long long)(x1 * 100) * 100000000 + (long long)(x2 * 100) * 100000 + (long long)(x3 * 10000) + (int)x4; }, v1, v2, v3, v4 )), 10031462800 + 'A' ); - visit( []( auto x1, auto x2, auto x3, auto x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, v1, v2, v3, v4 ); - visit( []( auto x1, auto x2, auto x3, auto x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, std::move(v1), std::move(v2), std::move(v3), std::move(v4) ); + visit( []( int x1, float x2, double x3, char x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, v1, v2, v3, v4 ); + visit( []( int x1, float x2, double x3, char x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, std::move(v1), std::move(v2), std::move(v3), std::move(v4) ); } {