Home | History | Annotate | Download | only in detail
      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