1 // Demonstrate and test boost/operators.hpp -------------------------------//
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)
7 // See http://www.boost.org/libs/utility for documentation.
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
24 #include <boost/config.hpp> // for BOOST_MSVC
25 #include <boost/operators.hpp> // for the tested items
26 #include <boost/utility/detail/minstd_rand.hpp> // for boost::detail::minstd_rand
27 #include <boost/core/lightweight_test.hpp>
29 #include <iostream> // for std::cout (std::endl indirectly)
33 // avoiding a template version of true_value so as to not confuse VC++
34 int true_value(int x
) { return x
; }
35 long true_value(long x
) { return x
; }
36 signed char true_value(signed char x
) { return x
; }
37 unsigned int true_value(unsigned int x
) { return x
; }
38 unsigned long true_value(unsigned long x
) { return x
; }
39 unsigned char true_value(unsigned char x
) { return x
; }
41 // verify the minimum requirements for some operators
42 class convertible_to_bool
47 typedef bool convertible_to_bool::*unspecified_bool_type
;
49 void operator!() const;
52 convertible_to_bool( const bool value
) : _value( value
) {}
54 operator unspecified_bool_type() const
55 { return _value
? &convertible_to_bool::_value
: 0; }
58 // The use of operators<> here tended to obscure
59 // interactions with certain compiler bugs
62 : boost::operators
<Wrapped1
<T
> >
63 , boost::shiftable
<Wrapped1
<T
> >
66 explicit Wrapped1( T v
= T() ) : _value(v
) {}
67 T
value() const { return _value
; }
69 convertible_to_bool
operator<(const Wrapped1
& x
) const
70 { return _value
< x
._value
; }
71 convertible_to_bool
operator==(const Wrapped1
& x
) const
72 { return _value
== x
._value
; }
74 Wrapped1
& operator+=(const Wrapped1
& x
)
75 { _value
+= x
._value
; return *this; }
76 Wrapped1
& operator-=(const Wrapped1
& x
)
77 { _value
-= x
._value
; return *this; }
78 Wrapped1
& operator*=(const Wrapped1
& x
)
79 { _value
*= x
._value
; return *this; }
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++() { ++_value
; return *this; }
95 Wrapped1
& operator--() { --_value
; return *this; }
101 T
true_value(Wrapped1
<T
> x
) { return x
.value(); }
103 template <class T
, class U
>
105 : boost::operators
<Wrapped2
<T
, U
> >
106 , boost::operators2
<Wrapped2
<T
, U
>, U
>
107 , boost::shiftable1
<Wrapped2
<T
, U
>
108 , boost::shiftable2
<Wrapped2
<T
, U
>, U
> >
111 explicit Wrapped2( T v
= T() ) : _value(v
) {}
112 T
value() const { return _value
; }
114 convertible_to_bool
operator<(const Wrapped2
& x
) const
115 { return _value
< x
._value
; }
116 convertible_to_bool
operator==(const Wrapped2
& x
) const
117 { return _value
== x
._value
; }
119 Wrapped2
& operator+=(const Wrapped2
& x
)
120 { _value
+= x
._value
; return *this; }
121 Wrapped2
& operator-=(const Wrapped2
& x
)
122 { _value
-= x
._value
; return *this; }
123 Wrapped2
& operator*=(const Wrapped2
& x
)
124 { _value
*= x
._value
; return *this; }
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++() { ++_value
; return *this; }
140 Wrapped2
& operator--() { --_value
; return *this; }
142 convertible_to_bool
operator<(U u
) const
143 { return _value
< u
; }
144 convertible_to_bool
operator>(U u
) const
145 { return _value
> u
; }
146 convertible_to_bool
operator==(U u
) const
147 { return _value
== u
; }
149 Wrapped2
& operator+=(U u
) { _value
+= u
; return *this; }
150 Wrapped2
& operator-=(U u
) { _value
-= u
; return *this; }
151 Wrapped2
& operator*=(U u
) { _value
*= u
; return *this; }
152 Wrapped2
& operator/=(U u
) { _value
/= u
; return *this; }
153 Wrapped2
& operator%=(U u
) { _value
%= u
; return *this; }
154 Wrapped2
& operator|=(U u
) { _value
|= u
; return *this; }
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; }
163 template <class T
, class U
>
164 T
true_value(Wrapped2
<T
,U
> x
) { return x
.value(); }
168 : boost::equivalent
<Wrapped3
<T
> >
169 , boost::partially_ordered
<Wrapped3
<T
> >
170 , boost::equality_comparable
<Wrapped3
<T
> >
173 explicit Wrapped3( T v
= T() ) : _value(v
) {}
174 T
value() const { return _value
; }
176 convertible_to_bool
operator<(const Wrapped3
& x
) const
177 { return _value
< x
._value
; }
183 T
true_value(Wrapped3
<T
> x
) { return x
.value(); }
185 template <class T
, class U
>
187 : boost::equality_comparable1
<Wrapped4
<T
, U
>
188 , boost::equivalent1
<Wrapped4
<T
, U
>
189 , boost::partially_ordered1
<Wrapped4
<T
, U
> > > >
190 , boost::partially_ordered2
<Wrapped4
<T
, U
>, U
191 , boost::equivalent2
<Wrapped4
<T
, U
>, U
192 , boost::equality_comparable2
<Wrapped4
<T
, U
>, U
> > >
195 explicit Wrapped4( T v
= T() ) : _value(v
) {}
196 T
value() const { return _value
; }
198 convertible_to_bool
operator<(const Wrapped4
& x
) const
199 { return _value
< x
._value
; }
201 convertible_to_bool
operator<(U u
) const
202 { return _value
< u
; }
203 convertible_to_bool
operator>(U u
) const
204 { return _value
> u
; }
209 template <class T
, class U
>
210 T
true_value(Wrapped4
<T
,U
> x
) { return x
.value(); }
212 // U must be convertible to T
213 template <class T
, class U
>
215 : boost::ordered_field_operators2
<Wrapped5
<T
, U
>, U
>
216 , boost::ordered_field_operators1
<Wrapped5
<T
, U
> >
219 explicit Wrapped5( T v
= T() ) : _value(v
) {}
221 // Conversion from U to Wrapped5<T,U>
222 Wrapped5(U u
) : _value(u
) {}
224 T
value() const { return _value
; }
226 convertible_to_bool
operator<(const Wrapped5
& x
) const
227 { return _value
< x
._value
; }
228 convertible_to_bool
operator<(U u
) const
229 { return _value
< u
; }
230 convertible_to_bool
operator>(U u
) const
231 { return _value
> u
; }
232 convertible_to_bool
operator==(const Wrapped5
& u
) const
233 { return _value
== u
._value
; }
234 convertible_to_bool
operator==(U u
) const
235 { return _value
== u
; }
237 Wrapped5
& operator/=(const Wrapped5
& u
) { _value
/= u
._value
; return *this;}
238 Wrapped5
& operator/=(U u
) { _value
/= u
; return *this;}
239 Wrapped5
& operator*=(const Wrapped5
& u
) { _value
*= u
._value
; return *this;}
240 Wrapped5
& operator*=(U u
) { _value
*= u
; return *this;}
241 Wrapped5
& operator-=(const Wrapped5
& u
) { _value
-= u
._value
; return *this;}
242 Wrapped5
& operator-=(U u
) { _value
-= u
; return *this;}
243 Wrapped5
& operator+=(const Wrapped5
& u
) { _value
+= u
._value
; return *this;}
244 Wrapped5
& operator+=(U u
) { _value
+= u
; return *this;}
249 template <class T
, class U
>
250 T
true_value(Wrapped5
<T
,U
> x
) { return x
.value(); }
252 // U must be convertible to T
253 template <class T
, class U
>
255 : boost::ordered_euclidean_ring_operators2
<Wrapped6
<T
, U
>, U
>
256 , boost::ordered_euclidean_ring_operators1
<Wrapped6
<T
, U
> >
259 explicit Wrapped6( T v
= T() ) : _value(v
) {}
261 // Conversion from U to Wrapped6<T,U>
262 Wrapped6(U u
) : _value(u
) {}
264 T
value() const { return _value
; }
266 convertible_to_bool
operator<(const Wrapped6
& x
) const
267 { return _value
< x
._value
; }
268 convertible_to_bool
operator<(U u
) const
269 { return _value
< u
; }
270 convertible_to_bool
operator>(U u
) const
271 { return _value
> u
; }
272 convertible_to_bool
operator==(const Wrapped6
& u
) const
273 { return _value
== u
._value
; }
274 convertible_to_bool
operator==(U u
) const
275 { return _value
== u
; }
277 Wrapped6
& operator%=(const Wrapped6
& u
) { _value
%= u
._value
; return *this;}
278 Wrapped6
& operator%=(U u
) { _value
%= u
; return *this;}
279 Wrapped6
& operator/=(const Wrapped6
& u
) { _value
/= u
._value
; return *this;}
280 Wrapped6
& operator/=(U u
) { _value
/= u
; return *this;}
281 Wrapped6
& operator*=(const Wrapped6
& u
) { _value
*= u
._value
; return *this;}
282 Wrapped6
& operator*=(U u
) { _value
*= u
; return *this;}
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;}
291 template <class T
, class U
>
292 T
true_value(Wrapped6
<T
,U
> x
) { return x
.value(); }
294 // MyInt uses only the single template-argument form of all_operators<>
295 typedef Wrapped1
<int> MyInt
;
297 typedef Wrapped2
<long, long> MyLong
;
299 typedef Wrapped3
<signed char> MyChar
;
301 typedef Wrapped4
<short, short> MyShort
;
303 typedef Wrapped5
<double, int> MyDoubleInt
;
305 typedef Wrapped6
<long, int> MyLongInt
;
307 template <class X1
, class Y1
, class X2
, class Y2
>
308 void sanity_check(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
310 BOOST_TEST( true_value(y1
) == true_value(y2
) );
311 BOOST_TEST( true_value(x1
) == true_value(x2
) );
314 template <class X1
, class Y1
, class X2
, class Y2
>
315 void test_less_than_comparable_aux(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
317 BOOST_TEST( static_cast<bool>(x1
< y1
) == static_cast<bool>(x2
< y2
) );
318 BOOST_TEST( static_cast<bool>(x1
<= y1
) == static_cast<bool>(x2
<= y2
) );
319 BOOST_TEST( static_cast<bool>(x1
>= y1
) == static_cast<bool>(x2
>= y2
) );
320 BOOST_TEST( static_cast<bool>(x1
> y1
) == static_cast<bool>(x2
> y2
) );
323 template <class X1
, class Y1
, class X2
, class Y2
>
324 void test_less_than_comparable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
326 sanity_check( x1
, y1
, x2
, y2
);
327 test_less_than_comparable_aux( x1
, y1
, x2
, y2
);
328 test_less_than_comparable_aux( y1
, x1
, y2
, x2
);
331 template <class X1
, class Y1
, class X2
, class Y2
>
332 void test_equality_comparable_aux(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
334 BOOST_TEST( static_cast<bool>(x1
== y1
) == static_cast<bool>(x2
== y2
) );
335 BOOST_TEST( static_cast<bool>(x1
!= y1
) == static_cast<bool>(x2
!= y2
) );
338 template <class X1
, class Y1
, class X2
, class Y2
>
339 void test_equality_comparable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
341 sanity_check( x1
, y1
, x2
, y2
);
342 test_equality_comparable_aux( x1
, y1
, x2
, y2
);
343 test_equality_comparable_aux( y1
, x1
, y2
, x2
);
346 template <class X1
, class Y1
, class X2
, class Y2
>
347 void test_multipliable_aux(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
349 BOOST_TEST( (x1
* y1
).value() == (x2
* y2
) );
352 template <class X1
, class Y1
, class X2
, class Y2
>
353 void test_multipliable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
355 sanity_check( x1
, y1
, x2
, y2
);
356 test_multipliable_aux( x1
, y1
, x2
, y2
);
357 test_multipliable_aux( y1
, x1
, y2
, x2
);
360 template <class A
, class B
>
361 void test_value_equality(A a
, B b
)
363 BOOST_TEST(a
.value() == b
);
366 #define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
367 #define TEST_OP_L(op) test_value_equality(y1 op x1, y2 op x2)
369 template <class X1
, class Y1
, class X2
, class Y2
>
370 void test_addable_aux(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
375 template <class X1
, class Y1
, class X2
, class Y2
>
376 void test_addable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
378 sanity_check( x1
, y1
, x2
, y2
);
379 test_addable_aux( x1
, y1
, x2
, y2
);
380 test_addable_aux( y1
, x1
, y2
, x2
);
383 template <class X1
, class Y1
, class X2
, class Y2
>
384 void test_subtractable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
386 sanity_check( x1
, y1
, x2
, y2
);
390 template <class X1
, class Y1
, class X2
, class Y2
>
391 void test_subtractable_left(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
393 sanity_check( x1
, y1
, x2
, y2
);
397 template <class X1
, class Y1
, class X2
, class Y2
>
398 void test_dividable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
400 sanity_check( x1
, y1
, x2
, y2
);
405 template <class X1
, class Y1
, class X2
, class Y2
>
406 void test_dividable_left(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
408 sanity_check( x1
, y1
, x2
, y2
);
413 template <class X1
, class Y1
, class X2
, class Y2
>
414 void test_modable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
416 sanity_check( x1
, y1
, x2
, y2
);
421 template <class X1
, class Y1
, class X2
, class Y2
>
422 void test_modable_left(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
424 sanity_check( x1
, y1
, x2
, y2
);
429 template <class X1
, class Y1
, class X2
, class Y2
>
430 void test_xorable_aux(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
435 template <class X1
, class Y1
, class X2
, class Y2
>
436 void test_xorable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
438 sanity_check( x1
, y1
, x2
, y2
);
439 test_xorable_aux( x1
, y1
, x2
, y2
);
440 test_xorable_aux( y1
, x1
, y2
, x2
);
443 template <class X1
, class Y1
, class X2
, class Y2
>
444 void test_andable_aux(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
449 template <class X1
, class Y1
, class X2
, class Y2
>
450 void test_andable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
452 sanity_check( x1
, y1
, x2
, y2
);
453 test_andable_aux( x1
, y1
, x2
, y2
);
454 test_andable_aux( y1
, x1
, y2
, x2
);
457 template <class X1
, class Y1
, class X2
, class Y2
>
458 void test_orable_aux(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
463 template <class X1
, class Y1
, class X2
, class Y2
>
464 void test_orable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
466 sanity_check( x1
, y1
, x2
, y2
);
467 test_orable_aux( x1
, y1
, x2
, y2
);
468 test_orable_aux( y1
, x1
, y2
, x2
);
471 template <class X1
, class Y1
, class X2
, class Y2
>
472 void test_left_shiftable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
474 sanity_check( x1
, y1
, x2
, y2
);
478 template <class X1
, class Y1
, class X2
, class Y2
>
479 void test_right_shiftable(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
481 sanity_check( x1
, y1
, x2
, y2
);
485 template <class X1
, class X2
>
486 void test_incrementable(X1 x1
, X2 x2
)
488 sanity_check( x1
, x1
, x2
, x2
);
489 BOOST_TEST( (x1
++).value() == x2
++ );
490 BOOST_TEST( x1
.value() == x2
);
493 template <class X1
, class X2
>
494 void test_decrementable(X1 x1
, X2 x2
)
496 sanity_check( x1
, x1
, x2
, x2
);
497 BOOST_TEST( (x1
--).value() == x2
-- );
498 BOOST_TEST( x1
.value() == x2
);
501 template <class X1
, class Y1
, class X2
, class Y2
>
502 void test_all(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
504 test_less_than_comparable( x1
, y1
, x2
, y2
);
505 test_equality_comparable( x1
, y1
, x2
, y2
);
506 test_multipliable( x1
, y1
, x2
, y2
);
507 test_addable( x1
, y1
, x2
, y2
);
508 test_subtractable( x1
, y1
, x2
, y2
);
509 test_dividable( x1
, y1
, x2
, y2
);
510 test_modable( x1
, y1
, x2
, y2
);
511 test_xorable( x1
, y1
, x2
, y2
);
512 test_andable( x1
, y1
, x2
, y2
);
513 test_orable( x1
, y1
, x2
, y2
);
514 test_left_shiftable( x1
, y1
, x2
, y2
);
515 test_right_shiftable( x1
, y1
, x2
, y2
);
516 test_incrementable( x1
, x2
);
517 test_decrementable( x1
, x2
);
520 template <class X1
, class Y1
, class X2
, class Y2
>
521 void test_left(X1 x1
, Y1 y1
, X2 x2
, Y2 y2
)
523 test_subtractable_left( x1
, y1
, x2
, y2
);
524 test_dividable_left( x1
, y1
, x2
, y2
);
525 test_modable_left( x1
, y1
, x2
, y2
);
528 template <class Big
, class Small
>
531 void operator()(boost::detail::minstd_rand
& randomizer
) const
533 Big b1
= Big( randomizer() );
534 Big b2
= Big( randomizer() );
535 Small s
= Small( randomizer() );
537 test_all( Wrapped1
<Big
>(b1
), Wrapped1
<Big
>(b2
), b1
, b2
);
538 test_all( Wrapped2
<Big
, Small
>(b1
), s
, b1
, s
);
542 template <class Big
, class Small
>
545 void operator()(boost::detail::minstd_rand
& randomizer
) const
547 Big b1
= Big( randomizer() );
548 Small s
= Small( randomizer() );
550 test_left( Wrapped6
<Big
, Small
>(b1
), s
, b1
, s
);
554 // added as a regression test. We had a bug which this uncovered.
556 : boost::addable
<Point
557 , boost::subtractable
<Point
> >
559 Point( int h
, int v
) : h(h
), v(v
) {}
560 Point() :h(0), v(0) {}
561 const Point
& operator+=( const Point
& rhs
)
562 { h
+= rhs
.h
; v
+= rhs
.v
; return *this; }
563 const Point
& operator-=( const Point
& rhs
)
564 { h
-= rhs
.h
; v
-= rhs
.v
; return *this; }
570 } // unnamed namespace
573 // workaround for MSVC bug; for some reasons the compiler doesn't instantiate
574 // inherited operator templates at the moment it must, so the following
575 // explicit instantiations force it to do that.
577 #if defined(BOOST_MSVC) && (_MSC_VER < 1300)
578 template Wrapped1
<int>;
579 template Wrapped1
<long>;
580 template Wrapped1
<unsigned int>;
581 template Wrapped1
<unsigned long>;
583 template Wrapped2
<int, int>;
584 template Wrapped2
<int, signed char>;
585 template Wrapped2
<long, signed char>;
586 template Wrapped2
<long, int>;
587 template Wrapped2
<long, long>;
588 template Wrapped2
<unsigned int, unsigned int>;
589 template Wrapped2
<unsigned int, unsigned char>;
590 template Wrapped2
<unsigned long, unsigned int>;
591 template Wrapped2
<unsigned long, unsigned char>;
592 template Wrapped2
<unsigned long, unsigned long>;
594 template Wrapped6
<long, int>;
595 template Wrapped6
<long, signed char>;
596 template Wrapped6
<int, signed char>;
597 template Wrapped6
<unsigned long, unsigned int>;
598 template Wrapped6
<unsigned long, unsigned char>;
599 template Wrapped6
<unsigned int, unsigned char>;
602 #define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
615 cout
<< "Created point, and operated on it." << endl
;
618 // Using random values produce UB in various tests, such as shifting by more than the left operand capacity or signed integer overflows
619 for (int n
= 0; n
< 1000; ++n
) // was 10,000 but took too long (Beman)
621 boost::detail::minstd_rand r
;
622 tester
<long, int>()(r
);
623 tester
<long, signed char>()(r
);
624 tester
<long, long>()(r
);
625 tester
<int, int>()(r
);
626 tester
<int, signed char>()(r
);
628 tester
<unsigned long, unsigned int>()(r
);
629 tester
<unsigned long, unsigned char>()(r
);
630 tester
<unsigned long, unsigned long>()(r
);
631 tester
<unsigned int, unsigned int>()(r
);
632 tester
<unsigned int, unsigned char>()(r
);
634 tester_left
<long, int>()(r
);
635 tester_left
<long, signed char>()(r
);
636 tester_left
<int, signed char>()(r
);
638 tester_left
<unsigned long, unsigned int>()(r
);
639 tester_left
<unsigned long, unsigned char>()(r
);
640 tester_left
<unsigned int, unsigned char>()(r
);
643 cout
<< "Did random tester loop." << endl
;
644 #endif // !defined(UBSAN)
650 BOOST_TEST( i1
.value() == 1 );
651 BOOST_TEST( i2
.value() == 2 );
652 BOOST_TEST( i
.value() == 0 );
654 cout
<< "Created MyInt objects.\n";
656 PRIVATE_EXPR_TEST( (i
= i2
), (i
.value() == 2) );
658 BOOST_TEST( static_cast<bool>(i2
== i
) );
659 BOOST_TEST( static_cast<bool>(i1
!= i2
) );
660 BOOST_TEST( static_cast<bool>(i1
< i2
) );
661 BOOST_TEST( static_cast<bool>(i1
<= i2
) );
662 BOOST_TEST( static_cast<bool>(i
<= i2
) );
663 BOOST_TEST( static_cast<bool>(i2
> i1
) );
664 BOOST_TEST( static_cast<bool>(i2
>= i1
) );
665 BOOST_TEST( static_cast<bool>(i2
>= i
) );
667 PRIVATE_EXPR_TEST( (i
= i1
+ i2
), (i
.value() == 3) );
668 PRIVATE_EXPR_TEST( (i
= i
+ i2
), (i
.value() == 5) );
669 PRIVATE_EXPR_TEST( (i
= i
- i1
), (i
.value() == 4) );
670 PRIVATE_EXPR_TEST( (i
= i
* i2
), (i
.value() == 8) );
671 PRIVATE_EXPR_TEST( (i
= i
/ i2
), (i
.value() == 4) );
672 PRIVATE_EXPR_TEST( (i
= i
% ( i
- i1
)), (i
.value() == 1) );
673 PRIVATE_EXPR_TEST( (i
= i2
+ i2
), (i
.value() == 4) );
674 PRIVATE_EXPR_TEST( (i
= i1
| i2
| i
), (i
.value() == 7) );
675 PRIVATE_EXPR_TEST( (i
= i
& i2
), (i
.value() == 2) );
676 PRIVATE_EXPR_TEST( (i
= i
+ i1
), (i
.value() == 3) );
677 PRIVATE_EXPR_TEST( (i
= i
^ i1
), (i
.value() == 2) );
678 PRIVATE_EXPR_TEST( (i
= ( i
+ i1
) * ( i2
| i1
)), (i
.value() == 9) );
680 PRIVATE_EXPR_TEST( (i
= i1
<< i2
), (i
.value() == 4) );
681 PRIVATE_EXPR_TEST( (i
= i2
>> i1
), (i
.value() == 1) );
683 cout
<< "Performed tests on MyInt objects.\n";
689 BOOST_TEST( j1
.value() == 1 );
690 BOOST_TEST( j2
.value() == 2 );
691 BOOST_TEST( j
.value() == 0 );
693 cout
<< "Created MyLong objects.\n";
695 PRIVATE_EXPR_TEST( (j
= j2
), (j
.value() == 2) );
697 BOOST_TEST( static_cast<bool>(j2
== j
) );
698 BOOST_TEST( static_cast<bool>(2 == j
) );
699 BOOST_TEST( static_cast<bool>(j2
== 2) );
700 BOOST_TEST( static_cast<bool>(j
== j2
) );
701 BOOST_TEST( static_cast<bool>(j1
!= j2
) );
702 BOOST_TEST( static_cast<bool>(j1
!= 2) );
703 BOOST_TEST( static_cast<bool>(1 != j2
) );
704 BOOST_TEST( static_cast<bool>(j1
< j2
) );
705 BOOST_TEST( static_cast<bool>(1 < j2
) );
706 BOOST_TEST( static_cast<bool>(j1
< 2) );
707 BOOST_TEST( static_cast<bool>(j1
<= j2
) );
708 BOOST_TEST( static_cast<bool>(1 <= j2
) );
709 BOOST_TEST( static_cast<bool>(j1
<= j
) );
710 BOOST_TEST( static_cast<bool>(j
<= j2
) );
711 BOOST_TEST( static_cast<bool>(2 <= j2
) );
712 BOOST_TEST( static_cast<bool>(j
<= 2) );
713 BOOST_TEST( static_cast<bool>(j2
> j1
) );
714 BOOST_TEST( static_cast<bool>(2 > j1
) );
715 BOOST_TEST( static_cast<bool>(j2
> 1) );
716 BOOST_TEST( static_cast<bool>(j2
>= j1
) );
717 BOOST_TEST( static_cast<bool>(2 >= j1
) );
718 BOOST_TEST( static_cast<bool>(j2
>= 1) );
719 BOOST_TEST( static_cast<bool>(j2
>= j
) );
720 BOOST_TEST( static_cast<bool>(2 >= j
) );
721 BOOST_TEST( static_cast<bool>(j2
>= 2) );
723 BOOST_TEST( static_cast<bool>((j1
+ 2) == 3) );
724 BOOST_TEST( static_cast<bool>((1 + j2
) == 3) );
725 PRIVATE_EXPR_TEST( (j
= j1
+ j2
), (j
.value() == 3) );
727 BOOST_TEST( static_cast<bool>((j
+ 2) == 5) );
728 BOOST_TEST( static_cast<bool>((3 + j2
) == 5) );
729 PRIVATE_EXPR_TEST( (j
= j
+ j2
), (j
.value() == 5) );
731 BOOST_TEST( static_cast<bool>((j
- 1) == 4) );
732 PRIVATE_EXPR_TEST( (j
= j
- j1
), (j
.value() == 4) );
734 BOOST_TEST( static_cast<bool>((j
* 2) == 8) );
735 BOOST_TEST( static_cast<bool>((4 * j2
) == 8) );
736 PRIVATE_EXPR_TEST( (j
= j
* j2
), (j
.value() == 8) );
738 BOOST_TEST( static_cast<bool>((j
/ 2) == 4) );
739 PRIVATE_EXPR_TEST( (j
= j
/ j2
), (j
.value() == 4) );
741 BOOST_TEST( static_cast<bool>((j
% 3) == 1) );
742 PRIVATE_EXPR_TEST( (j
= j
% ( j
- j1
)), (j
.value() == 1) );
744 PRIVATE_EXPR_TEST( (j
= j2
+ j2
), (j
.value() == 4) );
746 BOOST_TEST( static_cast<bool>((1 | j2
| j
) == 7) );
747 BOOST_TEST( static_cast<bool>((j1
| 2 | j
) == 7) );
748 BOOST_TEST( static_cast<bool>((j1
| j2
| 4) == 7) );
749 PRIVATE_EXPR_TEST( (j
= j1
| j2
| j
), (j
.value() == 7) );
751 BOOST_TEST( static_cast<bool>((7 & j2
) == 2) );
752 BOOST_TEST( static_cast<bool>((j
& 2) == 2) );
753 PRIVATE_EXPR_TEST( (j
= j
& j2
), (j
.value() == 2) );
755 PRIVATE_EXPR_TEST( (j
= j
| j1
), (j
.value() == 3) );
757 BOOST_TEST( static_cast<bool>((3 ^ j1
) == 2) );
758 BOOST_TEST( static_cast<bool>((j
^ 1) == 2) );
759 PRIVATE_EXPR_TEST( (j
= j
^ j1
), (j
.value() == 2) );
761 PRIVATE_EXPR_TEST( (j
= ( j
+ j1
) * ( j2
| j1
)), (j
.value() == 9) );
763 BOOST_TEST( static_cast<bool>((j1
<< 2) == 4) );
764 BOOST_TEST( static_cast<bool>((j2
<< 1) == 4) );
765 PRIVATE_EXPR_TEST( (j
= j1
<< j2
), (j
.value() == 4) );
767 BOOST_TEST( static_cast<bool>((j
>> 2) == 1) );
768 BOOST_TEST( static_cast<bool>((j2
>> 1) == 1) );
769 PRIVATE_EXPR_TEST( (j
= j2
>> j1
), (j
.value() == 1) );
771 cout
<< "Performed tests on MyLong objects.\n";
777 BOOST_TEST( k1
.value() == 1 );
778 BOOST_TEST( k2
.value() == 2 );
779 BOOST_TEST( k
.value() == 0 );
781 cout
<< "Created MyChar objects.\n";
783 PRIVATE_EXPR_TEST( (k
= k2
), (k
.value() == 2) );
785 BOOST_TEST( static_cast<bool>(k2
== k
) );
786 BOOST_TEST( static_cast<bool>(k1
!= k2
) );
787 BOOST_TEST( static_cast<bool>(k1
< k2
) );
788 BOOST_TEST( static_cast<bool>(k1
<= k2
) );
789 BOOST_TEST( static_cast<bool>(k
<= k2
) );
790 BOOST_TEST( static_cast<bool>(k2
> k1
) );
791 BOOST_TEST( static_cast<bool>(k2
>= k1
) );
792 BOOST_TEST( static_cast<bool>(k2
>= k
) );
794 cout
<< "Performed tests on MyChar objects.\n";
800 BOOST_TEST( l1
.value() == 1 );
801 BOOST_TEST( l2
.value() == 2 );
802 BOOST_TEST( l
.value() == 0 );
804 cout
<< "Created MyShort objects.\n";
806 PRIVATE_EXPR_TEST( (l
= l2
), (l
.value() == 2) );
808 BOOST_TEST( static_cast<bool>(l2
== l
) );
809 BOOST_TEST( static_cast<bool>(2 == l
) );
810 BOOST_TEST( static_cast<bool>(l2
== 2) );
811 BOOST_TEST( static_cast<bool>(l
== l2
) );
812 BOOST_TEST( static_cast<bool>(l1
!= l2
) );
813 BOOST_TEST( static_cast<bool>(l1
!= 2) );
814 BOOST_TEST( static_cast<bool>(1 != l2
) );
815 BOOST_TEST( static_cast<bool>(l1
< l2
) );
816 BOOST_TEST( static_cast<bool>(1 < l2
) );
817 BOOST_TEST( static_cast<bool>(l1
< 2) );
818 BOOST_TEST( static_cast<bool>(l1
<= l2
) );
819 BOOST_TEST( static_cast<bool>(1 <= l2
) );
820 BOOST_TEST( static_cast<bool>(l1
<= l
) );
821 BOOST_TEST( static_cast<bool>(l
<= l2
) );
822 BOOST_TEST( static_cast<bool>(2 <= l2
) );
823 BOOST_TEST( static_cast<bool>(l
<= 2) );
824 BOOST_TEST( static_cast<bool>(l2
> l1
) );
825 BOOST_TEST( static_cast<bool>(2 > l1
) );
826 BOOST_TEST( static_cast<bool>(l2
> 1) );
827 BOOST_TEST( static_cast<bool>(l2
>= l1
) );
828 BOOST_TEST( static_cast<bool>(2 >= l1
) );
829 BOOST_TEST( static_cast<bool>(l2
>= 1) );
830 BOOST_TEST( static_cast<bool>(l2
>= l
) );
831 BOOST_TEST( static_cast<bool>(2 >= l
) );
832 BOOST_TEST( static_cast<bool>(l2
>= 2) );
834 cout
<< "Performed tests on MyShort objects.\n";
838 MyDoubleInt
half(0.5);
842 BOOST_TEST( di1
.value() == 1 );
843 BOOST_TEST( di2
.value() == 2 );
844 BOOST_TEST( di2
.value() == 2 );
845 BOOST_TEST( di
.value() == 0 );
847 cout
<< "Created MyDoubleInt objects.\n";
849 PRIVATE_EXPR_TEST( (di
= di2
), (di
.value() == 2) );
851 BOOST_TEST( static_cast<bool>(di2
== di
) );
852 BOOST_TEST( static_cast<bool>(2 == di
) );
853 BOOST_TEST( static_cast<bool>(di
== 2) );
854 BOOST_TEST( static_cast<bool>(di1
< di2
) );
855 BOOST_TEST( static_cast<bool>(1 < di2
) );
856 BOOST_TEST( static_cast<bool>(di1
<= di2
) );
857 BOOST_TEST( static_cast<bool>(1 <= di2
) );
858 BOOST_TEST( static_cast<bool>(di2
> di1
) );
859 BOOST_TEST( static_cast<bool>(di2
> 1) );
860 BOOST_TEST( static_cast<bool>(di2
>= di1
) );
861 BOOST_TEST( static_cast<bool>(di2
>= 1) );
862 BOOST_TEST( static_cast<bool>(di1
/ di2
== half
) );
863 BOOST_TEST( static_cast<bool>(di1
/ 2 == half
) );
864 BOOST_TEST( static_cast<bool>(1 / di2
== half
) );
865 PRIVATE_EXPR_TEST( (tmp
=di1
), static_cast<bool>((tmp
/=2) == half
) );
866 PRIVATE_EXPR_TEST( (tmp
=di1
), static_cast<bool>((tmp
/=di2
) == half
) );
867 BOOST_TEST( static_cast<bool>(di1
* di2
== di2
) );
868 BOOST_TEST( static_cast<bool>(di1
* 2 == di2
) );
869 BOOST_TEST( static_cast<bool>(1 * di2
== di2
) );
870 PRIVATE_EXPR_TEST( (tmp
=di1
), static_cast<bool>((tmp
*=2) == di2
) );
871 PRIVATE_EXPR_TEST( (tmp
=di1
), static_cast<bool>((tmp
*=di2
) == di2
) );
872 BOOST_TEST( static_cast<bool>(di2
- di1
== di1
) );
873 BOOST_TEST( static_cast<bool>(di2
- 1 == di1
) );
874 BOOST_TEST( static_cast<bool>(2 - di1
== di1
) );
875 PRIVATE_EXPR_TEST( (tmp
=di2
), static_cast<bool>((tmp
-=1) == di1
) );
876 PRIVATE_EXPR_TEST( (tmp
=di2
), static_cast<bool>((tmp
-=di1
) == di1
) );
877 BOOST_TEST( static_cast<bool>(di1
+ di1
== di2
) );
878 BOOST_TEST( static_cast<bool>(di1
+ 1 == di2
) );
879 BOOST_TEST( static_cast<bool>(1 + di1
== di2
) );
880 PRIVATE_EXPR_TEST( (tmp
=di1
), static_cast<bool>((tmp
+=1) == di2
) );
881 PRIVATE_EXPR_TEST( (tmp
=di1
), static_cast<bool>((tmp
+=di1
) == di2
) );
883 cout
<< "Performed tests on MyDoubleInt objects.\n";
890 BOOST_TEST( li1
.value() == 1 );
891 BOOST_TEST( li2
.value() == 2 );
892 BOOST_TEST( li
.value() == 0 );
894 cout
<< "Created MyLongInt objects.\n";
896 PRIVATE_EXPR_TEST( (li
= li2
), (li
.value() == 2) );
898 BOOST_TEST( static_cast<bool>(li2
== li
) );
899 BOOST_TEST( static_cast<bool>(2 == li
) );
900 BOOST_TEST( static_cast<bool>(li
== 2) );
901 BOOST_TEST( static_cast<bool>(li1
< li2
) );
902 BOOST_TEST( static_cast<bool>(1 < li2
) );
903 BOOST_TEST( static_cast<bool>(li1
<= li2
) );
904 BOOST_TEST( static_cast<bool>(1 <= li2
) );
905 BOOST_TEST( static_cast<bool>(li2
> li1
) );
906 BOOST_TEST( static_cast<bool>(li2
> 1) );
907 BOOST_TEST( static_cast<bool>(li2
>= li1
) );
908 BOOST_TEST( static_cast<bool>(li2
>= 1) );
909 BOOST_TEST( static_cast<bool>(li1
% li2
== li1
) );
910 BOOST_TEST( static_cast<bool>(li1
% 2 == li1
) );
911 BOOST_TEST( static_cast<bool>(1 % li2
== li1
) );
912 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
%=2) == li1
) );
913 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
%=li2
) == li1
) );
914 BOOST_TEST( static_cast<bool>(li1
/ li2
== 0) );
915 BOOST_TEST( static_cast<bool>(li1
/ 2 == 0) );
916 BOOST_TEST( static_cast<bool>(1 / li2
== 0) );
917 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
/=2) == 0) );
918 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
/=li2
) == 0) );
919 BOOST_TEST( static_cast<bool>(li1
* li2
== li2
) );
920 BOOST_TEST( static_cast<bool>(li1
* 2 == li2
) );
921 BOOST_TEST( static_cast<bool>(1 * li2
== li2
) );
922 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
*=2) == li2
) );
923 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
*=li2
) == li2
) );
924 BOOST_TEST( static_cast<bool>(li2
- li1
== li1
) );
925 BOOST_TEST( static_cast<bool>(li2
- 1 == li1
) );
926 BOOST_TEST( static_cast<bool>(2 - li1
== li1
) );
927 PRIVATE_EXPR_TEST( (tmp2
=li2
), static_cast<bool>((tmp2
-=1) == li1
) );
928 PRIVATE_EXPR_TEST( (tmp2
=li2
), static_cast<bool>((tmp2
-=li1
) == li1
) );
929 BOOST_TEST( static_cast<bool>(li1
+ li1
== li2
) );
930 BOOST_TEST( static_cast<bool>(li1
+ 1 == li2
) );
931 BOOST_TEST( static_cast<bool>(1 + li1
== li2
) );
932 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
+=1) == li2
) );
933 PRIVATE_EXPR_TEST( (tmp2
=li1
), static_cast<bool>((tmp2
+=li1
) == li2
) );
935 cout
<< "Performed tests on MyLongInt objects.\n";
937 return boost::report_errors();