From fa3babf4e686ca98f5fb3b3d1ea478a7b23bc532 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 25 Feb 2026 14:10:14 +0200 Subject: [PATCH] Add unwrap_and_construct --- include/boost/system/unwrap_and_invoke.hpp | 22 +++++ test/CMakeLists.txt | 2 + test/Jamfile.v2 | 2 + test/unwrap_and_construct.cpp | 109 +++++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 test/unwrap_and_construct.cpp diff --git a/include/boost/system/unwrap_and_invoke.hpp b/include/boost/system/unwrap_and_invoke.hpp index 5b0d1d4..ff726b7 100644 --- a/include/boost/system/unwrap_and_invoke.hpp +++ b/include/boost/system/unwrap_and_invoke.hpp @@ -81,6 +81,28 @@ auto unwrap_and_invoke( F&& f, A&&... a ) -> result return compat::invoke( std::forward(f), detail::invoke_unwrap( std::forward(a) )... ); } +// unwrap_and_construct + +namespace detail +{ + +template struct construct +{ + template T operator()( A&&... a ) const + { + return T( std::forward(a)... ); + } +}; + +} // namespace detail + +template +auto unwrap_and_construct( A&&... a ) +-> decltype( unwrap_and_invoke( detail::construct(), std::forward(a)... ) ) +{ + return unwrap_and_invoke( detail::construct(), std::forward(a)... ); +} + } // namespace system } // namespace boost diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d2bab7..865fc29 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -190,3 +190,5 @@ boost_test(TYPE run SOURCES result_unsafe_value_access2.cpp) boost_test(TYPE run SOURCES unwrap_and_invoke.cpp) boost_test(TYPE run SOURCES unwrap_and_invoke2.cpp) + +boost_test(TYPE run SOURCES unwrap_and_construct.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dc76e48..9ff4b15 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -223,3 +223,5 @@ run result_unsafe_value_access2.cpp ; run unwrap_and_invoke.cpp ; run unwrap_and_invoke2.cpp ; + +run unwrap_and_construct.cpp ; diff --git a/test/unwrap_and_construct.cpp b/test/unwrap_and_construct.cpp new file mode 100644 index 0000000..43f3a55 --- /dev/null +++ b/test/unwrap_and_construct.cpp @@ -0,0 +1,109 @@ +// Copyright 2026 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +using namespace boost::system; + +struct X +{ + int v; +}; + +struct Y +{ + int v; + + explicit Y( X a1 = {}, X a2 = {}, X a3 = {}, X a4 = {} ): v( a1.v + a2.v + a3.v + a4.v ) + { + } +}; + +struct E +{ + int w; +}; + +int main() +{ + { + auto r = unwrap_and_construct( result( E{1} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 1 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ) ); + BOOST_TEST( r ) && BOOST_TEST_EQ( r.unsafe_value().v, 1 ); + } + + // + + { + auto r = unwrap_and_construct( result( E{1} ), result( E{2} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 1 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( E{2} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 2 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( X{2} ) ); + BOOST_TEST( r ) && BOOST_TEST_EQ( r.unsafe_value().v, 3 ); + } + + // + + { + auto r = unwrap_and_construct( result( E{1} ), result( E{2} ), result( E{3} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 1 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( E{2} ), result( E{3} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 2 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( X{2} ), result( E{3} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 3 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( X{2} ), result( X{3} ) ); + BOOST_TEST( r ) && BOOST_TEST_EQ( r.unsafe_value().v, 6 ); + } + + // + + { + auto r = unwrap_and_construct( result( E{1} ), result( E{2} ), result( E{3} ), result( E{4} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 1 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( E{2} ), result( E{3} ), result( E{4} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 2 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( X{2} ), result( E{3} ), result( E{4} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 3 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( X{2} ), result( X{3} ), result( E{4} ) ); + BOOST_TEST( !r ) && BOOST_TEST_EQ( r.error().w, 4 ); + } + + { + auto r = unwrap_and_construct( result( X{1} ), result( X{2} ), result( X{3} ), result( X{4} ) ); + BOOST_TEST( r ) && BOOST_TEST_EQ( r.unsafe_value().v, 10 ); + } + + return boost::report_errors(); +}