diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index 41bbfa655..bcc68581d 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -1118,6 +1118,25 @@ U operator&( result&& r, F&& f ) } } +// operator&= + +// result &= unary-returning-value + +template()( std::declval() ) ), + class En1 = typename std::enable_if::value>::type, + class En2 = typename std::enable_if::value>::type +> +result& operator&=( result& r, F&& f ) +{ + if( r ) + { + r = std::forward( f )( *std::move( r ) ); + } + + return r; +} + } // namespace system } // namespace boost diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8a441faa1..4d75ca52c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -174,3 +174,4 @@ boost_test(TYPE run SOURCES result_or_fn0v.cpp) boost_test(TYPE run SOURCES result_or_fn0r.cpp) boost_test(TYPE run SOURCES result_and_fn1v.cpp) boost_test(TYPE run SOURCES result_and_fn1r.cpp) +boost_test(TYPE run SOURCES result_and_eq_fn1v.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1bc16005f..bac182966 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -204,3 +204,4 @@ run result_or_fn0v.cpp : : : $(CPP11) ; run result_or_fn0r.cpp : : : $(CPP11) ; run result_and_fn1v.cpp : : : $(CPP11) ; run result_and_fn1r.cpp : : : $(CPP11) ; +run result_and_eq_fn1v.cpp : : : $(CPP11) ; diff --git a/test/result_and_eq_fn1v.cpp b/test/result_and_eq_fn1v.cpp new file mode 100644 index 000000000..40852287c --- /dev/null +++ b/test/result_and_eq_fn1v.cpp @@ -0,0 +1,114 @@ +// Copyright 2017, 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +using namespace boost::system; + +struct X +{ + int v_; +}; + +struct Y +{ + int v_; + + explicit Y( int v ): v_( v ) {} + Y( X x ): v_( x.v_) {} + + Y( Y const& ) = delete; + Y& operator=( Y const& ) = delete; + + Y( Y&& r ): v_( r.v_ ) + { + r.v_ = 0; + } + + Y& operator=( Y&& r ) + { + if( &r != this ) + { + v_ = r.v_; + r.v_ = 0; + } + + return *this; + } +}; + +struct E +{ +}; + +int f( int x ) +{ + return x * 2 + 1; +} + +X g( Y y ) +{ + return X{ y.v_ * 2 + 1 }; +} + +int& h( int& ) +{ + static int x = 2; + return x; +} + +int main() +{ + { + result r( 1 ); + + r &= f; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 3 ); + } + + { + result r( in_place_error ); + + r &= f; + + BOOST_TEST( r.has_error() ); + } + + { + result r( in_place_value, 1 ); + + r &= g; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 3 ); + } + + { + result r( in_place_error ); + + r &= g; + + BOOST_TEST( r.has_error() ); + } + + { + int x1 = 1; + result r( x1 ); + + r &= h; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &h( x1 ) ); + } + + { + result r( in_place_error ); + + r &= h; + + BOOST_TEST( r.has_error() ); + } + + return boost::report_errors(); +}