From d11dd4b3962349b46401479e456c43192b704c9d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 31 Oct 2023 03:08:02 +0200 Subject: [PATCH] Add operator&=( result&, unary-returning-result ) --- include/boost/system/result.hpp | 18 +++++ test/CMakeLists.txt | 1 + test/Jamfile.v2 | 1 + test/result_and_eq_fn1r.cpp | 126 ++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 test/result_and_eq_fn1r.cpp diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index bcc68581d..833254cb1 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -1137,6 +1137,24 @@ result& operator&=( result& r, F&& f ) return r; } +// result &= unary-returning-result + +template()( std::declval() ) ), + class En1 = typename std::enable_if::value>::type, + class En2 = typename std::enable_if::value>::type, + class En3 = 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 4d75ca52c..ada24895b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -175,3 +175,4 @@ 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) +boost_test(TYPE run SOURCES result_and_eq_fn1r.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index bac182966..4c3dcb845 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -205,3 +205,4 @@ 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) ; +run result_and_eq_fn1r.cpp : : : $(CPP11) ; diff --git a/test/result_and_eq_fn1r.cpp b/test/result_and_eq_fn1r.cpp new file mode 100644 index 000000000..c9519d7d6 --- /dev/null +++ b/test/result_and_eq_fn1r.cpp @@ -0,0 +1,126 @@ +// 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 +{ +}; + +struct E2 +{ + E2() {} + E2( E ) {} +}; + +result fi( int x ) +{ + return 2 * x + 1; +} + +result fi2( int ) +{ + return E2(); +} + +result fy( Y y ) +{ + return X{ 2 * y.v_ + 1 }; +} + +result fy2( Y ) +{ + return E2(); +} + +result fri( int& ) +{ + static int x = 2; + return x; +} + +result fri2( int& ) +{ + return E2(); +} + +int main() +{ + { + result r( 1 ); + + r &= fi; + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 3 ); + + r &= fi2; + BOOST_TEST( r.has_error() ); + + r &= fi; + BOOST_TEST( r.has_error() ); + } + + { + result r( in_place_value, 1 ); + + r &= fy; + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 3 ); + + r &= fy2; + BOOST_TEST( r.has_error() ); + + r &= fy; + BOOST_TEST( r.has_error() ); + } + + { + int x1 = 1; + result r( x1 ); + + r &= fri; + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &*fri( x1 ) ); + + r &= fri2; + BOOST_TEST( r.has_error() ); + + r &= fri; + BOOST_TEST( r.has_error() ); + } + + return boost::report_errors(); +}