mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
update to handle need to specify erased return type
This commit is contained in:
parent
088120db71
commit
36b3a3040c
@ -33,17 +33,49 @@
|
|||||||
#if defined(ASIO_STANDALONE)
|
#if defined(ASIO_STANDALONE)
|
||||||
#include <asio/async_result.hpp>
|
#include <asio/async_result.hpp>
|
||||||
#include <asio/error_code.hpp>
|
#include <asio/error_code.hpp>
|
||||||
|
#include <asio/version.hpp>
|
||||||
|
|
||||||
|
#if (ASIO_VERSION / 100 % 1000) <= 12
|
||||||
|
#define CTI_DETAIL_ASIO_HAS_NO_INTEGRATION
|
||||||
|
#elif (ASIO_VERSION / 100 % 1000) <= 14
|
||||||
|
#define CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
#include <asio/system_error.hpp>
|
#include <asio/system_error.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CTI_DETAIL_ASIO_NAMESPACE_BEGIN namespace asio {
|
#define CTI_DETAIL_ASIO_NAMESPACE_BEGIN namespace asio {
|
||||||
#define CTI_DETAIL_ASIO_NAMESPACE_END }
|
#define CTI_DETAIL_ASIO_NAMESPACE_END }
|
||||||
#else
|
#else
|
||||||
#include <boost/asio/async_result.hpp>
|
#include <boost/asio/async_result.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
#include <boost/system/system_error.hpp>
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
#define CTI_DETAIL_ASIO_NAMESPACE_BEGIN namespace boost { namespace asio {
|
#if (BOOST_VERSION / 100 % 1000) <= 69
|
||||||
#define CTI_DETAIL_ASIO_NAMESPACE_END }}
|
#define CTI_DETAIL_ASIO_HAS_NO_INTEGRATION
|
||||||
|
#elif (BOOST_VERSION / 100 % 1000) <= 71
|
||||||
|
#define CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
#include <boost/system/system_error.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CTI_DETAIL_ASIO_NAMESPACE_BEGIN \
|
||||||
|
namespace boost { \
|
||||||
|
namespace asio {
|
||||||
|
#define CTI_DETAIL_ASIO_NAMESPACE_END \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CTI_DETAIL_ASIO_HAS_NO_INTEGRATION)
|
||||||
|
#error \
|
||||||
|
"First-class ASIO support for continuable requires the form of "\
|
||||||
|
"`async_result` with an `initiate` static member function, which was added " \
|
||||||
|
"in standalone ASIO 1.13.0 and Boost ASIO 1.70. Older versions can be " \
|
||||||
|
"integrated manually with `cti::promisify`."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -54,10 +86,38 @@ namespace asio {
|
|||||||
|
|
||||||
#if defined(ASIO_STANDALONE)
|
#if defined(ASIO_STANDALONE)
|
||||||
using error_code_t = ::asio::error_code;
|
using error_code_t = ::asio::error_code;
|
||||||
|
using error_cond_t = std::error_condition;
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
using exception_t = ::asio::system_error;
|
using exception_t = ::asio::system_error;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
using error_code_t = ::boost::system::error_code;
|
using error_code_t = ::boost::system::error_code;
|
||||||
|
using error_cond_t = ::boost::system::error_condition;
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
using exception_t = ::boost::system::system_error;
|
using exception_t = ::boost::system::system_error;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
template <typename Promise>
|
||||||
|
void promise_exception_helper(Promise& promise, error_code_t e) noexcept {
|
||||||
|
promise.set_exception(std::make_exception_ptr(exception_t(std::move(e))));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <typename Promise>
|
||||||
|
void promise_exception_helper(Promise& promise, error_code_t e) noexcept
|
||||||
|
->decltype(promise.set_exception(std::move(e))) {
|
||||||
|
return promise.set_exception(std::move(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Promise>
|
||||||
|
void promise_exception_helper(Promise& promise, error_code_t e) noexcept
|
||||||
|
->decltype(promise.set_exception(error_cond_t(e.value(), e.category()))) {
|
||||||
|
promise.set_exception(error_cond_t(e.value(), e.category()));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Binds `promise` to the first argument of a continuable resolver, giving it
|
// Binds `promise` to the first argument of a continuable resolver, giving it
|
||||||
@ -65,41 +125,48 @@ using exception_t = ::boost::system::system_error;
|
|||||||
template <typename Promise>
|
template <typename Promise>
|
||||||
auto promise_resolver_handler(Promise&& promise) noexcept {
|
auto promise_resolver_handler(Promise&& promise) noexcept {
|
||||||
return [promise = std::forward<Promise>(promise)](
|
return [promise = std::forward<Promise>(promise)](
|
||||||
error_code_t e, auto&&... args) mutable noexcept {
|
error_code_t e, auto&&... args) mutable noexcept {
|
||||||
if (e) {
|
if (e) {
|
||||||
promise.set_exception(std::make_exception_ptr(exception_t(std::move(e))));
|
promise_exception_helper(promise, std::move(e));
|
||||||
} else {
|
} else {
|
||||||
promise.set_value(std::forward<decltype(args)>(args)...);
|
promise.set_value(std::forward<decltype(args)>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type deduction helper for `Result` in `cti::make_continuable<Result>`
|
// Helper struct wrapping a call to `cti::make_continuable` and, if needed,
|
||||||
|
// providing an erased, explicit `return_type` for `async_result`.
|
||||||
template <typename Signature>
|
template <typename Signature>
|
||||||
struct continuable_result;
|
struct initiate_make_continuable;
|
||||||
|
|
||||||
template <>
|
template <typename... Args>
|
||||||
struct continuable_result<void(error_code_t)> {
|
struct initiate_make_continuable<void(error_code_t, Args...)> {
|
||||||
using type = void;
|
using is_void_cti_t = std::integral_constant<bool, sizeof...(Args) == 0>;
|
||||||
|
|
||||||
|
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
|
||||||
|
using erased_return_type =
|
||||||
|
std::conditional_t<is_void_cti_t::value, cti::continuable<>,
|
||||||
|
cti::continuable<Args...>>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Continuation, typename IsVoid = is_void_cti_t>
|
||||||
|
auto operator()(Continuation&& continuation,
|
||||||
|
std::enable_if_t<IsVoid::value>* = 0) {
|
||||||
|
return cti::make_continuable<void>(
|
||||||
|
std::forward<Continuation>(continuation));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Continuation, typename IsVoid = is_void_cti_t>
|
||||||
|
auto operator()(Continuation&& continuation,
|
||||||
|
std::enable_if_t<!IsVoid::value>* = 0) {
|
||||||
|
return cti::make_continuable<Args...>(
|
||||||
|
std::forward<Continuation>(continuation));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <typename... Args>
|
||||||
struct continuable_result<void(error_code_t const&)>
|
struct initiate_make_continuable<void(error_code_t const&, Args...)>
|
||||||
: continuable_result<void(error_code_t)> {};
|
: initiate_make_continuable<void(error_code_t, Args...)> {};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct continuable_result<void(error_code_t, T)> {
|
|
||||||
using type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct continuable_result<void(error_code_t const&, T)>
|
|
||||||
: continuable_result<void(error_code_t, T)> {};
|
|
||||||
|
|
||||||
template <typename Signature>
|
|
||||||
using continuable_result_t = typename continuable_result<Signature>::type;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|||||||
@ -45,10 +45,20 @@ constexpr use_cti_t use_cti{};
|
|||||||
template <typename Signature>
|
template <typename Signature>
|
||||||
class async_result<use_cti_t, Signature> {
|
class async_result<use_cti_t, Signature> {
|
||||||
public:
|
public:
|
||||||
|
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
|
||||||
|
using return_type = typename cti::detail::asio::initiate_make_continuable<
|
||||||
|
Signature>::erased_return_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename Initiation, typename... Args>
|
template <typename Initiation, typename... Args>
|
||||||
static auto initiate(Initiation initiation, use_cti_t, Args... args) {
|
static
|
||||||
return cti::make_continuable<
|
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
|
||||||
cti::detail::asio::continuable_result_t<Signature>>(
|
return_type
|
||||||
|
#else
|
||||||
|
auto
|
||||||
|
#endif
|
||||||
|
initiate(Initiation initiation, use_cti_t, Args... args) {
|
||||||
|
return cti::detail::asio::initiate_make_continuable<Signature>{}(
|
||||||
[initiation = std::move(initiation),
|
[initiation = std::move(initiation),
|
||||||
init_args =
|
init_args =
|
||||||
std::make_tuple(std::move(args)...)](auto&& promise) mutable {
|
std::make_tuple(std::move(args)...)](auto&& promise) mutable {
|
||||||
@ -69,5 +79,6 @@ CTI_DETAIL_ASIO_NAMESPACE_END
|
|||||||
|
|
||||||
#undef CTI_DETAIL_ASIO_NAMESPACE_BEGIN
|
#undef CTI_DETAIL_ASIO_NAMESPACE_BEGIN
|
||||||
#undef CTI_DETAIL_ASIO_NAMESPACE_END
|
#undef CTI_DETAIL_ASIO_NAMESPACE_END
|
||||||
|
#undef CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION
|
||||||
|
|
||||||
#endif // CONTINUABLE_SUPPORT_ASIO_HPP_INCLUDED
|
#endif // CONTINUABLE_SUPPORT_ASIO_HPP_INCLUDED
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user