File indexing completed on 2025-06-30 08:08:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_IMPL_REDIRECT_ERROR_HPP
0012 #define BOOST_ASIO_IMPL_REDIRECT_ERROR_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 #include <boost/system/system_error.hpp>
0026
0027 #include <boost/asio/detail/push_options.hpp>
0028
0029 namespace boost {
0030 namespace asio {
0031 namespace detail {
0032
0033
0034 template <typename Handler>
0035 class redirect_error_handler
0036 {
0037 public:
0038 typedef void result_type;
0039
0040 template <typename CompletionToken>
0041 redirect_error_handler(redirect_error_t<CompletionToken> e)
0042 : ec_(e.ec_),
0043 handler_(static_cast<CompletionToken&&>(e.token_))
0044 {
0045 }
0046
0047 template <typename RedirectedHandler>
0048 redirect_error_handler(boost::system::error_code& ec,
0049 RedirectedHandler&& h)
0050 : ec_(ec),
0051 handler_(static_cast<RedirectedHandler&&>(h))
0052 {
0053 }
0054
0055 void operator()()
0056 {
0057 static_cast<Handler&&>(handler_)();
0058 }
0059
0060 template <typename Arg, typename... Args>
0061 enable_if_t<
0062 !is_same<decay_t<Arg>, boost::system::error_code>::value
0063 >
0064 operator()(Arg&& arg, Args&&... args)
0065 {
0066 static_cast<Handler&&>(handler_)(
0067 static_cast<Arg&&>(arg),
0068 static_cast<Args&&>(args)...);
0069 }
0070
0071 template <typename... Args>
0072 void operator()(const boost::system::error_code& ec, Args&&... args)
0073 {
0074 ec_ = ec;
0075 static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...);
0076 }
0077
0078
0079 boost::system::error_code& ec_;
0080 Handler handler_;
0081 };
0082
0083 template <typename Handler>
0084 inline bool asio_handler_is_continuation(
0085 redirect_error_handler<Handler>* this_handler)
0086 {
0087 return boost_asio_handler_cont_helpers::is_continuation(
0088 this_handler->handler_);
0089 }
0090
0091 template <typename Signature>
0092 struct redirect_error_signature
0093 {
0094 typedef Signature type;
0095 };
0096
0097 template <typename R, typename... Args>
0098 struct redirect_error_signature<R(boost::system::error_code, Args...)>
0099 {
0100 typedef R type(Args...);
0101 };
0102
0103 template <typename R, typename... Args>
0104 struct redirect_error_signature<R(const boost::system::error_code&, Args...)>
0105 {
0106 typedef R type(Args...);
0107 };
0108
0109 template <typename R, typename... Args>
0110 struct redirect_error_signature<R(boost::system::error_code, Args...) &>
0111 {
0112 typedef R type(Args...) &;
0113 };
0114
0115 template <typename R, typename... Args>
0116 struct redirect_error_signature<R(const boost::system::error_code&, Args...) &>
0117 {
0118 typedef R type(Args...) &;
0119 };
0120
0121 template <typename R, typename... Args>
0122 struct redirect_error_signature<R(boost::system::error_code, Args...) &&>
0123 {
0124 typedef R type(Args...) &&;
0125 };
0126
0127 template <typename R, typename... Args>
0128 struct redirect_error_signature<R(const boost::system::error_code&, Args...) &&>
0129 {
0130 typedef R type(Args...) &&;
0131 };
0132
0133 #if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
0134
0135 template <typename R, typename... Args>
0136 struct redirect_error_signature<
0137 R(boost::system::error_code, Args...) noexcept>
0138 {
0139 typedef R type(Args...) & noexcept;
0140 };
0141
0142 template <typename R, typename... Args>
0143 struct redirect_error_signature<
0144 R(const boost::system::error_code&, Args...) noexcept>
0145 {
0146 typedef R type(Args...) & noexcept;
0147 };
0148
0149 template <typename R, typename... Args>
0150 struct redirect_error_signature<
0151 R(boost::system::error_code, Args...) & noexcept>
0152 {
0153 typedef R type(Args...) & noexcept;
0154 };
0155
0156 template <typename R, typename... Args>
0157 struct redirect_error_signature<
0158 R(const boost::system::error_code&, Args...) & noexcept>
0159 {
0160 typedef R type(Args...) & noexcept;
0161 };
0162
0163 template <typename R, typename... Args>
0164 struct redirect_error_signature<
0165 R(boost::system::error_code, Args...) && noexcept>
0166 {
0167 typedef R type(Args...) && noexcept;
0168 };
0169
0170 template <typename R, typename... Args>
0171 struct redirect_error_signature<
0172 R(const boost::system::error_code&, Args...) && noexcept>
0173 {
0174 typedef R type(Args...) && noexcept;
0175 };
0176
0177 #endif
0178
0179 }
0180
0181 #if !defined(GENERATING_DOCUMENTATION)
0182
0183 template <typename CompletionToken, typename Signature>
0184 struct async_result<redirect_error_t<CompletionToken>, Signature>
0185 : async_result<CompletionToken,
0186 typename detail::redirect_error_signature<Signature>::type>
0187 {
0188 template <typename Initiation>
0189 struct init_wrapper : detail::initiation_base<Initiation>
0190 {
0191 using detail::initiation_base<Initiation>::initiation_base;
0192
0193 template <typename Handler, typename... Args>
0194 void operator()(Handler&& handler,
0195 boost::system::error_code* ec, Args&&... args) &&
0196 {
0197 static_cast<Initiation&&>(*this)(
0198 detail::redirect_error_handler<decay_t<Handler>>(
0199 *ec, static_cast<Handler&&>(handler)),
0200 static_cast<Args&&>(args)...);
0201 }
0202
0203 template <typename Handler, typename... Args>
0204 void operator()(Handler&& handler,
0205 boost::system::error_code* ec, Args&&... args) const &
0206 {
0207 static_cast<const Initiation&>(*this)(
0208 detail::redirect_error_handler<decay_t<Handler>>(
0209 *ec, static_cast<Handler&&>(handler)),
0210 static_cast<Args&&>(args)...);
0211 }
0212 };
0213
0214 template <typename Initiation, typename RawCompletionToken, typename... Args>
0215 static auto initiate(Initiation&& initiation,
0216 RawCompletionToken&& token, Args&&... args)
0217 -> decltype(
0218 async_initiate<
0219 conditional_t<
0220 is_const<remove_reference_t<RawCompletionToken>>::value,
0221 const CompletionToken, CompletionToken>,
0222 typename detail::redirect_error_signature<Signature>::type>(
0223 declval<init_wrapper<decay_t<Initiation>>>(),
0224 token.token_, &token.ec_, static_cast<Args&&>(args)...))
0225 {
0226 return async_initiate<
0227 conditional_t<
0228 is_const<remove_reference_t<RawCompletionToken>>::value,
0229 const CompletionToken, CompletionToken>,
0230 typename detail::redirect_error_signature<Signature>::type>(
0231 init_wrapper<decay_t<Initiation>>(
0232 static_cast<Initiation&&>(initiation)),
0233 token.token_, &token.ec_, static_cast<Args&&>(args)...);
0234 }
0235 };
0236
0237 template <template <typename, typename> class Associator,
0238 typename Handler, typename DefaultCandidate>
0239 struct associator<Associator,
0240 detail::redirect_error_handler<Handler>, DefaultCandidate>
0241 : Associator<Handler, DefaultCandidate>
0242 {
0243 static typename Associator<Handler, DefaultCandidate>::type get(
0244 const detail::redirect_error_handler<Handler>& h) noexcept
0245 {
0246 return Associator<Handler, DefaultCandidate>::get(h.handler_);
0247 }
0248
0249 static auto get(const detail::redirect_error_handler<Handler>& h,
0250 const DefaultCandidate& c) noexcept
0251 -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
0252 {
0253 return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
0254 }
0255 };
0256
0257 template <typename... Signatures>
0258 struct async_result<partial_redirect_error, Signatures...>
0259 {
0260 template <typename Initiation, typename RawCompletionToken, typename... Args>
0261 static auto initiate(Initiation&& initiation,
0262 RawCompletionToken&& token, Args&&... args)
0263 -> decltype(
0264 async_initiate<Signatures...>(
0265 static_cast<Initiation&&>(initiation),
0266 redirect_error_t<
0267 default_completion_token_t<associated_executor_t<Initiation>>>(
0268 default_completion_token_t<associated_executor_t<Initiation>>{},
0269 token.ec_),
0270 static_cast<Args&&>(args)...))
0271 {
0272 return async_initiate<Signatures...>(
0273 static_cast<Initiation&&>(initiation),
0274 redirect_error_t<
0275 default_completion_token_t<associated_executor_t<Initiation>>>(
0276 default_completion_token_t<associated_executor_t<Initiation>>{},
0277 token.ec_),
0278 static_cast<Args&&>(args)...);
0279 }
0280 };
0281
0282 #endif
0283
0284 }
0285 }
0286
0287 #include <boost/asio/detail/pop_options.hpp>
0288
0289 #endif