Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added boost

File size: 12.6 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
16using namespace boost;
17using std::string;
18using std::negate;
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 function0<void> func_void_type;
53
54  write_five_obj five = write_five_obj(); // Initialization for Borland C++ 5.5
55  write_three_obj three = write_three_obj(); // Ditto
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.empty());
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);
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(v1.empty());
96
97  // Assignment to an empty function from a free function
98  v1 = &write_five;
99  BOOST_CHECK(!v1.empty());
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 = &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 = (&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 = &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 = &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  // Initialization for Borland C++ 5.5
476  write_const_1_nonconst_2 one_or_two = write_const_1_nonconst_2(); 
477  const function0<void> v7(one_or_two);
478  function0<void> v8(one_or_two);
479
480  global_int = 0;
481  v7();
482  BOOST_CHECK(global_int == 2);
483
484  global_int = 0;
485  v8();
486  BOOST_CHECK(global_int == 2);
487
488  // Test construction from 0 and comparison to 0
489  func_void_type v9(0);
490  BOOST_CHECK(v9 == 0);
491# if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540 || defined(BOOST_STRICT_CONFIG)
492  BOOST_CHECK(0 == v9);
493#else
494  BOOST_CHECK(v9.empty());
495#endif
496
497  // Test return values
498  typedef function0<int> func_int_type;
499  // Initialization for Borland C++ 5.5
500  generate_five_obj gen_five = generate_five_obj();
501  generate_three_obj gen_three = generate_three_obj();
502  func_int_type i0(gen_five);
503
504  BOOST_CHECK(i0() == 5);
505  i0 = gen_three;
506  BOOST_CHECK(i0() == 3);
507  i0 = &generate_five;
508  BOOST_CHECK(i0() == 5);
509  i0 = &generate_three;
510  BOOST_CHECK(i0() == 3);
511  BOOST_CHECK(i0? true : false);
512  i0.clear();
513  BOOST_CHECK(!i0? true : false);
514
515  // Test return values with compatible types
516  typedef function0<long> func_long_type;
517  func_long_type i1(gen_five);
518
519  BOOST_CHECK(i1() == 5);
520  i1 = gen_three;
521  BOOST_CHECK(i1() == 3);
522  i1 = &generate_five;
523  BOOST_CHECK(i1() == 5);
524  i1 = &generate_three;
525  BOOST_CHECK(i1() == 3);
526  BOOST_CHECK(i1? true : false);
527  i1.clear();
528  BOOST_CHECK(!i1? true : false);
529}
530
531static void
532test_one_arg()
533{
534  negate<int> neg = negate<int>(); // Initialization for Borland C++ 5.5
535
536  function1<int, int> f1(neg);
537  BOOST_CHECK(f1(5) == -5);
538
539  function1<string, string> id(&identity_str);
540  BOOST_CHECK(id("str") == "str");
541
542  function1<std::string, const char*> id2(&identity_str);
543  BOOST_CHECK(id2("foo") == "foo");
544
545  add_to_obj add_to(5);
546  function1<int, int> f2(add_to);
547  BOOST_CHECK(f2(3) == 8);
548
549  const function1<int, int> cf2(add_to);
550  BOOST_CHECK(cf2(3) == 8);
551}
552
553static void
554test_two_args()
555{
556  function2<string, const string&, const string&> cat(&string_cat);
557  BOOST_CHECK(cat("str", "ing") == "string");
558
559  function2<int, short, short> sum(&sum_ints);
560  BOOST_CHECK(sum(2, 3) == 5);
561}
562
563static void
564test_emptiness()
565{
566  function0<float> f1;
567  BOOST_CHECK(f1.empty());
568
569  function0<float> f2;
570  f2 = f1;
571  BOOST_CHECK(f2.empty());
572
573  function0<double> f3;
574  f3 = f2;
575  BOOST_CHECK(f3.empty());
576}
577
578struct X {
579  X(int v) : value(v) {}
580
581  int twice() const { return 2*value; }
582  int plus(int v) { return value + v; }
583
584  int value;
585};
586
587static void
588test_member_functions()
589{
590
591  boost::function1<int, X*> f1(&X::twice);
592
593  X one(1);
594  X five(5);
595
596  BOOST_CHECK(f1(&one) == 2);
597  BOOST_CHECK(f1(&five) == 10);
598
599  boost::function1<int, X*> f1_2;
600  f1_2 = &X::twice;
601
602  BOOST_CHECK(f1_2(&one) == 2);
603  BOOST_CHECK(f1_2(&five) == 10);
604
605  boost::function2<int, X&, int> f2(&X::plus);
606  BOOST_CHECK(f2(one, 3) == 4);
607  BOOST_CHECK(f2(five, 4) == 9);
608}
609
610struct add_with_throw_on_copy {
611  int operator()(int x, int y) const { return x+y; }
612
613  add_with_throw_on_copy() {}
614
615  add_with_throw_on_copy(const add_with_throw_on_copy&)
616  {
617    throw std::runtime_error("But this CAN'T throw");
618  }
619
620  add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
621  {
622    throw std::runtime_error("But this CAN'T throw");
623  }
624};
625
626static void
627test_ref()
628{
629  add_with_throw_on_copy atc;
630  try {
631    boost::function2<int, int, int> f(ref(atc));
632    BOOST_CHECK(f(1, 3) == 4);
633  }
634  catch(std::runtime_error e) {
635    BOOST_ERROR("Nonthrowing constructor threw an exception");
636  }
637}
638
639int test_main(int, char* [])
640{
641  test_zero_args();
642  test_one_arg();
643  test_two_args();
644  test_emptiness();
645  test_member_functions();
646  test_ref();
647  return 0;
648}
Note: See TracBrowser for help on using the repository browser.