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