#ifndef BOOST_SYSTEM_UNWRAP_AND_INVOKE_HPP_INCLUDED #define BOOST_SYSTEM_UNWRAP_AND_INVOKE_HPP_INCLUDED // Copyright 2026 Peter Dimov // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #include #include #include #include #include #include #include namespace boost { namespace system { // unwrap_and_invoke namespace detail { // get_error_type template using first_if_same = mp11::mp_if, mp11::mp_first>>; template using get_error_type = mp11::mp_apply, is_result> > >; // invoke_unwrap template< class T, class En = typename std::enable_if< !is_result< compat::remove_cvref_t >::value >::type > auto invoke_unwrap( T&& t ) noexcept -> T&& { return std::forward( t ); } template< class T, class = void, class En = typename std::enable_if< is_result< compat::remove_cvref_t >::value >::type > auto invoke_unwrap( T&& t ) noexcept -> decltype( std::forward( t ).unsafe_value() ) { return std::forward( t ).unsafe_value(); } // invoke_test template int invoke_test( R&, A const& ) { return 0; } template int invoke_test( R& r, result const& r2 ) { if( r && r2.has_error() ) r = r2.error(); return 0; } } // namespace detail template(), detail::invoke_unwrap( std::declval() )... ) ), class E = detail::get_error_type...> > auto unwrap_and_invoke( F&& f, A&&... a ) -> result { { result r; using Q = int[]; (void)Q{ detail::invoke_test( r, a )... }; if( !r ) return r.error(); } return compat::invoke( std::forward(f), detail::invoke_unwrap( std::forward(a) )... ); } // unwrap_and_construct namespace detail { template struct construct { 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 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 #endif // #ifndef BOOST_SYSTEM_UNWRAP_AND_INVOKE_HPP_INCLUDED