From c5c49894e6b870c7403bf95041fcd5218a6f1b3a Mon Sep 17 00:00:00 2001 From: Klemens Date: Wed, 8 Mar 2023 08:07:38 +0800 Subject: [PATCH] Made result::error movable. Closes #108. --- doc/system/reference.adoc | 3 +- include/boost/system/result.hpp | 16 ++++- test/CMakeLists.txt | 1 + test/Jamfile.v2 | 1 + test/result_error_move.cpp | 108 ++++++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 test/result_error_move.cpp diff --git a/doc/system/reference.adoc b/doc/system/reference.adoc index d5ab46f..798cc75 100644 --- a/doc/system/reference.adoc +++ b/doc/system/reference.adoc @@ -1657,7 +1657,8 @@ public: // error access - constexpr E error() const; + constexpr E error() const &; + constexpr E error() &&; // emplace diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index 4084ca8..08eb899 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -401,12 +401,18 @@ public: // error access - constexpr E error() const + constexpr E error() const & noexcept( std::is_nothrow_default_constructible::value && std::is_nothrow_copy_constructible::value ) { return has_error()? variant2::unsafe_get<1>( v_ ): E(); } + BOOST_CXX14_CONSTEXPR E error() && + noexcept( std::is_nothrow_default_constructible::value && std::is_nothrow_move_constructible::value ) + { + return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); + } + // emplace template @@ -581,12 +587,18 @@ public: // error access - constexpr E error() const + constexpr E error() const & noexcept( std::is_nothrow_default_constructible::value && std::is_nothrow_copy_constructible::value ) { return has_error()? variant2::unsafe_get<1>( v_ ): E(); } + BOOST_CXX14_CONSTEXPR E error() && + noexcept( std::is_nothrow_default_constructible::value && std::is_nothrow_move_constructible::value ) + { + return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); + } + // emplace BOOST_CXX14_CONSTEXPR void emplace() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ff166a6..7bc6d67 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -163,3 +163,4 @@ boost_test(TYPE run SOURCES result_emplace.cpp) boost_test(TYPE run SOURCES result_error_construct4.cpp) boost_test(TYPE run SOURCES result_value_construct4.cpp) boost_test(TYPE run SOURCES result_value_construct5.cpp) +boost_test(TYPE run SOURCES result_error_move.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index df74b5e..139bb23 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -193,3 +193,4 @@ run result_emplace.cpp : : : $(CPP11) ; run result_error_construct4.cpp : : : $(CPP11) ; run result_value_construct4.cpp : : : $(CPP11) ; run result_value_construct5.cpp : : : $(CPP11) ; +run result_error_move.cpp : : : $(CPP11) ; diff --git a/test/result_error_move.cpp b/test/result_error_move.cpp new file mode 100644 index 0000000..771ca75 --- /dev/null +++ b/test/result_error_move.cpp @@ -0,0 +1,108 @@ +// Copyright 2023 Klemens Morgenstern +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +using namespace boost::system; + +struct XM +{ + int v_; + + explicit XM( int v = 0 ): v_( v ) {} + + XM( XM const& ) = delete; + XM& operator=( XM const& ) = delete; + XM( XM && ) = default; + XM& operator=( XM && ) = default; +}; + +int main() +{ + { + result r( 1 ); + + BOOST_TEST( !r.has_value() ); + BOOST_TEST( r.has_error() ); + + BOOST_TEST_EQ( std::move( r ).error().v_, 1 ); + } + + { + BOOST_TEST(( !result( 1 ).has_value() )); + BOOST_TEST(( result( 1 ).has_error() )); + + BOOST_TEST_EQ( (result( 1 ).error().v_), 1 ); + } + + { + result r( "s" ); + + BOOST_TEST( r.has_value() ); + BOOST_TEST( !r.has_error() ); + + BOOST_TEST_EQ( std::move( r ).error().v_, 0 ); + } + + { + result r( "s" ); + + BOOST_TEST( r.has_value() ); + BOOST_TEST( !r.has_error() ); + + BOOST_TEST_EQ( std::move( r ).error().v_, 0 ); + } + + { + BOOST_TEST(( result( "s" ).has_value() )); + BOOST_TEST(( !result( "s" ).has_error() )); + + BOOST_TEST_EQ( (result( "s" ).error().v_), 0 ); + } + + { + result r( 1 ); + + BOOST_TEST( !r.has_value() ); + BOOST_TEST( r.has_error() ); + + BOOST_TEST_EQ( std::move( r ).error().v_, 1 ); + } + + { + BOOST_TEST(( !result( 1 ).has_value() )); + BOOST_TEST(( result( 1 ).has_error() )); + + BOOST_TEST_EQ( (result( 1 ).error().v_), 1 ); + } + + { + result r; + + BOOST_TEST( r.has_value() ); + BOOST_TEST( !r.has_error() ); + + BOOST_TEST_EQ( std::move( r ).error().v_, 0 ); + } + + { + result r; + + BOOST_TEST( r.has_value() ); + BOOST_TEST( !r.has_error() ); + + BOOST_TEST_EQ( std::move( r ).error().v_, 0 ); + } + + { + BOOST_TEST(( result( ).has_value() )); + BOOST_TEST(( !result( ).has_error() )); + + BOOST_TEST_EQ( (result( ).error().v_), 0 ); + } + return boost::report_errors(); +}