From f18edb3d242936914f45cc010b5bb8715021a6d7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 1 Feb 2024 06:49:23 +0200 Subject: [PATCH] Add operator|=(result&, fn0v) --- include/boost/system/result.hpp | 16 +++++ test/CMakeLists.txt | 1 + test/Jamfile.v2 | 1 + test/result_or_eq_fn0v.cpp | 115 ++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 test/result_or_eq_fn0v.cpp diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index 0d5a866..3b7fb09 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -1084,6 +1084,22 @@ result& operator|=( result& r, U&& u ) return r; } +// result |= nullary-returning-value + +template()() ), + class En = 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 0bb84a4..dc20a82 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -175,3 +175,4 @@ boost_test(TYPE run SOURCES result_and_eq_fn1v.cpp) 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) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f757779..f9acaf0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -205,3 +205,4 @@ run result_and_eq_fn1v.cpp ; run result_and_eq_fn1r.cpp ; run result_in_place_use.cpp ; run result_or_eq_value.cpp ; +run result_or_eq_fn0v.cpp ; diff --git a/test/result_or_eq_fn0v.cpp b/test/result_or_eq_fn0v.cpp new file mode 100644 index 0000000..25897d0 --- /dev/null +++ b/test/result_or_eq_fn0v.cpp @@ -0,0 +1,115 @@ +// 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 +{ +}; + +int f() +{ + return 2; +} + +X g() +{ + return { 2 }; +} + +int& h() +{ + static int x = 2; + return x; +} + +int main() +{ + { + result r( 1 ); + + r |= f; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 1 ); + } + + { + result r( in_place_error ); + + r |= f; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 2 ); + } + + { + result r( in_place_value, 1 ); + + r |= g; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 1 ); + } + + { + result r( in_place_error ); + + r |= g; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 2 ); + } + + { + int x1 = 1; + + result r( x1 ); + + r |= h; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &x1 ); + } + + { + result r( in_place_error ); + + r |= h; + + BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &h() ); + } + + return boost::report_errors(); +}