diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index c587094..ebe2c04 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -935,6 +935,40 @@ template()() ), + class En = typename std::enable_if::value>::type +> + T operator|( result const& r, F&& f ) +{ + if( r ) + { + return *r; + } + else + { + return std::forward( f )(); + } +} + +template()() ), + class En = typename std::enable_if::value>::type +> + T operator|( result&& r, F&& f ) +{ + if( r ) + { + return *std::move( r ); + } + else + { + return std::forward( f )(); + } +} + } // namespace system } // namespace boost diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 00d5ed8..bd013b6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -170,3 +170,4 @@ boost_test(TYPE run SOURCES result_error_construct5.cpp) boost_test(TYPE run SOURCES result_or_value.cpp) boost_test(TYPE compile-fail SOURCES result_or_value_fail.cpp) boost_test(TYPE compile-fail SOURCES result_or_value_fail2.cpp) +boost_test(TYPE run SOURCES result_or_fn0v.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f13ab18..38efc9c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -200,3 +200,4 @@ run result_error_construct5.cpp : : : $(CPP11) ; run result_or_value.cpp : : : $(CPP11) ; compile-fail result_or_value_fail.cpp : $(CPP11) ; compile-fail result_or_value_fail2.cpp : $(CPP11) ; +run result_or_fn0v.cpp : : : $(CPP11) ; diff --git a/test/result_or_fn0v.cpp b/test/result_or_fn0v.cpp new file mode 100644 index 0000000..c0306d3 --- /dev/null +++ b/test/result_or_fn0v.cpp @@ -0,0 +1,162 @@ +// 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&& ) = delete; +}; + +struct E +{ +}; + +int f() +{ + return 2; +} + +X g() +{ + return { 2 }; +} + +int& h() +{ + static int x = 2; + return x; +} + +int main() +{ + { + result r( 1 ); + + int x = r | f; + + BOOST_TEST_EQ( x, 1 ); + } + + { + result const r( 1 ); + + int x = r | f; + + BOOST_TEST_EQ( x, 1 ); + } + + { + int x = result( 1 ) | f; + + BOOST_TEST_EQ( x, 1 ); + } + + { + result r( in_place_error ); + + int x = r | f; + + BOOST_TEST_EQ( x, 2 ); + } + + { + result const r( in_place_error ); + + int x = r | f; + + BOOST_TEST_EQ( x, 2 ); + } + + { + int x = result( in_place_error ) | f; + + BOOST_TEST_EQ( x, 2 ); + } + + { + Y y = result( in_place_value, 1 ) | g; + + BOOST_TEST_EQ( y.v_, 1 ); + } + + { + Y y = result( in_place_error ) | g; + + BOOST_TEST_EQ( y.v_, 2 ); + } + + { + int x1 = 1; + + result r( x1 ); + + int& x = r | h; + + BOOST_TEST_EQ( &x, &x1 ); + } + + { + int x1 = 1; + + result const r( x1 ); + + int& x = r | h; + + BOOST_TEST_EQ( &x, &x1 ); + } + + { + int x1 = 1; + + int& x = result( x1 ) | h; + + BOOST_TEST_EQ( &x, &x1 ); + } + + { + result r( in_place_error ); + + int& x = r | h; + + BOOST_TEST_EQ( &x, &h() ); + } + + { + result const r( in_place_error ); + + int& x = r | h; + + BOOST_TEST_EQ( &x, &h() ); + } + + { + int& x = result( in_place_error ) | h; + + BOOST_TEST_EQ( &x, &h() ); + } + + return boost::report_errors(); +}