2 // experimental/impl/redirect_error.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP
12 #define BOOST_ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/associated_executor.hpp>
20 #include <boost/asio/associated_allocator.hpp>
21 #include <boost/asio/async_result.hpp>
22 #include <boost/asio/detail/handler_alloc_helpers.hpp>
23 #include <boost/asio/detail/handler_cont_helpers.hpp>
24 #include <boost/asio/detail/handler_invoke_helpers.hpp>
25 #include <boost/asio/detail/type_traits.hpp>
26 #include <boost/asio/detail/variadic_templates.hpp>
27 #include <boost/asio/handler_type.hpp>
28 #include <boost/system/system_error.hpp>
30 #include <boost/asio/detail/push_options.hpp>
34 namespace experimental {
37 // Class to adapt a redirect_error_t as a completion handler.
38 template <typename Handler>
39 class redirect_error_handler
42 template <typename CompletionToken>
43 redirect_error_handler(redirect_error_t<CompletionToken> e)
45 handler_(BOOST_ASIO_MOVE_CAST(CompletionToken)(e.token_))
54 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
56 template <typename Arg, typename... Args>
58 !is_same<typename decay<Arg>::type, boost::system::error_code>::value
60 operator()(BOOST_ASIO_MOVE_ARG(Arg) arg, BOOST_ASIO_MOVE_ARG(Args)... args)
62 handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg),
63 BOOST_ASIO_MOVE_CAST(Args)(args)...);
66 template <typename... Args>
67 void operator()(const boost::system::error_code& ec,
68 BOOST_ASIO_MOVE_ARG(Args)... args)
71 handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
74 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
76 template <typename Arg>
78 !is_same<typename decay<Arg>::type, boost::system::error_code>::value
80 operator()(BOOST_ASIO_MOVE_ARG(Arg) arg)
82 handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg));
85 void operator()(const boost::system::error_code& ec)
91 #define BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \
92 template <typename Arg, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
94 !is_same<typename decay<Arg>::type, boost::system::error_code>::value \
96 operator()(BOOST_ASIO_MOVE_ARG(Arg) arg, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
98 handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg), \
99 BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
102 template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
103 void operator()(const boost::system::error_code& ec, \
104 BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
107 handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
110 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF)
111 #undef BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF
113 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
116 boost::system::error_code& ec_;
120 template <typename Handler>
121 inline void* asio_handler_allocate(std::size_t size,
122 redirect_error_handler<Handler>* this_handler)
124 return boost_asio_handler_alloc_helpers::allocate(
125 size, this_handler->handler_);
128 template <typename Handler>
129 inline void asio_handler_deallocate(void* pointer, std::size_t size,
130 redirect_error_handler<Handler>* this_handler)
132 boost_asio_handler_alloc_helpers::deallocate(
133 pointer, size, this_handler->handler_);
136 template <typename Handler>
137 inline bool asio_handler_is_continuation(
138 redirect_error_handler<Handler>* this_handler)
140 return boost_asio_handler_cont_helpers::is_continuation(
141 this_handler->handler_);
144 template <typename Function, typename Handler>
145 inline void asio_handler_invoke(Function& function,
146 redirect_error_handler<Handler>* this_handler)
148 boost_asio_handler_invoke_helpers::invoke(
149 function, this_handler->handler_);
152 template <typename Function, typename Handler>
153 inline void asio_handler_invoke(const Function& function,
154 redirect_error_handler<Handler>* this_handler)
156 boost_asio_handler_invoke_helpers::invoke(
157 function, this_handler->handler_);
160 template <typename Signature>
161 struct redirect_error_signature
163 typedef Signature type;
166 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
168 template <typename R, typename... Args>
169 struct redirect_error_signature<R(boost::system::error_code, Args...)>
171 typedef R type(Args...);
174 template <typename R, typename... Args>
175 struct redirect_error_signature<R(const boost::system::error_code&, Args...)>
177 typedef R type(Args...);
180 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
182 template <typename R>
183 struct redirect_error_signature<R(boost::system::error_code)>
188 template <typename R>
189 struct redirect_error_signature<R(const boost::system::error_code&)>
194 #define BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \
195 template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
196 struct redirect_error_signature< \
197 R(boost::system::error_code, BOOST_ASIO_VARIADIC_TARGS(n))> \
199 typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)); \
202 template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
203 struct redirect_error_signature< \
204 R(const boost::system::error_code&, BOOST_ASIO_VARIADIC_TARGS(n))> \
206 typedef R type(BOOST_ASIO_VARIADIC_TARGS(n)); \
209 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF)
210 #undef BOOST_ASIO_PRIVATE_REDIRECT_ERROR_DEF
212 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
214 } // namespace detail
215 } // namespace experimental
217 #if !defined(GENERATING_DOCUMENTATION)
219 template <typename CompletionToken, typename Signature>
220 struct async_result<experimental::redirect_error_t<CompletionToken>, Signature>
221 : async_result<CompletionToken,
222 typename experimental::detail::redirect_error_signature<Signature>::type>
224 typedef experimental::detail::redirect_error_handler<
225 typename async_result<CompletionToken,
226 typename experimental::detail::redirect_error_signature<Signature>::type>
227 ::completion_handler_type> completion_handler_type;
229 explicit async_result(completion_handler_type& h)
230 : async_result<CompletionToken,
231 typename experimental::detail::redirect_error_signature<
232 Signature>::type>(h.handler_)
237 #if !defined(BOOST_ASIO_NO_DEPRECATED)
239 template <typename CompletionToken, typename Signature>
240 struct handler_type<experimental::redirect_error_t<CompletionToken>, Signature>
242 typedef experimental::detail::redirect_error_handler<
243 typename async_result<CompletionToken,
244 typename experimental::detail::redirect_error_signature<Signature>::type>
245 ::completion_handler_type> type;
248 template <typename Handler>
249 struct async_result<experimental::detail::redirect_error_handler<Handler> >
250 : async_result<Handler>
252 explicit async_result(
253 experimental::detail::redirect_error_handler<Handler>& h)
254 : async_result<Handler>(h.handler_)
259 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
261 template <typename Handler, typename Executor>
262 struct associated_executor<
263 experimental::detail::redirect_error_handler<Handler>, Executor>
265 typedef typename associated_executor<Handler, Executor>::type type;
268 const experimental::detail::redirect_error_handler<Handler>& h,
269 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
271 return associated_executor<Handler, Executor>::get(h.handler_, ex);
275 template <typename Handler, typename Allocator>
276 struct associated_allocator<
277 experimental::detail::redirect_error_handler<Handler>, Allocator>
279 typedef typename associated_allocator<Handler, Allocator>::type type;
282 const experimental::detail::redirect_error_handler<Handler>& h,
283 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
285 return associated_allocator<Handler, Allocator>::get(h.handler_, a);
289 #endif // !defined(GENERATING_DOCUMENTATION)
294 #include <boost/asio/detail/pop_options.hpp>
296 #endif // BOOST_ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP