Enable pointers to members in r & f, where f returns a value

This commit is contained in:
Peter Dimov
2025-12-03 13:55:15 +02:00
parent 05cb8f459c
commit 4d8f6f85cd
5 changed files with 162 additions and 9 deletions
+38
View File
@@ -0,0 +1,38 @@
#ifndef BOOST_SYSTEM_DETAIL_INVOKE_HPP_INCLUDED
#define BOOST_SYSTEM_DETAIL_INVOKE_HPP_INCLUDED
// Copyright 2024, 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0
// http://www.boost.org/LICENSE_1_0.txt
#include <functional>
#include <type_traits>
#define BOOST_SYSTEM_DETAIL_RETURNS(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
namespace boost
{
namespace system
{
namespace detail
{
// invoke
template<class F, class... A>
constexpr auto invoke( F&& f, A&&... a )
BOOST_SYSTEM_DETAIL_RETURNS( std::forward<F>(f)(std::forward<A>(a)...) )
template<class M, class T, class... A>
constexpr auto invoke( M T::* pm, A&&... a )
BOOST_SYSTEM_DETAIL_RETURNS( std::mem_fn(pm)(std::forward<A>(a)...) )
// invoke_result_t
template<class F, class... A> using invoke_result_t = decltype( detail::invoke( std::declval<F>(), std::declval<A>()... ) );
} // namespace detail
} // namespace system
} // namespace boost
#endif // #ifndef BOOST_SYSTEM_DETAIL_INVOKE_HPP_INCLUDED
+10 -9
View File
@@ -1,7 +1,7 @@
#ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED
#define BOOST_SYSTEM_RESULT_HPP_INCLUDED
// Copyright 2017, 2021, 2022 Peter Dimov.
// Copyright 2017, 2021-2025 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -9,6 +9,7 @@
#include <boost/system/system_error.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/detail/error_category_impl.hpp>
#include <boost/system/detail/invoke.hpp>
#include <boost/variant2/variant.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert/source_location.hpp>
@@ -1130,7 +1131,7 @@ result<T, E>& operator|=( result<T, E>& r, F&& f )
// result & unary-returning-value
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T const&>() ) ),
class U = detail::invoke_result_t<F, T const&>,
class En1 = typename std::enable_if<!detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<!std::is_void<U>::value>::type
>
@@ -1142,12 +1143,12 @@ result<U, E> operator&( result<T, E> const& r, F&& f )
}
else
{
return std::forward<F>( f )( *r );
return detail::invoke( std::forward<F>( f ), *r );
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
class U = detail::invoke_result_t<F, T>,
class En1 = typename std::enable_if<!detail::is_result<U>::value>::type,
class En2 = typename std::enable_if<!std::is_void<U>::value>::type
>
@@ -1159,12 +1160,12 @@ result<U, E> operator&( result<T, E>&& r, F&& f )
}
else
{
return std::forward<F>( f )( *std::move( r ) );
return detail::invoke( std::forward<F>( f ), *std::move( r ) );
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T const&>() ) ),
class U = detail::invoke_result_t<F, T const&>,
class En = typename std::enable_if<std::is_void<U>::value>::type
>
result<U, E> operator&( result<T, E> const& r, F&& f )
@@ -1175,13 +1176,13 @@ result<U, E> operator&( result<T, E> const& r, F&& f )
}
else
{
std::forward<F>( f )( *r );
detail::invoke( std::forward<F>( f ), *r );
return {};
}
}
template<class T, class E, class F,
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
class U = detail::invoke_result_t<F, T>,
class En = typename std::enable_if<std::is_void<U>::value>::type
>
result<U, E> operator&( result<T, E>&& r, F&& f )
@@ -1192,7 +1193,7 @@ result<U, E> operator&( result<T, E>&& r, F&& f )
}
else
{
std::forward<F>( f )( *std::move( r ) );
detail::invoke( std::forward<F>( f ), *std::move( r ) );
return {};
}
}