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
22namespace asio {
23namespace detail {
24
25template <typename Handler, typename Arg1>
26class binder1
27{
28public:
29  binder1(const Handler& handler, const Arg1& arg1)
30    : handler_(handler),
31      arg1_(arg1)
32  {
33  }
34
35  binder1(Handler& handler, const Arg1& arg1)
36    : handler_(ASIO_MOVE_CAST(Handler)(handler)),
37      arg1_(arg1)
38  {
39  }
40
41  void operator()()
42  {
43    handler_(static_cast<const Arg1&>(arg1_));
44  }
45
46  void operator()() const
47  {
48    handler_(arg1_);
49  }
50
51//private:
52  Handler handler_;
53  Arg1 arg1_;
54};
55
56template <typename Handler, typename Arg1>
57inline 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
64template <typename Handler, typename Arg1>
65inline 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
72template <typename Handler, typename Arg1>
73inline 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
80template <typename Function, typename Handler, typename Arg1>
81inline 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
88template <typename Function, typename Handler, typename Arg1>
89inline 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
96template <typename Handler, typename Arg1>
97inline binder1<Handler, Arg1> bind_handler(Handler handler,
98    const Arg1& arg1)
99{
100  return binder1<Handler, Arg1>(handler, arg1);
101}
102
103template <typename Handler, typename Arg1, typename Arg2>
104class binder2
105{
106public:
107  binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2)
108    : handler_(handler),
109      arg1_(arg1),
110      arg2_(arg2)
111  {
112  }
113
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
121  void operator()()
122  {
123    handler_(static_cast<const Arg1&>(arg1_),
124        static_cast<const Arg2&>(arg2_));
125  }
126
127  void operator()() const
128  {
129    handler_(arg1_, arg2_);
130  }
131
132//private:
133  Handler handler_;
134  Arg1 arg1_;
135  Arg2 arg2_;
136};
137
138template <typename Handler, typename Arg1, typename Arg2>
139inline 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
146template <typename Handler, typename Arg1, typename Arg2>
147inline 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
154template <typename Handler, typename Arg1, typename Arg2>
155inline 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
162template <typename Function, typename Handler, typename Arg1, typename Arg2>
163inline 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
170template <typename Function, typename Handler, typename Arg1, typename Arg2>
171inline 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
178template <typename Handler, typename Arg1, typename Arg2>
179inline 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
185template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
186class binder3
187{
188public:
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
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
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
214  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
226template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
227inline 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
234template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
235inline 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
242template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
243inline 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
250template <typename Function, typename Handler, typename Arg1, typename Arg2,
251    typename Arg3>
252inline 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
259template <typename Function, typename Handler, typename Arg1, typename Arg2,
260    typename Arg3>
261inline 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
268template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
269inline 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
275template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
276    typename Arg4>
277class binder4
278{
279public:
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
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
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
308  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
321template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
322    typename Arg4>
323inline 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
330template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
331    typename Arg4>
332inline 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
339template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
340    typename Arg4>
341inline 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
348template <typename Function, typename Handler, typename Arg1, typename Arg2,
349    typename Arg3, typename Arg4>
350inline 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
357template <typename Function, typename Handler, typename Arg1, typename Arg2,
358    typename Arg3, typename Arg4>
359inline 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
366template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
367    typename Arg4>
368inline 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
376template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
377    typename Arg4, typename Arg5>
378class binder5
379{
380public:
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
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
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
412  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
426template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
427    typename Arg4, typename Arg5>
428inline 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
435template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
436    typename Arg4, typename Arg5>
437inline 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
444template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
445    typename Arg4, typename Arg5>
446inline 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
453template <typename Function, typename Handler, typename Arg1, typename Arg2,
454    typename Arg3, typename Arg4, typename Arg5>
455inline 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
462template <typename Function, typename Handler, typename Arg1, typename Arg2,
463    typename Arg3, typename Arg4, typename Arg5>
464inline 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
471template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
472    typename Arg4, typename Arg5>
473inline 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