operators.hpp 36 KB

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