From 50f84f16dcc04f410a5a3728e65de29e05bf7419 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 17 Sep 2021 19:22:15 +0300 Subject: [PATCH] Add result specialization --- include/boost/system/result.hpp | 150 ++++++++++++++++++++++++++++++ test/result_default_construct.cpp | 7 ++ 2 files changed, 157 insertions(+) diff --git a/include/boost/system/result.hpp b/include/boost/system/result.hpp index 63672ea..dca8bda 100644 --- a/include/boost/system/result.hpp +++ b/include/boost/system/result.hpp @@ -337,6 +337,156 @@ template std::basic_ostream& opera return os; } +// result + +template class result +{ +private: + + variant2::variant v_; + +public: + + // constructors + + // default + constexpr result() noexcept + : v_( in_place_value ) + { + } + + // explicit, error + template::value && + !std::is_convertible::value + >::type> + explicit constexpr result( A&& a ) + noexcept( std::is_nothrow_constructible::value ) + : v_( in_place_error, std::forward(a) ) + { + } + + // implicit, error + template::value + >::type> + constexpr result( A&& a ) + noexcept( std::is_nothrow_constructible::value ) + : v_( in_place_error, std::forward(a) ) + { + } + + // more than one arg, error + template::value && + sizeof...(A) >= 2 + >::type> + constexpr result( A&&... a ) + noexcept( std::is_nothrow_constructible::value ) + : v_( in_place_error, std::forward(a)... ) + { + } + + // tagged, value + constexpr result( in_place_value_t ) noexcept + : v_( in_place_value ) + { + } + + // tagged, error + template::value + >::type> + constexpr result( in_place_error_t, A&&... a ) + noexcept( std::is_nothrow_constructible::value ) + : v_( in_place_error, std::forward(a)... ) + { + } + + // queries + + constexpr bool has_value() const noexcept + { + return v_.index() == 0; + } + + constexpr bool has_error() const noexcept + { + return v_.index() != 0; + } + + constexpr explicit operator bool() const noexcept + { + return v_.index() == 0; + } + + // checked value access + + BOOST_CXX14_CONSTEXPR void value() const + { + if( has_value() ) + { + } + else + { + throw_exception_from_error( variant2::unsafe_get<1>( v_ ) ); + } + } + + // unchecked value access + + BOOST_CXX14_CONSTEXPR void* operator->() noexcept + { + return variant2::get_if<0>( &v_ ); + } + + BOOST_CXX14_CONSTEXPR void const* operator->() const noexcept + { + return variant2::get_if<0>( &v_ ); + } + + BOOST_CXX14_CONSTEXPR void operator*() const noexcept + { + BOOST_ASSERT( has_value() ); + } + + // error access + + 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(); + } + + // swap + + BOOST_CXX14_CONSTEXPR void swap( result& r ) + noexcept( noexcept( v_.swap( r.v_ ) ) ) + { + v_.swap( r.v_ ); + } + + friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 ) + noexcept( noexcept( r1.swap( r2 ) ) ) + { + r1.swap( r2 ); + } + + // equality + + friend constexpr bool operator==( result const & r1, result const & r2 ) + noexcept( noexcept( r1.v_ == r2.v_ ) ) + { + return r1.v_ == r2.v_; + } + + friend constexpr bool operator!=( result const & r1, result const & r2 ) + noexcept( noexcept( !( r1 == r2 ) ) ) + { + return !( r1 == r2 ); + } +}; + } // namespace system } // namespace boost diff --git a/test/result_default_construct.cpp b/test/result_default_construct.cpp index b054d50..525976b 100644 --- a/test/result_default_construct.cpp +++ b/test/result_default_construct.cpp @@ -30,5 +30,12 @@ int main() BOOST_TEST( !r.has_error() ); } + { + result r; + + BOOST_TEST( r.has_value() ); + BOOST_TEST( !r.has_error() ); + } + return boost::report_errors(); }