1 //
2 // detail/bind_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_BIND_HANDLER_HPP
12 #define ASIO_DETAIL_BIND_HANDLER_HPP
13 
14 
15 #include "asio/detail/config.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 template <typename Handler, typename Arg1>
26 class binder1
27 {
28 public:
binder1(const Handler & handler,const Arg1 & arg1)29   binder1(const Handler& handler, const Arg1& arg1)
30     : handler_(handler),
31       arg1_(arg1)
32   {
33   }
34 
binder1(Handler & handler,const Arg1 & arg1)35   binder1(Handler& handler, const Arg1& arg1)
36     : handler_(ASIO_MOVE_CAST(Handler)(handler)),
37       arg1_(arg1)
38   {
39   }
40 
operator ()()41   void operator()()
42   {
43     handler_(static_cast<const Arg1&>(arg1_));
44   }
45 
operator ()() const46   void operator()() const
47   {
48     handler_(arg1_);
49   }
50 
51 //private:
52   Handler handler_;
53   Arg1 arg1_;
54 };
55 
56 template <typename Handler, typename Arg1>
asio_handler_allocate(std::size_t size,binder1<Handler,Arg1> * this_handler)57 inline void* asio_handler_allocate(std::size_t size,
58     binder1<Handler, Arg1>* this_handler)
59 {
60   return asio_handler_alloc_helpers::allocate(
61       size, this_handler->handler_);
62 }
63 
64 template <typename Handler, typename Arg1>
asio_handler_deallocate(void * pointer,std::size_t size,binder1<Handler,Arg1> * this_handler)65 inline void asio_handler_deallocate(void* pointer, std::size_t size,
66     binder1<Handler, Arg1>* this_handler)
67 {
68   asio_handler_alloc_helpers::deallocate(
69       pointer, size, this_handler->handler_);
70 }
71 
72 template <typename Handler, typename Arg1>
asio_handler_is_continuation(binder1<Handler,Arg1> * this_handler)73 inline bool asio_handler_is_continuation(
74     binder1<Handler, Arg1>* this_handler)
75 {
76   return asio_handler_cont_helpers::is_continuation(
77       this_handler->handler_);
78 }
79 
80 template <typename Function, typename Handler, typename Arg1>
asio_handler_invoke(Function & function,binder1<Handler,Arg1> * this_handler)81 inline void asio_handler_invoke(Function& function,
82     binder1<Handler, Arg1>* this_handler)
83 {
84   asio_handler_invoke_helpers::invoke(
85       function, this_handler->handler_);
86 }
87 
88 template <typename Function, typename Handler, typename Arg1>
asio_handler_invoke(const Function & function,binder1<Handler,Arg1> * this_handler)89 inline void asio_handler_invoke(const Function& function,
90     binder1<Handler, Arg1>* this_handler)
91 {
92   asio_handler_invoke_helpers::invoke(
93       function, this_handler->handler_);
94 }
95 
96 template <typename Handler, typename Arg1>
bind_handler(Handler handler,const Arg1 & arg1)97 inline binder1<Handler, Arg1> bind_handler(Handler handler,
98     const Arg1& arg1)
99 {
100   return binder1<Handler, Arg1>(handler, arg1);
101 }
102 
103 template <typename Handler, typename Arg1, typename Arg2>
104 class binder2
105 {
106 public:
binder2(const Handler & handler,const Arg1 & arg1,const Arg2 & arg2)107   binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2)
108     : handler_(handler),
109       arg1_(arg1),
110       arg2_(arg2)
111   {
112   }
113 
binder2(Handler & handler,const Arg1 & arg1,const Arg2 & arg2)114   binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)
115     : handler_(ASIO_MOVE_CAST(Handler)(handler)),
116       arg1_(arg1),
117       arg2_(arg2)
118   {
119   }
120 
operator ()()121   void operator()()
122   {
123     handler_(static_cast<const Arg1&>(arg1_),
124         static_cast<const Arg2&>(arg2_));
125   }
126 
operator ()() const127   void operator()() const
128   {
129     handler_(arg1_, arg2_);
130   }
131 
132 //private:
133   Handler handler_;
134   Arg1 arg1_;
135   Arg2 arg2_;
136 };
137 
138 template <typename Handler, typename Arg1, typename Arg2>
asio_handler_allocate(std::size_t size,binder2<Handler,Arg1,Arg2> * this_handler)139 inline void* asio_handler_allocate(std::size_t size,
140     binder2<Handler, Arg1, Arg2>* this_handler)
141 {
142   return asio_handler_alloc_helpers::allocate(
143       size, this_handler->handler_);
144 }
145 
146 template <typename Handler, typename Arg1, typename Arg2>
asio_handler_deallocate(void * pointer,std::size_t size,binder2<Handler,Arg1,Arg2> * this_handler)147 inline void asio_handler_deallocate(void* pointer, std::size_t size,
148     binder2<Handler, Arg1, Arg2>* this_handler)
149 {
150   asio_handler_alloc_helpers::deallocate(
151       pointer, size, this_handler->handler_);
152 }
153 
154 template <typename Handler, typename Arg1, typename Arg2>
asio_handler_is_continuation(binder2<Handler,Arg1,Arg2> * this_handler)155 inline bool asio_handler_is_continuation(
156     binder2<Handler, Arg1, Arg2>* this_handler)
157 {
158   return asio_handler_cont_helpers::is_continuation(
159       this_handler->handler_);
160 }
161 
162 template <typename Function, typename Handler, typename Arg1, typename Arg2>
asio_handler_invoke(Function & function,binder2<Handler,Arg1,Arg2> * this_handler)163 inline void asio_handler_invoke(Function& function,
164     binder2<Handler, Arg1, Arg2>* this_handler)
165 {
166   asio_handler_invoke_helpers::invoke(
167       function, this_handler->handler_);
168 }
169 
170 template <typename Function, typename Handler, typename Arg1, typename Arg2>
asio_handler_invoke(const Function & function,binder2<Handler,Arg1,Arg2> * this_handler)171 inline void asio_handler_invoke(const Function& function,
172     binder2<Handler, Arg1, Arg2>* this_handler)
173 {
174   asio_handler_invoke_helpers::invoke(
175       function, this_handler->handler_);
176 }
177 
178 template <typename Handler, typename Arg1, typename Arg2>
bind_handler(Handler handler,const Arg1 & arg1,const Arg2 & arg2)179 inline binder2<Handler, Arg1, Arg2> bind_handler(Handler handler,
180     const Arg1& arg1, const Arg2& arg2)
181 {
182   return binder2<Handler, Arg1, Arg2>(handler, arg1, arg2);
183 }
184 
185 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
186 class binder3
187 {
188 public:
binder3(const Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3)189   binder3(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
190       const Arg3& arg3)
191     : handler_(handler),
192       arg1_(arg1),
193       arg2_(arg2),
194       arg3_(arg3)
195   {
196   }
197 
binder3(Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3)198   binder3(Handler& handler, const Arg1& arg1, const Arg2& arg2,
199       const Arg3& arg3)
200     : handler_(ASIO_MOVE_CAST(Handler)(handler)),
201       arg1_(arg1),
202       arg2_(arg2),
203       arg3_(arg3)
204   {
205   }
206 
operator ()()207   void operator()()
208   {
209     handler_(static_cast<const Arg1&>(arg1_),
210         static_cast<const Arg2&>(arg2_),
211         static_cast<const Arg3&>(arg3_));
212   }
213 
operator ()() const214   void operator()() const
215   {
216     handler_(arg1_, arg2_, arg3_);
217   }
218 
219 //private:
220   Handler handler_;
221   Arg1 arg1_;
222   Arg2 arg2_;
223   Arg3 arg3_;
224 };
225 
226 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
asio_handler_allocate(std::size_t size,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)227 inline void* asio_handler_allocate(std::size_t size,
228     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
229 {
230   return asio_handler_alloc_helpers::allocate(
231       size, this_handler->handler_);
232 }
233 
234 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
asio_handler_deallocate(void * pointer,std::size_t size,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)235 inline void asio_handler_deallocate(void* pointer, std::size_t size,
236     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
237 {
238   asio_handler_alloc_helpers::deallocate(
239       pointer, size, this_handler->handler_);
240 }
241 
242 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
asio_handler_is_continuation(binder3<Handler,Arg1,Arg2,Arg3> * this_handler)243 inline bool asio_handler_is_continuation(
244     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
245 {
246   return asio_handler_cont_helpers::is_continuation(
247       this_handler->handler_);
248 }
249 
250 template <typename Function, typename Handler, typename Arg1, typename Arg2,
251     typename Arg3>
asio_handler_invoke(Function & function,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)252 inline void asio_handler_invoke(Function& function,
253     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
254 {
255   asio_handler_invoke_helpers::invoke(
256       function, this_handler->handler_);
257 }
258 
259 template <typename Function, typename Handler, typename Arg1, typename Arg2,
260     typename Arg3>
asio_handler_invoke(const Function & function,binder3<Handler,Arg1,Arg2,Arg3> * this_handler)261 inline void asio_handler_invoke(const Function& function,
262     binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
263 {
264   asio_handler_invoke_helpers::invoke(
265       function, this_handler->handler_);
266 }
267 
268 template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
bind_handler(Handler handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3)269 inline binder3<Handler, Arg1, Arg2, Arg3> bind_handler(Handler handler,
270     const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
271 {
272   return binder3<Handler, Arg1, Arg2, Arg3>(handler, arg1, arg2, arg3);
273 }
274 
275 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
276     typename Arg4>
277 class binder4
278 {
279 public:
binder4(const Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4)280   binder4(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
281       const Arg3& arg3, const Arg4& arg4)
282     : handler_(handler),
283       arg1_(arg1),
284       arg2_(arg2),
285       arg3_(arg3),
286       arg4_(arg4)
287   {
288   }
289 
binder4(Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4)290   binder4(Handler& handler, const Arg1& arg1, const Arg2& arg2,
291       const Arg3& arg3, const Arg4& arg4)
292     : handler_(ASIO_MOVE_CAST(Handler)(handler)),
293       arg1_(arg1),
294       arg2_(arg2),
295       arg3_(arg3),
296       arg4_(arg4)
297   {
298   }
299 
operator ()()300   void operator()()
301   {
302     handler_(static_cast<const Arg1&>(arg1_),
303         static_cast<const Arg2&>(arg2_),
304         static_cast<const Arg3&>(arg3_),
305         static_cast<const Arg4&>(arg4_));
306   }
307 
operator ()() const308   void operator()() const
309   {
310     handler_(arg1_, arg2_, arg3_, arg4_);
311   }
312 
313 //private:
314   Handler handler_;
315   Arg1 arg1_;
316   Arg2 arg2_;
317   Arg3 arg3_;
318   Arg4 arg4_;
319 };
320 
321 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
322     typename Arg4>
asio_handler_allocate(std::size_t size,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)323 inline void* asio_handler_allocate(std::size_t size,
324     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
325 {
326   return asio_handler_alloc_helpers::allocate(
327       size, this_handler->handler_);
328 }
329 
330 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
331     typename Arg4>
asio_handler_deallocate(void * pointer,std::size_t size,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)332 inline void asio_handler_deallocate(void* pointer, std::size_t size,
333     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
334 {
335   asio_handler_alloc_helpers::deallocate(
336       pointer, size, this_handler->handler_);
337 }
338 
339 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
340     typename Arg4>
asio_handler_is_continuation(binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)341 inline bool asio_handler_is_continuation(
342     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
343 {
344   return asio_handler_cont_helpers::is_continuation(
345       this_handler->handler_);
346 }
347 
348 template <typename Function, typename Handler, typename Arg1, typename Arg2,
349     typename Arg3, typename Arg4>
asio_handler_invoke(Function & function,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)350 inline void asio_handler_invoke(Function& function,
351     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
352 {
353   asio_handler_invoke_helpers::invoke(
354       function, this_handler->handler_);
355 }
356 
357 template <typename Function, typename Handler, typename Arg1, typename Arg2,
358     typename Arg3, typename Arg4>
asio_handler_invoke(const Function & function,binder4<Handler,Arg1,Arg2,Arg3,Arg4> * this_handler)359 inline void asio_handler_invoke(const Function& function,
360     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
361 {
362   asio_handler_invoke_helpers::invoke(
363       function, this_handler->handler_);
364 }
365 
366 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
367     typename Arg4>
bind_handler(Handler handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4)368 inline binder4<Handler, Arg1, Arg2, Arg3, Arg4> bind_handler(
369     Handler handler, const Arg1& arg1, const Arg2& arg2,
370     const Arg3& arg3, const Arg4& arg4)
371 {
372   return binder4<Handler, Arg1, Arg2, Arg3, Arg4>(handler, arg1, arg2, arg3,
373       arg4);
374 }
375 
376 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
377     typename Arg4, typename Arg5>
378 class binder5
379 {
380 public:
binder5(const Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4,const Arg5 & arg5)381   binder5(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
382       const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
383     : handler_(handler),
384       arg1_(arg1),
385       arg2_(arg2),
386       arg3_(arg3),
387       arg4_(arg4),
388       arg5_(arg5)
389   {
390   }
391 
binder5(Handler & handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4,const Arg5 & arg5)392   binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2,
393       const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
394     : handler_(ASIO_MOVE_CAST(Handler)(handler)),
395       arg1_(arg1),
396       arg2_(arg2),
397       arg3_(arg3),
398       arg4_(arg4),
399       arg5_(arg5)
400   {
401   }
402 
operator ()()403   void operator()()
404   {
405     handler_(static_cast<const Arg1&>(arg1_),
406         static_cast<const Arg2&>(arg2_),
407         static_cast<const Arg3&>(arg3_),
408         static_cast<const Arg4&>(arg4_),
409         static_cast<const Arg5&>(arg5_));
410   }
411 
operator ()() const412   void operator()() const
413   {
414     handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
415   }
416 
417 //private:
418   Handler handler_;
419   Arg1 arg1_;
420   Arg2 arg2_;
421   Arg3 arg3_;
422   Arg4 arg4_;
423   Arg5 arg5_;
424 };
425 
426 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
427     typename Arg4, typename Arg5>
asio_handler_allocate(std::size_t size,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)428 inline void* asio_handler_allocate(std::size_t size,
429     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
430 {
431   return asio_handler_alloc_helpers::allocate(
432       size, this_handler->handler_);
433 }
434 
435 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
436     typename Arg4, typename Arg5>
asio_handler_deallocate(void * pointer,std::size_t size,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)437 inline void asio_handler_deallocate(void* pointer, std::size_t size,
438     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
439 {
440   asio_handler_alloc_helpers::deallocate(
441       pointer, size, this_handler->handler_);
442 }
443 
444 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
445     typename Arg4, typename Arg5>
asio_handler_is_continuation(binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)446 inline bool asio_handler_is_continuation(
447     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
448 {
449   return asio_handler_cont_helpers::is_continuation(
450       this_handler->handler_);
451 }
452 
453 template <typename Function, typename Handler, typename Arg1, typename Arg2,
454     typename Arg3, typename Arg4, typename Arg5>
asio_handler_invoke(Function & function,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)455 inline void asio_handler_invoke(Function& function,
456     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
457 {
458   asio_handler_invoke_helpers::invoke(
459       function, this_handler->handler_);
460 }
461 
462 template <typename Function, typename Handler, typename Arg1, typename Arg2,
463     typename Arg3, typename Arg4, typename Arg5>
asio_handler_invoke(const Function & function,binder5<Handler,Arg1,Arg2,Arg3,Arg4,Arg5> * this_handler)464 inline void asio_handler_invoke(const Function& function,
465     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
466 {
467   asio_handler_invoke_helpers::invoke(
468       function, this_handler->handler_);
469 }
470 
471 template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
472     typename Arg4, typename Arg5>
bind_handler(Handler handler,const Arg1 & arg1,const Arg2 & arg2,const Arg3 & arg3,const Arg4 & arg4,const Arg5 & arg5)473 inline binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5> bind_handler(
474     Handler handler, const Arg1& arg1, const Arg2& arg2,
475     const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
476 {
477   return binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>(handler, arg1, arg2,
478       arg3, arg4, arg5);
479 }
480 
481 } // namespace detail
482 } // namespace asio
483 
484 #include "asio/detail/pop_options.hpp"
485 
486 #endif // ASIO_DETAIL_BIND_HANDLER_HPP
487