PageRenderTime 113ms CodeModel.GetById 14ms app.highlight 87ms RepoModel.GetById 6ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/function/test/function_test.cpp

http://hadesmem.googlecode.com/
C++ | 707 lines | 453 code | 152 blank | 102 comment | 73 complexity | b048c0ef7090a7b8023ce67e6c7d0adc MD5 | raw file
  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 boost::function;
 17using std::string;
 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  std::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 std::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 std::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(boost::ref(atc));
625    BOOST_CHECK(f(1, 3) == 4);
626  }
627  catch(std::runtime_error e) {
628    BOOST_ERROR("Nonthrowing constructor threw an exception");
629  }
630}
631
632static void dummy() {}
633
634static void test_empty_ref()
635{
636  boost::function<void()> f1;
637  boost::function<void()> f2(boost::ref(f1));
638
639  try {
640    f2();
641    BOOST_ERROR("Exception didn't throw for reference to empty function.");
642  }
643  catch(std::runtime_error e) {}
644
645  f1 = dummy;
646
647  try {
648    f2();
649  }
650  catch(std::runtime_error e) {
651    BOOST_ERROR("Error calling referenced function.");
652  }
653}
654
655
656static void test_exception()
657{
658  boost::function<int (int, int)> f;
659  try {
660    f(5, 4);
661    BOOST_CHECK(false);
662  }
663  catch(boost::bad_function_call) {
664    // okay
665  }
666}
667
668typedef boost::function< void * (void * reader) > reader_type;
669typedef std::pair<int, reader_type> mapped_type;
670
671static void test_implicit()
672{
673  mapped_type m;
674  m = mapped_type();
675}
676
677static void test_call_obj(boost::function<int (int, int)> f)
678{
679  BOOST_CHECK(!f.empty());
680}
681
682static void test_call_cref(const boost::function<int (int, int)>& f)
683{
684  BOOST_CHECK(!f.empty());
685}
686
687static void test_call()
688{
689  test_call_obj(std::plus<int>());
690  test_call_cref(std::plus<int>());
691}
692
693int test_main(int, char* [])
694{
695  test_zero_args();
696  test_one_arg();
697  test_two_args();
698  test_emptiness();
699  test_member_functions();
700  test_ref();
701  test_empty_ref();
702  test_exception();
703  test_implicit();
704  test_call();
705
706  return 0;
707}