1 #include <boost/config.hpp>
2 
3 #if defined(BOOST_MSVC)
4 #pragma warning(disable: 4786)  // identifier truncated in debug info
5 #pragma warning(disable: 4710)  // function not inlined
6 #pragma warning(disable: 4711)  // function selected for automatic inline expansion
7 #pragma warning(disable: 4514)  // unreferenced inline removed
8 #endif
9 
10 //
11 //  bind_test.cpp - monolithic test for bind.hpp
12 //
13 //  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
14 //  Copyright (c) 2001 David Abrahams
15 //
16 // Distributed under the Boost Software License, Version 1.0. (See
17 // accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19 //
20 
21 #include <boost/bind.hpp>
22 #include <boost/ref.hpp>
23 
24 #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
25 #pragma warning(push, 3)
26 #endif
27 
28 #include <iostream>
29 
30 #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
31 #pragma warning(pop)
32 #endif
33 
34 #include <boost/detail/lightweight_test.hpp>
35 
36 //
37 
f_0()38 long f_0()
39 {
40     return 17041L;
41 }
42 
f_1(long a)43 long f_1(long a)
44 {
45     return a;
46 }
47 
f_2(long a,long b)48 long f_2(long a, long b)
49 {
50     return a + 10 * b;
51 }
52 
f_3(long a,long b,long c)53 long f_3(long a, long b, long c)
54 {
55     return a + 10 * b + 100 * c;
56 }
57 
f_4(long a,long b,long c,long d)58 long f_4(long a, long b, long c, long d)
59 {
60     return a + 10 * b + 100 * c + 1000 * d;
61 }
62 
f_5(long a,long b,long c,long d,long e)63 long f_5(long a, long b, long c, long d, long e)
64 {
65     return a + 10 * b + 100 * c + 1000 * d + 10000 * e;
66 }
67 
f_6(long a,long b,long c,long d,long e,long f)68 long f_6(long a, long b, long c, long d, long e, long f)
69 {
70     return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f;
71 }
72 
f_7(long a,long b,long c,long d,long e,long f,long g)73 long f_7(long a, long b, long c, long d, long e, long f, long g)
74 {
75     return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g;
76 }
77 
f_8(long a,long b,long c,long d,long e,long f,long g,long h)78 long f_8(long a, long b, long c, long d, long e, long f, long g, long h)
79 {
80     return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h;
81 }
82 
f_9(long a,long b,long c,long d,long e,long f,long g,long h,long i)83 long f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i)
84 {
85     return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i;
86 }
87 
88 long global_result;
89 
fv_0()90 void fv_0()
91 {
92     global_result = 17041L;
93 }
94 
fv_1(long a)95 void fv_1(long a)
96 {
97     global_result = a;
98 }
99 
fv_2(long a,long b)100 void fv_2(long a, long b)
101 {
102     global_result = a + 10 * b;
103 }
104 
fv_3(long a,long b,long c)105 void fv_3(long a, long b, long c)
106 {
107     global_result = a + 10 * b + 100 * c;
108 }
109 
fv_4(long a,long b,long c,long d)110 void fv_4(long a, long b, long c, long d)
111 {
112     global_result = a + 10 * b + 100 * c + 1000 * d;
113 }
114 
fv_5(long a,long b,long c,long d,long e)115 void fv_5(long a, long b, long c, long d, long e)
116 {
117     global_result = a + 10 * b + 100 * c + 1000 * d + 10000 * e;
118 }
119 
fv_6(long a,long b,long c,long d,long e,long f)120 void fv_6(long a, long b, long c, long d, long e, long f)
121 {
122     global_result = a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f;
123 }
124 
fv_7(long a,long b,long c,long d,long e,long f,long g)125 void fv_7(long a, long b, long c, long d, long e, long f, long g)
126 {
127     global_result = a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g;
128 }
129 
fv_8(long a,long b,long c,long d,long e,long f,long g,long h)130 void fv_8(long a, long b, long c, long d, long e, long f, long g, long h)
131 {
132     global_result = a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h;
133 }
134 
fv_9(long a,long b,long c,long d,long e,long f,long g,long h,long i)135 void fv_9(long a, long b, long c, long d, long e, long f, long g, long h, long i)
136 {
137     global_result = a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i;
138 }
139 
function_test()140 void function_test()
141 {
142     using namespace boost;
143 
144     int const i = 1;
145 
146     BOOST_TEST( bind(f_0)(i) == 17041L );
147     BOOST_TEST( bind(f_1, _1)(i) == 1L );
148     BOOST_TEST( bind(f_2, _1, 2)(i) == 21L );
149     BOOST_TEST( bind(f_3, _1, 2, 3)(i) == 321L );
150     BOOST_TEST( bind(f_4, _1, 2, 3, 4)(i) == 4321L );
151     BOOST_TEST( bind(f_5, _1, 2, 3, 4, 5)(i) == 54321L );
152     BOOST_TEST( bind(f_6, _1, 2, 3, 4, 5, 6)(i) == 654321L );
153     BOOST_TEST( bind(f_7, _1, 2, 3, 4, 5, 6, 7)(i) == 7654321L );
154     BOOST_TEST( bind(f_8, _1, 2, 3, 4, 5, 6, 7, 8)(i) == 87654321L );
155     BOOST_TEST( bind(f_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i) == 987654321L );
156 
157     BOOST_TEST( (bind(fv_0)(i), (global_result == 17041L)) );
158     BOOST_TEST( (bind(fv_1, _1)(i), (global_result == 1L)) );
159     BOOST_TEST( (bind(fv_2, _1, 2)(i), (global_result == 21L)) );
160     BOOST_TEST( (bind(fv_3, _1, 2, 3)(i), (global_result == 321L)) );
161     BOOST_TEST( (bind(fv_4, _1, 2, 3, 4)(i), (global_result == 4321L)) );
162     BOOST_TEST( (bind(fv_5, _1, 2, 3, 4, 5)(i), (global_result == 54321L)) );
163     BOOST_TEST( (bind(fv_6, _1, 2, 3, 4, 5, 6)(i), (global_result == 654321L)) );
164     BOOST_TEST( (bind(fv_7, _1, 2, 3, 4, 5, 6, 7)(i), (global_result == 7654321L)) );
165     BOOST_TEST( (bind(fv_8, _1, 2, 3, 4, 5, 6, 7, 8)(i), (global_result == 87654321L)) );
166     BOOST_TEST( (bind(fv_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i), (global_result == 987654321L)) );
167 }
168 
169 //
170 
171 struct Y
172 {
operator ()Y173     short operator()(short & r) const { return ++r; }
operator ()Y174     int operator()(int a, int b) const { return a + 10 * b; }
operator ()Y175     long operator() (long a, long b, long c) const { return a + 10 * b + 100 * c; }
operator ()Y176     void operator() (long a, long b, long c, long d) const { global_result = a + 10 * b + 100 * c + 1000 * d; }
177 };
178 
function_object_test()179 void function_object_test()
180 {
181     using namespace boost;
182 
183     short i(6);
184 
185     int const k = 3;
186 
187     BOOST_TEST( bind<short>(Y(), ref(i))() == 7 );
188     BOOST_TEST( bind<short>(Y(), ref(i))() == 8 );
189     BOOST_TEST( bind<int>(Y(), i, _1)(k) == 38 );
190     BOOST_TEST( bind<long>(Y(), i, _1, 9)(k) == 938 );
191 
192 #if !defined(__MWERKS__) || (__MWERKS__ > 0x2407)     // Fails for this version of the compiler.
193 
194     global_result = 0;
195     bind<void>(Y(), i, _1, 9, 4)(k);
196     BOOST_TEST( global_result == 4938 );
197 
198 #endif
199 }
200 
function_object_test2()201 void function_object_test2()
202 {
203     using namespace boost;
204 
205     short i(6);
206 
207     int const k = 3;
208 
209     BOOST_TEST( bind(type<short>(), Y(), ref(i))() == 7 );
210     BOOST_TEST( bind(type<short>(), Y(), ref(i))() == 8 );
211     BOOST_TEST( bind(type<int>(), Y(), i, _1)(k) == 38 );
212     BOOST_TEST( bind(type<long>(), Y(), i, _1, 9)(k) == 938 );
213 
214     global_result = 0;
215     bind(type<void>(), Y(), i, _1, 9, 4)(k);
216     BOOST_TEST( global_result == 4938 );
217 }
218 
219 //
220 
221 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
222 
223 struct Z
224 {
225     typedef int result_type;
operator ()Z226     int operator()(int a, int b) const { return a + 10 * b; }
227 };
228 
adaptable_function_object_test()229 void adaptable_function_object_test()
230 {
231     BOOST_TEST( boost::bind(Z(), 7, 4)() == 47 );
232 }
233 
234 #endif
235 
236 //
237 
238 struct X
239 {
240     mutable unsigned int hash;
241 
XX242     X(): hash(0) {}
243 
f0X244     int f0() { f1(17); return 0; }
g0X245     int g0() const { g1(17); return 0; }
246 
f1X247     int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
g1X248     int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
249 
f2X250     int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
g2X251     int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
252 
f3X253     int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
g3X254     int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
255 
f4X256     int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
g4X257     int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
258 
f5X259     int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
g5X260     int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
261 
f6X262     int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
g6X263     int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
264 
f7X265     int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
g7X266     int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
267 
f8X268     int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
g8X269     int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
270 };
271 
272 struct V
273 {
274     mutable unsigned int hash;
275 
VV276     V(): hash(0) {}
277 
f0V278     void f0() { f1(17); }
g0V279     void g0() const { g1(17); }
280 
f1V281     void f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
g1V282     void g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
283 
f2V284     void f2(int a1, int a2) { f1(a1); f1(a2); }
g2V285     void g2(int a1, int a2) const { g1(a1); g1(a2); }
286 
f3V287     void f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
g3V288     void g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
289 
f4V290     void f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
g4V291     void g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
292 
f5V293     void f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
g5V294     void g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
295 
f6V296     void f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
g6V297     void g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
298 
f7V299     void f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
g7V300     void g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
301 
f8V302     void f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
g8V303     void g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
304 };
305 
member_function_test()306 void member_function_test()
307 {
308     using namespace boost;
309 
310     X x;
311 
312     // 0
313 
314     bind(&X::f0, &x)();
315     bind(&X::f0, ref(x))();
316 
317     bind(&X::g0, &x)();
318     bind(&X::g0, x)();
319     bind(&X::g0, ref(x))();
320 
321     // 1
322 
323     bind(&X::f1, &x, 1)();
324     bind(&X::f1, ref(x), 1)();
325 
326     bind(&X::g1, &x, 1)();
327     bind(&X::g1, x, 1)();
328     bind(&X::g1, ref(x), 1)();
329 
330     // 2
331 
332     bind(&X::f2, &x, 1, 2)();
333     bind(&X::f2, ref(x), 1, 2)();
334 
335     bind(&X::g2, &x, 1, 2)();
336     bind(&X::g2, x, 1, 2)();
337     bind(&X::g2, ref(x), 1, 2)();
338 
339     // 3
340 
341     bind(&X::f3, &x, 1, 2, 3)();
342     bind(&X::f3, ref(x), 1, 2, 3)();
343 
344     bind(&X::g3, &x, 1, 2, 3)();
345     bind(&X::g3, x, 1, 2, 3)();
346     bind(&X::g3, ref(x), 1, 2, 3)();
347 
348     // 4
349 
350     bind(&X::f4, &x, 1, 2, 3, 4)();
351     bind(&X::f4, ref(x), 1, 2, 3, 4)();
352 
353     bind(&X::g4, &x, 1, 2, 3, 4)();
354     bind(&X::g4, x, 1, 2, 3, 4)();
355     bind(&X::g4, ref(x), 1, 2, 3, 4)();
356 
357     // 5
358 
359     bind(&X::f5, &x, 1, 2, 3, 4, 5)();
360     bind(&X::f5, ref(x), 1, 2, 3, 4, 5)();
361 
362     bind(&X::g5, &x, 1, 2, 3, 4, 5)();
363     bind(&X::g5, x, 1, 2, 3, 4, 5)();
364     bind(&X::g5, ref(x), 1, 2, 3, 4, 5)();
365 
366     // 6
367 
368     bind(&X::f6, &x, 1, 2, 3, 4, 5, 6)();
369     bind(&X::f6, ref(x), 1, 2, 3, 4, 5, 6)();
370 
371     bind(&X::g6, &x, 1, 2, 3, 4, 5, 6)();
372     bind(&X::g6, x, 1, 2, 3, 4, 5, 6)();
373     bind(&X::g6, ref(x), 1, 2, 3, 4, 5, 6)();
374 
375     // 7
376 
377     bind(&X::f7, &x, 1, 2, 3, 4, 5, 6, 7)();
378     bind(&X::f7, ref(x), 1, 2, 3, 4, 5, 6, 7)();
379 
380     bind(&X::g7, &x, 1, 2, 3, 4, 5, 6, 7)();
381     bind(&X::g7, x, 1, 2, 3, 4, 5, 6, 7)();
382     bind(&X::g7, ref(x), 1, 2, 3, 4, 5, 6, 7)();
383 
384     // 8
385 
386     bind(&X::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8)();
387     bind(&X::f8, ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
388 
389     bind(&X::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8)();
390     bind(&X::g8, x, 1, 2, 3, 4, 5, 6, 7, 8)();
391     bind(&X::g8, ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
392 
393     BOOST_TEST( x.hash == 23558 );
394 }
395 
member_function_void_test()396 void member_function_void_test()
397 {
398     using namespace boost;
399 
400     V v;
401 
402     // 0
403 
404     bind(&V::f0, &v)();
405     bind(&V::f0, ref(v))();
406 
407     bind(&V::g0, &v)();
408     bind(&V::g0, v)();
409     bind(&V::g0, ref(v))();
410 
411     // 1
412 
413     bind(&V::f1, &v, 1)();
414     bind(&V::f1, ref(v), 1)();
415 
416     bind(&V::g1, &v, 1)();
417     bind(&V::g1, v, 1)();
418     bind(&V::g1, ref(v), 1)();
419 
420     // 2
421 
422     bind(&V::f2, &v, 1, 2)();
423     bind(&V::f2, ref(v), 1, 2)();
424 
425     bind(&V::g2, &v, 1, 2)();
426     bind(&V::g2, v, 1, 2)();
427     bind(&V::g2, ref(v), 1, 2)();
428 
429     // 3
430 
431     bind(&V::f3, &v, 1, 2, 3)();
432     bind(&V::f3, ref(v), 1, 2, 3)();
433 
434     bind(&V::g3, &v, 1, 2, 3)();
435     bind(&V::g3, v, 1, 2, 3)();
436     bind(&V::g3, ref(v), 1, 2, 3)();
437 
438     // 4
439 
440     bind(&V::f4, &v, 1, 2, 3, 4)();
441     bind(&V::f4, ref(v), 1, 2, 3, 4)();
442 
443     bind(&V::g4, &v, 1, 2, 3, 4)();
444     bind(&V::g4, v, 1, 2, 3, 4)();
445     bind(&V::g4, ref(v), 1, 2, 3, 4)();
446 
447     // 5
448 
449     bind(&V::f5, &v, 1, 2, 3, 4, 5)();
450     bind(&V::f5, ref(v), 1, 2, 3, 4, 5)();
451 
452     bind(&V::g5, &v, 1, 2, 3, 4, 5)();
453     bind(&V::g5, v, 1, 2, 3, 4, 5)();
454     bind(&V::g5, ref(v), 1, 2, 3, 4, 5)();
455 
456     // 6
457 
458     bind(&V::f6, &v, 1, 2, 3, 4, 5, 6)();
459     bind(&V::f6, ref(v), 1, 2, 3, 4, 5, 6)();
460 
461     bind(&V::g6, &v, 1, 2, 3, 4, 5, 6)();
462     bind(&V::g6, v, 1, 2, 3, 4, 5, 6)();
463     bind(&V::g6, ref(v), 1, 2, 3, 4, 5, 6)();
464 
465     // 7
466 
467     bind(&V::f7, &v, 1, 2, 3, 4, 5, 6, 7)();
468     bind(&V::f7, ref(v), 1, 2, 3, 4, 5, 6, 7)();
469 
470     bind(&V::g7, &v, 1, 2, 3, 4, 5, 6, 7)();
471     bind(&V::g7, v, 1, 2, 3, 4, 5, 6, 7)();
472     bind(&V::g7, ref(v), 1, 2, 3, 4, 5, 6, 7)();
473 
474     // 8
475 
476     bind(&V::f8, &v, 1, 2, 3, 4, 5, 6, 7, 8)();
477     bind(&V::f8, ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
478 
479     bind(&V::g8, &v, 1, 2, 3, 4, 5, 6, 7, 8)();
480     bind(&V::g8, v, 1, 2, 3, 4, 5, 6, 7, 8)();
481     bind(&V::g8, ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
482 
483     BOOST_TEST( v.hash == 23558 );
484 }
485 
nested_bind_test()486 void nested_bind_test()
487 {
488     using namespace boost;
489 
490     int const x = 1;
491     int const y = 2;
492 
493     BOOST_TEST( bind(f_1, bind(f_1, _1))(x) == 1L );
494     BOOST_TEST( bind(f_1, bind(f_2, _1, _2))(x, y) == 21L );
495     BOOST_TEST( bind(f_2, bind(f_1, _1), bind(f_1, _1))(x) == 11L );
496     BOOST_TEST( bind(f_2, bind(f_1, _1), bind(f_1, _2))(x, y) == 21L );
497     BOOST_TEST( bind(f_1, bind(f_0))() == 17041L );
498 
499     BOOST_TEST( (bind(fv_1, bind(f_1, _1))(x), (global_result == 1L)) );
500     BOOST_TEST( (bind(fv_1, bind(f_2, _1, _2))(x, y), (global_result == 21L)) );
501     BOOST_TEST( (bind(fv_2, bind(f_1, _1), bind(f_1, _1))(x), (global_result == 11L)) );
502     BOOST_TEST( (bind(fv_2, bind(f_1, _1), bind(f_1, _2))(x, y), (global_result == 21L)) );
503     BOOST_TEST( (bind(fv_1, bind(f_0))(), (global_result == 17041L)) );
504 }
505 
main()506 int main()
507 {
508     function_test();
509     function_object_test();
510     function_object_test2();
511 
512 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
513     adaptable_function_object_test();
514 #endif
515 
516     member_function_test();
517     member_function_void_test();
518     nested_bind_test();
519 
520     return boost::report_errors();
521 }
522