File indexing completed on 2026-08-17 08:38:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_IMPL_REDIRECT_DISPOSITION_HPP
0012 #define BOOST_ASIO_IMPL_REDIRECT_DISPOSITION_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/associated_executor.hpp>
0020 #include <boost/asio/associator.hpp>
0021 #include <boost/asio/async_result.hpp>
0022 #include <boost/asio/detail/handler_cont_helpers.hpp>
0023 #include <boost/asio/detail/initiation_base.hpp>
0024 #include <boost/asio/detail/type_traits.hpp>
0025
0026 #include <boost/asio/detail/push_options.hpp>
0027
0028 namespace boost {
0029 namespace asio {
0030 namespace detail {
0031
0032
0033 template <typename Disposition, typename Handler>
0034 class redirect_disposition_handler
0035 {
0036 public:
0037 typedef void result_type;
0038
0039 template <typename CompletionToken>
0040 redirect_disposition_handler(
0041 redirect_disposition_t<CompletionToken, Disposition> e)
0042 : d_(e.d_),
0043 handler_(static_cast<CompletionToken&&>(e.token_))
0044 {
0045 }
0046
0047 template <typename RedirectedHandler>
0048 redirect_disposition_handler(Disposition& d, RedirectedHandler&& h)
0049 : d_(d),
0050 handler_(static_cast<RedirectedHandler&&>(h))
0051 {
0052 }
0053
0054 void operator()()
0055 {
0056 static_cast<Handler&&>(handler_)();
0057 }
0058
0059 template <typename Arg, typename... Args>
0060 enable_if_t<
0061 !is_same<decay_t<Arg>, Disposition>::value
0062 >
0063 operator()(Arg&& arg, Args&&... args)
0064 {
0065 static_cast<Handler&&>(handler_)(
0066 static_cast<Arg&&>(arg),
0067 static_cast<Args&&>(args)...);
0068 }
0069
0070 template <typename... Args>
0071 void operator()(const Disposition& d, Args&&... args)
0072 {
0073 d_ = d;
0074 static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...);
0075 }
0076
0077
0078 Disposition& d_;
0079 Handler handler_;
0080 };
0081
0082 template <typename Handler>
0083 class redirect_disposition_handler<std::exception_ptr, Handler>
0084 {
0085 public:
0086 typedef void result_type;
0087
0088 template <typename CompletionToken>
0089 redirect_disposition_handler(
0090 redirect_disposition_t<CompletionToken, std::exception_ptr> e)
0091 : d_(e.d_),
0092 handler_(static_cast<CompletionToken&&>(e.token_))
0093 {
0094 }
0095
0096 template <typename RedirectedHandler>
0097 redirect_disposition_handler(std::exception_ptr& d, RedirectedHandler&& h)
0098 : d_(d),
0099 handler_(static_cast<RedirectedHandler&&>(h))
0100 {
0101 }
0102
0103 void operator()()
0104 {
0105 static_cast<Handler&&>(handler_)();
0106 }
0107
0108 template <typename Arg, typename... Args>
0109 enable_if_t<
0110 !is_disposition<decay_t<Arg>>::value
0111 >
0112 operator()(Arg&& arg, Args&&... args)
0113 {
0114 static_cast<Handler&&>(handler_)(
0115 static_cast<Arg&&>(arg),
0116 static_cast<Args&&>(args)...);
0117 }
0118
0119 template <typename Disposition, typename... Args>
0120 enable_if_t<
0121 is_disposition<Disposition>::value
0122 >
0123 operator()(const Disposition& d, Args&&... args)
0124 {
0125 d_ = disposition_traits<Disposition>::to_exception_ptr(d);
0126 static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...);
0127 }
0128
0129
0130 std::exception_ptr& d_;
0131 Handler handler_;
0132 };
0133
0134 template <typename Disposition, typename Handler>
0135 inline bool asio_handler_is_continuation(
0136 redirect_disposition_handler<Disposition, Handler>* this_handler)
0137 {
0138 return boost_asio_handler_cont_helpers::is_continuation(
0139 this_handler->handler_);
0140 }
0141
0142 template <typename Disposition, typename Signature, typename = void>
0143 struct redirect_disposition_signature
0144 {
0145 typedef Signature type;
0146 };
0147
0148 template <typename Disposition, typename R, typename... Args>
0149 struct redirect_disposition_signature<
0150 Disposition, R(Disposition, Args...)>
0151 {
0152 typedef R type(Args...);
0153 };
0154
0155 template <typename Disposition, typename R, typename... Args>
0156 struct redirect_disposition_signature<
0157 Disposition, R(const Disposition&, Args...)>
0158 {
0159 typedef R type(Args...);
0160 };
0161
0162 template <typename Disposition, typename R, typename... Args>
0163 struct redirect_disposition_signature<
0164 Disposition, R(Disposition, Args...) &>
0165 {
0166 typedef R type(Args...) &;
0167 };
0168
0169 template <typename Disposition, typename R, typename... Args>
0170 struct redirect_disposition_signature<
0171 Disposition, R(const Disposition&, Args...) &>
0172 {
0173 typedef R type(Args...) &;
0174 };
0175
0176 template <typename Disposition, typename R, typename... Args>
0177 struct redirect_disposition_signature<
0178 Disposition, R(Disposition, Args...) &&>
0179 {
0180 typedef R type(Args...) &&;
0181 };
0182
0183 template <typename Disposition, typename R, typename... Args>
0184 struct redirect_disposition_signature<
0185 Disposition, R(const Disposition&, Args...) &&>
0186 {
0187 typedef R type(Args...) &&;
0188 };
0189
0190 #if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
0191
0192 template <typename Disposition, typename R, typename... Args>
0193 struct redirect_disposition_signature<
0194 Disposition, R(Disposition, Args...) noexcept>
0195 {
0196 typedef R type(Args...) & noexcept;
0197 };
0198
0199 template <typename Disposition, typename R, typename... Args>
0200 struct redirect_disposition_signature<
0201 Disposition, R(const Disposition&, Args...) noexcept>
0202 {
0203 typedef R type(Args...) & noexcept;
0204 };
0205
0206 template <typename Disposition, typename R, typename... Args>
0207 struct redirect_disposition_signature<
0208 Disposition, R(Disposition, Args...) & noexcept>
0209 {
0210 typedef R type(Args...) & noexcept;
0211 };
0212
0213 template <typename Disposition, typename R, typename... Args>
0214 struct redirect_disposition_signature<
0215 Disposition, R(const Disposition&, Args...) & noexcept>
0216 {
0217 typedef R type(Args...) & noexcept;
0218 };
0219
0220 template <typename Disposition, typename R, typename... Args>
0221 struct redirect_disposition_signature<
0222 Disposition, R(Disposition, Args...) && noexcept>
0223 {
0224 typedef R type(Args...) && noexcept;
0225 };
0226
0227 template <typename Disposition, typename R, typename... Args>
0228 struct redirect_disposition_signature<
0229 Disposition, R(const Disposition&, Args...) && noexcept>
0230 {
0231 typedef R type(Args...) && noexcept;
0232 };
0233
0234 #endif
0235
0236 template <typename Disposition, typename R, typename... Args>
0237 struct redirect_disposition_signature<
0238 std::exception_ptr, R(Disposition, Args...),
0239 enable_if_t<is_disposition<Disposition>::value>>
0240 {
0241 typedef R type(Args...);
0242 };
0243
0244 template <typename Disposition, typename R, typename... Args>
0245 struct redirect_disposition_signature<
0246 std::exception_ptr, R(const Disposition&, Args...),
0247 enable_if_t<is_disposition<Disposition>::value>>
0248 {
0249 typedef R type(Args...);
0250 };
0251
0252 template <typename Disposition, typename R, typename... Args>
0253 struct redirect_disposition_signature<
0254 std::exception_ptr, R(Disposition, Args...) &,
0255 enable_if_t<is_disposition<Disposition>::value>>
0256 {
0257 typedef R type(Args...) &;
0258 };
0259
0260 template <typename Disposition, typename R, typename... Args>
0261 struct redirect_disposition_signature<
0262 std::exception_ptr, R(const Disposition&, Args...) &,
0263 enable_if_t<is_disposition<Disposition>::value>>
0264 {
0265 typedef R type(Args...) &;
0266 };
0267
0268 template <typename Disposition, typename R, typename... Args>
0269 struct redirect_disposition_signature<
0270 std::exception_ptr, R(Disposition, Args...) &&,
0271 enable_if_t<is_disposition<Disposition>::value>>
0272 {
0273 typedef R type(Args...) &&;
0274 };
0275
0276 template <typename Disposition, typename R, typename... Args>
0277 struct redirect_disposition_signature<
0278 std::exception_ptr, R(const Disposition&, Args...) &&,
0279 enable_if_t<is_disposition<Disposition>::value>>
0280 {
0281 typedef R type(Args...) &&;
0282 };
0283
0284 #if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
0285
0286 template <typename Disposition, typename R, typename... Args>
0287 struct redirect_disposition_signature<
0288 std::exception_ptr, R(Disposition, Args...) noexcept,
0289 enable_if_t<is_disposition<Disposition>::value>>
0290 {
0291 typedef R type(Args...) & noexcept;
0292 };
0293
0294 template <typename Disposition, typename R, typename... Args>
0295 struct redirect_disposition_signature<
0296 std::exception_ptr, R(const Disposition&, Args...) noexcept,
0297 enable_if_t<is_disposition<Disposition>::value>>
0298 {
0299 typedef R type(Args...) & noexcept;
0300 };
0301
0302 template <typename Disposition, typename R, typename... Args>
0303 struct redirect_disposition_signature<
0304 std::exception_ptr, R(Disposition, Args...) & noexcept,
0305 enable_if_t<is_disposition<Disposition>::value>>
0306 {
0307 typedef R type(Args...) & noexcept;
0308 };
0309
0310 template <typename Disposition, typename R, typename... Args>
0311 struct redirect_disposition_signature<
0312 std::exception_ptr, R(const Disposition&, Args...) & noexcept,
0313 enable_if_t<is_disposition<Disposition>::value>>
0314 {
0315 typedef R type(Args...) & noexcept;
0316 };
0317
0318 template <typename Disposition, typename R, typename... Args>
0319 struct redirect_disposition_signature<
0320 std::exception_ptr, R(Disposition, Args...) && noexcept,
0321 enable_if_t<is_disposition<Disposition>::value>>
0322 {
0323 typedef R type(Args...) && noexcept;
0324 };
0325
0326 template <typename Disposition, typename R, typename... Args>
0327 struct redirect_disposition_signature<
0328 std::exception_ptr, R(const Disposition&, Args...) && noexcept,
0329 enable_if_t<is_disposition<Disposition>::value>>
0330 {
0331 typedef R type(Args...) && noexcept;
0332 };
0333
0334 #endif
0335
0336 }
0337
0338 #if !defined(GENERATING_DOCUMENTATION)
0339
0340 template <typename CompletionToken, typename Disposition, typename Signature>
0341 struct async_result<
0342 redirect_disposition_t<CompletionToken, Disposition>, Signature>
0343 : async_result<CompletionToken,
0344 typename detail::redirect_disposition_signature<
0345 Disposition, Signature>::type>
0346 {
0347 template <typename Initiation>
0348 struct init_wrapper : detail::initiation_base<Initiation>
0349 {
0350 using detail::initiation_base<Initiation>::initiation_base;
0351
0352 template <typename Handler, typename... Args>
0353 void operator()(Handler&& handler,
0354 Disposition* d, Args&&... args) &&
0355 {
0356 static_cast<Initiation&&>(*this)(
0357 detail::redirect_disposition_handler<Disposition, decay_t<Handler>>(
0358 *d, static_cast<Handler&&>(handler)),
0359 static_cast<Args&&>(args)...);
0360 }
0361
0362 template <typename Handler, typename... Args>
0363 void operator()(Handler&& handler,
0364 Disposition* d, Args&&... args) const &
0365 {
0366 static_cast<const Initiation&>(*this)(
0367 detail::redirect_disposition_handler<Disposition, decay_t<Handler>>(
0368 *d, static_cast<Handler&&>(handler)),
0369 static_cast<Args&&>(args)...);
0370 }
0371 };
0372
0373 template <typename Initiation, typename RawCompletionToken, typename... Args>
0374 static auto initiate(Initiation&& initiation,
0375 RawCompletionToken&& token, Args&&... args)
0376 -> decltype(
0377 async_initiate<
0378 conditional_t<
0379 is_const<remove_reference_t<RawCompletionToken>>::value,
0380 const CompletionToken, CompletionToken>,
0381 typename detail::redirect_disposition_signature<
0382 Disposition, Signature>::type>(
0383 declval<init_wrapper<decay_t<Initiation>>>(),
0384 token.token_, &token.d_, static_cast<Args&&>(args)...))
0385 {
0386 return async_initiate<
0387 conditional_t<
0388 is_const<remove_reference_t<RawCompletionToken>>::value,
0389 const CompletionToken, CompletionToken>,
0390 typename detail::redirect_disposition_signature<
0391 Disposition, Signature>::type>(
0392 init_wrapper<decay_t<Initiation>>(
0393 static_cast<Initiation&&>(initiation)),
0394 token.token_, &token.d_, static_cast<Args&&>(args)...);
0395 }
0396 };
0397
0398 template <template <typename, typename> class Associator,
0399 typename Disposition, typename Handler, typename DefaultCandidate>
0400 struct associator<Associator,
0401 detail::redirect_disposition_handler<
0402 Disposition, Handler>, DefaultCandidate>
0403 : Associator<Handler, DefaultCandidate>
0404 {
0405 static typename Associator<Handler, DefaultCandidate>::type get(
0406 const detail::redirect_disposition_handler<Disposition, Handler>& h)
0407 noexcept
0408 {
0409 return Associator<Handler, DefaultCandidate>::get(h.handler_);
0410 }
0411
0412 static auto get(
0413 const detail::redirect_disposition_handler<Disposition, Handler>& h,
0414 const DefaultCandidate& c) noexcept
0415 -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
0416 {
0417 return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
0418 }
0419 };
0420
0421 template <typename Disposition, typename... Signatures>
0422 struct async_result<partial_redirect_disposition<Disposition>, Signatures...>
0423 {
0424 template <typename Initiation, typename RawCompletionToken, typename... Args>
0425 static auto initiate(Initiation&& initiation,
0426 RawCompletionToken&& token, Args&&... args)
0427 -> decltype(
0428 async_initiate<Signatures...>(
0429 static_cast<Initiation&&>(initiation),
0430 redirect_disposition_t<
0431 default_completion_token_t<associated_executor_t<Initiation>>,
0432 Disposition>(
0433 default_completion_token_t<associated_executor_t<Initiation>>{},
0434 token.d_),
0435 static_cast<Args&&>(args)...))
0436 {
0437 return async_initiate<Signatures...>(
0438 static_cast<Initiation&&>(initiation),
0439 redirect_disposition_t<
0440 default_completion_token_t<associated_executor_t<Initiation>>,
0441 Disposition>(
0442 default_completion_token_t<associated_executor_t<Initiation>>{},
0443 token.d_),
0444 static_cast<Args&&>(args)...);
0445 }
0446 };
0447
0448 #endif
0449
0450 }
0451 }
0452
0453 #include <boost/asio/detail/pop_options.hpp>
0454
0455 #endif