1 // 2 // detail/wrapped_handler.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 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) 9 // 10 11 #ifndef ASIO_DETAIL_WRAPPED_HANDLER_HPP 12 #define ASIO_DETAIL_WRAPPED_HANDLER_HPP 13 14 15 #include "asio/detail/bind_handler.hpp" 16 #include "asio/detail/handler_alloc_helpers.hpp" 17 #include "asio/detail/handler_cont_helpers.hpp" 18 #include "asio/detail/handler_invoke_helpers.hpp" 19 20 #include "asio/detail/push_options.hpp" 21 22 namespace asio { 23 namespace detail { 24 25 struct is_continuation_delegated 26 { 27 template <typename Dispatcher, typename Handler> 28 bool operator()(Dispatcher&, Handler& handler) const 29 { 30 return asio_handler_cont_helpers::is_continuation(handler); 31 } 32 }; 33 34 struct is_continuation_if_running 35 { 36 template <typename Dispatcher, typename Handler> 37 bool operator()(Dispatcher& dispatcher, Handler&) const 38 { 39 return dispatcher.running_in_this_thread(); 40 } 41 }; 42 43 template <typename Dispatcher, typename Handler, 44 typename IsContinuation = is_continuation_delegated> 45 class wrapped_handler 46 { 47 public: 48 typedef void result_type; 49 50 wrapped_handler(Dispatcher dispatcher, Handler& handler) 51 : dispatcher_(dispatcher), 52 handler_(ASIO_MOVE_CAST(Handler)(handler)) 53 { 54 } 55 56 wrapped_handler(const wrapped_handler& other) 57 : dispatcher_(other.dispatcher_), 58 handler_(other.handler_) 59 { 60 } 61 62 wrapped_handler(wrapped_handler&& other) 63 : dispatcher_(other.dispatcher_), 64 handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) 65 { 66 } 67 68 void operator()() 69 { 70 dispatcher_.dispatch(ASIO_MOVE_CAST(Handler)(handler_)); 71 } 72 73 void operator()() const 74 { 75 dispatcher_.dispatch(handler_); 76 } 77 78 template <typename Arg1> 79 void operator()(const Arg1& arg1) 80 { 81 dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); 82 } 83 84 template <typename Arg1> 85 void operator()(const Arg1& arg1) const 86 { 87 dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); 88 } 89 90 template <typename Arg1, typename Arg2> 91 void operator()(const Arg1& arg1, const Arg2& arg2) 92 { 93 dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); 94 } 95 96 template <typename Arg1, typename Arg2> 97 void operator()(const Arg1& arg1, const Arg2& arg2) const 98 { 99 dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); 100 } 101 102 template <typename Arg1, typename Arg2, typename Arg3> 103 void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) 104 { 105 dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); 106 } 107 108 template <typename Arg1, typename Arg2, typename Arg3> 109 void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const 110 { 111 dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); 112 } 113 114 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 115 void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, 116 const Arg4& arg4) 117 { 118 dispatcher_.dispatch( 119 detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); 120 } 121 122 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 123 void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, 124 const Arg4& arg4) const 125 { 126 dispatcher_.dispatch( 127 detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); 128 } 129 130 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, 131 typename Arg5> 132 void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, 133 const Arg4& arg4, const Arg5& arg5) 134 { 135 dispatcher_.dispatch( 136 detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); 137 } 138 139 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, 140 typename Arg5> 141 void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, 142 const Arg4& arg4, const Arg5& arg5) const 143 { 144 dispatcher_.dispatch( 145 detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); 146 } 147 148 //private: 149 Dispatcher dispatcher_; 150 Handler handler_; 151 }; 152 153 template <typename Handler, typename Context> 154 class rewrapped_handler 155 { 156 public: 157 explicit rewrapped_handler(Handler& handler, const Context& context) 158 : context_(context), 159 handler_(ASIO_MOVE_CAST(Handler)(handler)) 160 { 161 } 162 163 explicit rewrapped_handler(const Handler& handler, const Context& context) 164 : context_(context), 165 handler_(handler) 166 { 167 } 168 169 rewrapped_handler(const rewrapped_handler& other) 170 : context_(other.context_), 171 handler_(other.handler_) 172 { 173 } 174 175 rewrapped_handler(rewrapped_handler&& other) 176 : context_(ASIO_MOVE_CAST(Context)(other.context_)), 177 handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) 178 { 179 } 180 181 void operator()() 182 { 183 handler_(); 184 } 185 186 void operator()() const 187 { 188 handler_(); 189 } 190 191 //private: 192 Context context_; 193 Handler handler_; 194 }; 195 196 template <typename Dispatcher, typename Handler, typename IsContinuation> 197 inline void* asio_handler_allocate(std::size_t size, 198 wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler) 199 { 200 return asio_handler_alloc_helpers::allocate( 201 size, this_handler->handler_); 202 } 203 204 template <typename Dispatcher, typename Handler, typename IsContinuation> 205 inline void asio_handler_deallocate(void* pointer, std::size_t size, 206 wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler) 207 { 208 asio_handler_alloc_helpers::deallocate( 209 pointer, size, this_handler->handler_); 210 } 211 212 template <typename Dispatcher, typename Handler, typename IsContinuation> 213 inline bool asio_handler_is_continuation( 214 wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler) 215 { 216 return IsContinuation()(this_handler->dispatcher_, this_handler->handler_); 217 } 218 219 template <typename Function, typename Dispatcher, 220 typename Handler, typename IsContinuation> 221 inline void asio_handler_invoke(Function& function, 222 wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler) 223 { 224 this_handler->dispatcher_.dispatch( 225 rewrapped_handler<Function, Handler>( 226 function, this_handler->handler_)); 227 } 228 229 template <typename Function, typename Dispatcher, 230 typename Handler, typename IsContinuation> 231 inline void asio_handler_invoke(const Function& function, 232 wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler) 233 { 234 this_handler->dispatcher_.dispatch( 235 rewrapped_handler<Function, Handler>( 236 function, this_handler->handler_)); 237 } 238 239 template <typename Handler, typename Context> 240 inline void* asio_handler_allocate(std::size_t size, 241 rewrapped_handler<Handler, Context>* this_handler) 242 { 243 return asio_handler_alloc_helpers::allocate( 244 size, this_handler->context_); 245 } 246 247 template <typename Handler, typename Context> 248 inline void asio_handler_deallocate(void* pointer, std::size_t size, 249 rewrapped_handler<Handler, Context>* this_handler) 250 { 251 asio_handler_alloc_helpers::deallocate( 252 pointer, size, this_handler->context_); 253 } 254 255 template <typename Dispatcher, typename Context> 256 inline bool asio_handler_is_continuation( 257 rewrapped_handler<Dispatcher, Context>* this_handler) 258 { 259 return asio_handler_cont_helpers::is_continuation( 260 this_handler->context_); 261 } 262 263 template <typename Function, typename Handler, typename Context> 264 inline void asio_handler_invoke(Function& function, 265 rewrapped_handler<Handler, Context>* this_handler) 266 { 267 asio_handler_invoke_helpers::invoke( 268 function, this_handler->context_); 269 } 270 271 template <typename Function, typename Handler, typename Context> 272 inline void asio_handler_invoke(const Function& function, 273 rewrapped_handler<Handler, Context>* this_handler) 274 { 275 asio_handler_invoke_helpers::invoke( 276 function, this_handler->context_); 277 } 278 279 } // namespace detail 280 } // namespace asio 281 282 #include "asio/detail/pop_options.hpp" 283 284 #endif // ASIO_DETAIL_WRAPPED_HANDLER_HPP 285