Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/function/test/function_test.cpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 13.0 KB
Line 
1// Boost.Function library
2
3//  Copyright Douglas Gregor 2001-2003. Use, modification and
4//  distribution is subject to the Boost Software License, Version
5//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6//  http://www.boost.org/LICENSE_1_0.txt)
7
8// For more information, see http://www.boost.org
9
10#include <boost/test/minimal.hpp>
11#include <boost/function.hpp>
12#include <functional>
13#include <string>
14#include <utility>
15
16using namespace boost;
17using namespace std;
18
19int global_int;
20
21struct write_five_obj { void operator()() const { global_int = 5; } };
22struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
23static void write_five() { global_int = 5; }
24static void write_three() { global_int = 3; }
25struct generate_five_obj { int operator()() const { return 5; } };
26struct generate_three_obj { int operator()() const { return 3; } };
27static int generate_five() { return 5; }
28static int generate_three() { return 3; }
29static string identity_str(const string& s) { return s; }
30static string string_cat(const string& s1, const string& s2) { return s1+s2; }
31static int sum_ints(int x, int y) { return x+y; }
32
33struct write_const_1_nonconst_2
34{
35  void operator()() { global_int = 2; }
36  void operator()() const { global_int = 1; }
37};
38
39struct add_to_obj
40{
41  add_to_obj(int v) : value(v) {}
42
43  int operator()(int x) const { return value + x; }
44
45  int value;
46};
47
48static void
49test_zero_args()
50{
51  typedef function<void ()> func_void_type;
52
53  write_five_obj five;
54  write_three_obj three;
55
56  // Default construction
57  func_void_type v1;
58  BOOST_CHECK(v1.empty());
59
60  // Assignment to an empty function
61  v1 = five;
62  BOOST_CHECK(v1 != 0);
63
64  // Invocation of a function
65  global_int = 0;
66  v1();
67  BOOST_CHECK(global_int == 5);
68
69  // clear() method
70  v1.clear();
71  BOOST_CHECK(v1 == 0);
72
73  // Assignment to an empty function
74  v1 = three;
75  BOOST_CHECK(!v1.empty());
76
77  // Invocation and self-assignment
78  global_int = 0;
79  v1 = v1;
80  v1();
81  BOOST_CHECK(global_int == 3);
82
83  // Assignment to a non-empty function
84  v1 = five;
85
86  // Invocation and self-assignment
87  global_int = 0;
88  v1 = (v1);
89  v1();
90  BOOST_CHECK(global_int == 5);
91
92  // clear
93  v1 = 0;
94  BOOST_CHECK(0 == v1);
95
96  // Assignment to an empty function from a free function
97  v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
98  BOOST_CHECK(0 != v1);
99
100  // Invocation
101  global_int = 0;
102  v1();
103  BOOST_CHECK(global_int == 5);
104
105  // Assignment to a non-empty function from a free function
106  v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
107  BOOST_CHECK(!v1.empty());
108
109  // Invocation
110  global_int = 0;
111  v1();
112  BOOST_CHECK(global_int == 3);
113
114  // Assignment
115  v1 = five;
116  BOOST_CHECK(!v1.empty());
117
118  // Invocation
119  global_int = 0;
120  v1();
121  BOOST_CHECK(global_int == 5);
122
123  // Assignment to a non-empty function from a free function
124  v1 = &write_three;
125  BOOST_CHECK(!v1.empty());
126
127  // Invocation
128  global_int = 0;
129  v1();
130  BOOST_CHECK(global_int == 3);
131
132  // Construction from another function (that is empty)
133  v1.clear();
134  func_void_type v2(v1);
135  BOOST_CHECK(!v2? true : false);
136
137  // Assignment to an empty function
138  v2 = three;
139  BOOST_CHECK(!v2.empty());
140
141  // Invocation
142  global_int = 0;
143  v2();
144  BOOST_CHECK(global_int == 3);
145
146  // Assignment to a non-empty function
147  v2 = (five);
148
149  // Invocation
150  global_int = 0;
151  v2();
152  BOOST_CHECK(global_int == 5);
153
154  v2.clear();
155  BOOST_CHECK(v2.empty());
156
157  // Assignment to an empty function from a free function
158  v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
159  BOOST_CHECK(v2? true : false);
160
161  // Invocation
162  global_int = 0;
163  v2();
164  BOOST_CHECK(global_int == 5);
165
166  // Assignment to a non-empty function from a free function
167  v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
168  BOOST_CHECK(!v2.empty());
169
170  // Invocation
171  global_int = 0;
172  v2();
173  BOOST_CHECK(global_int == 3);
174
175  // Swapping
176  v1 = five;
177  swap(v1, v2);
178  v2();
179  BOOST_CHECK(global_int == 5);
180  v1();
181  BOOST_CHECK(global_int == 3);
182  swap(v1, v2);
183  v1.clear();
184
185  // Assignment
186  v2 = five;
187  BOOST_CHECK(!v2.empty());
188
189  // Invocation
190  global_int = 0;
191  v2();
192  BOOST_CHECK(global_int == 5);
193
194  // Assignment to a non-empty function from a free function
195  v2 = &write_three;
196  BOOST_CHECK(!v2.empty());
197
198  // Invocation
199  global_int = 0;
200  v2();
201  BOOST_CHECK(global_int == 3);
202
203  // Assignment to a function from an empty function
204  v2 = v1;
205  BOOST_CHECK(v2.empty());
206
207  // Assignment to a function from a function with a functor
208  v1 = three;
209  v2 = v1;
210  BOOST_CHECK(!v1.empty());
211  BOOST_CHECK(!v2.empty());
212
213  // Invocation
214  global_int = 0;
215  v1();
216  BOOST_CHECK(global_int == 3);
217  global_int = 0;
218  v2();
219  BOOST_CHECK(global_int == 3);
220
221  // Assign to a function from a function with a function
222  v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
223  v1 = v2;
224  BOOST_CHECK(!v1.empty());
225  BOOST_CHECK(!v2.empty());
226  global_int = 0;
227  v1();
228  BOOST_CHECK(global_int == 5);
229  global_int = 0;
230  v2();
231  BOOST_CHECK(global_int == 5);
232
233  // Construct a function given another function containing a function
234  func_void_type v3(v1);
235
236  // Invocation of a function
237  global_int = 0;
238  v3();
239  BOOST_CHECK(global_int == 5);
240
241  // clear() method
242  v3.clear();
243  BOOST_CHECK(!v3? true : false);
244
245  // Assignment to an empty function
246  v3 = three;
247  BOOST_CHECK(!v3.empty());
248
249  // Invocation
250  global_int = 0;
251  v3();
252  BOOST_CHECK(global_int == 3);
253
254  // Assignment to a non-empty function
255  v3 = five;
256
257  // Invocation
258  global_int = 0;
259  v3();
260  BOOST_CHECK(global_int == 5);
261
262  // clear()
263  v3.clear();
264  BOOST_CHECK(v3.empty());
265
266  // Assignment to an empty function from a free function
267  v3 = &write_five;
268  BOOST_CHECK(!v3.empty());
269
270  // Invocation
271  global_int = 0;
272  v3();
273  BOOST_CHECK(global_int == 5);
274
275  // Assignment to a non-empty function from a free function
276  v3 = &write_three;
277  BOOST_CHECK(!v3.empty());
278
279  // Invocation
280  global_int = 0;
281  v3();
282  BOOST_CHECK(global_int == 3);
283
284  // Assignment
285  v3 = five;
286  BOOST_CHECK(!v3.empty());
287
288  // Invocation
289  global_int = 0;
290  v3();
291  BOOST_CHECK(global_int == 5);
292
293  // Construction of a function from a function containing a functor
294  func_void_type v4(v3);
295
296  // Invocation of a function
297  global_int = 0;
298  v4();
299  BOOST_CHECK(global_int == 5);
300
301  // clear() method
302  v4.clear();
303  BOOST_CHECK(v4.empty());
304
305  // Assignment to an empty function
306  v4 = three;
307  BOOST_CHECK(!v4.empty());
308
309  // Invocation
310  global_int = 0;
311  v4();
312  BOOST_CHECK(global_int == 3);
313
314  // Assignment to a non-empty function
315  v4 = five;
316
317  // Invocation
318  global_int = 0;
319  v4();
320  BOOST_CHECK(global_int == 5);
321
322  // clear()
323  v4.clear();
324  BOOST_CHECK(v4.empty());
325
326  // Assignment to an empty function from a free function
327  v4 = &write_five;
328  BOOST_CHECK(!v4.empty());
329
330  // Invocation
331  global_int = 0;
332  v4();
333  BOOST_CHECK(global_int == 5);
334
335  // Assignment to a non-empty function from a free function
336  v4 = &write_three;
337  BOOST_CHECK(!v4.empty());
338
339  // Invocation
340  global_int = 0;
341  v4();
342  BOOST_CHECK(global_int == 3);
343
344  // Assignment
345  v4 = five;
346  BOOST_CHECK(!v4.empty());
347
348  // Invocation
349  global_int = 0;
350  v4();
351  BOOST_CHECK(global_int == 5);
352
353  // Construction of a function from a functor
354  func_void_type v5(five);
355
356  // Invocation of a function
357  global_int = 0;
358  v5();
359  BOOST_CHECK(global_int == 5);
360
361  // clear() method
362  v5.clear();
363  BOOST_CHECK(v5.empty());
364
365  // Assignment to an empty function
366  v5 = three;
367  BOOST_CHECK(!v5.empty());
368
369  // Invocation
370  global_int = 0;
371  v5();
372  BOOST_CHECK(global_int == 3);
373
374  // Assignment to a non-empty function
375  v5 = five;
376
377  // Invocation
378  global_int = 0;
379  v5();
380  BOOST_CHECK(global_int == 5);
381
382  // clear()
383  v5.clear();
384  BOOST_CHECK(v5.empty());
385
386  // Assignment to an empty function from a free function
387  v5 = &write_five;
388  BOOST_CHECK(!v5.empty());
389
390  // Invocation
391  global_int = 0;
392  v5();
393  BOOST_CHECK(global_int == 5);
394
395  // Assignment to a non-empty function from a free function
396  v5 = &write_three;
397  BOOST_CHECK(!v5.empty());
398
399  // Invocation
400  global_int = 0;
401  v5();
402  BOOST_CHECK(global_int == 3);
403
404  // Assignment
405  v5 = five;
406  BOOST_CHECK(!v5.empty());
407
408  // Invocation
409  global_int = 0;
410  v5();
411  BOOST_CHECK(global_int == 5);
412
413  // Construction of a function from a function
414  func_void_type v6(&write_five);
415
416  // Invocation of a function
417  global_int = 0;
418  v6();
419  BOOST_CHECK(global_int == 5);
420
421  // clear() method
422  v6.clear();
423  BOOST_CHECK(v6.empty());
424
425  // Assignment to an empty function
426  v6 = three;
427  BOOST_CHECK(!v6.empty());
428
429  // Invocation
430  global_int = 0;
431  v6();
432  BOOST_CHECK(global_int == 3);
433
434  // Assignment to a non-empty function
435  v6 = five;
436
437  // Invocation
438  global_int = 0;
439  v6();
440  BOOST_CHECK(global_int == 5);
441
442  // clear()
443  v6.clear();
444  BOOST_CHECK(v6.empty());
445
446  // Assignment to an empty function from a free function
447  v6 = &write_five;
448  BOOST_CHECK(!v6.empty());
449
450  // Invocation
451  global_int = 0;
452  v6();
453  BOOST_CHECK(global_int == 5);
454
455  // Assignment to a non-empty function from a free function
456  v6 = &write_three;
457  BOOST_CHECK(!v6.empty());
458
459  // Invocation
460  global_int = 0;
461  v6();
462  BOOST_CHECK(global_int == 3);
463
464  // Assignment
465  v6 = five;
466  BOOST_CHECK(!v6.empty());
467
468  // Invocation
469  global_int = 0;
470  v6();
471  BOOST_CHECK(global_int == 5);
472
473  // Const vs. non-const
474  write_const_1_nonconst_2 one_or_two;
475  const function<void ()> v7(one_or_two);
476  function<void ()> v8(one_or_two);
477
478  global_int = 0;
479  v7();
480  BOOST_CHECK(global_int == 2);
481
482  global_int = 0;
483  v8();
484  BOOST_CHECK(global_int == 2);
485
486  // Test construction from 0 and comparison to 0
487  func_void_type v9(0);
488  BOOST_CHECK(v9 == 0);
489  BOOST_CHECK(0 == v9);
490
491  // Test return values
492  typedef function<int ()> func_int_type;
493  generate_five_obj gen_five;
494  generate_three_obj gen_three;
495
496  func_int_type i0(gen_five);
497
498  BOOST_CHECK(i0() == 5);
499  i0 = gen_three;
500  BOOST_CHECK(i0() == 3);
501  i0 = &generate_five;
502  BOOST_CHECK(i0() == 5);
503  i0 = &generate_three;
504  BOOST_CHECK(i0() == 3);
505  BOOST_CHECK(i0? true : false);
506  i0.clear();
507  BOOST_CHECK(!i0? true : false);
508
509  // Test return values with compatible types
510  typedef function<long ()> func_long_type;
511  func_long_type i1(gen_five);
512
513  BOOST_CHECK(i1() == 5);
514  i1 = gen_three;
515  BOOST_CHECK(i1() == 3);
516  i1 = &generate_five;
517  BOOST_CHECK(i1() == 5);
518  i1 = &generate_three;
519  BOOST_CHECK(i1() == 3);
520  BOOST_CHECK(i1? true : false);
521  i1.clear();
522  BOOST_CHECK(!i1? true : false);
523}
524
525static void
526test_one_arg()
527{
528  negate<int> neg;
529
530  function<int (int)> f1(neg);
531  BOOST_CHECK(f1(5) == -5);
532
533  function<string (string)> id(&identity_str);
534  BOOST_CHECK(id("str") == "str");
535
536  function<string (const char*)> id2(&identity_str);
537  BOOST_CHECK(id2("foo") == "foo");
538
539  add_to_obj add_to(5);
540  function<int (int)> f2(add_to);
541  BOOST_CHECK(f2(3) == 8);
542
543  const function<int (int)> cf2(add_to);
544  BOOST_CHECK(cf2(3) == 8);
545}
546
547static void
548test_two_args()
549{
550  function<string (const string&, const string&)> cat(&string_cat);
551  BOOST_CHECK(cat("str", "ing") == "string");
552
553  function<int (short, short)> sum(&sum_ints);
554  BOOST_CHECK(sum(2, 3) == 5);
555}
556
557static void
558test_emptiness()
559{
560  function<float ()> f1;
561  BOOST_CHECK(f1.empty());
562
563  function<float ()> f2;
564  f2 = f1;
565  BOOST_CHECK(f2.empty());
566
567  function<double ()> f3;
568  f3 = f2;
569  BOOST_CHECK(f3.empty());
570}
571
572struct X {
573  X(int v) : value(v) {}
574
575  int twice() const { return 2*value; }
576  int plus(int v) { return value + v; }
577
578  int value;
579};
580
581static void
582test_member_functions()
583{
584  boost::function<int (X*)> f1(&X::twice);
585
586  X one(1);
587  X five(5);
588
589  BOOST_CHECK(f1(&one) == 2);
590  BOOST_CHECK(f1(&five) == 10);
591
592  boost::function<int (X*)> f1_2;
593  f1_2 = &X::twice;
594
595  BOOST_CHECK(f1_2(&one) == 2);
596  BOOST_CHECK(f1_2(&five) == 10);
597
598  boost::function<int (X&, int)> f2(&X::plus);
599  BOOST_CHECK(f2(one, 3) == 4);
600  BOOST_CHECK(f2(five, 4) == 9);
601}
602
603struct add_with_throw_on_copy {
604  int operator()(int x, int y) const { return x+y; }
605
606  add_with_throw_on_copy() {}
607
608  add_with_throw_on_copy(const add_with_throw_on_copy&)
609  {
610    throw runtime_error("But this CAN'T throw");
611  }
612
613  add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
614  {
615    throw runtime_error("But this CAN'T throw");
616  }
617};
618
619static void
620test_ref()
621{
622  add_with_throw_on_copy atc;
623  try {
624    boost::function<int (int, int)> f(ref(atc));
625    BOOST_CHECK(f(1, 3) == 4);
626  }
627  catch(runtime_error e) {
628    BOOST_ERROR("Nonthrowing constructor threw an exception");
629  }
630}
631
632static void test_exception()
633{
634  boost::function<int (int, int)> f;
635  try {
636    f(5, 4);
637    BOOST_CHECK(false);
638  }
639  catch(boost::bad_function_call) {
640    // okay
641  }
642}
643
644typedef boost::function< void * (void * reader) > reader_type;
645typedef std::pair<int, reader_type> mapped_type;
646
647static void test_implicit()
648{
649  mapped_type m;
650  m = mapped_type();
651}
652
653static void test_call_obj(boost::function<int (int, int)> f)
654{
655  BOOST_CHECK(!f.empty());
656}
657
658static void test_call_cref(const boost::function<int (int, int)>& f)
659{
660  BOOST_CHECK(!f.empty());
661}
662
663static void test_call()
664{
665  test_call_obj(std::plus<int>());
666  test_call_cref(std::plus<int>());
667}
668
669int test_main(int, char* [])
670{
671  test_zero_args();
672  test_one_arg();
673  test_two_args();
674  test_emptiness();
675  test_member_functions();
676  test_ref();
677  test_exception();
678  test_implicit();
679  test_call();
680
681  return 0;
682}
Note: See TracBrowser for help on using the repository browser.