1// Demonstrate and test boost/operators.hpp -------------------------------//
2
3// Copyright Beman Dawes 1999. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7// See http://www.boost.org/libs/utility for documentation.
8
9// Revision History
10// 03 Apr 08 Added convertible_to_bool (Daniel Frey)
11// 01 Oct 01 Added tests for "left" operators
12// and new grouped operators. (Helmut Zeisel)
13// 20 May 01 Output progress messages. Added tests for new operator
14// templates. Updated random number generator. Changed tests to
15// use Boost Test Tools library. (Daryle Walker)
16// 04 Jun 00 Added regression test for a bug I found (David Abrahams)
17// 17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
18// ?? ??? 00 Major update to randomly test all one- and two- argument forms by
19// wrapping integral types and comparing the results of operations
20// to the results for the raw types (David Abrahams)
21// 12 Dec 99 Minor update, output confirmation message.
22// 15 Nov 99 Initial version
23
24#define BOOST_INCLUDE_MAIN
25
26#include <boost/config.hpp> // for BOOST_MSVC
27#include <boost/cstdlib.hpp> // for boost::exit_success
28#include <boost/operators.hpp> // for the tested items
29#include <boost/random/linear_congruential.hpp> // for boost::minstd_rand
30#include <boost/test/test_tools.hpp> // for main
31
32#include <iostream> // for std::cout (std::endl indirectly)
33
34
35namespace
36{
37 // avoiding a template version of true_value so as to not confuse VC++
38 int true_value(int x) { return x; }
39 long true_value(long x) { return x; }
40 signed char true_value(signed char x) { return x; }
41 short true_value(short x) { return x; }
42 unsigned int true_value(unsigned int x) { return x; }
43 unsigned long true_value(unsigned long x) { return x; }
44 unsigned char true_value(unsigned char x) { return x; }
45 unsigned short true_value(unsigned short x) { return x; }
46
47 // verify the minimum requirements for some operators
48 class convertible_to_bool
49 {
50 private:
51 bool _value;
52
53 typedef bool convertible_to_bool::*unspecified_bool_type;
54
55 void operator!() const;
56
57 public:
58 convertible_to_bool( const bool value ) : _value( value ) {}
59
60 operator unspecified_bool_type() const
61 { return _value ? &convertible_to_bool::_value : 0; }
62 };
63
64 // The use of operators<> here tended to obscure
65 // interactions with certain compiler bugs
66 template <class T>
67 class Wrapped1
68 : boost::operators<Wrapped1<T> >
69 , boost::shiftable<Wrapped1<T> >
70 {
71 public:
72 explicit Wrapped1( T v = T() ) : _value(v) {}
73 T value() const { return _value; }
74
75 convertible_to_bool operator<(const Wrapped1& x) const
76 { return _value < x._value; }
77 convertible_to_bool operator==(const Wrapped1& x) const
78 { return _value == x._value; }
79
80 Wrapped1& operator+=(const Wrapped1& x)
81 { _value += x._value; return *this; }
82 Wrapped1& operator-=(const Wrapped1& x)
83 { _value -= x._value; return *this; }
84 Wrapped1& operator*=(const Wrapped1& x)
85 { _value *= x._value; return *this; }
86 Wrapped1& operator/=(const Wrapped1& x)
87 { _value /= x._value; return *this; }
88 Wrapped1& operator%=(const Wrapped1& x)
89 { _value %= x._value; return *this; }
90 Wrapped1& operator|=(const Wrapped1& x)
91 { _value |= x._value; return *this; }
92 Wrapped1& operator&=(const Wrapped1& x)
93 { _value &= x._value; return *this; }
94 Wrapped1& operator^=(const Wrapped1& x)
95 { _value ^= x._value; return *this; }
96 Wrapped1& operator<<=(const Wrapped1& x)
97 { _value <<= x._value; return *this; }
98 Wrapped1& operator>>=(const Wrapped1& x)
99 { _value >>= x._value; return *this; }
100 Wrapped1& operator++() { ++_value; return *this; }
101 Wrapped1& operator--() { --_value; return *this; }
102
103 private:
104 T _value;
105 };
106 template <class T>
107 T true_value(Wrapped1<T> x) { return x.value(); }
108
109 template <class T, class U>
110 class Wrapped2
111 : boost::operators<Wrapped2<T, U> >
112 , boost::operators2<Wrapped2<T, U>, U>
113 , boost::shiftable1<Wrapped2<T, U>
114 , boost::shiftable2<Wrapped2<T, U>, U > >
115 {
116 public:
117 explicit Wrapped2( T v = T() ) : _value(v) {}
118 T value() const { return _value; }
119
120 convertible_to_bool operator<(const Wrapped2& x) const
121 { return _value < x._value; }
122 convertible_to_bool operator==(const Wrapped2& x) const
123 { return _value == x._value; }
124
125 Wrapped2& operator+=(const Wrapped2& x)
126 { _value += x._value; return *this; }
127 Wrapped2& operator-=(const Wrapped2& x)
128 { _value -= x._value; return *this; }
129 Wrapped2& operator*=(const Wrapped2& x)
130 { _value *= x._value; return *this; }
131 Wrapped2& operator/=(const Wrapped2& x)
132 { _value /= x._value; return *this; }
133 Wrapped2& operator%=(const Wrapped2& x)
134 { _value %= x._value; return *this; }
135 Wrapped2& operator|=(const Wrapped2& x)
136 { _value |= x._value; return *this; }
137 Wrapped2& operator&=(const Wrapped2& x)
138 { _value &= x._value; return *this; }
139 Wrapped2& operator^=(const Wrapped2& x)
140 { _value ^= x._value; return *this; }
141 Wrapped2& operator<<=(const Wrapped2& x)
142 { _value <<= x._value; return *this; }
143 Wrapped2& operator>>=(const Wrapped2& x)
144 { _value >>= x._value; return *this; }
145 Wrapped2& operator++() { ++_value; return *this; }
146 Wrapped2& operator--() { --_value; return *this; }
147
148 convertible_to_bool operator<(U u) const
149 { return _value < u; }
150 convertible_to_bool operator>(U u) const
151 { return _value > u; }
152 convertible_to_bool operator==(U u) const
153 { return _value == u; }
154
155 Wrapped2& operator+=(U u) { _value += u; return *this; }
156 Wrapped2& operator-=(U u) { _value -= u; return *this; }
157 Wrapped2& operator*=(U u) { _value *= u; return *this; }
158 Wrapped2& operator/=(U u) { _value /= u; return *this; }
159 Wrapped2& operator%=(U u) { _value %= u; return *this; }
160 Wrapped2& operator|=(U u) { _value |= u; return *this; }
161 Wrapped2& operator&=(U u) { _value &= u; return *this; }
162 Wrapped2& operator^=(U u) { _value ^= u; return *this; }
163 Wrapped2& operator<<=(U u) { _value <<= u; return *this; }
164 Wrapped2& operator>>=(U u) { _value >>= u; return *this; }
165
166 private:
167 T _value;
168 };
169 template <class T, class U>
170 T true_value(Wrapped2<T,U> x) { return x.value(); }
171
172 template <class T>
173 class Wrapped3
174 : boost::equivalent<Wrapped3<T> >
175 , boost::partially_ordered<Wrapped3<T> >
176 , boost::equality_comparable<Wrapped3<T> >
177 {
178 public:
179 explicit Wrapped3( T v = T() ) : _value(v) {}
180 T value() const { return _value; }
181
182 convertible_to_bool operator<(const Wrapped3& x) const
183 { return _value < x._value; }
184
185 private:
186 T _value;
187 };
188 template <class T>
189 T true_value(Wrapped3<T> x) { return x.value(); }
190
191 template <class T, class U>
192 class Wrapped4
193 : boost::equality_comparable1<Wrapped4<T, U>
194 , boost::equivalent1<Wrapped4<T, U>
195 , boost::partially_ordered1<Wrapped4<T, U> > > >
196 , boost::partially_ordered2<Wrapped4<T, U>, U
197 , boost::equivalent2<Wrapped4<T, U>, U
198 , boost::equality_comparable2<Wrapped4<T, U>, U> > >
199 {
200 public:
201 explicit Wrapped4( T v = T() ) : _value(v) {}
202 T value() const { return _value; }
203
204 convertible_to_bool operator<(const Wrapped4& x) const
205 { return _value < x._value; }
206
207 convertible_to_bool operator<(U u) const
208 { return _value < u; }
209 convertible_to_bool operator>(U u) const
210 { return _value > u; }
211
212 private:
213 T _value;
214 };
215 template <class T, class U>
216 T true_value(Wrapped4<T,U> x) { return x.value(); }
217
218 // U must be convertible to T
219 template <class T, class U>
220 class Wrapped5
221 : boost::ordered_field_operators2<Wrapped5<T, U>, U>
222 , boost::ordered_field_operators1<Wrapped5<T, U> >
223 {
224 public:
225 explicit Wrapped5( T v = T() ) : _value(v) {}
226
227 // Conversion from U to Wrapped5<T,U>
228 Wrapped5(U u) : _value(u) {}
229
230 T value() const { return _value; }
231
232 convertible_to_bool operator<(const Wrapped5& x) const
233 { return _value < x._value; }
234 convertible_to_bool operator<(U u) const
235 { return _value < u; }
236 convertible_to_bool operator>(U u) const
237 { return _value > u; }
238 convertible_to_bool operator==(const Wrapped5& u) const
239 { return _value == u._value; }
240 convertible_to_bool operator==(U u) const
241 { return _value == u; }
242
243 Wrapped5& operator/=(const Wrapped5& u) { _value /= u._value; return *this;}
244 Wrapped5& operator/=(U u) { _value /= u; return *this;}
245 Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;}
246 Wrapped5& operator*=(U u) { _value *= u; return *this;}
247 Wrapped5& operator-=(const Wrapped5& u) { _value -= u._value; return *this;}
248 Wrapped5& operator-=(U u) { _value -= u; return *this;}
249 Wrapped5& operator+=(const Wrapped5& u) { _value += u._value; return *this;}
250 Wrapped5& operator+=(U u) { _value += u; return *this;}
251
252 private:
253 T _value;
254 };
255 template <class T, class U>
256 T true_value(Wrapped5<T,U> x) { return x.value(); }
257
258 // U must be convertible to T
259 template <class T, class U>
260 class Wrapped6
261 : boost::ordered_euclidean_ring_operators2<Wrapped6<T, U>, U>
262 , boost::ordered_euclidean_ring_operators1<Wrapped6<T, U> >
263 {
264 public:
265 explicit Wrapped6( T v = T() ) : _value(v) {}
266
267 // Conversion from U to Wrapped6<T,U>
268 Wrapped6(U u) : _value(u) {}
269
270 T value() const { return _value; }
271
272 convertible_to_bool operator<(const Wrapped6& x) const
273 { return _value < x._value; }
274 convertible_to_bool operator<(U u) const
275 { return _value < u; }
276 convertible_to_bool operator>(U u) const
277 { return _value > u; }
278 convertible_to_bool operator==(const Wrapped6& u) const
279 { return _value == u._value; }
280 convertible_to_bool operator==(U u) const
281 { return _value == u; }
282
283 Wrapped6& operator%=(const Wrapped6& u) { _value %= u._value; return *this;}
284 Wrapped6& operator%=(U u) { _value %= u; return *this;}
285 Wrapped6& operator/=(const Wrapped6& u) { _value /= u._value; return *this;}
286 Wrapped6& operator/=(U u) { _value /= u; return *this;}
287 Wrapped6& operator*=(const Wrapped6& u) { _value *= u._value; return *this;}
288 Wrapped6& operator*=(U u) { _value *= u; return *this;}
289 Wrapped6& operator-=(const Wrapped6& u) { _value -= u._value; return *this;}
290 Wrapped6& operator-=(U u) { _value -= u; return *this;}
291 Wrapped6& operator+=(const Wrapped6& u) { _value += u._value; return *this;}
292 Wrapped6& operator+=(U u) { _value += u; return *this;}
293
294 private:
295 T _value;
296 };
297 template <class T, class U>
298 T true_value(Wrapped6<T,U> x) { return x.value(); }
299
300 // MyInt uses only the single template-argument form of all_operators<>
301 typedef Wrapped1<int> MyInt;
302
303 typedef Wrapped2<long, long> MyLong;
304
305 typedef Wrapped3<signed char> MyChar;
306
307 typedef Wrapped4<short, short> MyShort;
308
309 typedef Wrapped5<double, int> MyDoubleInt;
310
311 typedef Wrapped6<long, int> MyLongInt;
312
313 template <class X1, class Y1, class X2, class Y2>
314 void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
315 {
316 BOOST_CHECK( true_value(y1) == true_value(y2) );
317 BOOST_CHECK( true_value(x1) == true_value(x2) );
318 }
319
320 template <class X1, class Y1, class X2, class Y2>
321 void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
322 {
323 BOOST_CHECK( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
324 BOOST_CHECK( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
325 BOOST_CHECK( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
326 BOOST_CHECK( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
327 }
328
329 template <class X1, class Y1, class X2, class Y2>
330 void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
331 {
332 sanity_check( x1, y1, x2, y2 );
333 test_less_than_comparable_aux( x1, y1, x2, y2 );
334 test_less_than_comparable_aux( y1, x1, y2, x2 );
335 }
336
337 template <class X1, class Y1, class X2, class Y2>
338 void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
339 {
340 BOOST_CHECK( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
341 BOOST_CHECK( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
342 }
343
344 template <class X1, class Y1, class X2, class Y2>
345 void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
346 {
347 sanity_check( x1, y1, x2, y2 );
348 test_equality_comparable_aux( x1, y1, x2, y2 );
349 test_equality_comparable_aux( y1, x1, y2, x2 );
350 }
351
352 template <class X1, class Y1, class X2, class Y2>
353 void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
354 {
355 BOOST_CHECK( (x1 * y1).value() == (x2 * y2) );
356 }
357
358 template <class X1, class Y1, class X2, class Y2>
359 void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
360 {
361 sanity_check( x1, y1, x2, y2 );
362 test_multipliable_aux( x1, y1, x2, y2 );
363 test_multipliable_aux( y1, x1, y2, x2 );
364 }
365
366 template <class A, class B>
367 void test_value_equality(A a, B b)
368 {
369 BOOST_CHECK(a.value() == b);
370 }
371
372#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
373#define TEST_OP_L(op) test_value_equality(y1 op x1, y2 op x2)
374
375 template <class X1, class Y1, class X2, class Y2>
376 void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
377 {
378 TEST_OP_R(+);
379 }
380
381 template <class X1, class Y1, class X2, class Y2>
382 void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
383 {
384 sanity_check( x1, y1, x2, y2 );
385 test_addable_aux( x1, y1, x2, y2 );
386 test_addable_aux( y1, x1, y2, x2 );
387 }
388
389 template <class X1, class Y1, class X2, class Y2>
390 void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
391 {
392 sanity_check( x1, y1, x2, y2 );
393 TEST_OP_R(-);
394 }
395
396 template <class X1, class Y1, class X2, class Y2>
397 void test_subtractable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
398 {
399 sanity_check( x1, y1, x2, y2 );
400 TEST_OP_L(-);
401 }
402
403 template <class X1, class Y1, class X2, class Y2>
404 void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
405 {
406 sanity_check( x1, y1, x2, y2 );
407 if ( y2 != 0 )
408 TEST_OP_R(/);
409 }
410
411 template <class X1, class Y1, class X2, class Y2>
412 void test_dividable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
413 {
414 sanity_check( x1, y1, x2, y2 );
415 if ( x2 != 0 )
416 TEST_OP_L(/);
417 }
418
419 template <class X1, class Y1, class X2, class Y2>
420 void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
421 {
422 sanity_check( x1, y1, x2, y2 );
423 if ( y2 != 0 )
424 TEST_OP_R(%);
425 }
426
427 template <class X1, class Y1, class X2, class Y2>
428 void test_modable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
429 {
430 sanity_check( x1, y1, x2, y2 );
431 if ( x2 != 0 )
432 TEST_OP_L(%);
433 }
434
435 template <class X1, class Y1, class X2, class Y2>
436 void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
437 {
438 TEST_OP_R(^);
439 }
440
441 template <class X1, class Y1, class X2, class Y2>
442 void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
443 {
444 sanity_check( x1, y1, x2, y2 );
445 test_xorable_aux( x1, y1, x2, y2 );
446 test_xorable_aux( y1, x1, y2, x2 );
447 }
448
449 template <class X1, class Y1, class X2, class Y2>
450 void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
451 {
452 TEST_OP_R(&);
453 }
454
455 template <class X1, class Y1, class X2, class Y2>
456 void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
457 {
458 sanity_check( x1, y1, x2, y2 );
459 test_andable_aux( x1, y1, x2, y2 );
460 test_andable_aux( y1, x1, y2, x2 );
461 }
462
463 template <class X1, class Y1, class X2, class Y2>
464 void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
465 {
466 TEST_OP_R(|);
467 }
468
469 template <class X1, class Y1, class X2, class Y2>
470 void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
471 {
472 sanity_check( x1, y1, x2, y2 );
473 test_orable_aux( x1, y1, x2, y2 );
474 test_orable_aux( y1, x1, y2, x2 );
475 }
476
477 template <class X1, class Y1, class X2, class Y2>
478 void test_left_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
479 {
480 sanity_check( x1, y1, x2, y2 );
481 TEST_OP_R(<<);
482 }
483
484 template <class X1, class Y1, class X2, class Y2>
485 void test_right_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
486 {
487 sanity_check( x1, y1, x2, y2 );
488 TEST_OP_R(>>);
489 }
490
491 template <class X1, class X2>
492 void test_incrementable(X1 x1, X2 x2)
493 {
494 sanity_check( x1, x1, x2, x2 );
495 BOOST_CHECK( (x1++).value() == x2++ );
496 BOOST_CHECK( x1.value() == x2 );
497 }
498
499 template <class X1, class X2>
500 void test_decrementable(X1 x1, X2 x2)
501 {
502 sanity_check( x1, x1, x2, x2 );
503 BOOST_CHECK( (x1--).value() == x2-- );
504 BOOST_CHECK( x1.value() == x2 );
505 }
506
507 template <class X1, class Y1, class X2, class Y2>
508 void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
509 {
510 test_less_than_comparable( x1, y1, x2, y2 );
511 test_equality_comparable( x1, y1, x2, y2 );
512 test_multipliable( x1, y1, x2, y2 );
513 test_addable( x1, y1, x2, y2 );
514 test_subtractable( x1, y1, x2, y2 );
515 test_dividable( x1, y1, x2, y2 );
516 test_modable( x1, y1, x2, y2 );
517 test_xorable( x1, y1, x2, y2 );
518 test_andable( x1, y1, x2, y2 );
519 test_orable( x1, y1, x2, y2 );
520 test_left_shiftable( x1, y1, x2, y2 );
521 test_right_shiftable( x1, y1, x2, y2 );
522 test_incrementable( x1, x2 );
523 test_decrementable( x1, x2 );
524 }
525
526 template <class X1, class Y1, class X2, class Y2>
527 void test_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
528 {
529 test_subtractable_left( x1, y1, x2, y2 );
530 test_dividable_left( x1, y1, x2, y2 );
531 test_modable_left( x1, y1, x2, y2 );
532 }
533
534 template <class Big, class Small>
535 struct tester
536 {
537 void operator()(boost::minstd_rand& randomizer) const
538 {
539 Big b1 = Big( randomizer() );
540 Big b2 = Big( randomizer() );
541 Small s = Small( randomizer() );
542
543 test_all( Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2 );
544 test_all( Wrapped2<Big, Small>(b1), s, b1, s );
545 }
546 };
547
548 template <class Big, class Small>
549 struct tester_left
550 {
551 void operator()(boost::minstd_rand& randomizer) const
552 {
553 Big b1 = Big( randomizer() );
554 Small s = Small( randomizer() );
555
556 test_left( Wrapped6<Big, Small>(b1), s, b1, s );
557 }
558 };
559
560 // added as a regression test. We had a bug which this uncovered.
561 struct Point
562 : boost::addable<Point
563 , boost::subtractable<Point> >
564 {
565 Point( int h, int v ) : h(h), v(v) {}
566 Point() :h(0), v(0) {}
567 const Point& operator+=( const Point& rhs )
568 { h += rhs.h; v += rhs.v; return *this; }
569 const Point& operator-=( const Point& rhs )
570 { h -= rhs.h; v -= rhs.v; return *this; }
571
572 int h;
573 int v;
574 };
575
576} // unnamed namespace
577
578
579// workaround for MSVC bug; for some reasons the compiler doesn't instantiate
580// inherited operator templates at the moment it must, so the following
581// explicit instantiations force it to do that.
582
583#if defined(BOOST_MSVC) && (_MSC_VER < 1300)
584template Wrapped1<int>;
585template Wrapped1<long>;
586template Wrapped1<unsigned int>;
587template Wrapped1<unsigned long>;
588
589template Wrapped2<int, int>;
590template Wrapped2<int, signed char>;
591template Wrapped2<long, signed char>;
592template Wrapped2<long, int>;
593template Wrapped2<long, long>;
594template Wrapped2<unsigned int, unsigned int>;
595template Wrapped2<unsigned int, unsigned char>;
596template Wrapped2<unsigned long, unsigned int>;
597template Wrapped2<unsigned long, unsigned char>;
598template Wrapped2<unsigned long, unsigned long>;
599
600template Wrapped6<long, int>;
601template Wrapped6<long, signed char>;
602template Wrapped6<int, signed char>;
603template Wrapped6<unsigned long, unsigned int>;
604template Wrapped6<unsigned long, unsigned char>;
605template Wrapped6<unsigned int, unsigned char>;
606#endif
607
608#define PRIVATE_EXPR_TEST(e, t) BOOST_CHECK( ((e), (t)) )
609
610int
611test_main( int , char * [] )
612{
613 using std::cout;
614 using std::endl;
615
616 // Regression test.
617 Point x;
618 x = x + Point(3, 4);
619 x = x - Point(3, 4);
620
621 cout << "Created point, and operated on it." << endl;
622
623 for (int n = 0; n < 1000; ++n) // was 10,000 but took too long (Beman)
624 {
625 boost::minstd_rand r;
626 tester<long, int>()(r);
627 tester<long, signed char>()(r);
628 tester<long, long>()(r);
629 tester<int, int>()(r);
630 tester<int, signed char>()(r);
631
632 tester<unsigned long, unsigned int>()(r);
633 tester<unsigned long, unsigned char>()(r);
634 tester<unsigned long, unsigned long>()(r);
635 tester<unsigned int, unsigned int>()(r);
636 tester<unsigned int, unsigned char>()(r);
637
638 tester_left<long, int>()(r);
639 tester_left<long, signed char>()(r);
640 tester_left<int, signed char>()(r);
641
642 tester_left<unsigned long, unsigned int>()(r);
643 tester_left<unsigned long, unsigned char>()(r);
644 tester_left<unsigned int, unsigned char>()(r);
645 }
646
647 cout << "Did random tester loop." << endl;
648
649 MyInt i1(1);
650 MyInt i2(2);
651 MyInt i;
652
653 BOOST_CHECK( i1.value() == 1 );
654 BOOST_CHECK( i2.value() == 2 );
655 BOOST_CHECK( i.value() == 0 );
656
657 cout << "Created MyInt objects.\n";
658
659 PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
660
661 BOOST_CHECK( static_cast<bool>(i2 == i) );
662 BOOST_CHECK( static_cast<bool>(i1 != i2) );
663 BOOST_CHECK( static_cast<bool>(i1 < i2) );
664 BOOST_CHECK( static_cast<bool>(i1 <= i2) );
665 BOOST_CHECK( static_cast<bool>(i <= i2) );
666 BOOST_CHECK( static_cast<bool>(i2 > i1) );
667 BOOST_CHECK( static_cast<bool>(i2 >= i1) );
668 BOOST_CHECK( static_cast<bool>(i2 >= i) );
669
670 PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
671 PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
672 PRIVATE_EXPR_TEST( (i = i - i1), (i.value() == 4) );
673 PRIVATE_EXPR_TEST( (i = i * i2), (i.value() == 8) );
674 PRIVATE_EXPR_TEST( (i = i / i2), (i.value() == 4) );
675 PRIVATE_EXPR_TEST( (i = i % ( i - i1 )), (i.value() == 1) );
676 PRIVATE_EXPR_TEST( (i = i2 + i2), (i.value() == 4) );
677 PRIVATE_EXPR_TEST( (i = i1 | i2 | i), (i.value() == 7) );
678 PRIVATE_EXPR_TEST( (i = i & i2), (i.value() == 2) );
679 PRIVATE_EXPR_TEST( (i = i + i1), (i.value() == 3) );
680 PRIVATE_EXPR_TEST( (i = i ^ i1), (i.value() == 2) );
681 PRIVATE_EXPR_TEST( (i = ( i + i1 ) * ( i2 | i1 )), (i.value() == 9) );
682
683 PRIVATE_EXPR_TEST( (i = i1 << i2), (i.value() == 4) );
684 PRIVATE_EXPR_TEST( (i = i2 >> i1), (i.value() == 1) );
685
686 cout << "Performed tests on MyInt objects.\n";
687
688 MyLong j1(1);
689 MyLong j2(2);
690 MyLong j;
691
692 BOOST_CHECK( j1.value() == 1 );
693 BOOST_CHECK( j2.value() == 2 );
694 BOOST_CHECK( j.value() == 0 );
695
696 cout << "Created MyLong objects.\n";
697
698 PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
699
700 BOOST_CHECK( static_cast<bool>(j2 == j) );
701 BOOST_CHECK( static_cast<bool>(2 == j) );
702 BOOST_CHECK( static_cast<bool>(j2 == 2) );
703 BOOST_CHECK( static_cast<bool>(j == j2) );
704 BOOST_CHECK( static_cast<bool>(j1 != j2) );
705 BOOST_CHECK( static_cast<bool>(j1 != 2) );
706 BOOST_CHECK( static_cast<bool>(1 != j2) );
707 BOOST_CHECK( static_cast<bool>(j1 < j2) );
708 BOOST_CHECK( static_cast<bool>(1 < j2) );
709 BOOST_CHECK( static_cast<bool>(j1 < 2) );
710 BOOST_CHECK( static_cast<bool>(j1 <= j2) );
711 BOOST_CHECK( static_cast<bool>(1 <= j2) );
712 BOOST_CHECK( static_cast<bool>(j1 <= j) );
713 BOOST_CHECK( static_cast<bool>(j <= j2) );
714 BOOST_CHECK( static_cast<bool>(2 <= j2) );
715 BOOST_CHECK( static_cast<bool>(j <= 2) );
716 BOOST_CHECK( static_cast<bool>(j2 > j1) );
717 BOOST_CHECK( static_cast<bool>(2 > j1) );
718 BOOST_CHECK( static_cast<bool>(j2 > 1) );
719 BOOST_CHECK( static_cast<bool>(j2 >= j1) );
720 BOOST_CHECK( static_cast<bool>(2 >= j1) );
721 BOOST_CHECK( static_cast<bool>(j2 >= 1) );
722 BOOST_CHECK( static_cast<bool>(j2 >= j) );
723 BOOST_CHECK( static_cast<bool>(2 >= j) );
724 BOOST_CHECK( static_cast<bool>(j2 >= 2) );
725
726 BOOST_CHECK( static_cast<bool>((j1 + 2) == 3) );
727 BOOST_CHECK( static_cast<bool>((1 + j2) == 3) );
728 PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
729
730 BOOST_CHECK( static_cast<bool>((j + 2) == 5) );
731 BOOST_CHECK( static_cast<bool>((3 + j2) == 5) );
732 PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
733
734 BOOST_CHECK( static_cast<bool>((j - 1) == 4) );
735 PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
736
737 BOOST_CHECK( static_cast<bool>((j * 2) == 8) );
738 BOOST_CHECK( static_cast<bool>((4 * j2) == 8) );
739 PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
740
741 BOOST_CHECK( static_cast<bool>((j / 2) == 4) );
742 PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
743
744 BOOST_CHECK( static_cast<bool>((j % 3) == 1) );
745 PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
746
747 PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
748
749 BOOST_CHECK( static_cast<bool>((1 | j2 | j) == 7) );
750 BOOST_CHECK( static_cast<bool>((j1 | 2 | j) == 7) );
751 BOOST_CHECK( static_cast<bool>((j1 | j2 | 4) == 7) );
752 PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
753
754 BOOST_CHECK( static_cast<bool>((7 & j2) == 2) );
755 BOOST_CHECK( static_cast<bool>((j & 2) == 2) );
756 PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
757
758 PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
759
760 BOOST_CHECK( static_cast<bool>((3 ^ j1) == 2) );
761 BOOST_CHECK( static_cast<bool>((j ^ 1) == 2) );
762 PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
763
764 PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
765
766 BOOST_CHECK( static_cast<bool>((j1 << 2) == 4) );
767 BOOST_CHECK( static_cast<bool>((j2 << 1) == 4) );
768 PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
769
770 BOOST_CHECK( static_cast<bool>((j >> 2) == 1) );
771 BOOST_CHECK( static_cast<bool>((j2 >> 1) == 1) );
772 PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
773
774 cout << "Performed tests on MyLong objects.\n";
775
776 MyChar k1(1);
777 MyChar k2(2);
778 MyChar k;
779
780 BOOST_CHECK( k1.value() == 1 );
781 BOOST_CHECK( k2.value() == 2 );
782 BOOST_CHECK( k.value() == 0 );
783
784 cout << "Created MyChar objects.\n";
785
786 PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
787
788 BOOST_CHECK( static_cast<bool>(k2 == k) );
789 BOOST_CHECK( static_cast<bool>(k1 != k2) );
790 BOOST_CHECK( static_cast<bool>(k1 < k2) );
791 BOOST_CHECK( static_cast<bool>(k1 <= k2) );
792 BOOST_CHECK( static_cast<bool>(k <= k2) );
793 BOOST_CHECK( static_cast<bool>(k2 > k1) );
794 BOOST_CHECK( static_cast<bool>(k2 >= k1) );
795 BOOST_CHECK( static_cast<bool>(k2 >= k) );
796
797 cout << "Performed tests on MyChar objects.\n";
798
799 MyShort l1(1);
800 MyShort l2(2);
801 MyShort l;
802
803 BOOST_CHECK( l1.value() == 1 );
804 BOOST_CHECK( l2.value() == 2 );
805 BOOST_CHECK( l.value() == 0 );
806
807 cout << "Created MyShort objects.\n";
808
809 PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
810
811 BOOST_CHECK( static_cast<bool>(l2 == l) );
812 BOOST_CHECK( static_cast<bool>(2 == l) );
813 BOOST_CHECK( static_cast<bool>(l2 == 2) );
814 BOOST_CHECK( static_cast<bool>(l == l2) );
815 BOOST_CHECK( static_cast<bool>(l1 != l2) );
816 BOOST_CHECK( static_cast<bool>(l1 != 2) );
817 BOOST_CHECK( static_cast<bool>(1 != l2) );
818 BOOST_CHECK( static_cast<bool>(l1 < l2) );
819 BOOST_CHECK( static_cast<bool>(1 < l2) );
820 BOOST_CHECK( static_cast<bool>(l1 < 2) );
821 BOOST_CHECK( static_cast<bool>(l1 <= l2) );
822 BOOST_CHECK( static_cast<bool>(1 <= l2) );
823 BOOST_CHECK( static_cast<bool>(l1 <= l) );
824 BOOST_CHECK( static_cast<bool>(l <= l2) );
825 BOOST_CHECK( static_cast<bool>(2 <= l2) );
826 BOOST_CHECK( static_cast<bool>(l <= 2) );
827 BOOST_CHECK( static_cast<bool>(l2 > l1) );
828 BOOST_CHECK( static_cast<bool>(2 > l1) );
829 BOOST_CHECK( static_cast<bool>(l2 > 1) );
830 BOOST_CHECK( static_cast<bool>(l2 >= l1) );
831 BOOST_CHECK( static_cast<bool>(2 >= l1) );
832 BOOST_CHECK( static_cast<bool>(l2 >= 1) );
833 BOOST_CHECK( static_cast<bool>(l2 >= l) );
834 BOOST_CHECK( static_cast<bool>(2 >= l) );
835 BOOST_CHECK( static_cast<bool>(l2 >= 2) );
836
837 cout << "Performed tests on MyShort objects.\n";
838
839 MyDoubleInt di1(1);
840 MyDoubleInt di2(2.);
841 MyDoubleInt half(0.5);
842 MyDoubleInt di;
843 MyDoubleInt tmp;
844
845 BOOST_CHECK( di1.value() == 1 );
846 BOOST_CHECK( di2.value() == 2 );
847 BOOST_CHECK( di2.value() == 2 );
848 BOOST_CHECK( di.value() == 0 );
849
850 cout << "Created MyDoubleInt objects.\n";
851
852 PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
853
854 BOOST_CHECK( static_cast<bool>(di2 == di) );
855 BOOST_CHECK( static_cast<bool>(2 == di) );
856 BOOST_CHECK( static_cast<bool>(di == 2) );
857 BOOST_CHECK( static_cast<bool>(di1 < di2) );
858 BOOST_CHECK( static_cast<bool>(1 < di2) );
859 BOOST_CHECK( static_cast<bool>(di1 <= di2) );
860 BOOST_CHECK( static_cast<bool>(1 <= di2) );
861 BOOST_CHECK( static_cast<bool>(di2 > di1) );
862 BOOST_CHECK( static_cast<bool>(di2 > 1) );
863 BOOST_CHECK( static_cast<bool>(di2 >= di1) );
864 BOOST_CHECK( static_cast<bool>(di2 >= 1) );
865 BOOST_CHECK( static_cast<bool>(di1 / di2 == half) );
866 BOOST_CHECK( static_cast<bool>(di1 / 2 == half) );
867 BOOST_CHECK( static_cast<bool>(1 / di2 == half) );
868 PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
869 PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
870 BOOST_CHECK( static_cast<bool>(di1 * di2 == di2) );
871 BOOST_CHECK( static_cast<bool>(di1 * 2 == di2) );
872 BOOST_CHECK( static_cast<bool>(1 * di2 == di2) );
873 PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
874 PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
875 BOOST_CHECK( static_cast<bool>(di2 - di1 == di1) );
876 BOOST_CHECK( static_cast<bool>(di2 - 1 == di1) );
877 BOOST_CHECK( static_cast<bool>(2 - di1 == di1) );
878 PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
879 PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
880 BOOST_CHECK( static_cast<bool>(di1 + di1 == di2) );
881 BOOST_CHECK( static_cast<bool>(di1 + 1 == di2) );
882 BOOST_CHECK( static_cast<bool>(1 + di1 == di2) );
883 PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
884 PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
885
886 cout << "Performed tests on MyDoubleInt objects.\n";
887
888 MyLongInt li1(1);
889 MyLongInt li2(2);
890 MyLongInt li;
891 MyLongInt tmp2;
892
893 BOOST_CHECK( li1.value() == 1 );
894 BOOST_CHECK( li2.value() == 2 );
895 BOOST_CHECK( li.value() == 0 );
896
897 cout << "Created MyLongInt objects.\n";
898
899 PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
900
901 BOOST_CHECK( static_cast<bool>(li2 == li) );
902 BOOST_CHECK( static_cast<bool>(2 == li) );
903 BOOST_CHECK( static_cast<bool>(li == 2) );
904 BOOST_CHECK( static_cast<bool>(li1 < li2) );
905 BOOST_CHECK( static_cast<bool>(1 < li2) );
906 BOOST_CHECK( static_cast<bool>(li1 <= li2) );
907 BOOST_CHECK( static_cast<bool>(1 <= li2) );
908 BOOST_CHECK( static_cast<bool>(li2 > li1) );
909 BOOST_CHECK( static_cast<bool>(li2 > 1) );
910 BOOST_CHECK( static_cast<bool>(li2 >= li1) );
911 BOOST_CHECK( static_cast<bool>(li2 >= 1) );
912 BOOST_CHECK( static_cast<bool>(li1 % li2 == li1) );
913 BOOST_CHECK( static_cast<bool>(li1 % 2 == li1) );
914 BOOST_CHECK( static_cast<bool>(1 % li2 == li1) );
915 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
916 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
917 BOOST_CHECK( static_cast<bool>(li1 / li2 == 0) );
918 BOOST_CHECK( static_cast<bool>(li1 / 2 == 0) );
919 BOOST_CHECK( static_cast<bool>(1 / li2 == 0) );
920 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
921 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
922 BOOST_CHECK( static_cast<bool>(li1 * li2 == li2) );
923 BOOST_CHECK( static_cast<bool>(li1 * 2 == li2) );
924 BOOST_CHECK( static_cast<bool>(1 * li2 == li2) );
925 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
926 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
927 BOOST_CHECK( static_cast<bool>(li2 - li1 == li1) );
928 BOOST_CHECK( static_cast<bool>(li2 - 1 == li1) );
929 BOOST_CHECK( static_cast<bool>(2 - li1 == li1) );
930 PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
931 PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
932 BOOST_CHECK( static_cast<bool>(li1 + li1 == li2) );
933 BOOST_CHECK( static_cast<bool>(li1 + 1 == li2) );
934 BOOST_CHECK( static_cast<bool>(1 + li1 == li2) );
935 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
936 PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
937
938 cout << "Performed tests on MyLongInt objects.\n";
939
940 return boost::exit_success;
941}
942

source code of boost/libs/utility/operators_test.cpp