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