~ubuntu-branches/debian/sid/boost1.49/sid

« back to all changes in this revision

Viewing changes to libs/function/test/function_test.cpp

  • Committer: Package Import Robot
  • Author(s): Steve M. Robbins
  • Date: 2012-02-26 00:31:44 UTC
  • Revision ID: package-import@ubuntu.com-20120226003144-eaytp12cbf6ubpms
Tags: upstream-1.49.0
ImportĀ upstreamĀ versionĀ 1.49.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
16
using boost::function;
 
17
using std::string;
 
18
 
 
19
int global_int;
 
20
 
 
21
struct write_five_obj { void operator()() const { global_int = 5; } };
 
22
struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
 
23
static void write_five() { global_int = 5; }
 
24
static void write_three() { global_int = 3; }
 
25
struct generate_five_obj { int operator()() const { return 5; } };
 
26
struct generate_three_obj { int operator()() const { return 3; } };
 
27
static int generate_five() { return 5; }
 
28
static int generate_three() { return 3; }
 
29
static string identity_str(const string& s) { return s; }
 
30
static string string_cat(const string& s1, const string& s2) { return s1+s2; }
 
31
static int sum_ints(int x, int y) { return x+y; }
 
32
 
 
33
struct write_const_1_nonconst_2
 
34
{
 
35
  void operator()() { global_int = 2; }
 
36
  void operator()() const { global_int = 1; }
 
37
};
 
38
 
 
39
struct 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
 
 
48
static void
 
49
test_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
 
 
525
static void
 
526
test_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
 
 
547
static void
 
548
test_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
 
 
557
static void
 
558
test_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
 
 
572
struct 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
 
 
581
static void
 
582
test_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
 
 
603
struct 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
 
 
619
static void
 
620
test_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
 
 
632
static void dummy() {}
 
633
 
 
634
static 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
 
 
656
static 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
 
 
668
typedef boost::function< void * (void * reader) > reader_type;
 
669
typedef std::pair<int, reader_type> mapped_type;
 
670
 
 
671
static void test_implicit()
 
672
{
 
673
  mapped_type m;
 
674
  m = mapped_type();
 
675
}
 
676
 
 
677
static void test_call_obj(boost::function<int (int, int)> f)
 
678
{
 
679
  BOOST_CHECK(!f.empty());
 
680
}
 
681
 
 
682
static void test_call_cref(const boost::function<int (int, int)>& f)
 
683
{
 
684
  BOOST_CHECK(!f.empty());
 
685
}
 
686
 
 
687
static void test_call()
 
688
{
 
689
  test_call_obj(std::plus<int>());
 
690
  test_call_cref(std::plus<int>());
 
691
}
 
692
 
 
693
int 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
}