operators_test.cpp 33 KB

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