1 // LAF Base Library
2 // Copyright (c) 2001-2016 David Capello
3 //
4 // This file is released under the terms of the MIT license.
5 // Read LICENSE.txt for more information.
6 
7 #ifndef BASE_BIND_H_INCLUDED
8 #define BASE_BIND_H_INCLUDED
9 #pragma once
10 
11 namespace base {
12 
13 // BindAdapter0_fun
14 template<typename R, typename F>
15 class BindAdapter0_fun
16 {
17   F f;
18 public:
BindAdapter0_fun(const F & f)19   BindAdapter0_fun(const F& f) : f(f) { }
20 
operator()21   R operator()() { return f(); }
22 
23   template<typename A1>
operator()24   R operator()(const A1& a1) { return f(); }
25 
26   template<typename A1, typename A2>
operator()27   R operator()(const A1& a1, const A2& a2) { return f(); }
28 
29   template<typename A1, typename A2, typename A3>
operator()30   R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(); }
31 
32   template<typename A1, typename A2, typename A3, typename A4>
operator()33   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(); }
34 };
35 
36 template<typename F>
37 class BindAdapter0_fun<void, F>
38 {
39   F f;
40 public:
BindAdapter0_fun(const F & f)41   BindAdapter0_fun(const F& f) : f(f) { }
42 
operator()43   void operator()() { f(); }
44 
45   template<typename A1>
operator()46   void operator()(const A1& a1) { f(); }
47 
48   template<typename A1, typename A2>
operator()49   void operator()(const A1& a1, const A2& a2) { f(); }
50 
51   template<typename A1, typename A2, typename A3>
operator()52   void operator()(const A1& a1, const A2& a2, const A3& a3) { f(); }
53 
54   template<typename A1, typename A2, typename A3, typename A4>
operator()55   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(); }
56 };
57 
58 template<typename R, typename F>
59 BindAdapter0_fun<R, F>
Bind(const F & f)60 Bind(const F& f)
61 {
62   return BindAdapter0_fun<R, F>(f);
63 }
64 
65 // BindAdapter0_mem
66 template<typename R, typename T>
67 class BindAdapter0_mem
68 {
69   R (T::*m)();
70   T* t;
71 public:
72   template<typename T2>
BindAdapter0_mem(R (T::* m)(),T2 * t)73   BindAdapter0_mem(R (T::*m)(), T2* t) : m(m), t(t) { }
74 
operator()75   R operator()() { return (t->*m)(); }
76 
77   template <typename A1>
operator()78   R operator()(const A1& a1) { return (t->*m)(); }
79 
80   template <typename A1, typename A2>
operator()81   R operator()(const A1& a1, const A2& a2) { return (t->*m)(); }
82 
83   template <typename A1, typename A2, typename A3>
operator()84   R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(); }
85 
86   template <typename A1, typename A2, typename A3, typename A4>
operator()87   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(); }
88 };
89 
90 template<typename T>
91 class BindAdapter0_mem<void, T>
92 {
93   void (T::*m)();
94   T* t;
95 public:
96   template<typename T2>
BindAdapter0_mem(void (T::* m)(),T2 * t)97   BindAdapter0_mem(void (T::*m)(), T2* t) : m(m), t(t) { }
98 
operator()99   void operator()() { (t->*m)(); }
100 
101   template <typename A1>
operator()102   void operator()(const A1& a1) { (t->*m)(); }
103 
104   template <typename A1, typename A2>
operator()105   void operator()(const A1& a1, const A2& a2) { (t->*m)(); }
106 
107   template <typename A1, typename A2, typename A3>
operator()108   void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(); }
109 
110   template <typename A1, typename A2, typename A3, typename A4>
operator()111   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(); }
112 };
113 
114 template<typename R, typename T, typename T2>
115 BindAdapter0_mem<R, T>
Bind(R (T::* m)(),T2 * t)116 Bind(R (T::*m)(), T2* t)
117 {
118   return BindAdapter0_mem<R, T>(m, t);
119 }
120 
121 // BindAdapter1_fun
122 template<typename R, typename F,
123          typename X1>
124 class BindAdapter1_fun
125 {
126   F f;
127   X1 x1;
128 public:
BindAdapter1_fun(const F & f,X1 x1)129   BindAdapter1_fun(const F& f, X1 x1) : f(f), x1(x1) { }
130 
operator()131   R operator()() { return f(x1); }
132 
133   template<typename A1>
operator()134   R operator()(const A1& a1) { return f(x1); }
135 
136   template<typename A1, typename A2>
operator()137   R operator()(const A1& a1, const A2& a2) { return f(x1); }
138 
139   template<typename A1, typename A2, typename A3>
operator()140   R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1); }
141 
142   template<typename A1, typename A2, typename A3, typename A4>
operator()143   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1); }
144 };
145 
146 template<typename F,
147          typename X1>
148 class BindAdapter1_fun<void, F, X1>
149 {
150   F f;
151   X1 x1;
152 public:
BindAdapter1_fun(const F & f,X1 x1)153   BindAdapter1_fun(const F& f, X1 x1) : f(f), x1(x1) { }
154 
operator()155   void operator()() { f(x1); }
156 
157   template<typename A1>
operator()158   void operator()(const A1& a1) { f(x1); }
159 
160   template<typename A1, typename A2>
operator()161   void operator()(const A1& a1, const A2& a2) { f(x1); }
162 
163   template<typename A1, typename A2, typename A3>
operator()164   void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1); }
165 
166   template<typename A1, typename A2, typename A3, typename A4>
operator()167   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1); }
168 };
169 
170 template<typename R, typename F,
171          typename X1>
172 BindAdapter1_fun<R, F, X1>
Bind(const F & f,X1 x1)173 Bind(const F& f, X1 x1)
174 {
175   return BindAdapter1_fun<R, F, X1>(f, x1);
176 }
177 
178 // BindAdapter1_mem
179 template<typename R, typename T,
180          typename B1,
181          typename X1>
182 class BindAdapter1_mem
183 {
184   R (T::*m)(B1);
185   T* t;
186   X1 x1;
187 public:
188   template<typename T2>
BindAdapter1_mem(R (T::* m)(B1),T2 * t,X1 x1)189   BindAdapter1_mem(R (T::*m)(B1), T2* t, X1 x1) : m(m), t(t), x1(x1) { }
190 
operator()191   R operator()() { return (t->*m)(x1); }
192 
193   template <typename A1>
operator()194   R operator()(const A1& a1) { return (t->*m)(x1); }
195 
196   template <typename A1, typename A2>
operator()197   R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1); }
198 
199   template <typename A1, typename A2, typename A3>
operator()200   R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1); }
201 
202   template <typename A1, typename A2, typename A3, typename A4>
operator()203   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1); }
204 };
205 
206 template<typename T,
207          typename B1,
208          typename X1>
209 class BindAdapter1_mem<void, T, B1, X1>
210 {
211   void (T::*m)(B1);
212   T* t;
213   X1 x1;
214 public:
215   template<typename T2>
BindAdapter1_mem(void (T::* m)(B1),T2 * t,X1 x1)216   BindAdapter1_mem(void (T::*m)(B1), T2* t, X1 x1) : m(m), t(t), x1(x1) { }
217 
operator()218   void operator()() { (t->*m)(x1); }
219 
220   template <typename A1>
operator()221   void operator()(const A1& a1) { (t->*m)(x1); }
222 
223   template <typename A1, typename A2>
operator()224   void operator()(const A1& a1, const A2& a2) { (t->*m)(x1); }
225 
226   template <typename A1, typename A2, typename A3>
operator()227   void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1); }
228 
229   template <typename A1, typename A2, typename A3, typename A4>
operator()230   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1); }
231 };
232 
233 template<typename R, typename T, typename T2,
234          typename B1, typename X1>
235 BindAdapter1_mem<R, T, B1, X1>
Bind(R (T::* m)(B1),T2 * t,X1 x1)236 Bind(R (T::*m)(B1), T2* t, X1 x1)
237 {
238   return BindAdapter1_mem<R, T, B1, X1>(m, t, x1);
239 }
240 
241 // BindAdapter2_fun
242 template<typename R, typename F,
243          typename X1, typename X2>
244 class BindAdapter2_fun
245 {
246   F f;
247   X1 x1;
248   X2 x2;
249 public:
BindAdapter2_fun(const F & f,X1 x1,X2 x2)250   BindAdapter2_fun(const F& f, X1 x1, X2 x2) : f(f), x1(x1), x2(x2) { }
251 
operator()252   R operator()() { return f(x1, x2); }
253 
254   template<typename A1>
operator()255   R operator()(const A1& a1) { return f(x1, x2); }
256 
257   template<typename A1, typename A2>
operator()258   R operator()(const A1& a1, const A2& a2) { return f(x1, x2); }
259 
260   template<typename A1, typename A2, typename A3>
operator()261   R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1, x2); }
262 
263   template<typename A1, typename A2, typename A3, typename A4>
operator()264   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1, x2); }
265 };
266 
267 template<typename F,
268          typename X1, typename X2>
269 class BindAdapter2_fun<void, F, X1, X2>
270 {
271   F f;
272   X1 x1;
273   X2 x2;
274 public:
BindAdapter2_fun(const F & f,X1 x1,X2 x2)275   BindAdapter2_fun(const F& f, X1 x1, X2 x2) : f(f), x1(x1), x2(x2) { }
276 
operator()277   void operator()() { f(x1, x2); }
278 
279   template<typename A1>
operator()280   void operator()(const A1& a1) { f(x1, x2); }
281 
282   template<typename A1, typename A2>
operator()283   void operator()(const A1& a1, const A2& a2) { f(x1, x2); }
284 
285   template<typename A1, typename A2, typename A3>
operator()286   void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1, x2); }
287 
288   template<typename A1, typename A2, typename A3, typename A4>
operator()289   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1, x2); }
290 };
291 
292 template<typename R, typename F,
293          typename X1, typename X2>
294 BindAdapter2_fun<R, F, X1, X2>
Bind(const F & f,X1 x1,X2 x2)295 Bind(const F& f, X1 x1, X2 x2)
296 {
297   return BindAdapter2_fun<R, F, X1, X2>(f, x1, x2);
298 }
299 
300 // BindAdapter2_mem
301 template<typename R, typename T,
302          typename B1, typename B2,
303          typename X1, typename X2>
304 class BindAdapter2_mem
305 {
306   R (T::*m)(B1, B2);
307   T* t;
308   X1 x1;
309   X2 x2;
310 public:
311   template<typename T2>
BindAdapter2_mem(R (T::* m)(B1,B2),T2 * t,X1 x1,X2 x2)312   BindAdapter2_mem(R (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { }
313 
operator()314   R operator()() { return (t->*m)(x1, x2); }
315 
316   template<typename A1>
operator()317   R operator()(const A1& a1) { return (t->*m)(x1, x2); }
318 
319   template<typename A1, typename A2>
operator()320   R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1, x2); }
321 
322   template<typename A1, typename A2, typename A3>
operator()323   R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1, x2); }
324 
325   template<typename A1, typename A2, typename A3, typename A4>
operator()326   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1, x2); }
327 };
328 
329 template<typename T,
330          typename B1, typename B2,
331          typename X1, typename X2>
332 class BindAdapter2_mem<void, T, B1, B2, X1, X2>
333 {
334   void (T::*m)(B1, B2);
335   T* t;
336   X1 x1;
337   X2 x2;
338 public:
339   template<typename T2>
BindAdapter2_mem(void (T::* m)(B1,B2),T2 * t,X1 x1,X2 x2)340   BindAdapter2_mem(void (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { }
341 
operator()342   void operator()() { (t->*m)(x1, x2); }
343 
344   template<typename A1>
operator()345   void operator()(const A1& a1) { (t->*m)(x1, x2); }
346 
347   template<typename A1, typename A2>
operator()348   void operator()(const A1& a1, const A2& a2) { (t->*m)(x1, x2); }
349 
350   template<typename A1, typename A2, typename A3>
operator()351   void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1, x2); }
352 
353   template<typename A1, typename A2, typename A3, typename A4>
operator()354   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1, x2); }
355 };
356 
357 template<typename R, typename T, typename T2, typename B1, typename B2, typename X1, typename X2>
358 BindAdapter2_mem<R, T, B1, B2, X1, X2>
Bind(R (T::* m)(B1,B2),T2 * t,X1 x1,X2 x2)359 Bind(R (T::*m)(B1, B2), T2* t, X1 x1, X2 x2)
360 {
361   return BindAdapter2_mem<R, T, B1, B2, X1, X2>(m, t, x1, x2);
362 }
363 
364 // BindAdapter3_fun
365 template<typename R, typename F,
366          typename X1, typename X2, typename X3>
367 class BindAdapter3_fun
368 {
369   F f;
370   X1 x1;
371   X2 x2;
372   X3 x3;
373 public:
BindAdapter3_fun(const F & f,X1 x1,X2 x2,X3 x3)374   BindAdapter3_fun(const F& f, X1 x1, X2 x2, X3 x3) : f(f), x1(x1), x2(x2), x3(x3) { }
375 
operator()376   R operator()() { return f(x1, x2, x3); }
377 
378   template<typename A1>
operator()379   R operator()(const A1& a1) { return f(x1, x2, x3); }
380 
381   template<typename A1, typename A2>
operator()382   R operator()(const A1& a1, const A2& a2) { return f(x1, x2, x3); }
383 
384   template<typename A1, typename A2, typename A3>
operator()385   R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1, x2, x3); }
386 
387   template<typename A1, typename A2, typename A3, typename A4>
operator()388   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1, x2, x3); }
389 };
390 
391 template<typename F,
392          typename X1, typename X2, typename X3>
393 class BindAdapter3_fun<void, F, X1, X2, X3>
394 {
395   F f;
396   X1 x1;
397   X2 x2;
398   X3 x3;
399 public:
BindAdapter3_fun(const F & f,X1 x1,X2 x2,X3 x3)400   BindAdapter3_fun(const F& f, X1 x1, X2 x2, X3 x3) : f(f), x1(x1), x2(x2), x3(x3) { }
401 
operator()402   void operator()() { f(x1, x2, x3); }
403 
404   template<typename A1>
operator()405   void operator()(const A1& a1) { f(x1, x2, x3); }
406 
407   template<typename A1, typename A2>
operator()408   void operator()(const A1& a1, const A2& a2) { f(x1, x2, x3); }
409 
410   template<typename A1, typename A2, typename A3>
operator()411   void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1, x2, x3); }
412 
413   template<typename A1, typename A2, typename A3, typename A4>
operator()414   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1, x2, x3); }
415 };
416 
417 template<typename R, typename F,
418          typename X1, typename X2, typename X3>
419 BindAdapter3_fun<R, F, X1, X2, X3>
Bind(const F & f,X1 x1,X2 x2,X3 x3)420 Bind(const F& f, X1 x1, X2 x2, X3 x3)
421 {
422   return BindAdapter3_fun<R, F, X1, X2, X3>(f, x1, x2, x3);
423 }
424 
425 // BindAdapter3_mem
426 template<typename R, typename T,
427          typename B1, typename B2, typename B3,
428            typename X1, typename X2, typename X3>
429 class BindAdapter3_mem
430 {
431   R (T::*m)(B1, B2, B3);
432   T* t;
433   X1 x1;
434   X2 x2;
435   X3 x3;
436 public:
437   template<typename T2>
BindAdapter3_mem(R (T::* m)(B1,B2,B3),T2 * t,X1 x1,X2 x2,X3 x3)438   BindAdapter3_mem(R (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2, X3 x3) : m(m), t(t), x1(x1), x2(x2), x3(x3) { }
439 
operator()440   R operator()() { return (t->*m)(x1, x2, x3); }
441 
442   template<typename A1>
operator()443   R operator()(const A1& a1) { return (t->*m)(x1, x2, x3); }
444 
445   template<typename A1, typename A2>
operator()446   R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1, x2, x3); }
447 
448   template<typename A1, typename A2, typename A3>
operator()449   R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1, x2, x3); }
450 
451   template<typename A1, typename A2, typename A3, typename A4>
operator()452   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1, x2, x3); }
453 };
454 
455 template<typename T,
456          typename B1, typename B2, typename B3,
457          typename X1, typename X2, typename X3>
458 class BindAdapter3_mem<void, T, B1, B2, B3, X1, X2, X3>
459 {
460   void (T::*m)(B1, B2, B3);
461   T* t;
462   X1 x1;
463   X2 x2;
464   X3 x3;
465 public:
466   template<typename T2>
BindAdapter3_mem(void (T::* m)(B1,B2,B3),T2 * t,X1 x1,X2 x2,X3 x3)467   BindAdapter3_mem(void (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2, X3 x3) : m(m), t(t), x1(x1), x2(x2), x3(x3) { }
468 
operator()469   void operator()() { (t->*m)(x1, x2, x3); }
470 
471   template<typename A1>
operator()472   void operator()(const A1& a1) { (t->*m)(x1, x2, x3); }
473 
474   template<typename A1, typename A2>
operator()475   void operator()(const A1& a1, const A2& a2) { (t->*m)(x1, x2, x3); }
476 
477   template<typename A1, typename A2, typename A3>
operator()478   void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1, x2, x3); }
479 
480   template<typename A1, typename A2, typename A3, typename A4>
operator()481   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1, x2, x3); }
482 };
483 
484 template<typename R, typename T, typename T2,
485          typename B1, typename B2, typename B3,
486          typename X1, typename X2, typename X3>
487 BindAdapter3_mem<R, T, B1, B2, B3, X1, X2, X3>
Bind(R (T::* m)(B1,B2,B3),T2 * t,X1 x1,X2 x2,X3 x3)488 Bind(R (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2, X3 x3)
489 {
490   return BindAdapter3_mem<R, T, B1, B2, B3, X1, X2, X3>(m, t, x1, x2, x3);
491 }
492 
493 
494 // BindAdapter4_fun
495 template<typename R, typename F,
496          typename X1, typename X2, typename X3, typename X4>
497 class BindAdapter4_fun
498 {
499   F f;
500   X1 x1;
501   X2 x2;
502   X3 x3;
503   X4 x4;
504 public:
BindAdapter4_fun(const F & f,X1 x1,X2 x2,X3 x3,X4 x4)505   BindAdapter4_fun(const F& f, X1 x1, X2 x2, X3 x3, X4 x4) : f(f), x1(x1), x2(x2), x3(x3), x4(x4) { }
506 
operator()507   R operator()() { return f(x1, x2, x3, x4); }
508 
509   template<typename A1>
operator()510   R operator()(const A1& a1) { return f(x1, x2, x3, x4); }
511 
512   template<typename A1, typename A2>
operator()513   R operator()(const A1& a1, const A2& a2) { return f(x1, x2, x3, x4); }
514 
515   template<typename A1, typename A2, typename A3>
operator()516   R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1, x2, x3, x4); }
517 
518   template<typename A1, typename A2, typename A3, typename A4>
operator()519   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1, x2, x3, x4); }
520 };
521 
522 template<typename F,
523          typename X1, typename X2, typename X3, typename X4>
524 class BindAdapter4_fun<void, F, X1, X2, X3, X4>
525 {
526   F f;
527   X1 x1;
528   X2 x2;
529   X3 x3;
530   X4 x4;
531 public:
BindAdapter4_fun(const F & f,X1 x1,X2 x2,X3 x3,X4 x4)532   BindAdapter4_fun(const F& f, X1 x1, X2 x2, X3 x3, X4 x4) : f(f), x1(x1), x2(x2), x3(x3), x4(x4) { }
533 
operator()534   void operator()() { f(x1, x2, x3, x4); }
535 
536   template<typename A1>
operator()537   void operator()(const A1& a1) { f(x1, x2, x3, x4); }
538 
539   template<typename A1, typename A2>
operator()540   void operator()(const A1& a1, const A2& a2) { f(x1, x2, x3, x4); }
541 
542   template<typename A1, typename A2, typename A3>
operator()543   void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1, x2, x3, x4); }
544 
545   template<typename A1, typename A2, typename A3, typename A4>
operator()546   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1, x2, x3, x4); }
547 };
548 
549 template<typename R, typename F,
550          typename X1, typename X2, typename X3, typename X4>
551 BindAdapter4_fun<R, F, X1, X2, X3, X4>
Bind(const F & f,X1 x1,X2 x2,X3 x3,X4 x4)552 Bind(const F& f, X1 x1, X2 x2, X3 x3, X4 x4)
553 {
554   return BindAdapter4_fun<R, F, X1, X2, X3, X4>(f, x1, x2, x3, x4);
555 }
556 
557 // BindAdapter4_mem
558 template<typename R, typename T,
559          typename B1, typename B2, typename B3, typename B4,
560          typename X1, typename X2, typename X3, typename X4>
561 class BindAdapter4_mem
562 {
563   R (T::*m)(B1, B2, B3, B4);
564   T* t;
565   X1 x1;
566   X2 x2;
567   X3 x3;
568   X4 x4;
569 public:
570   template<typename T2>
BindAdapter4_mem(R (T::* m)(B1,B2,B3,B4),T2 * t,X1 x1,X2 x2,X3 x3,X4 x4)571   BindAdapter4_mem(R (T::*m)(B1, B2, B3, B4), T2* t, X1 x1, X2 x2, X3 x3, X4 x4)
572     : m(m), t(t), x1(x1), x2(x2), x3(x3), x4(x4) { }
573 
operator()574   R operator()() { return (t->*m)(x1, x2, x3, x4); }
575 
576   template<typename A1>
operator()577   R operator()(const A1& a1) { return (t->*m)(x1, x2, x3, x4); }
578 
579   template<typename A1, typename A2>
operator()580   R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1, x2, x3, x4); }
581 
582   template<typename A1, typename A2, typename A3>
operator()583   R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1, x2, x3, x4); }
584 
585   template<typename A1, typename A2, typename A3, typename A4>
operator()586   R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1, x2, x3, x4); }
587 };
588 
589 template<typename T,
590          typename B1, typename B2, typename B3, typename B4,
591          typename X1, typename X2, typename X3, typename X4>
592 class BindAdapter4_mem<void, T, B1, B2, B3, B4, X1, X2, X3, X4>
593 {
594   void (T::*m)(B1, B2, B3, B4);
595   T* t;
596   X1 x1;
597   X2 x2;
598   X3 x3;
599   X4 x4;
600 public:
601   template<typename T2>
BindAdapter4_mem(void (T::* m)(B1,B2,B3),T2 * t,X1 x1,X2 x2,X3 x3,X4 x4)602   BindAdapter4_mem(void (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2, X3 x3, X4 x4)
603     : m(m), t(t), x1(x1), x2(x2), x3(x3), x4(x4) { }
604 
operator()605   void operator()() { (t->*m)(x1, x2, x3, x4); }
606 
607   template<typename A1>
operator()608   void operator()(const A1& a1) { (t->*m)(x1, x2, x3, x4); }
609 
610   template<typename A1, typename A2>
operator()611   void operator()(const A1& a1, const A2& a2) { (t->*m)(x1, x2, x3, x4); }
612 
613   template<typename A1, typename A2, typename A3>
operator()614   void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1, x2, x3, x4); }
615 
616   template<typename A1, typename A2, typename A3, typename A4>
operator()617   void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1, x2, x3, x4); }
618 };
619 
620 template<typename R, typename T, typename T2,
621          typename B1, typename B2, typename B3, typename B4,
622          typename X1, typename X2, typename X3, typename X4>
623 BindAdapter4_mem<R, T, B1, B2, B3, B4, X1, X2, X3, X4>
Bind(R (T::* m)(B1,B2,B3,B4),T2 * t,X1 x1,X2 x2,X3 x3,X4 x4)624 Bind(R (T::*m)(B1, B2, B3, B4), T2* t, X1 x1, X2 x2, X3 x3, X4 x4)
625 {
626   return BindAdapter4_mem<R, T, B1, B2, B3, B4, X1, X2, X3, X4>(m, t, x1, x2, x3, x4);
627 }
628 
629 // Helper class to holds references as pointers (to avoid copying the
630 // original object).
631 template<class T>
632 class RefWrapper
633 {
634   T* ptr;
635 public:
RefWrapper(T & ref)636   RefWrapper(T& ref) : ptr(&ref) { }
637   operator T&() const { return *ptr; }
638 };
639 
640 // Creates RefWrappers, useful to wrap arguments that have to be
641 // passed as a reference when you use Bind.
642 template<class T>
Ref(T & ref)643 RefWrapper<T> Ref(T& ref)
644 {
645   return RefWrapper<T>(ref);
646 }
647 
648 } // namespace base
649 
650 #endif
651