diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index 3b7fb09..03ab010 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -1100,6 +1100,24 @@ result& operator|=( result& r, F&& f ) return r; } +// result |= nullary-returning-result + +template()() ), + 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 )(); + } + + return r; +} + // operator& // result & unary-returning-value diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dc20a82..7bda2f4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -176,3 +176,4 @@ boost_test(TYPE run SOURCES result_and_eq_fn1r.cpp) boost_test(TYPE run SOURCES result_in_place_use.cpp) boost_test(TYPE run SOURCES result_or_eq_value.cpp) boost_test(TYPE run SOURCES result_or_eq_fn0v.cpp) +boost_test(TYPE run SOURCES result_or_eq_fn0r.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f9acaf0..8e3e5a8 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -206,3 +206,4 @@ run result_and_eq_fn1r.cpp ; run result_in_place_use.cpp ; run result_or_eq_value.cpp ; run result_or_eq_fn0v.cpp ; +run result_or_eq_fn0r.cpp ; diff --git a/test/result_or_eq_fn0r.cpp b/test/result_or_eq_fn0r.cpp new file mode 100644 index 0000000..b333081 --- /dev/null +++ b/test/result_or_eq_fn0r.cpp @@ -0,0 +1,160 @@ +// Copyright 2017, 2021-2024 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() +{ + return 2; +} + +result fi2() +{ + return E2(); +} + +result fy() +{ + return X{ 2 }; +} + +result fy2() +{ + return E2(); +} + +result fri() +{ + static int x = 2; + return x; +} + +result fri2() +{ + return E2(); +} + +int main() +{ + { + result r( 1 ); + + r |= fi; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 1 ); + + r |= fi2; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 1 ); + } + + { + result r( in_place_error ); + + r |= fi2; + + BOOST_TEST( r.has_error() ); + + r |= fi; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 2 ); + } + + { + result r( in_place_value, 1 ); + + r |= fy; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 1 ); + + r |= fy2; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 1 ); + } + + { + result r( in_place_error ); + + r |= fy2; + + BOOST_TEST( r.has_error() ); + + r |= fy; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 2 ); + } + + { + int x1 = 1; + + result r( x1 ); + + r |= fri; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x1 ); + + r |= fri2; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x1 ); + } + + { + result r( in_place_error ); + + r |= fri2; + + BOOST_TEST( r.has_error() ); + + r |= fri; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &*fri() ); + } + + return boost::report_errors(); +}