operators_v1.hpp 37 KB

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