diff --git a/include/boost/system/unwrap_and_invoke.hpp b/include/boost/system/unwrap_and_invoke.hpp index ff726b7..b18db3e 100644 --- a/include/boost/system/unwrap_and_invoke.hpp +++ b/include/boost/system/unwrap_and_invoke.hpp @@ -6,6 +6,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include +#include #include #include #include @@ -88,10 +89,24 @@ namespace detail template struct construct { - template T operator()( A&&... a ) const +private: + + template static inline T call_impl( std::false_type, A&&... a ) { return T( std::forward(a)... ); } + + template static inline T call_impl( std::true_type, A&&... a ) + { + return T{ std::forward(a)... }; + } + +public: + + template inline T operator()( A&&... a ) const + { + return this->call_impl( detail::is_aggregate(), std::forward(a)... ); + } }; } // namespace detail diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5bffdc5..64fe753 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -192,5 +192,6 @@ 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) +boost_test(TYPE run SOURCES unwrap_and_construct2.cpp) boost_test(TYPE run SOURCES detail_is_aggregate_test.cpp) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a77b3ec..99619af 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -225,5 +225,6 @@ run unwrap_and_invoke.cpp ; run unwrap_and_invoke2.cpp ; run unwrap_and_construct.cpp ; +run unwrap_and_construct2.cpp ; run detail_is_aggregate_test.cpp ; diff --git a/test/unwrap_and_construct2.cpp b/test/unwrap_and_construct2.cpp new file mode 100644 index 0000000..a0b7761 --- /dev/null +++ b/test/unwrap_and_construct2.cpp @@ -0,0 +1,129 @@ +// 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 +{ + X x1{}, x2{}, x3{}, x4{}; +}; + +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().x1.v, 1 ) + && BOOST_TEST_EQ( r.unsafe_value().x2.v, 0 ) + && BOOST_TEST_EQ( r.unsafe_value().x3.v, 0 ) + && BOOST_TEST_EQ( r.unsafe_value().x4.v, 0 ) + ; + } + + // + + { + 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().x1.v, 1 ) + && BOOST_TEST_EQ( r.unsafe_value().x2.v, 2 ) + && BOOST_TEST_EQ( r.unsafe_value().x3.v, 0 ) + && BOOST_TEST_EQ( r.unsafe_value().x4.v, 0 ) + ; + } + + // + + { + 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().x1.v, 1 ) + && BOOST_TEST_EQ( r.unsafe_value().x2.v, 2 ) + && BOOST_TEST_EQ( r.unsafe_value().x3.v, 3 ) + && BOOST_TEST_EQ( r.unsafe_value().x4.v, 0 ) + ; + } + + // + + { + 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().x1.v, 1 ) + && BOOST_TEST_EQ( r.unsafe_value().x2.v, 2 ) + && BOOST_TEST_EQ( r.unsafe_value().x3.v, 3 ) + && BOOST_TEST_EQ( r.unsafe_value().x4.v, 4 ) + ; + } + + return boost::report_errors(); +}