From 0b387f5116ed3e78302c99364741045696fb6bef Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 2 Jun 2017 18:11:43 +0300 Subject: [PATCH 1/3] Add .then --- include/boost/variant2/expected.hpp | 31 ++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/include/boost/variant2/expected.hpp b/include/boost/variant2/expected.hpp index fb90ea1..452ae35 100644 --- a/include/boost/variant2/expected.hpp +++ b/include/boost/variant2/expected.hpp @@ -95,7 +95,7 @@ public: } }; -// expected +// throw_on_unexpected template void throw_on_unexpected( E const& e ) { @@ -119,6 +119,13 @@ void throw_on_unexpected( std::exception_ptr const & e ) } } +// expected + +template class expected; + +template struct is_expected: std::false_type {}; +template struct is_expected>: std::true_type {}; + template class expected { private: @@ -387,6 +394,28 @@ public: }); } + + // then + +private: + + template using then_result_ = decltype( std::declval()( std::declval() ) ); + + template> using then_result = mp_if, R, expected>; + +public: + + template then_result then( F && f ) const + { + if( has_value() ) + { + return std::forward(f)( **this ); + } + else + { + return unexpected(); + } + } }; template inline constexpr bool operator==( expected const & x1, expected const & x2 ) From 9b3121fac0f0435b289c28f418df821c4cb79cac Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 2 Jun 2017 18:25:11 +0300 Subject: [PATCH 2/3] Rename mp_for_index to mp_with_index --- include/boost/variant2/variant.hpp | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 9c6b47d..cb669ad 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -551,7 +551,7 @@ template struct variant_base_impl { if( ix_ > 0 ) { - mp_for_index<1 + sizeof...(T)>( ix_, [&]( auto I ){ + mp_with_index<1 + sizeof...(T)>( ix_, [&]( auto I ){ using U = mp_at_c, I>; st1_.get( I ).~U(); @@ -653,7 +653,7 @@ template struct variant_base_impl { if( ix_ > 0 ) { - mp_for_index<1 + sizeof...(T)>( ix_, [&]( auto I ){ + mp_with_index<1 + sizeof...(T)>( ix_, [&]( auto I ){ using U = mp_at_c, I>; st1_.get( I ).~U(); @@ -662,7 +662,7 @@ template struct variant_base_impl } else if( ix_ < 0 ) { - mp_for_index<1 + sizeof...(T)>( -ix_, [&]( auto I ){ + mp_with_index<1 + sizeof...(T)>( -ix_, [&]( auto I ){ using U = mp_at_c, I>; st2_.get( I ).~U(); @@ -833,7 +833,7 @@ public: variant( variant const& r ) noexcept( mp_all...>::value ) { - mp_for_index( r.index(), [&]( auto I ){ + mp_with_index( r.index(), [&]( auto I ){ ::new( static_cast(this) ) variant_base( I, r._get_impl( I ) ); @@ -844,7 +844,7 @@ public: variant( variant && r ) noexcept( mp_all...>::value ) { - mp_for_index( r.index(), [&]( auto I ){ + mp_with_index( r.index(), [&]( auto I ){ ::new( static_cast(this) ) variant_base( I, std::move( r._get_impl( I ) ) ); @@ -888,7 +888,7 @@ public: variant& operator=( variant const & r ) noexcept( mp_all..., std::is_nothrow_copy_assignable...>::value ) { - mp_for_index( r.index(), [&]( auto I ){ + mp_with_index( r.index(), [&]( auto I ){ if( this->index() == I ) { @@ -908,7 +908,7 @@ public: variant& operator=( variant && r ) noexcept( mp_all..., std::is_nothrow_move_assignable...>::value ) { - mp_for_index( r.index(), [&]( auto I ){ + mp_with_index( r.index(), [&]( auto I ){ if( this->index() == I ) { @@ -986,7 +986,7 @@ public: { if( index() == r.index() ) { - mp_for_index( index(), [&]( auto I ){ + mp_with_index( index(), [&]( auto I ){ using std::swap; swap( this->_get_impl( I ), r._get_impl( I ) ); @@ -1017,7 +1017,7 @@ public: variant( variant const& r ) noexcept( mp_all...>::value ) { - mp_for_index( r.index(), [&]( auto I ){ + mp_with_index( r.index(), [&]( auto I ){ using J = mp_find, mp_at_c, I>>; @@ -1031,7 +1031,7 @@ public: variant( variant && r ) noexcept( mp_all...>::value ) { - mp_for_index( r.index(), [&]( auto I ){ + mp_with_index( r.index(), [&]( auto I ){ using J = mp_find, mp_at_c, I>>; @@ -1060,7 +1060,7 @@ public: class E2 = mp_if..., mp_contains, U>...>, void> > constexpr variant subset() & { - return mp_for_index( index(), [&]( auto I ){ + return mp_with_index( index(), [&]( auto I ){ using J = mp_find, mp_at_c, I>>; @@ -1073,7 +1073,7 @@ public: class E2 = mp_if..., mp_contains, U>...>, void> > constexpr variant subset() const& { - return mp_for_index( index(), [&]( auto I ){ + return mp_with_index( index(), [&]( auto I ){ using J = mp_find, mp_at_c, I>>; @@ -1086,7 +1086,7 @@ public: class E2 = mp_if..., mp_contains, U>...>, void> > constexpr variant subset() && { - return mp_for_index( index(), [&]( auto I ){ + return mp_with_index( index(), [&]( auto I ){ using J = mp_find, mp_at_c, I>>; @@ -1099,7 +1099,7 @@ public: class E2 = mp_if..., mp_contains, U>...>, void> > constexpr variant subset() const&& { - return mp_for_index( index(), [&]( auto I ){ + return mp_with_index( index(), [&]( auto I ){ using J = mp_find, mp_at_c, I>>; @@ -1114,7 +1114,7 @@ template constexpr bool operator==( variant const & v, variant { if( v.index() != w.index() ) return false; - return mp_for_index( v.index(), [&]( auto I ){ + return mp_with_index( v.index(), [&]( auto I ){ return v._get_impl( I ) == w._get_impl( I ); @@ -1125,7 +1125,7 @@ template constexpr bool operator!=( variant const & v, variant { if( v.index() != w.index() ) return true; - return mp_for_index( v.index(), [&]( auto I ){ + return mp_with_index( v.index(), [&]( auto I ){ return v._get_impl( I ) != w._get_impl( I ); @@ -1137,7 +1137,7 @@ template constexpr bool operator<( variant const & v, variant< if( v.index() < w.index() ) return true; if( v.index() > w.index() ) return false; - return mp_for_index( v.index(), [&]( auto I ){ + return mp_with_index( v.index(), [&]( auto I ){ return v._get_impl( I ) < w._get_impl( I ); @@ -1149,7 +1149,7 @@ template constexpr bool operator>( variant const & v, variant if( v.index() > w.index() ) return true; if( v.index() < w.index() ) return false; - return mp_for_index( v.index(), [&]( auto I ){ + return mp_with_index( v.index(), [&]( auto I ){ return v._get_impl( I ) > w._get_impl( I ); @@ -1161,7 +1161,7 @@ template constexpr bool operator<=( variant const & v, variant if( v.index() < w.index() ) return true; if( v.index() > w.index() ) return false; - return mp_for_index( v.index(), [&]( auto I ){ + return mp_with_index( v.index(), [&]( auto I ){ return v._get_impl( I ) <= w._get_impl( I ); @@ -1173,7 +1173,7 @@ template constexpr bool operator>=( variant const & v, variant if( v.index() > w.index() ) return true; if( v.index() < w.index() ) return false; - return mp_for_index( v.index(), [&]( auto I ){ + return mp_with_index( v.index(), [&]( auto I ){ return v._get_impl( I ) >= w._get_impl( I ); @@ -1225,7 +1225,7 @@ template constexpr auto visit( F&& f ) -> decltype(std::forward(f)() template constexpr auto visit( F&& f, V1&& v1 ) -> variant2::detail::Vret { - return mp_for_index>( v1.index(), [&]( auto I ){ + return mp_with_index>( v1.index(), [&]( auto I ){ return std::forward(f)( get( std::forward(v1) ) ); @@ -1236,7 +1236,7 @@ template constexpr auto visit( F&& f, V1&& v1 ) -> variant2:: template constexpr auto visit( F&& f, V1&& v1, V2&& v2 ) -> variant2::detail::Vret { - return mp_for_index>( v1.index(), [&]( auto I ){ + return mp_with_index>( v1.index(), [&]( auto I ){ auto f2 = [&]( auto&&... a ){ return std::forward(f)( get( std::forward(v1) ), std::forward(a)... ); }; return visit( f2, std::forward(v2) ); @@ -1246,7 +1246,7 @@ template constexpr auto visit( F&& f, V1&& v1, V2&& template constexpr auto visit( F&& f, V1&& v1, V2&& v2, V3&& v3 ) -> variant2::detail::Vret { - return mp_for_index>( v1.index(), [&]( auto I ){ + return mp_with_index>( v1.index(), [&]( auto I ){ auto f2 = [&]( auto&&... a ){ return std::forward(f)( get( std::forward(v1) ), std::forward(a)... ); }; return visit( f2, std::forward(v2), std::forward(v3) ); @@ -1256,7 +1256,7 @@ template constexpr auto visit( F&& f, V1& template constexpr auto visit( F&& f, V1&& v1, V2&& v2, V3&& v3, V4&& v4 ) -> variant2::detail::Vret { - return mp_for_index>( v1.index(), [&]( auto I ){ + return mp_with_index>( v1.index(), [&]( auto I ){ auto f2 = [&]( auto&&... a ){ return std::forward(f)( get( std::forward(v1) ), std::forward(a)... ); }; return visit( f2, std::forward(v2), std::forward(v3), std::forward(v4) ); @@ -1268,7 +1268,7 @@ template constexpr auto visit( template constexpr auto visit( F&& f, V1&& v1, V2&& v2, V&&... v ) -> variant2::detail::Vret { - return mp_for_index>( v1.index(), [&]( auto I ){ + return mp_with_index>( v1.index(), [&]( auto I ){ auto f2 = [&]( auto&&... a ){ return std::forward(f)( get( std::forward(v1) ), std::forward(a)... ); }; return visit( f2, std::forward(v2), std::forward(v)... ); From c867329bb847fa7a70a70cba13886d2b6d0656c8 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 2 Jun 2017 18:27:08 +0300 Subject: [PATCH 3/3] Rename mp_for_index to mp_with_index in expected.hpp, too --- include/boost/variant2/expected.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/variant2/expected.hpp b/include/boost/variant2/expected.hpp index 452ae35..4673ab5 100644 --- a/include/boost/variant2/expected.hpp +++ b/include/boost/variant2/expected.hpp @@ -136,7 +136,7 @@ private: void _bad_access() const { - mp_for_index>( v_.index(), [&]( auto I ) + mp_with_index>( v_.index(), [&]( auto I ) { if( I == 0 ) { @@ -375,7 +375,7 @@ public: { using R = remapped; - return mp_for_index>( v_.index(), [&]( auto I ) { + return mp_with_index>( v_.index(), [&]( auto I ) { return _remap_error( I, f, get(v_) ); @@ -388,7 +388,7 @@ public: auto f = []( auto const& e ){ return make_error_code(e); }; - return mp_for_index>( v_.index(), [&]( auto I ) { + return mp_with_index>( v_.index(), [&]( auto I ) { return _remap_error( I, f, get(v_) );