From 194b84e6632b7083ee6ea44f47d92819e4523ff9 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 29 Oct 2023 19:37:43 +0200 Subject: [PATCH] Add operator&( result, unary-returning-value ) --- include/boost/system/result.hpp | 34 +++++++ test/CMakeLists.txt | 1 + test/Jamfile.v2 | 1 + test/result_and_fn0v.cpp | 158 ++++++++++++++++++++++++++++++++ 4 files changed, 194 insertions(+) create mode 100644 test/result_and_fn0v.cpp diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index 3aa565ef1..4490cb66f 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -1046,6 +1046,40 @@ template()( std::declval() ) ), + class En = typename std::enable_if::value>::type +> + result operator&( result const& r, F&& f ) +{ + if( r ) + { + return std::forward( f )( *r ); + } + else + { + return r.error(); + } +} + +template()( std::declval() ) ), + class En = typename std::enable_if::value>::type +> + result operator&( result&& r, F&& f ) +{ + if( r ) + { + return std::forward( f )( *std::move( r ) ); + } + else + { + return r.error(); + } +} + } // namespace system } // namespace boost diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c493aebfb..6d4e2b32a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -172,3 +172,4 @@ 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) boost_test(TYPE run SOURCES result_or_fn0r.cpp) +boost_test(TYPE run SOURCES result_and_fn0v.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2d484fcbc..1864c0734 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -202,3 +202,4 @@ compile-fail result_or_value_fail.cpp : $(CPP11) ; compile-fail result_or_value_fail2.cpp : $(CPP11) ; run result_or_fn0v.cpp : : : $(CPP11) ; run result_or_fn0r.cpp : : : $(CPP11) ; +run result_and_fn0v.cpp : : : $(CPP11) ; diff --git a/test/result_and_fn0v.cpp b/test/result_and_fn0v.cpp new file mode 100644 index 000000000..8dac8d1da --- /dev/null +++ b/test/result_and_fn0v.cpp @@ -0,0 +1,158 @@ +// 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( 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 ); + result r2 = r & f; + + BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 ); + } + + { + result const r( 1 ); + result r2 = r & f; + + BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 ); + } + + { + result r2 = result( 1 ) & f; + + BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 ); + } + + { + result r( in_place_error ); + result r2 = r & f; + + BOOST_TEST( r2.has_error() ); + } + + { + result const r( in_place_error ); + result r2 = r & f; + + BOOST_TEST( r2.has_error() ); + } + + { + result r2 = result( in_place_error ) & f; + + BOOST_TEST( r2.has_error() ); + } + + { + result r2 = result( in_place_value, 1 ) & g; + + BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2->v_, 3 ); + } + + { + result r2 = result( in_place_error ) & g; + + BOOST_TEST( r2.has_error() ); + } + + { + int x1 = 1; + + result r( x1 ); + + result r2 = r & h; + + BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) ); + } + + { + int x1 = 1; + + result const r( x1 ); + + result r2 = r & h; + + BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) ); + } + + { + int x1 = 1; + + result r2 = result( x1 ) & h; + + BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) ); + } + + { + result r( in_place_error ); + + result r2 = r & h; + + BOOST_TEST( r2.has_error() ); + } + + { + result const r( in_place_error ); + + result r2 = r & h; + + BOOST_TEST( r2.has_error() ); + } + + { + result r2 = result( in_place_error ) & h; + + BOOST_TEST( r2.has_error() ); + } + + return boost::report_errors(); +}