1 //
2 // detail/bind_handler.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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 BOOST_ASIO_DETAIL_BIND_HANDLER_HPP
12 #define BOOST_ASIO_DETAIL_BIND_HANDLER_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/associated_allocator.hpp>
20 #include <boost/asio/associated_executor.hpp>
21 #include <boost/asio/detail/handler_alloc_helpers.hpp>
22 #include <boost/asio/detail/handler_cont_helpers.hpp>
23 #include <boost/asio/detail/handler_invoke_helpers.hpp>
24 #include <boost/asio/detail/type_traits.hpp>
25 
26 #include <boost/asio/detail/push_options.hpp>
27 
28 namespace boost {
29 namespace asio {
30 namespace detail {
31 
32 template <typename Handler, typename Arg1>
33 class binder1
34 {
35 public:
36   template <typename T>
binder1(int,BOOST_ASIO_MOVE_ARG (T)handler,const Arg1 & arg1)37   binder1(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1)
38     : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
39       arg1_(arg1)
40   {
41   }
42 
binder1(Handler & handler,const Arg1 & arg1)43   binder1(Handler& handler, const Arg1& arg1)
44     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
45       arg1_(arg1)
46   {
47   }
48 
49 #if defined(BOOST_ASIO_HAS_MOVE)
binder1(const binder1 & other)50   binder1(const binder1& other)
51     : handler_(other.handler_),
52       arg1_(other.arg1_)
53   {
54   }
55 
binder1(binder1 && other)56   binder1(binder1&& other)
57     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
58       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
59   {
60   }
61 #endif // defined(BOOST_ASIO_HAS_MOVE)
62 
operator ()()63   void operator()()
64   {
65     handler_(static_cast<const Arg1&>(arg1_));
66   }
67 
operator ()() const68   void operator()() const
69   {
70     handler_(arg1_);
71   }
72 
73 //private:
74   Handler handler_;
75   Arg1 arg1_;
76 };
77 
78 template <typename Handler, typename Arg1>
79 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,binder1<Handler,Arg1> * this_handler)80 asio_handler_allocate(std::size_t size,
81     binder1<Handler, Arg1>* this_handler)
82 {
83 #if defined(BOOST_ASIO_NO_DEPRECATED)
84   boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
85   return asio_handler_allocate_is_no_longer_used();
86 #else // defined(BOOST_ASIO_NO_DEPRECATED)
87   return boost_asio_handler_alloc_helpers::allocate(
88       size, this_handler->handler_);
89 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
90 }
91 
92 template <typename Handler, typename Arg1>
93 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,binder1<Handler,Arg1> * this_handler)94 asio_handler_deallocate(void* pointer, std::size_t size,
95     binder1<Handler, Arg1>* this_handler)
96 {
97   boost_asio_handler_alloc_helpers::deallocate(
98       pointer, size, this_handler->handler_);
99 #if defined(BOOST_ASIO_NO_DEPRECATED)
100   return asio_handler_deallocate_is_no_longer_used();
101 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
102 }
103 
104 template <typename Handler, typename Arg1>
asio_handler_is_continuation(binder1<Handler,Arg1> * this_handler)105 inline bool asio_handler_is_continuation(
106     binder1<Handler, Arg1>* this_handler)
107 {
108   return boost_asio_handler_cont_helpers::is_continuation(
109       this_handler->handler_);
110 }
111 
112 template <typename Function, typename Handler, typename Arg1>
113 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,binder1<Handler,Arg1> * this_handler)114 asio_handler_invoke(Function& function,
115     binder1<Handler, Arg1>* this_handler)
116 {
117   boost_asio_handler_invoke_helpers::invoke(
118       function, this_handler->handler_);
119 #if defined(BOOST_ASIO_NO_DEPRECATED)
120   return asio_handler_invoke_is_no_longer_used();
121 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
122 }
123 
124 template <typename Function, typename Handler, typename Arg1>
125 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,binder1<Handler,Arg1> * this_handler)126 asio_handler_invoke(const Function& function,
127     binder1<Handler, Arg1>* this_handler)
128 {
129   boost_asio_handler_invoke_helpers::invoke(
130       function, this_handler->handler_);
131 #if defined(BOOST_ASIO_NO_DEPRECATED)
132   return asio_handler_invoke_is_no_longer_used();
133 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
134 }
135 
136 template <typename Handler, typename Arg1>
bind_handler(BOOST_ASIO_MOVE_ARG (Handler)handler,const Arg1 & arg1)137 inline binder1<typename decay<Handler>::type, Arg1> bind_handler(
138     BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1)
139 {
140   return binder1<typename decay<Handler>::type, Arg1>(0,
141       BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1);
142 }
143 
144 template <typename Handler, typename Arg1, typename Arg2>
145 class binder2
146 {
147 public:
148   template <typename T>
binder2(int,BOOST_ASIO_MOVE_ARG (T)handler,const Arg1 & arg1,const Arg2 & arg2)149   binder2(int, BOOST_ASIO_MOVE_ARG(T) handler,
150       const Arg1& arg1, const Arg2& arg2)
151     : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
152       arg1_(arg1),
153       arg2_(arg2)
154   {
155   }
156 
binder2(Handler & handler,const Arg1 & arg1,const Arg2 & arg2)157   binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)
158     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
159       arg1_(arg1),
160       arg2_(arg2)
161   {
162   }
163 
164 #if defined(BOOST_ASIO_HAS_MOVE)
binder2(const binder2 & other)165   binder2(const binder2& other)
166     : handler_(other.handler_),
167       arg1_(other.arg1_),
168       arg2_(other.arg2_)
169   {
170   }
171 
binder2(binder2 && other)172   binder2(binder2&& other)
173     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
174       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
175       arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
176   {
177   }
178 #endif // defined(BOOST_ASIO_HAS_MOVE)
179 
operator ()()180   void operator()()
181   {
182     handler_(static_cast<const Arg1&>(arg1_),
183         static_cast<const Arg2&>(arg2_));
184   }
185 
operator ()() const186   void operator()() const
187   {
188     handler_(arg1_, arg2_);
189   }
190 
191 //private:
192   Handler handler_;
193   Arg1 arg1_;
194   Arg2 arg2_;
195 };
196 
197 template <typename Handler, typename Arg1, typename Arg2>
198 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,binder2<Handler,Arg1,Arg2> * this_handler)199 asio_handler_allocate(std::size_t size,
200     binder2<Handler, Arg1, Arg2>* this_handler)
201 {
202 #if defined(BOOST_ASIO_NO_DEPRECATED)
203   boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
204   return asio_handler_allocate_is_no_longer_used();
205 #else // defined(BOOST_ASIO_NO_DEPRECATED)
206   return boost_asio_handler_alloc_helpers::allocate(
207       size, this_handler->handler_);
208 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
209 }
210 
211 template <typename Handler, typename Arg1, typename Arg2>
212 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,binder2<Handler,Arg1,Arg2> * this_handler)213 asio_handler_deallocate(void* pointer, std::size_t size,
214     binder2<Handler, Arg1, Arg2>* this_handler)
215 {
216   boost_asio_handler_alloc_helpers::deallocate(
217       pointer, size, this_handler->handler_);
218 #if defined(BOOST_ASIO_NO_DEPRECATED)
219   return asio_handler_deallocate_is_no_longer_used();
220 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
221 }
222 
223 template <typename Handler, typename Arg1, typename Arg2>
asio_handler_is_continuation(binder2<Handler,Arg1,Arg2> * this_handler)224 inline bool asio_handler_is_continuation(
225     binder2<Handler, Arg1, Arg2>* this_handler)
226 {
227   return boost_asio_handler_cont_helpers::is_continuation(
228       this_handler->handler_);
229 }
230 
231 template <typename Function, typename Handler, typename Arg1, typename Arg2>
232 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,binder2<Handler,Arg1,Arg2> * this_handler)233 asio_handler_invoke(Function& function,
234     binder2<Handler, Arg1, Arg2>* this_handler)
235 {
236   boost_asio_handler_invoke_helpers::invoke(
237       function, this_handler->handler_);
238 #if defined(BOOST_ASIO_NO_DEPRECATED)
239   return asio_handler_invoke_is_no_longer_used();
240 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
241 }
242 
243 template <typename Function, typename Handler, typename Arg1, typename Arg2>
244 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,binder2<Handler,Arg1,Arg2> * this_handler)245 asio_handler_invoke(const Function& function,
246     binder2<Handler, Arg1, Arg2>* this_handler)
247 {
248   boost_asio_handler_invoke_helpers::invoke(
249       function, this_handler->handler_);
250 #if defined(BOOST_ASIO_NO_DEPRECATED)
251   return asio_handler_invoke_is_no_longer_used();
252 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
253 }
254 
255 template <typename Handler, typename Arg1, typename Arg2>
bind_handler(BOOST_ASIO_MOVE_ARG (Handler)handler,const Arg1 & arg1,const Arg2 & arg2)256 inline binder2<typename decay<Handler>::type, Arg1, Arg2> bind_handler(
257     BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2)
258 {
259   return binder2<typename decay<Handler>::type, Arg1, Arg2>(0,
260       BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2);
261 }
262 
263 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
264 class binder3
265 {
266 public:
267   template <typename T>
binder3(int,BOOST_ASIO_MOVE_ARG (T)handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3)268   binder3(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
269       const Arg2& arg2, const Arg3& arg3)
270     : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
271       arg1_(arg1),
272       arg2_(arg2),
273       arg3_(arg3)
274   {
275   }
276 
binder3(Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3)277   binder3(Handler& handler, const Arg1& arg1,
278       const Arg2& arg2, const Arg3& arg3)
279     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
280       arg1_(arg1),
281       arg2_(arg2),
282       arg3_(arg3)
283   {
284   }
285 
286 #if defined(BOOST_ASIO_HAS_MOVE)
binder3(const binder3 & other)287   binder3(const binder3& other)
288     : handler_(other.handler_),
289       arg1_(other.arg1_),
290       arg2_(other.arg2_),
291       arg3_(other.arg3_)
292   {
293   }
294 
binder3(binder3 && other)295   binder3(binder3&& other)
296     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
297       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
298       arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
299       arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_))
300   {
301   }
302 #endif // defined(BOOST_ASIO_HAS_MOVE)
303 
operator ()()304   void operator()()
305   {
306     handler_(static_cast<const Arg1&>(arg1_),
307         static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));
308   }
309 
operator ()() const310   void operator()() const
311   {
312     handler_(arg1_, arg2_, arg3_);
313   }
314 
315 //private:
316   Handler handler_;
317   Arg1 arg1_;
318   Arg2 arg2_;
319   Arg3 arg3_;
320 };
321 
322 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
323 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)324 asio_handler_allocate(std::size_t size,
325     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
326 {
327 #if defined(BOOST_ASIO_NO_DEPRECATED)
328   boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
329   return asio_handler_allocate_is_no_longer_used();
330 #else // defined(BOOST_ASIO_NO_DEPRECATED)
331   return boost_asio_handler_alloc_helpers::allocate(
332       size, this_handler->handler_);
333 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
334 }
335 
336 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
337 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)338 asio_handler_deallocate(void* pointer, std::size_t size,
339     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
340 {
341   boost_asio_handler_alloc_helpers::deallocate(
342       pointer, size, this_handler->handler_);
343 #if defined(BOOST_ASIO_NO_DEPRECATED)
344   return asio_handler_deallocate_is_no_longer_used();
345 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
346 }
347 
348 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
asio_handler_is_continuation(binder3<Handler,Arg1,Arg2,Arg3> * this_handler)349 inline bool asio_handler_is_continuation(
350     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
351 {
352   return boost_asio_handler_cont_helpers::is_continuation(
353       this_handler->handler_);
354 }
355 
356 template <typename Function, typename Handler,
357     typename Arg1, typename Arg2, typename Arg3>
358 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)359 asio_handler_invoke(Function& function,
360     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
361 {
362   boost_asio_handler_invoke_helpers::invoke(
363       function, this_handler->handler_);
364 #if defined(BOOST_ASIO_NO_DEPRECATED)
365   return asio_handler_invoke_is_no_longer_used();
366 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
367 }
368 
369 template <typename Function, typename Handler,
370     typename Arg1, typename Arg2, typename Arg3>
371 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)372 asio_handler_invoke(const Function& function,
373     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
374 {
375   boost_asio_handler_invoke_helpers::invoke(
376       function, this_handler->handler_);
377 #if defined(BOOST_ASIO_NO_DEPRECATED)
378   return asio_handler_invoke_is_no_longer_used();
379 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
380 }
381 
382 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
bind_handler(BOOST_ASIO_MOVE_ARG (Handler)handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3)383 inline binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(
384     BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2,
385     const Arg3& arg3)
386 {
387   return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,
388       BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3);
389 }
390 
391 template <typename Handler, typename Arg1,
392     typename Arg2, typename Arg3, typename Arg4>
393 class binder4
394 {
395 public:
396   template <typename T>
binder4(int,BOOST_ASIO_MOVE_ARG (T)handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4)397   binder4(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
398       const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
399     : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
400       arg1_(arg1),
401       arg2_(arg2),
402       arg3_(arg3),
403       arg4_(arg4)
404   {
405   }
406 
binder4(Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4)407   binder4(Handler& handler, const Arg1& arg1,
408       const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
409     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
410       arg1_(arg1),
411       arg2_(arg2),
412       arg3_(arg3),
413       arg4_(arg4)
414   {
415   }
416 
417 #if defined(BOOST_ASIO_HAS_MOVE)
binder4(const binder4 & other)418   binder4(const binder4& other)
419     : handler_(other.handler_),
420       arg1_(other.arg1_),
421       arg2_(other.arg2_),
422       arg3_(other.arg3_),
423       arg4_(other.arg4_)
424   {
425   }
426 
binder4(binder4 && other)427   binder4(binder4&& other)
428     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
429       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
430       arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
431       arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
432       arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_))
433   {
434   }
435 #endif // defined(BOOST_ASIO_HAS_MOVE)
436 
operator ()()437   void operator()()
438   {
439     handler_(static_cast<const Arg1&>(arg1_),
440         static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
441         static_cast<const Arg4&>(arg4_));
442   }
443 
operator ()() const444   void operator()() const
445   {
446     handler_(arg1_, arg2_, arg3_, arg4_);
447   }
448 
449 //private:
450   Handler handler_;
451   Arg1 arg1_;
452   Arg2 arg2_;
453   Arg3 arg3_;
454   Arg4 arg4_;
455 };
456 
457 template <typename Handler, typename Arg1,
458     typename Arg2, typename Arg3, typename Arg4>
459 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)460 asio_handler_allocate(std::size_t size,
461     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
462 {
463 #if defined(BOOST_ASIO_NO_DEPRECATED)
464   boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
465   return asio_handler_allocate_is_no_longer_used();
466 #else // defined(BOOST_ASIO_NO_DEPRECATED)
467   return boost_asio_handler_alloc_helpers::allocate(
468       size, this_handler->handler_);
469 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
470 }
471 
472 template <typename Handler, typename Arg1,
473     typename Arg2, typename Arg3, typename Arg4>
474 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)475 asio_handler_deallocate(void* pointer, std::size_t size,
476     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
477 {
478   boost_asio_handler_alloc_helpers::deallocate(
479       pointer, size, this_handler->handler_);
480 #if defined(BOOST_ASIO_NO_DEPRECATED)
481   return asio_handler_deallocate_is_no_longer_used();
482 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
483 }
484 
485 template <typename Handler, typename Arg1,
486     typename Arg2, typename Arg3, typename Arg4>
asio_handler_is_continuation(binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)487 inline bool asio_handler_is_continuation(
488     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
489 {
490   return boost_asio_handler_cont_helpers::is_continuation(
491       this_handler->handler_);
492 }
493 
494 template <typename Function, typename Handler, typename Arg1,
495     typename Arg2, typename Arg3, typename Arg4>
496 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)497 asio_handler_invoke(Function& function,
498     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
499 {
500   boost_asio_handler_invoke_helpers::invoke(
501       function, this_handler->handler_);
502 #if defined(BOOST_ASIO_NO_DEPRECATED)
503   return asio_handler_invoke_is_no_longer_used();
504 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
505 }
506 
507 template <typename Function, typename Handler, typename Arg1,
508     typename Arg2, typename Arg3, typename Arg4>
509 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)510 asio_handler_invoke(const Function& function,
511     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
512 {
513   boost_asio_handler_invoke_helpers::invoke(
514       function, this_handler->handler_);
515 #if defined(BOOST_ASIO_NO_DEPRECATED)
516   return asio_handler_invoke_is_no_longer_used();
517 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
518 }
519 
520 template <typename Handler, typename Arg1,
521     typename Arg2, typename Arg3, typename Arg4>
522 inline binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>
bind_handler(BOOST_ASIO_MOVE_ARG (Handler)handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4)523 bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
524     const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
525 {
526   return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,
527       BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4);
528 }
529 
530 template <typename Handler, typename Arg1, typename Arg2,
531     typename Arg3, typename Arg4, typename Arg5>
532 class binder5
533 {
534 public:
535   template <typename T>
binder5(int,BOOST_ASIO_MOVE_ARG (T)handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4,const Arg5 & arg5)536   binder5(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
537       const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
538     : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
539       arg1_(arg1),
540       arg2_(arg2),
541       arg3_(arg3),
542       arg4_(arg4),
543       arg5_(arg5)
544   {
545   }
546 
binder5(Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4,const Arg5 & arg5)547   binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2,
548       const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
549     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
550       arg1_(arg1),
551       arg2_(arg2),
552       arg3_(arg3),
553       arg4_(arg4),
554       arg5_(arg5)
555   {
556   }
557 
558 #if defined(BOOST_ASIO_HAS_MOVE)
binder5(const binder5 & other)559   binder5(const binder5& other)
560     : handler_(other.handler_),
561       arg1_(other.arg1_),
562       arg2_(other.arg2_),
563       arg3_(other.arg3_),
564       arg4_(other.arg4_),
565       arg5_(other.arg5_)
566   {
567   }
568 
binder5(binder5 && other)569   binder5(binder5&& other)
570     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
571       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
572       arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
573       arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
574       arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_)),
575       arg5_(BOOST_ASIO_MOVE_CAST(Arg5)(other.arg5_))
576   {
577   }
578 #endif // defined(BOOST_ASIO_HAS_MOVE)
579 
operator ()()580   void operator()()
581   {
582     handler_(static_cast<const Arg1&>(arg1_),
583         static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
584         static_cast<const Arg4&>(arg4_), static_cast<const Arg5&>(arg5_));
585   }
586 
operator ()() const587   void operator()() const
588   {
589     handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
590   }
591 
592 //private:
593   Handler handler_;
594   Arg1 arg1_;
595   Arg2 arg2_;
596   Arg3 arg3_;
597   Arg4 arg4_;
598   Arg5 arg5_;
599 };
600 
601 template <typename Handler, typename Arg1, typename Arg2,
602     typename Arg3, typename Arg4, typename Arg5>
603 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)604 asio_handler_allocate(std::size_t size,
605     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
606 {
607 #if defined(BOOST_ASIO_NO_DEPRECATED)
608   boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
609   return asio_handler_allocate_is_no_longer_used();
610 #else // defined(BOOST_ASIO_NO_DEPRECATED)
611   return boost_asio_handler_alloc_helpers::allocate(
612       size, this_handler->handler_);
613 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
614 }
615 
616 template <typename Handler, typename Arg1, typename Arg2,
617     typename Arg3, typename Arg4, typename Arg5>
618 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)619 asio_handler_deallocate(void* pointer, std::size_t size,
620     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
621 {
622   boost_asio_handler_alloc_helpers::deallocate(
623       pointer, size, this_handler->handler_);
624 #if defined(BOOST_ASIO_NO_DEPRECATED)
625   return asio_handler_deallocate_is_no_longer_used();
626 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
627 }
628 
629 template <typename Handler, typename Arg1, typename Arg2,
630     typename Arg3, typename Arg4, typename Arg5>
asio_handler_is_continuation(binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)631 inline bool asio_handler_is_continuation(
632     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
633 {
634   return boost_asio_handler_cont_helpers::is_continuation(
635       this_handler->handler_);
636 }
637 
638 template <typename Function, typename Handler, typename Arg1,
639     typename Arg2, typename Arg3, typename Arg4, typename Arg5>
640 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)641 asio_handler_invoke(Function& function,
642     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
643 {
644   boost_asio_handler_invoke_helpers::invoke(
645       function, this_handler->handler_);
646 #if defined(BOOST_ASIO_NO_DEPRECATED)
647   return asio_handler_invoke_is_no_longer_used();
648 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
649 }
650 
651 template <typename Function, typename Handler, typename Arg1,
652     typename Arg2, typename Arg3, typename Arg4, typename Arg5>
653 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)654 asio_handler_invoke(const Function& function,
655     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
656 {
657   boost_asio_handler_invoke_helpers::invoke(
658       function, this_handler->handler_);
659 #if defined(BOOST_ASIO_NO_DEPRECATED)
660   return asio_handler_invoke_is_no_longer_used();
661 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
662 }
663 
664 template <typename Handler, typename Arg1, typename Arg2,
665     typename Arg3, typename Arg4, typename Arg5>
666 inline binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>
bind_handler(BOOST_ASIO_MOVE_ARG (Handler)handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4,const Arg5 & arg5)667 bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
668     const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
669 {
670   return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,
671       BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5);
672 }
673 
674 #if defined(BOOST_ASIO_HAS_MOVE)
675 
676 template <typename Handler, typename Arg1>
677 class move_binder1
678 {
679 public:
move_binder1(int,BOOST_ASIO_MOVE_ARG (Handler)handler,BOOST_ASIO_MOVE_ARG (Arg1)arg1)680   move_binder1(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
681       BOOST_ASIO_MOVE_ARG(Arg1) arg1)
682     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
683       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1))
684   {
685   }
686 
move_binder1(move_binder1 && other)687   move_binder1(move_binder1&& other)
688     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
689       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
690   {
691   }
692 
operator ()()693   void operator()()
694   {
695     handler_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1_));
696   }
697 
698 //private:
699   Handler handler_;
700   Arg1 arg1_;
701 };
702 
703 template <typename Handler, typename Arg1>
704 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,move_binder1<Handler,Arg1> * this_handler)705 asio_handler_allocate(std::size_t size,
706     move_binder1<Handler, Arg1>* this_handler)
707 {
708 #if defined(BOOST_ASIO_NO_DEPRECATED)
709   boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
710   return asio_handler_allocate_is_no_longer_used();
711 #else // defined(BOOST_ASIO_NO_DEPRECATED)
712   return boost_asio_handler_alloc_helpers::allocate(
713       size, this_handler->handler_);
714 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
715 }
716 
717 template <typename Handler, typename Arg1>
718 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,move_binder1<Handler,Arg1> * this_handler)719 asio_handler_deallocate(void* pointer, std::size_t size,
720     move_binder1<Handler, Arg1>* this_handler)
721 {
722   boost_asio_handler_alloc_helpers::deallocate(
723       pointer, size, this_handler->handler_);
724 #if defined(BOOST_ASIO_NO_DEPRECATED)
725   return asio_handler_deallocate_is_no_longer_used();
726 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
727 }
728 
729 template <typename Handler, typename Arg1>
asio_handler_is_continuation(move_binder1<Handler,Arg1> * this_handler)730 inline bool asio_handler_is_continuation(
731     move_binder1<Handler, Arg1>* this_handler)
732 {
733   return boost_asio_handler_cont_helpers::is_continuation(
734       this_handler->handler_);
735 }
736 
737 template <typename Function, typename Handler, typename Arg1>
738 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(BOOST_ASIO_MOVE_ARG (Function)function,move_binder1<Handler,Arg1> * this_handler)739 asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
740     move_binder1<Handler, Arg1>* this_handler)
741 {
742   boost_asio_handler_invoke_helpers::invoke(
743       BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
744 #if defined(BOOST_ASIO_NO_DEPRECATED)
745   return asio_handler_invoke_is_no_longer_used();
746 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
747 }
748 
749 template <typename Handler, typename Arg1, typename Arg2>
750 class move_binder2
751 {
752 public:
move_binder2(int,BOOST_ASIO_MOVE_ARG (Handler)handler,const Arg1 & arg1,BOOST_ASIO_MOVE_ARG (Arg2)arg2)753   move_binder2(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
754       const Arg1& arg1, BOOST_ASIO_MOVE_ARG(Arg2) arg2)
755     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
756       arg1_(arg1),
757       arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(arg2))
758   {
759   }
760 
move_binder2(move_binder2 && other)761   move_binder2(move_binder2&& other)
762     : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
763       arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
764       arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
765   {
766   }
767 
operator ()()768   void operator()()
769   {
770     handler_(static_cast<const Arg1&>(arg1_),
771         BOOST_ASIO_MOVE_CAST(Arg2)(arg2_));
772   }
773 
774 //private:
775   Handler handler_;
776   Arg1 arg1_;
777   Arg2 arg2_;
778 };
779 
780 template <typename Handler, typename Arg1, typename Arg2>
781 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,move_binder2<Handler,Arg1,Arg2> * this_handler)782 asio_handler_allocate(std::size_t size,
783     move_binder2<Handler, Arg1, Arg2>* this_handler)
784 {
785 #if defined(BOOST_ASIO_NO_DEPRECATED)
786   boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
787   return asio_handler_allocate_is_no_longer_used();
788 #else // defined(BOOST_ASIO_NO_DEPRECATED)
789   return boost_asio_handler_alloc_helpers::allocate(
790       size, this_handler->handler_);
791 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
792 }
793 
794 template <typename Handler, typename Arg1, typename Arg2>
795 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,move_binder2<Handler,Arg1,Arg2> * this_handler)796 asio_handler_deallocate(void* pointer, std::size_t size,
797     move_binder2<Handler, Arg1, Arg2>* this_handler)
798 {
799   boost_asio_handler_alloc_helpers::deallocate(
800       pointer, size, this_handler->handler_);
801 #if defined(BOOST_ASIO_NO_DEPRECATED)
802   return asio_handler_deallocate_is_no_longer_used();
803 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
804 }
805 
806 template <typename Handler, typename Arg1, typename Arg2>
asio_handler_is_continuation(move_binder2<Handler,Arg1,Arg2> * this_handler)807 inline bool asio_handler_is_continuation(
808     move_binder2<Handler, Arg1, Arg2>* this_handler)
809 {
810   return boost_asio_handler_cont_helpers::is_continuation(
811       this_handler->handler_);
812 }
813 
814 template <typename Function, typename Handler, typename Arg1, typename Arg2>
815 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(BOOST_ASIO_MOVE_ARG (Function)function,move_binder2<Handler,Arg1,Arg2> * this_handler)816 asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
817     move_binder2<Handler, Arg1, Arg2>* this_handler)
818 {
819   boost_asio_handler_invoke_helpers::invoke(
820       BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
821 #if defined(BOOST_ASIO_NO_DEPRECATED)
822   return asio_handler_invoke_is_no_longer_used();
823 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
824 }
825 
826 #endif // defined(BOOST_ASIO_HAS_MOVE)
827 
828 } // namespace detail
829 
830 template <typename Handler, typename Arg1, typename Allocator>
831 struct associated_allocator<detail::binder1<Handler, Arg1>, Allocator>
832 {
833   typedef typename associated_allocator<Handler, Allocator>::type type;
834 
getboost::asio::associated_allocator835   static type get(const detail::binder1<Handler, Arg1>& h,
836       const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
837   {
838     return associated_allocator<Handler, Allocator>::get(h.handler_, a);
839   }
840 };
841 
842 template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
843 struct associated_allocator<detail::binder2<Handler, Arg1, Arg2>, Allocator>
844 {
845   typedef typename associated_allocator<Handler, Allocator>::type type;
846 
getboost::asio::associated_allocator847   static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
848       const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
849   {
850     return associated_allocator<Handler, Allocator>::get(h.handler_, a);
851   }
852 };
853 
854 template <typename Handler, typename Arg1, typename Executor>
855 struct associated_executor<detail::binder1<Handler, Arg1>, Executor>
856   : detail::associated_executor_forwarding_base<Handler, Executor>
857 {
858   typedef typename associated_executor<Handler, Executor>::type type;
859 
getboost::asio::associated_executor860   static type get(const detail::binder1<Handler, Arg1>& h,
861       const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
862   {
863     return associated_executor<Handler, Executor>::get(h.handler_, ex);
864   }
865 };
866 
867 template <typename Handler, typename Arg1, typename Arg2, typename Executor>
868 struct associated_executor<detail::binder2<Handler, Arg1, Arg2>, Executor>
869   : detail::associated_executor_forwarding_base<Handler, Executor>
870 {
871   typedef typename associated_executor<Handler, Executor>::type type;
872 
getboost::asio::associated_executor873   static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
874       const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
875   {
876     return associated_executor<Handler, Executor>::get(h.handler_, ex);
877   }
878 };
879 
880 #if defined(BOOST_ASIO_HAS_MOVE)
881 
882 template <typename Handler, typename Arg1, typename Allocator>
883 struct associated_allocator<detail::move_binder1<Handler, Arg1>, Allocator>
884 {
885   typedef typename associated_allocator<Handler, Allocator>::type type;
886 
getboost::asio::associated_allocator887   static type get(const detail::move_binder1<Handler, Arg1>& h,
888       const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
889   {
890     return associated_allocator<Handler, Allocator>::get(h.handler_, a);
891   }
892 };
893 
894 template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
895 struct associated_allocator<
896     detail::move_binder2<Handler, Arg1, Arg2>, Allocator>
897 {
898   typedef typename associated_allocator<Handler, Allocator>::type type;
899 
getboost::asio::associated_allocator900   static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
901       const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
902   {
903     return associated_allocator<Handler, Allocator>::get(h.handler_, a);
904   }
905 };
906 
907 template <typename Handler, typename Arg1, typename Executor>
908 struct associated_executor<detail::move_binder1<Handler, Arg1>, Executor>
909   : detail::associated_executor_forwarding_base<Handler, Executor>
910 {
911   typedef typename associated_executor<Handler, Executor>::type type;
912 
getboost::asio::associated_executor913   static type get(const detail::move_binder1<Handler, Arg1>& h,
914       const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
915   {
916     return associated_executor<Handler, Executor>::get(h.handler_, ex);
917   }
918 };
919 
920 template <typename Handler, typename Arg1, typename Arg2, typename Executor>
921 struct associated_executor<detail::move_binder2<Handler, Arg1, Arg2>, Executor>
922   : detail::associated_executor_forwarding_base<Handler, Executor>
923 {
924   typedef typename associated_executor<Handler, Executor>::type type;
925 
getboost::asio::associated_executor926   static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
927       const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
928   {
929     return associated_executor<Handler, Executor>::get(h.handler_, ex);
930   }
931 };
932 
933 #endif // defined(BOOST_ASIO_HAS_MOVE)
934 
935 } // namespace asio
936 } // namespace boost
937 
938 #include <boost/asio/detail/pop_options.hpp>
939 
940 #endif // BOOST_ASIO_DETAIL_BIND_HANDLER_HPP
941