18#ifndef TRINITYCORE_EXPECTED_COMPLETION_HANDLER_H
19#define TRINITYCORE_EXPECTED_COMPLETION_HANDLER_H
21#include <boost/asio/associated_executor.hpp>
22#include <boost/asio/async_result.hpp>
23#include <boost/asio/handler_continuation_hook.hpp>
24#include <boost/outcome/result.hpp>
25#include <boost/preprocessor/empty.hpp>
26#include <boost/preprocessor/comma.hpp>
35template <
typename CompletionToken>
40 constexpr AsExpected(std::type_identity<void> = {}, CompletionToken token = {})
41 :
token_(
std::forward<CompletionToken>(token))
45 template <
typename T>
requires (!std::same_as<T, AsExpected>)
47 :
token_(std::forward<T>(completion_token))
53 template <
typename InnerExecutor>
60 template <
typename InnerExecutor1>
64 !std::is_same_v<InnerExecutor1, executor_with_default>,
65 std::is_convertible<InnerExecutor1, InnerExecutor>,
78 using as_default_on_t =
typename T::template rebind_executor<executor_with_default<typename T::executor_type>>::other;
95 template <
typename CompletionToken>
115 || std::same_as<std::remove_cvref_t<T>, std::exception_ptr>;
117template <
typename Handler>
123 template <
typename CompletionToken>
126 template <
typename RedirectedHandler>
requires (!std::same_as<RedirectedHandler, AsExpectedHandler>)
129 template <CompletionTokenError Error>
132 using return_type = boost::outcome_v2::result<void, std::remove_cvref_t<Error>>;
135 static_cast<Handler&&
>(
handler_)(return_type(boost::outcome_v2::failure(std::forward<Error>(e))));
137 static_cast<Handler&&
>(
handler_)(return_type(boost::outcome_v2::success()));
140 template <CompletionTokenError Error,
typename Arg>
143 using return_type = boost::outcome_v2::result<std::decay_t<Arg>, std::remove_cvref_t<Error>>;
146 static_cast<Handler&&
>(
handler_)(return_type(boost::outcome_v2::failure(std::forward<Error>(e))));
148 static_cast<Handler&&
>(
handler_)(return_type(boost::outcome_v2::success(std::forward<Arg>(value))));
154 using return_type = boost::outcome_v2::result<std::tuple<std::decay_t<Arg>, std::decay_t<Args>...>, std::remove_cvref_t<Error>>;
157 static_cast<Handler&&
>(
handler_)(return_type(boost::outcome_v2::failure(std::forward<Error>(e))));
159 static_cast<Handler&&
>(
handler_)(return_type(boost::outcome_v2::success(std::make_tuple(std::forward<Arg>(first), std::forward<Args>(rest)...))));
165template <
typename Handler>
168 using boost::asio::asio_handler_is_continuation;
172template <
typename Signature>
175#define STAMP_AS_EXPECTED_SIGNATURE(qualifier) \
176 template <typename R, CompletionTokenError Error> \
177 struct AsExpectedSignature<R(Error) qualifier> \
179 using type = R(boost::outcome_v2::result<void, std::remove_cvref_t<Error>>) qualifier; \
181 template <typename R, CompletionTokenError Error, typename Arg> \
182 struct AsExpectedSignature<R(Error, Arg) qualifier> \
184 using type = R(boost::outcome_v2::result<std::decay_t<Arg>, std::remove_cvref_t<Error>>) qualifier; \
186 template <typename R, CompletionTokenError Error, typename Arg, typename... Args> \
187 struct AsExpectedSignature<R(Error, Arg, Args...) qualifier> \
189 using type = R(boost::outcome_v2::result<std::tuple<std::decay_t<Arg>, std::decay_t<Args>...>, std::remove_cvref_t<Error>>) qualifier; \
199#undef STAMP_AS_EXPECTED_SIGNATURE
206#if BOOST_VERSION >= 107700
207template <
typename CompletionToken,
typename... Signatures>
208class async_result<
Trinity::
Asio::AsExpected<CompletionToken>, Signatures...> : async_result<CompletionToken, typename Trinity::Asio::Impl::AsExpectedSignature<Signatures>::type...>
210 template <
typename Initiation>
213 explicit init_wrapper(Initiation
const& initiation) : initiation_(initiation) { }
214 explicit init_wrapper(Initiation&& initiation) : initiation_(
std::move(initiation)) { }
216 template <
typename Handler,
typename... Args>
217 inline void operator()(Handler&& handler, Args&&... args) &&
222 template <
typename Handler,
typename... Args>
223 inline void operator()(Handler&& handler, Args&&... args)
const &
228 Initiation initiation_;
232 template <
typename Initiation,
typename RawCompletionToken,
typename... Args>
233 static inline auto initiate(Initiation&& initiation, RawCompletionToken&& token, Args&&... args)
235 return async_initiate<
237 is_const<remove_reference_t<RawCompletionToken>>::value,
238 CompletionToken
const, CompletionToken>,
240 init_wrapper<std::decay_t<Initiation>>(
241 std::forward<Initiation>(initiation)),
242 token.token_, std::forward<Args>(args)...);
246#if BOOST_VERSION >= 108600
247#define TRINITY_BOOST_ASIO_ASSOCIATOR_SFINAE_PARAM(param) param
249#define TRINITY_BOOST_ASIO_ASSOCIATOR_SFINAE_PARAM(param)
252template <
template <
typename,
typename>
class Associator,
typename Handler,
typename DefaultCandidate TRINITY_BOOST_ASIO_ASSOCIATOR_SFINAE_PARAM(BOOST_PP_COMMA()
typename _)>
255template <
template <
typename,
typename>
class Associator,
typename Handler,
typename DefaultCandidate>
256struct associator<Associator,
Trinity::Asio::Impl::AsExpectedHandler<Handler>, DefaultCandidate TRINITY_BOOST_ASIO_ASSOCIATOR_SFINAE_PARAM(BOOST_PP_COMMA() void)> : Associator<Handler, DefaultCandidate>
260 return Associator<Handler, DefaultCandidate>::get(h.handler_);
265 return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
269#undef TRINITY_BOOST_ASIO_ASSOCIATOR_SFINAE_PARAM
271template <
typename... Signatures>
272class async_result<
Trinity::Asio::AsExpectedFn, Signatures...>
275 template <
typename Initiation,
typename RawCompletionToken,
typename... Args>
276 static inline auto initiate(Initiation&& initiation, RawCompletionToken&&, Args&&... args)
278 return async_initiate<Signatures...>(
279 std::forward<Initiation>(initiation),
281 default_completion_token_t<associated_executor_t<Initiation>>>{},
282 std::forward<Args>(args)...);
286template <
typename CompletionToken,
typename Signature>
287class async_result<
Trinity::Asio::AsExpected<CompletionToken>,
Signature> : async_result<CompletionToken, typename Trinity::Asio::Impl::AsExpectedSignature<Signature>::type>
289 template <
typename Initiation>
292 explicit init_wrapper(Initiation
const& initiation) : initiation_(initiation) { }
293 explicit init_wrapper(Initiation&& initiation) : initiation_(
std::move(initiation)) { }
295 template <
typename Handler,
typename... Args>
301 template <
typename Handler,
typename... Args>
302 inline void operator()(Handler&& handler, Args&&... args)
const &
311 template <
typename Initiation,
typename RawCompletionToken,
typename... Args>
312 static inline auto initiate(Initiation&& initiation, RawCompletionToken&& token, Args&&... args)
314 return async_initiate<
316 is_const<remove_reference_t<RawCompletionToken>>::value,
317 CompletionToken
const, CompletionToken>,
319 init_wrapper<std::decay_t<Initiation>>(
320 std::forward<Initiation>(initiation)),
321 token.token_, std::forward<Args>(args)...);
#define STAMP_AS_EXPECTED_SIGNATURE(qualifier)
std::pair< uint32, ObjectGuid > Signature
constexpr AsExpected(std::type_identity< void >={}, CompletionToken token={})
typename T::template rebind_executor< executor_with_default< typename T::executor_type > >::other as_default_on_t
constexpr AsExpected(T &&completion_token)
static auto as_default_on(T &&object)
AsExpectedHandler(RedirectedHandler &&h)
AsExpectedHandler(AsExpected< CompletionToken > e)
void operator()(Error &&e, Arg &&first, Args &&... rest)
void operator()(Error &&e, Arg &&value)
void operator()(Error &&e)
static auto initiate(Initiation &&initiation, RawCompletionToken &&token, Args &&... args)
bool asio_handler_is_continuation(AsExpectedHandler< Handler > *this_handler)
constexpr AsExpectedFn as_expected
void Error(char const *file, int line, char const *function, char const *message) noexcept
constexpr AsExpected< std::decay_t< CompletionToken > > operator()(CompletionToken &&completion_token) const
executor_with_default(InnerExecutor1 const &ex, std::enable_if_t< std::conditional_t< !std::is_same_v< InnerExecutor1, executor_with_default >, std::is_convertible< InnerExecutor1, InnerExecutor >, std::false_type >::value, int >=0) noexcept
Construct the adapted executor from the inner executor type.
AsExpected default_completion_token_type
Specify AsExpected as the default completion token type.
void operator()(Handler &&handler, Args &&... args) &&
init_wrapper(Initiation &&initiation)
init_wrapper(Initiation const &initiation)
void operator()(Handler &&handler, Args &&... args) const &