Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/function/test/function_test.cpp @ 12

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

added boost

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