operators.hpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. // Boost operators.hpp header file ----------------------------------------//
  2. // (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org/libs/utility/operators.htm for documentation.
  7. // Revision History
  8. // 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
  9. // (Matthew Bradbury, fixes #4432)
  10. // 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
  11. // 03 Apr 08 Make sure "convertible to bool" is sufficient
  12. // for T::operator<, etc. (Daniel Frey)
  13. // 24 May 07 Changed empty_base to depend on T, see
  14. // http://svn.boost.org/trac/boost/ticket/979
  15. // 21 Oct 02 Modified implementation of operators to allow compilers with a
  16. // correct named return value optimization (NRVO) to produce optimal
  17. // code. (Daniel Frey)
  18. // 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
  19. // 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
  20. // 27 Aug 01 'left' form for non commutative operators added;
  21. // additional classes for groups of related operators added;
  22. // workaround for empty base class optimization
  23. // bug of GCC 3.0 (Helmut Zeisel)
  24. // 25 Jun 01 output_iterator_helper changes: removed default template
  25. // parameters, added support for self-proxying, additional
  26. // documentation and tests (Aleksey Gurtovoy)
  27. // 29 May 01 Added operator classes for << and >>. Added input and output
  28. // iterator helper classes. Added classes to connect equality and
  29. // relational operators. Added classes for groups of related
  30. // operators. Reimplemented example operator and iterator helper
  31. // classes in terms of the new groups. (Daryle Walker, with help
  32. // from Alexy Gurtovoy)
  33. // 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
  34. // supplied arguments from actually being used (Dave Abrahams)
  35. // 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
  36. // refactoring of compiler workarounds, additional documentation
  37. // (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
  38. // Dave Abrahams)
  39. // 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
  40. // Jeremy Siek (Dave Abrahams)
  41. // 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
  42. // (Mark Rodgers)
  43. // 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
  44. // 10 Jun 00 Support for the base class chaining technique was added
  45. // (Aleksey Gurtovoy). See documentation and the comments below
  46. // for the details.
  47. // 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
  48. // 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
  49. // specializations of dividable, subtractable, modable (Ed Brey)
  50. // 17 Nov 99 Add comments (Beman Dawes)
  51. // Remove unnecessary specialization of operators<> (Ed Brey)
  52. // 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
  53. // operators.(Beman Dawes)
  54. // 12 Nov 99 Add operators templates (Ed Brey)
  55. // 11 Nov 99 Add single template parameter version for compilers without
  56. // partial specialization (Beman Dawes)
  57. // 10 Nov 99 Initial version
  58. // 10 Jun 00:
  59. // An additional optional template parameter was added to most of
  60. // operator templates to support the base class chaining technique (see
  61. // documentation for the details). Unfortunately, a straightforward
  62. // implementation of this change would have broken compatibility with the
  63. // previous version of the library by making it impossible to use the same
  64. // template name (e.g. 'addable') for both the 1- and 2-argument versions of
  65. // an operator template. This implementation solves the backward-compatibility
  66. // issue at the cost of some simplicity.
  67. //
  68. // One of the complications is an existence of special auxiliary class template
  69. // 'is_chained_base<>' (see 'detail' namespace below), which is used
  70. // to determine whether its template parameter is a library's operator template
  71. // or not. You have to specialize 'is_chained_base<>' for each new
  72. // operator template you add to the library.
  73. //
  74. // However, most of the non-trivial implementation details are hidden behind
  75. // several local macros defined below, and as soon as you understand them,
  76. // you understand the whole library implementation.
  77. #ifndef BOOST_OPERATORS_HPP
  78. #define BOOST_OPERATORS_HPP
  79. #include <boost/config.hpp>
  80. #include <boost/iterator.hpp>
  81. #include <boost/detail/workaround.hpp>
  82. #if defined(__sgi) && !defined(__GNUC__)
  83. # pragma set woff 1234
  84. #endif
  85. #if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
  86. # pragma warning( disable : 4284 ) // complaint about return type of
  87. #endif // operator-> not begin a UDT
  88. namespace boost {
  89. namespace detail {
  90. template <typename T> class empty_base {
  91. // Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
  92. #if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
  93. bool dummy;
  94. #endif
  95. };
  96. } // namespace detail
  97. } // namespace boost
  98. // In this section we supply the xxxx1 and xxxx2 forms of the operator
  99. // templates, which are explicitly targeted at the 1-type-argument and
  100. // 2-type-argument operator forms, respectively. Some compilers get confused
  101. // when inline friend functions are overloaded in namespaces other than the
  102. // global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
  103. // these templates must go in the global namespace.
  104. #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
  105. namespace boost
  106. {
  107. #endif
  108. // Basic operator classes (contributed by Dave Abrahams) ------------------//
  109. // Note that friend functions defined in a class are implicitly inline.
  110. // See the C++ std, 11.4 [class.friend] paragraph 5
  111. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  112. struct less_than_comparable2 : B
  113. {
  114. friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
  115. friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
  116. friend bool operator>(const U& x, const T& y) { return y < x; }
  117. friend bool operator<(const U& x, const T& y) { return y > x; }
  118. friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
  119. friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
  120. };
  121. template <class T, class B = ::boost::detail::empty_base<T> >
  122. struct less_than_comparable1 : B
  123. {
  124. friend bool operator>(const T& x, const T& y) { return y < x; }
  125. friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
  126. friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
  127. };
  128. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  129. struct equality_comparable2 : B
  130. {
  131. friend bool operator==(const U& y, const T& x) { return x == y; }
  132. friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
  133. friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
  134. };
  135. template <class T, class B = ::boost::detail::empty_base<T> >
  136. struct equality_comparable1 : B
  137. {
  138. friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
  139. };
  140. // A macro which produces "name_2left" from "name".
  141. #define BOOST_OPERATOR2_LEFT(name) name##2##_##left
  142. // NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
  143. #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
  144. // This is the optimal implementation for ISO/ANSI C++,
  145. // but it requires the compiler to implement the NRVO.
  146. // If the compiler has no NRVO, this is the best symmetric
  147. // implementation available.
  148. #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
  149. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  150. struct NAME##2 : B \
  151. { \
  152. friend T operator OP( const T& lhs, const U& rhs ) \
  153. { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
  154. friend T operator OP( const U& lhs, const T& rhs ) \
  155. { T nrv( rhs ); nrv OP##= lhs; return nrv; } \
  156. }; \
  157. \
  158. template <class T, class B = ::boost::detail::empty_base<T> > \
  159. struct NAME##1 : B \
  160. { \
  161. friend T operator OP( const T& lhs, const T& rhs ) \
  162. { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
  163. };
  164. #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
  165. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  166. struct NAME##2 : B \
  167. { \
  168. friend T operator OP( const T& lhs, const U& rhs ) \
  169. { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
  170. }; \
  171. \
  172. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  173. struct BOOST_OPERATOR2_LEFT(NAME) : B \
  174. { \
  175. friend T operator OP( const U& lhs, const T& rhs ) \
  176. { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
  177. }; \
  178. \
  179. template <class T, class B = ::boost::detail::empty_base<T> > \
  180. struct NAME##1 : B \
  181. { \
  182. friend T operator OP( const T& lhs, const T& rhs ) \
  183. { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
  184. };
  185. #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
  186. // For compilers without NRVO the following code is optimal, but not
  187. // symmetric! Note that the implementation of
  188. // BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
  189. // optimization opportunities to the compiler :)
  190. #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
  191. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  192. struct NAME##2 : B \
  193. { \
  194. friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
  195. friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
  196. }; \
  197. \
  198. template <class T, class B = ::boost::detail::empty_base<T> > \
  199. struct NAME##1 : B \
  200. { \
  201. friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
  202. };
  203. #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
  204. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  205. struct NAME##2 : B \
  206. { \
  207. friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
  208. }; \
  209. \
  210. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  211. struct BOOST_OPERATOR2_LEFT(NAME) : B \
  212. { \
  213. friend T operator OP( const U& lhs, const T& rhs ) \
  214. { return T( lhs ) OP##= rhs; } \
  215. }; \
  216. \
  217. template <class T, class B = ::boost::detail::empty_base<T> > \
  218. struct NAME##1 : B \
  219. { \
  220. friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
  221. };
  222. #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
  223. BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
  224. BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
  225. BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
  226. BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
  227. BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
  228. BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
  229. BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
  230. BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
  231. #undef BOOST_BINARY_OPERATOR_COMMUTATIVE
  232. #undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
  233. #undef BOOST_OPERATOR2_LEFT
  234. // incrementable and decrementable contributed by Jeremy Siek
  235. template <class T, class B = ::boost::detail::empty_base<T> >
  236. struct incrementable : B
  237. {
  238. friend T operator++(T& x, int)
  239. {
  240. incrementable_type nrv(x);
  241. ++x;
  242. return nrv;
  243. }
  244. private: // The use of this typedef works around a Borland bug
  245. typedef T incrementable_type;
  246. };
  247. template <class T, class B = ::boost::detail::empty_base<T> >
  248. struct decrementable : B
  249. {
  250. friend T operator--(T& x, int)
  251. {
  252. decrementable_type nrv(x);
  253. --x;
  254. return nrv;
  255. }
  256. private: // The use of this typedef works around a Borland bug
  257. typedef T decrementable_type;
  258. };
  259. // Iterator operator classes (contributed by Jeremy Siek) ------------------//
  260. template <class T, class P, class B = ::boost::detail::empty_base<T> >
  261. struct dereferenceable : B
  262. {
  263. P operator->() const
  264. {
  265. return &*static_cast<const T&>(*this);
  266. }
  267. };
  268. template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
  269. struct indexable : B
  270. {
  271. R operator[](I n) const
  272. {
  273. return *(static_cast<const T&>(*this) + n);
  274. }
  275. };
  276. // More operator classes (contributed by Daryle Walker) --------------------//
  277. // (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
  278. #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
  279. #define BOOST_BINARY_OPERATOR( NAME, OP ) \
  280. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  281. struct NAME##2 : B \
  282. { \
  283. friend T operator OP( const T& lhs, const U& rhs ) \
  284. { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
  285. }; \
  286. \
  287. template <class T, class B = ::boost::detail::empty_base<T> > \
  288. struct NAME##1 : B \
  289. { \
  290. friend T operator OP( const T& lhs, const T& rhs ) \
  291. { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
  292. };
  293. #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
  294. #define BOOST_BINARY_OPERATOR( NAME, OP ) \
  295. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  296. struct NAME##2 : B \
  297. { \
  298. friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
  299. }; \
  300. \
  301. template <class T, class B = ::boost::detail::empty_base<T> > \
  302. struct NAME##1 : B \
  303. { \
  304. friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
  305. };
  306. #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
  307. BOOST_BINARY_OPERATOR( left_shiftable, << )
  308. BOOST_BINARY_OPERATOR( right_shiftable, >> )
  309. #undef BOOST_BINARY_OPERATOR
  310. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  311. struct equivalent2 : B
  312. {
  313. friend bool operator==(const T& x, const U& y)
  314. {
  315. return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
  316. }
  317. };
  318. template <class T, class B = ::boost::detail::empty_base<T> >
  319. struct equivalent1 : B
  320. {
  321. friend bool operator==(const T&x, const T&y)
  322. {
  323. return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
  324. }
  325. };
  326. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  327. struct partially_ordered2 : B
  328. {
  329. friend bool operator<=(const T& x, const U& y)
  330. { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
  331. friend bool operator>=(const T& x, const U& y)
  332. { return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
  333. friend bool operator>(const U& x, const T& y)
  334. { return y < x; }
  335. friend bool operator<(const U& x, const T& y)
  336. { return y > x; }
  337. friend bool operator<=(const U& x, const T& y)
  338. { return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
  339. friend bool operator>=(const U& x, const T& y)
  340. { return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
  341. };
  342. template <class T, class B = ::boost::detail::empty_base<T> >
  343. struct partially_ordered1 : B
  344. {
  345. friend bool operator>(const T& x, const T& y)
  346. { return y < x; }
  347. friend bool operator<=(const T& x, const T& y)
  348. { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
  349. friend bool operator>=(const T& x, const T& y)
  350. { return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
  351. };
  352. // Combined operator classes (contributed by Daryle Walker) ----------------//
  353. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  354. struct totally_ordered2
  355. : less_than_comparable2<T, U
  356. , equality_comparable2<T, U, B
  357. > > {};
  358. template <class T, class B = ::boost::detail::empty_base<T> >
  359. struct totally_ordered1
  360. : less_than_comparable1<T
  361. , equality_comparable1<T, B
  362. > > {};
  363. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  364. struct additive2
  365. : addable2<T, U
  366. , subtractable2<T, U, B
  367. > > {};
  368. template <class T, class B = ::boost::detail::empty_base<T> >
  369. struct additive1
  370. : addable1<T
  371. , subtractable1<T, B
  372. > > {};
  373. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  374. struct multiplicative2
  375. : multipliable2<T, U
  376. , dividable2<T, U, B
  377. > > {};
  378. template <class T, class B = ::boost::detail::empty_base<T> >
  379. struct multiplicative1
  380. : multipliable1<T
  381. , dividable1<T, B
  382. > > {};
  383. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  384. struct integer_multiplicative2
  385. : multiplicative2<T, U
  386. , modable2<T, U, B
  387. > > {};
  388. template <class T, class B = ::boost::detail::empty_base<T> >
  389. struct integer_multiplicative1
  390. : multiplicative1<T
  391. , modable1<T, B
  392. > > {};
  393. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  394. struct arithmetic2
  395. : additive2<T, U
  396. , multiplicative2<T, U, B
  397. > > {};
  398. template <class T, class B = ::boost::detail::empty_base<T> >
  399. struct arithmetic1
  400. : additive1<T
  401. , multiplicative1<T, B
  402. > > {};
  403. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  404. struct integer_arithmetic2
  405. : additive2<T, U
  406. , integer_multiplicative2<T, U, B
  407. > > {};
  408. template <class T, class B = ::boost::detail::empty_base<T> >
  409. struct integer_arithmetic1
  410. : additive1<T
  411. , integer_multiplicative1<T, B
  412. > > {};
  413. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  414. struct bitwise2
  415. : xorable2<T, U
  416. , andable2<T, U
  417. , orable2<T, U, B
  418. > > > {};
  419. template <class T, class B = ::boost::detail::empty_base<T> >
  420. struct bitwise1
  421. : xorable1<T
  422. , andable1<T
  423. , orable1<T, B
  424. > > > {};
  425. template <class T, class B = ::boost::detail::empty_base<T> >
  426. struct unit_steppable
  427. : incrementable<T
  428. , decrementable<T, B
  429. > > {};
  430. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  431. struct shiftable2
  432. : left_shiftable2<T, U
  433. , right_shiftable2<T, U, B
  434. > > {};
  435. template <class T, class B = ::boost::detail::empty_base<T> >
  436. struct shiftable1
  437. : left_shiftable1<T
  438. , right_shiftable1<T, B
  439. > > {};
  440. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  441. struct ring_operators2
  442. : additive2<T, U
  443. , subtractable2_left<T, U
  444. , multipliable2<T, U, B
  445. > > > {};
  446. template <class T, class B = ::boost::detail::empty_base<T> >
  447. struct ring_operators1
  448. : additive1<T
  449. , multipliable1<T, B
  450. > > {};
  451. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  452. struct ordered_ring_operators2
  453. : ring_operators2<T, U
  454. , totally_ordered2<T, U, B
  455. > > {};
  456. template <class T, class B = ::boost::detail::empty_base<T> >
  457. struct ordered_ring_operators1
  458. : ring_operators1<T
  459. , totally_ordered1<T, B
  460. > > {};
  461. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  462. struct field_operators2
  463. : ring_operators2<T, U
  464. , dividable2<T, U
  465. , dividable2_left<T, U, B
  466. > > > {};
  467. template <class T, class B = ::boost::detail::empty_base<T> >
  468. struct field_operators1
  469. : ring_operators1<T
  470. , dividable1<T, B
  471. > > {};
  472. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  473. struct ordered_field_operators2
  474. : field_operators2<T, U
  475. , totally_ordered2<T, U, B
  476. > > {};
  477. template <class T, class B = ::boost::detail::empty_base<T> >
  478. struct ordered_field_operators1
  479. : field_operators1<T
  480. , totally_ordered1<T, B
  481. > > {};
  482. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  483. struct euclidian_ring_operators2
  484. : ring_operators2<T, U
  485. , dividable2<T, U
  486. , dividable2_left<T, U
  487. , modable2<T, U
  488. , modable2_left<T, U, B
  489. > > > > > {};
  490. template <class T, class B = ::boost::detail::empty_base<T> >
  491. struct euclidian_ring_operators1
  492. : ring_operators1<T
  493. , dividable1<T
  494. , modable1<T, B
  495. > > > {};
  496. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  497. struct ordered_euclidian_ring_operators2
  498. : totally_ordered2<T, U
  499. , euclidian_ring_operators2<T, U, B
  500. > > {};
  501. template <class T, class B = ::boost::detail::empty_base<T> >
  502. struct ordered_euclidian_ring_operators1
  503. : totally_ordered1<T
  504. , euclidian_ring_operators1<T, B
  505. > > {};
  506. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  507. struct euclidean_ring_operators2
  508. : ring_operators2<T, U
  509. , dividable2<T, U
  510. , dividable2_left<T, U
  511. , modable2<T, U
  512. , modable2_left<T, U, B
  513. > > > > > {};
  514. template <class T, class B = ::boost::detail::empty_base<T> >
  515. struct euclidean_ring_operators1
  516. : ring_operators1<T
  517. , dividable1<T
  518. , modable1<T, B
  519. > > > {};
  520. template <class T, class U, class B = ::boost::detail::empty_base<T> >
  521. struct ordered_euclidean_ring_operators2
  522. : totally_ordered2<T, U
  523. , euclidean_ring_operators2<T, U, B
  524. > > {};
  525. template <class T, class B = ::boost::detail::empty_base<T> >
  526. struct ordered_euclidean_ring_operators1
  527. : totally_ordered1<T
  528. , euclidean_ring_operators1<T, B
  529. > > {};
  530. template <class T, class P, class B = ::boost::detail::empty_base<T> >
  531. struct input_iteratable
  532. : equality_comparable1<T
  533. , incrementable<T
  534. , dereferenceable<T, P, B
  535. > > > {};
  536. template <class T, class B = ::boost::detail::empty_base<T> >
  537. struct output_iteratable
  538. : incrementable<T, B
  539. > {};
  540. template <class T, class P, class B = ::boost::detail::empty_base<T> >
  541. struct forward_iteratable
  542. : input_iteratable<T, P, B
  543. > {};
  544. template <class T, class P, class B = ::boost::detail::empty_base<T> >
  545. struct bidirectional_iteratable
  546. : forward_iteratable<T, P
  547. , decrementable<T, B
  548. > > {};
  549. // To avoid repeated derivation from equality_comparable,
  550. // which is an indirect base class of bidirectional_iterable,
  551. // random_access_iteratable must not be derived from totally_ordered1
  552. // but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
  553. template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
  554. struct random_access_iteratable
  555. : bidirectional_iteratable<T, P
  556. , less_than_comparable1<T
  557. , additive2<T, D
  558. , indexable<T, D, R, B
  559. > > > > {};
  560. #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
  561. } // namespace boost
  562. #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
  563. // BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
  564. //
  565. // When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
  566. // operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
  567. // for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
  568. // two-argument forms. Note that these macros expect to be invoked from within
  569. // boost.
  570. #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
  571. // The template is already in boost so we have nothing to do.
  572. # define BOOST_IMPORT_TEMPLATE4(template_name)
  573. # define BOOST_IMPORT_TEMPLATE3(template_name)
  574. # define BOOST_IMPORT_TEMPLATE2(template_name)
  575. # define BOOST_IMPORT_TEMPLATE1(template_name)
  576. #else // BOOST_NO_OPERATORS_IN_NAMESPACE
  577. # ifndef BOOST_NO_USING_TEMPLATE
  578. // Bring the names in with a using-declaration
  579. // to avoid stressing the compiler.
  580. # define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
  581. # define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
  582. # define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
  583. # define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
  584. # else
  585. // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
  586. // from working, we are forced to use inheritance for that compiler.
  587. # define BOOST_IMPORT_TEMPLATE4(template_name) \
  588. template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
  589. struct template_name : ::template_name<T, U, V, W, B> {};
  590. # define BOOST_IMPORT_TEMPLATE3(template_name) \
  591. template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
  592. struct template_name : ::template_name<T, U, V, B> {};
  593. # define BOOST_IMPORT_TEMPLATE2(template_name) \
  594. template <class T, class U, class B = ::boost::detail::empty_base<T> > \
  595. struct template_name : ::template_name<T, U, B> {};
  596. # define BOOST_IMPORT_TEMPLATE1(template_name) \
  597. template <class T, class B = ::boost::detail::empty_base<T> > \
  598. struct template_name : ::template_name<T, B> {};
  599. # endif // BOOST_NO_USING_TEMPLATE
  600. #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
  601. //
  602. // Here's where we put it all together, defining the xxxx forms of the templates
  603. // in namespace boost. We also define specializations of is_chained_base<> for
  604. // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
  605. // necessary.
  606. //
  607. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  608. // is_chained_base<> - a traits class used to distinguish whether an operator
  609. // template argument is being used for base class chaining, or is specifying a
  610. // 2nd argument type.
  611. namespace boost {
  612. // A type parameter is used instead of a plain bool because Borland's compiler
  613. // didn't cope well with the more obvious non-type template parameter.
  614. namespace detail {
  615. struct true_t {};
  616. struct false_t {};
  617. } // namespace detail
  618. // Unspecialized version assumes that most types are not being used for base
  619. // class chaining. We specialize for the operator templates defined in this
  620. // library.
  621. template<class T> struct is_chained_base {
  622. typedef ::boost::detail::false_t value;
  623. };
  624. } // namespace boost
  625. // Import a 4-type-argument operator template into boost (if necessary) and
  626. // provide a specialization of 'is_chained_base<>' for it.
  627. # define BOOST_OPERATOR_TEMPLATE4(template_name4) \
  628. BOOST_IMPORT_TEMPLATE4(template_name4) \
  629. template<class T, class U, class V, class W, class B> \
  630. struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
  631. typedef ::boost::detail::true_t value; \
  632. };
  633. // Import a 3-type-argument operator template into boost (if necessary) and
  634. // provide a specialization of 'is_chained_base<>' for it.
  635. # define BOOST_OPERATOR_TEMPLATE3(template_name3) \
  636. BOOST_IMPORT_TEMPLATE3(template_name3) \
  637. template<class T, class U, class V, class B> \
  638. struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
  639. typedef ::boost::detail::true_t value; \
  640. };
  641. // Import a 2-type-argument operator template into boost (if necessary) and
  642. // provide a specialization of 'is_chained_base<>' for it.
  643. # define BOOST_OPERATOR_TEMPLATE2(template_name2) \
  644. BOOST_IMPORT_TEMPLATE2(template_name2) \
  645. template<class T, class U, class B> \
  646. struct is_chained_base< ::boost::template_name2<T, U, B> > { \
  647. typedef ::boost::detail::true_t value; \
  648. };
  649. // Import a 1-type-argument operator template into boost (if necessary) and
  650. // provide a specialization of 'is_chained_base<>' for it.
  651. # define BOOST_OPERATOR_TEMPLATE1(template_name1) \
  652. BOOST_IMPORT_TEMPLATE1(template_name1) \
  653. template<class T, class B> \
  654. struct is_chained_base< ::boost::template_name1<T, B> > { \
  655. typedef ::boost::detail::true_t value; \
  656. };
  657. // BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
  658. // can be used for specifying both 1-argument and 2-argument forms. Requires the
  659. // existence of two previously defined class templates named '<template_name>1'
  660. // and '<template_name>2' which must implement the corresponding 1- and 2-
  661. // argument forms.
  662. //
  663. // The template type parameter O == is_chained_base<U>::value is used to
  664. // distinguish whether the 2nd argument to <template_name> is being used for
  665. // base class chaining from another boost operator template or is describing a
  666. // 2nd operand type. O == true_t only when U is actually an another operator
  667. // template from the library. Partial specialization is used to select an
  668. // implementation in terms of either '<template_name>1' or '<template_name>2'.
  669. //
  670. # define BOOST_OPERATOR_TEMPLATE(template_name) \
  671. template <class T \
  672. ,class U = T \
  673. ,class B = ::boost::detail::empty_base<T> \
  674. ,class O = typename is_chained_base<U>::value \
  675. > \
  676. struct template_name : template_name##2<T, U, B> {}; \
  677. \
  678. template<class T, class U, class B> \
  679. struct template_name<T, U, B, ::boost::detail::true_t> \
  680. : template_name##1<T, U> {}; \
  681. \
  682. template <class T, class B> \
  683. struct template_name<T, T, B, ::boost::detail::false_t> \
  684. : template_name##1<T, B> {}; \
  685. \
  686. template<class T, class U, class B, class O> \
  687. struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
  688. typedef ::boost::detail::true_t value; \
  689. }; \
  690. \
  691. BOOST_OPERATOR_TEMPLATE2(template_name##2) \
  692. BOOST_OPERATOR_TEMPLATE1(template_name##1)
  693. #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  694. # define BOOST_OPERATOR_TEMPLATE4(template_name4) \
  695. BOOST_IMPORT_TEMPLATE4(template_name4)
  696. # define BOOST_OPERATOR_TEMPLATE3(template_name3) \
  697. BOOST_IMPORT_TEMPLATE3(template_name3)
  698. # define BOOST_OPERATOR_TEMPLATE2(template_name2) \
  699. BOOST_IMPORT_TEMPLATE2(template_name2)
  700. # define BOOST_OPERATOR_TEMPLATE1(template_name1) \
  701. BOOST_IMPORT_TEMPLATE1(template_name1)
  702. // In this case we can only assume that template_name<> is equivalent to the
  703. // more commonly needed template_name1<> form.
  704. # define BOOST_OPERATOR_TEMPLATE(template_name) \
  705. template <class T, class B = ::boost::detail::empty_base<T> > \
  706. struct template_name : template_name##1<T, B> {};
  707. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  708. namespace boost {
  709. BOOST_OPERATOR_TEMPLATE(less_than_comparable)
  710. BOOST_OPERATOR_TEMPLATE(equality_comparable)
  711. BOOST_OPERATOR_TEMPLATE(multipliable)
  712. BOOST_OPERATOR_TEMPLATE(addable)
  713. BOOST_OPERATOR_TEMPLATE(subtractable)
  714. BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
  715. BOOST_OPERATOR_TEMPLATE(dividable)
  716. BOOST_OPERATOR_TEMPLATE2(dividable2_left)
  717. BOOST_OPERATOR_TEMPLATE(modable)
  718. BOOST_OPERATOR_TEMPLATE2(modable2_left)
  719. BOOST_OPERATOR_TEMPLATE(xorable)
  720. BOOST_OPERATOR_TEMPLATE(andable)
  721. BOOST_OPERATOR_TEMPLATE(orable)
  722. BOOST_OPERATOR_TEMPLATE1(incrementable)
  723. BOOST_OPERATOR_TEMPLATE1(decrementable)
  724. BOOST_OPERATOR_TEMPLATE2(dereferenceable)
  725. BOOST_OPERATOR_TEMPLATE3(indexable)
  726. BOOST_OPERATOR_TEMPLATE(left_shiftable)
  727. BOOST_OPERATOR_TEMPLATE(right_shiftable)
  728. BOOST_OPERATOR_TEMPLATE(equivalent)
  729. BOOST_OPERATOR_TEMPLATE(partially_ordered)
  730. BOOST_OPERATOR_TEMPLATE(totally_ordered)
  731. BOOST_OPERATOR_TEMPLATE(additive)
  732. BOOST_OPERATOR_TEMPLATE(multiplicative)
  733. BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
  734. BOOST_OPERATOR_TEMPLATE(arithmetic)
  735. BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
  736. BOOST_OPERATOR_TEMPLATE(bitwise)
  737. BOOST_OPERATOR_TEMPLATE1(unit_steppable)
  738. BOOST_OPERATOR_TEMPLATE(shiftable)
  739. BOOST_OPERATOR_TEMPLATE(ring_operators)
  740. BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
  741. BOOST_OPERATOR_TEMPLATE(field_operators)
  742. BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
  743. BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
  744. BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
  745. BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
  746. BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
  747. BOOST_OPERATOR_TEMPLATE2(input_iteratable)
  748. BOOST_OPERATOR_TEMPLATE1(output_iteratable)
  749. BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
  750. BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
  751. BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
  752. #undef BOOST_OPERATOR_TEMPLATE
  753. #undef BOOST_OPERATOR_TEMPLATE4
  754. #undef BOOST_OPERATOR_TEMPLATE3
  755. #undef BOOST_OPERATOR_TEMPLATE2
  756. #undef BOOST_OPERATOR_TEMPLATE1
  757. #undef BOOST_IMPORT_TEMPLATE1
  758. #undef BOOST_IMPORT_TEMPLATE2
  759. #undef BOOST_IMPORT_TEMPLATE3
  760. #undef BOOST_IMPORT_TEMPLATE4
  761. // The following 'operators' classes can only be used portably if the derived class
  762. // declares ALL of the required member operators.
  763. template <class T, class U>
  764. struct operators2
  765. : totally_ordered2<T,U
  766. , integer_arithmetic2<T,U
  767. , bitwise2<T,U
  768. > > > {};
  769. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  770. template <class T, class U = T>
  771. struct operators : operators2<T, U> {};
  772. template <class T> struct operators<T, T>
  773. #else
  774. template <class T> struct operators
  775. #endif
  776. : totally_ordered<T
  777. , integer_arithmetic<T
  778. , bitwise<T
  779. , unit_steppable<T
  780. > > > > {};
  781. // Iterator helper classes (contributed by Jeremy Siek) -------------------//
  782. // (Input and output iterator helpers contributed by Daryle Walker) -------//
  783. // (Changed to use combined operator classes by Daryle Walker) ------------//
  784. template <class T,
  785. class V,
  786. class D = std::ptrdiff_t,
  787. class P = V const *,
  788. class R = V const &>
  789. struct input_iterator_helper
  790. : input_iteratable<T, P
  791. , boost::iterator<std::input_iterator_tag, V, D, P, R
  792. > > {};
  793. template<class T>
  794. struct output_iterator_helper
  795. : output_iteratable<T
  796. , boost::iterator<std::output_iterator_tag, void, void, void, void
  797. > >
  798. {
  799. T& operator*() { return static_cast<T&>(*this); }
  800. T& operator++() { return static_cast<T&>(*this); }
  801. };
  802. template <class T,
  803. class V,
  804. class D = std::ptrdiff_t,
  805. class P = V*,
  806. class R = V&>
  807. struct forward_iterator_helper
  808. : forward_iteratable<T, P
  809. , boost::iterator<std::forward_iterator_tag, V, D, P, R
  810. > > {};
  811. template <class T,
  812. class V,
  813. class D = std::ptrdiff_t,
  814. class P = V*,
  815. class R = V&>
  816. struct bidirectional_iterator_helper
  817. : bidirectional_iteratable<T, P
  818. , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
  819. > > {};
  820. template <class T,
  821. class V,
  822. class D = std::ptrdiff_t,
  823. class P = V*,
  824. class R = V&>
  825. struct random_access_iterator_helper
  826. : random_access_iteratable<T, P, D, R
  827. , boost::iterator<std::random_access_iterator_tag, V, D, P, R
  828. > >
  829. {
  830. friend D requires_difference_operator(const T& x, const T& y) {
  831. return x - y;
  832. }
  833. }; // random_access_iterator_helper
  834. } // namespace boost
  835. #if defined(__sgi) && !defined(__GNUC__)
  836. #pragma reset woff 1234
  837. #endif
  838. #endif // BOOST_OPERATORS_HPP