1 // Boost operators.hpp header file ----------------------------------------//
\r
3 // (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
\r
4 // Distributed under the Boost Software License, Version 1.0. (See
\r
5 // accompanying file LICENSE_1_0.txt or copy at
\r
6 // http://www.boost.org/LICENSE_1_0.txt)
\r
8 // See http://www.boost.org/libs/utility/operators.htm for documentation.
\r
11 // 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
\r
12 // 03 Apr 08 Make sure "convertible to bool" is sufficient
\r
13 // for T::operator<, etc. (Daniel Frey)
\r
14 // 24 May 07 Changed empty_base to depend on T, see
\r
15 // http://svn.boost.org/trac/boost/ticket/979
\r
16 // 21 Oct 02 Modified implementation of operators to allow compilers with a
\r
17 // correct named return value optimization (NRVO) to produce optimal
\r
18 // code. (Daniel Frey)
\r
19 // 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
\r
20 // 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
\r
21 // 27 Aug 01 'left' form for non commutative operators added;
\r
22 // additional classes for groups of related operators added;
\r
23 // workaround for empty base class optimization
\r
24 // bug of GCC 3.0 (Helmut Zeisel)
\r
25 // 25 Jun 01 output_iterator_helper changes: removed default template
\r
26 // parameters, added support for self-proxying, additional
\r
27 // documentation and tests (Aleksey Gurtovoy)
\r
28 // 29 May 01 Added operator classes for << and >>. Added input and output
\r
29 // iterator helper classes. Added classes to connect equality and
\r
30 // relational operators. Added classes for groups of related
\r
31 // operators. Reimplemented example operator and iterator helper
\r
32 // classes in terms of the new groups. (Daryle Walker, with help
\r
33 // from Alexy Gurtovoy)
\r
34 // 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
\r
35 // supplied arguments from actually being used (Dave Abrahams)
\r
36 // 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
\r
37 // refactoring of compiler workarounds, additional documentation
\r
38 // (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
\r
40 // 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
\r
41 // Jeremy Siek (Dave Abrahams)
\r
42 // 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
\r
44 // 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
\r
45 // 10 Jun 00 Support for the base class chaining technique was added
\r
46 // (Aleksey Gurtovoy). See documentation and the comments below
\r
47 // for the details.
\r
48 // 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
\r
49 // 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
\r
50 // specializations of dividable, subtractable, modable (Ed Brey)
\r
51 // 17 Nov 99 Add comments (Beman Dawes)
\r
52 // Remove unnecessary specialization of operators<> (Ed Brey)
\r
53 // 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
\r
54 // operators.(Beman Dawes)
\r
55 // 12 Nov 99 Add operators templates (Ed Brey)
\r
56 // 11 Nov 99 Add single template parameter version for compilers without
\r
57 // partial specialization (Beman Dawes)
\r
58 // 10 Nov 99 Initial version
\r
61 // An additional optional template parameter was added to most of
\r
62 // operator templates to support the base class chaining technique (see
\r
63 // documentation for the details). Unfortunately, a straightforward
\r
64 // implementation of this change would have broken compatibility with the
\r
65 // previous version of the library by making it impossible to use the same
\r
66 // template name (e.g. 'addable') for both the 1- and 2-argument versions of
\r
67 // an operator template. This implementation solves the backward-compatibility
\r
68 // issue at the cost of some simplicity.
\r
70 // One of the complications is an existence of special auxiliary class template
\r
71 // 'is_chained_base<>' (see 'detail' namespace below), which is used
\r
72 // to determine whether its template parameter is a library's operator template
\r
73 // or not. You have to specialize 'is_chained_base<>' for each new
\r
74 // operator template you add to the library.
\r
76 // However, most of the non-trivial implementation details are hidden behind
\r
77 // several local macros defined below, and as soon as you understand them,
\r
78 // you understand the whole library implementation.
\r
80 #ifndef BOOST_OPERATORS_HPP
\r
81 #define BOOST_OPERATORS_HPP
\r
83 #include <boost/config.hpp>
\r
84 #include <boost/iterator.hpp>
\r
85 #include <boost/detail/workaround.hpp>
\r
87 #if defined(__sgi) && !defined(__GNUC__)
\r
88 # pragma set woff 1234
\r
91 #if defined(BOOST_MSVC)
\r
92 # pragma warning( disable : 4284 ) // complaint about return type of
\r
93 #endif // operator-> not begin a UDT
\r
98 template <typename T> class empty_base {
\r
100 // Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
\r
101 #if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
\r
107 } // namespace detail
\r
108 } // namespace boost
\r
110 // In this section we supply the xxxx1 and xxxx2 forms of the operator
\r
111 // templates, which are explicitly targeted at the 1-type-argument and
\r
112 // 2-type-argument operator forms, respectively. Some compilers get confused
\r
113 // when inline friend functions are overloaded in namespaces other than the
\r
114 // global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
\r
115 // these templates must go in the global namespace.
\r
117 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
\r
122 // Basic operator classes (contributed by Dave Abrahams) ------------------//
\r
124 // Note that friend functions defined in a class are implicitly inline.
\r
125 // See the C++ std, 11.4 [class.friend] paragraph 5
\r
127 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
128 struct less_than_comparable2 : B
\r
130 friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
\r
131 friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
\r
132 friend bool operator>(const U& x, const T& y) { return y < x; }
\r
133 friend bool operator<(const U& x, const T& y) { return y > x; }
\r
134 friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
\r
135 friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
\r
138 template <class T, class B = ::boost::detail::empty_base<T> >
\r
139 struct less_than_comparable1 : B
\r
141 friend bool operator>(const T& x, const T& y) { return y < x; }
\r
142 friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
\r
143 friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
\r
146 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
147 struct equality_comparable2 : B
\r
149 friend bool operator==(const U& y, const T& x) { return x == y; }
\r
150 friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
\r
151 friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
\r
154 template <class T, class B = ::boost::detail::empty_base<T> >
\r
155 struct equality_comparable1 : B
\r
157 friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
\r
160 // A macro which produces "name_2left" from "name".
\r
161 #define BOOST_OPERATOR2_LEFT(name) name##2##_##left
\r
163 // NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
\r
165 #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
\r
167 // This is the optimal implementation for ISO/ANSI C++,
\r
168 // but it requires the compiler to implement the NRVO.
\r
169 // If the compiler has no NRVO, this is the best symmetric
\r
170 // implementation available.
\r
172 #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
\r
173 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
174 struct NAME##2 : B \
\r
176 friend T operator OP( const T& lhs, const U& rhs ) \
\r
177 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
\r
178 friend T operator OP( const U& lhs, const T& rhs ) \
\r
179 { T nrv( rhs ); nrv OP##= lhs; return nrv; } \
\r
182 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
183 struct NAME##1 : B \
\r
185 friend T operator OP( const T& lhs, const T& rhs ) \
\r
186 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
\r
189 #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
\r
190 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
191 struct NAME##2 : B \
\r
193 friend T operator OP( const T& lhs, const U& rhs ) \
\r
194 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
\r
197 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
198 struct BOOST_OPERATOR2_LEFT(NAME) : B \
\r
200 friend T operator OP( const U& lhs, const T& rhs ) \
\r
201 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
\r
204 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
205 struct NAME##1 : B \
\r
207 friend T operator OP( const T& lhs, const T& rhs ) \
\r
208 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
\r
211 #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
\r
213 // For compilers without NRVO the following code is optimal, but not
\r
214 // symmetric! Note that the implementation of
\r
215 // BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
\r
216 // optimization opportunities to the compiler :)
\r
218 #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
\r
219 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
220 struct NAME##2 : B \
\r
222 friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
\r
223 friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
\r
226 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
227 struct NAME##1 : B \
\r
229 friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
\r
232 #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
\r
233 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
234 struct NAME##2 : B \
\r
236 friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
\r
239 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
240 struct BOOST_OPERATOR2_LEFT(NAME) : B \
\r
242 friend T operator OP( const U& lhs, const T& rhs ) \
\r
243 { return T( lhs ) OP##= rhs; } \
\r
246 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
247 struct NAME##1 : B \
\r
249 friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
\r
252 #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
\r
254 BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
\r
255 BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
\r
256 BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
\r
257 BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
\r
258 BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
\r
259 BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
\r
260 BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
\r
261 BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
\r
263 #undef BOOST_BINARY_OPERATOR_COMMUTATIVE
\r
264 #undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
\r
265 #undef BOOST_OPERATOR2_LEFT
\r
267 // incrementable and decrementable contributed by Jeremy Siek
\r
269 template <class T, class B = ::boost::detail::empty_base<T> >
\r
270 struct incrementable : B
\r
272 friend T operator++(T& x, int)
\r
274 incrementable_type nrv(x);
\r
278 private: // The use of this typedef works around a Borland bug
\r
279 typedef T incrementable_type;
\r
282 template <class T, class B = ::boost::detail::empty_base<T> >
\r
283 struct decrementable : B
\r
285 friend T operator--(T& x, int)
\r
287 decrementable_type nrv(x);
\r
291 private: // The use of this typedef works around a Borland bug
\r
292 typedef T decrementable_type;
\r
295 // Iterator operator classes (contributed by Jeremy Siek) ------------------//
\r
297 template <class T, class P, class B = ::boost::detail::empty_base<T> >
\r
298 struct dereferenceable : B
\r
300 P operator->() const
\r
302 return &*static_cast<const T&>(*this);
\r
306 template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
\r
307 struct indexable : B
\r
309 R operator[](I n) const
\r
311 return *(static_cast<const T&>(*this) + n);
\r
315 // More operator classes (contributed by Daryle Walker) --------------------//
\r
316 // (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
\r
318 #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
\r
320 #define BOOST_BINARY_OPERATOR( NAME, OP ) \
\r
321 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
322 struct NAME##2 : B \
\r
324 friend T operator OP( const T& lhs, const U& rhs ) \
\r
325 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
\r
328 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
329 struct NAME##1 : B \
\r
331 friend T operator OP( const T& lhs, const T& rhs ) \
\r
332 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \
\r
335 #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
\r
337 #define BOOST_BINARY_OPERATOR( NAME, OP ) \
\r
338 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
339 struct NAME##2 : B \
\r
341 friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
\r
344 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
345 struct NAME##1 : B \
\r
347 friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
\r
350 #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
\r
352 BOOST_BINARY_OPERATOR( left_shiftable, << )
\r
353 BOOST_BINARY_OPERATOR( right_shiftable, >> )
\r
355 #undef BOOST_BINARY_OPERATOR
\r
357 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
358 struct equivalent2 : B
\r
360 friend bool operator==(const T& x, const U& y)
\r
362 return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
\r
366 template <class T, class B = ::boost::detail::empty_base<T> >
\r
367 struct equivalent1 : B
\r
369 friend bool operator==(const T&x, const T&y)
\r
371 return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
\r
375 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
376 struct partially_ordered2 : B
\r
378 friend bool operator<=(const T& x, const U& y)
\r
379 { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
\r
380 friend bool operator>=(const T& x, const U& y)
\r
381 { return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
\r
382 friend bool operator>(const U& x, const T& y)
\r
384 friend bool operator<(const U& x, const T& y)
\r
386 friend bool operator<=(const U& x, const T& y)
\r
387 { return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
\r
388 friend bool operator>=(const U& x, const T& y)
\r
389 { return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
\r
392 template <class T, class B = ::boost::detail::empty_base<T> >
\r
393 struct partially_ordered1 : B
\r
395 friend bool operator>(const T& x, const T& y)
\r
397 friend bool operator<=(const T& x, const T& y)
\r
398 { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
\r
399 friend bool operator>=(const T& x, const T& y)
\r
400 { return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
\r
403 // Combined operator classes (contributed by Daryle Walker) ----------------//
\r
405 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
406 struct totally_ordered2
\r
407 : less_than_comparable2<T, U
\r
408 , equality_comparable2<T, U, B
\r
411 template <class T, class B = ::boost::detail::empty_base<T> >
\r
412 struct totally_ordered1
\r
413 : less_than_comparable1<T
\r
414 , equality_comparable1<T, B
\r
417 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
420 , subtractable2<T, U, B
\r
423 template <class T, class B = ::boost::detail::empty_base<T> >
\r
426 , subtractable1<T, B
\r
429 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
430 struct multiplicative2
\r
431 : multipliable2<T, U
\r
432 , dividable2<T, U, B
\r
435 template <class T, class B = ::boost::detail::empty_base<T> >
\r
436 struct multiplicative1
\r
441 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
442 struct integer_multiplicative2
\r
443 : multiplicative2<T, U
\r
447 template <class T, class B = ::boost::detail::empty_base<T> >
\r
448 struct integer_multiplicative1
\r
449 : multiplicative1<T
\r
453 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
456 , multiplicative2<T, U, B
\r
459 template <class T, class B = ::boost::detail::empty_base<T> >
\r
462 , multiplicative1<T, B
\r
465 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
466 struct integer_arithmetic2
\r
468 , integer_multiplicative2<T, U, B
\r
471 template <class T, class B = ::boost::detail::empty_base<T> >
\r
472 struct integer_arithmetic1
\r
474 , integer_multiplicative1<T, B
\r
477 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
484 template <class T, class B = ::boost::detail::empty_base<T> >
\r
491 template <class T, class B = ::boost::detail::empty_base<T> >
\r
492 struct unit_steppable
\r
494 , decrementable<T, B
\r
497 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
499 : left_shiftable2<T, U
\r
500 , right_shiftable2<T, U, B
\r
503 template <class T, class B = ::boost::detail::empty_base<T> >
\r
505 : left_shiftable1<T
\r
506 , right_shiftable1<T, B
\r
509 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
510 struct ring_operators2
\r
512 , subtractable2_left<T, U
\r
513 , multipliable2<T, U, B
\r
516 template <class T, class B = ::boost::detail::empty_base<T> >
\r
517 struct ring_operators1
\r
519 , multipliable1<T, B
\r
522 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
523 struct ordered_ring_operators2
\r
524 : ring_operators2<T, U
\r
525 , totally_ordered2<T, U, B
\r
528 template <class T, class B = ::boost::detail::empty_base<T> >
\r
529 struct ordered_ring_operators1
\r
530 : ring_operators1<T
\r
531 , totally_ordered1<T, B
\r
534 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
535 struct field_operators2
\r
536 : ring_operators2<T, U
\r
538 , dividable2_left<T, U, B
\r
541 template <class T, class B = ::boost::detail::empty_base<T> >
\r
542 struct field_operators1
\r
543 : ring_operators1<T
\r
547 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
548 struct ordered_field_operators2
\r
549 : field_operators2<T, U
\r
550 , totally_ordered2<T, U, B
\r
553 template <class T, class B = ::boost::detail::empty_base<T> >
\r
554 struct ordered_field_operators1
\r
555 : field_operators1<T
\r
556 , totally_ordered1<T, B
\r
559 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
560 struct euclidian_ring_operators2
\r
561 : ring_operators2<T, U
\r
563 , dividable2_left<T, U
\r
565 , modable2_left<T, U, B
\r
568 template <class T, class B = ::boost::detail::empty_base<T> >
\r
569 struct euclidian_ring_operators1
\r
570 : ring_operators1<T
\r
575 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
576 struct ordered_euclidian_ring_operators2
\r
577 : totally_ordered2<T, U
\r
578 , euclidian_ring_operators2<T, U, B
\r
581 template <class T, class B = ::boost::detail::empty_base<T> >
\r
582 struct ordered_euclidian_ring_operators1
\r
583 : totally_ordered1<T
\r
584 , euclidian_ring_operators1<T, B
\r
587 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
588 struct euclidean_ring_operators2
\r
589 : ring_operators2<T, U
\r
591 , dividable2_left<T, U
\r
593 , modable2_left<T, U, B
\r
596 template <class T, class B = ::boost::detail::empty_base<T> >
\r
597 struct euclidean_ring_operators1
\r
598 : ring_operators1<T
\r
603 template <class T, class U, class B = ::boost::detail::empty_base<T> >
\r
604 struct ordered_euclidean_ring_operators2
\r
605 : totally_ordered2<T, U
\r
606 , euclidean_ring_operators2<T, U, B
\r
609 template <class T, class B = ::boost::detail::empty_base<T> >
\r
610 struct ordered_euclidean_ring_operators1
\r
611 : totally_ordered1<T
\r
612 , euclidean_ring_operators1<T, B
\r
615 template <class T, class P, class B = ::boost::detail::empty_base<T> >
\r
616 struct input_iteratable
\r
617 : equality_comparable1<T
\r
619 , dereferenceable<T, P, B
\r
622 template <class T, class B = ::boost::detail::empty_base<T> >
\r
623 struct output_iteratable
\r
624 : incrementable<T, B
\r
627 template <class T, class P, class B = ::boost::detail::empty_base<T> >
\r
628 struct forward_iteratable
\r
629 : input_iteratable<T, P, B
\r
632 template <class T, class P, class B = ::boost::detail::empty_base<T> >
\r
633 struct bidirectional_iteratable
\r
634 : forward_iteratable<T, P
\r
635 , decrementable<T, B
\r
638 // To avoid repeated derivation from equality_comparable,
\r
639 // which is an indirect base class of bidirectional_iterable,
\r
640 // random_access_iteratable must not be derived from totally_ordered1
\r
641 // but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
\r
642 template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
\r
643 struct random_access_iteratable
\r
644 : bidirectional_iteratable<T, P
\r
645 , less_than_comparable1<T
\r
647 , indexable<T, D, R, B
\r
650 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
\r
651 } // namespace boost
\r
652 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
\r
655 // BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
\r
657 // When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
\r
658 // operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
\r
659 // for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
\r
660 // two-argument forms. Note that these macros expect to be invoked from within
\r
663 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
\r
665 // The template is already in boost so we have nothing to do.
\r
666 # define BOOST_IMPORT_TEMPLATE4(template_name)
\r
667 # define BOOST_IMPORT_TEMPLATE3(template_name)
\r
668 # define BOOST_IMPORT_TEMPLATE2(template_name)
\r
669 # define BOOST_IMPORT_TEMPLATE1(template_name)
\r
671 #else // BOOST_NO_OPERATORS_IN_NAMESPACE
\r
673 # ifndef BOOST_NO_USING_TEMPLATE
\r
675 // Bring the names in with a using-declaration
\r
676 // to avoid stressing the compiler.
\r
677 # define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
\r
678 # define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
\r
679 # define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
\r
680 # define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
\r
684 // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
\r
685 // from working, we are forced to use inheritance for that compiler.
\r
686 # define BOOST_IMPORT_TEMPLATE4(template_name) \
\r
687 template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
\r
688 struct template_name : ::template_name<T, U, V, W, B> {};
\r
690 # define BOOST_IMPORT_TEMPLATE3(template_name) \
\r
691 template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
\r
692 struct template_name : ::template_name<T, U, V, B> {};
\r
694 # define BOOST_IMPORT_TEMPLATE2(template_name) \
\r
695 template <class T, class U, class B = ::boost::detail::empty_base<T> > \
\r
696 struct template_name : ::template_name<T, U, B> {};
\r
698 # define BOOST_IMPORT_TEMPLATE1(template_name) \
\r
699 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
700 struct template_name : ::template_name<T, B> {};
\r
702 # endif // BOOST_NO_USING_TEMPLATE
\r
704 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
\r
707 // Here's where we put it all together, defining the xxxx forms of the templates
\r
708 // in namespace boost. We also define specializations of is_chained_base<> for
\r
709 // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
\r
712 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
714 // is_chained_base<> - a traits class used to distinguish whether an operator
\r
715 // template argument is being used for base class chaining, or is specifying a
\r
716 // 2nd argument type.
\r
719 // A type parameter is used instead of a plain bool because Borland's compiler
\r
720 // didn't cope well with the more obvious non-type template parameter.
\r
724 } // namespace detail
\r
726 // Unspecialized version assumes that most types are not being used for base
\r
727 // class chaining. We specialize for the operator templates defined in this
\r
729 template<class T> struct is_chained_base {
\r
730 typedef ::boost::detail::false_t value;
\r
733 } // namespace boost
\r
735 // Import a 4-type-argument operator template into boost (if necessary) and
\r
736 // provide a specialization of 'is_chained_base<>' for it.
\r
737 # define BOOST_OPERATOR_TEMPLATE4(template_name4) \
\r
738 BOOST_IMPORT_TEMPLATE4(template_name4) \
\r
739 template<class T, class U, class V, class W, class B> \
\r
740 struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
\r
741 typedef ::boost::detail::true_t value; \
\r
744 // Import a 3-type-argument operator template into boost (if necessary) and
\r
745 // provide a specialization of 'is_chained_base<>' for it.
\r
746 # define BOOST_OPERATOR_TEMPLATE3(template_name3) \
\r
747 BOOST_IMPORT_TEMPLATE3(template_name3) \
\r
748 template<class T, class U, class V, class B> \
\r
749 struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
\r
750 typedef ::boost::detail::true_t value; \
\r
753 // Import a 2-type-argument operator template into boost (if necessary) and
\r
754 // provide a specialization of 'is_chained_base<>' for it.
\r
755 # define BOOST_OPERATOR_TEMPLATE2(template_name2) \
\r
756 BOOST_IMPORT_TEMPLATE2(template_name2) \
\r
757 template<class T, class U, class B> \
\r
758 struct is_chained_base< ::boost::template_name2<T, U, B> > { \
\r
759 typedef ::boost::detail::true_t value; \
\r
762 // Import a 1-type-argument operator template into boost (if necessary) and
\r
763 // provide a specialization of 'is_chained_base<>' for it.
\r
764 # define BOOST_OPERATOR_TEMPLATE1(template_name1) \
\r
765 BOOST_IMPORT_TEMPLATE1(template_name1) \
\r
766 template<class T, class B> \
\r
767 struct is_chained_base< ::boost::template_name1<T, B> > { \
\r
768 typedef ::boost::detail::true_t value; \
\r
771 // BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
\r
772 // can be used for specifying both 1-argument and 2-argument forms. Requires the
\r
773 // existence of two previously defined class templates named '<template_name>1'
\r
774 // and '<template_name>2' which must implement the corresponding 1- and 2-
\r
777 // The template type parameter O == is_chained_base<U>::value is used to
\r
778 // distinguish whether the 2nd argument to <template_name> is being used for
\r
779 // base class chaining from another boost operator template or is describing a
\r
780 // 2nd operand type. O == true_t only when U is actually an another operator
\r
781 // template from the library. Partial specialization is used to select an
\r
782 // implementation in terms of either '<template_name>1' or '<template_name>2'.
\r
785 # define BOOST_OPERATOR_TEMPLATE(template_name) \
\r
786 template <class T \
\r
788 ,class B = ::boost::detail::empty_base<T> \
\r
789 ,class O = typename is_chained_base<U>::value \
\r
791 struct template_name : template_name##2<T, U, B> {}; \
\r
793 template<class T, class U, class B> \
\r
794 struct template_name<T, U, B, ::boost::detail::true_t> \
\r
795 : template_name##1<T, U> {}; \
\r
797 template <class T, class B> \
\r
798 struct template_name<T, T, B, ::boost::detail::false_t> \
\r
799 : template_name##1<T, B> {}; \
\r
801 template<class T, class U, class B, class O> \
\r
802 struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
\r
803 typedef ::boost::detail::true_t value; \
\r
806 BOOST_OPERATOR_TEMPLATE2(template_name##2) \
\r
807 BOOST_OPERATOR_TEMPLATE1(template_name##1)
\r
810 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
812 # define BOOST_OPERATOR_TEMPLATE4(template_name4) \
\r
813 BOOST_IMPORT_TEMPLATE4(template_name4)
\r
814 # define BOOST_OPERATOR_TEMPLATE3(template_name3) \
\r
815 BOOST_IMPORT_TEMPLATE3(template_name3)
\r
816 # define BOOST_OPERATOR_TEMPLATE2(template_name2) \
\r
817 BOOST_IMPORT_TEMPLATE2(template_name2)
\r
818 # define BOOST_OPERATOR_TEMPLATE1(template_name1) \
\r
819 BOOST_IMPORT_TEMPLATE1(template_name1)
\r
821 // In this case we can only assume that template_name<> is equivalent to the
\r
822 // more commonly needed template_name1<> form.
\r
823 # define BOOST_OPERATOR_TEMPLATE(template_name) \
\r
824 template <class T, class B = ::boost::detail::empty_base<T> > \
\r
825 struct template_name : template_name##1<T, B> {};
\r
827 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
831 BOOST_OPERATOR_TEMPLATE(less_than_comparable)
\r
832 BOOST_OPERATOR_TEMPLATE(equality_comparable)
\r
833 BOOST_OPERATOR_TEMPLATE(multipliable)
\r
834 BOOST_OPERATOR_TEMPLATE(addable)
\r
835 BOOST_OPERATOR_TEMPLATE(subtractable)
\r
836 BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
\r
837 BOOST_OPERATOR_TEMPLATE(dividable)
\r
838 BOOST_OPERATOR_TEMPLATE2(dividable2_left)
\r
839 BOOST_OPERATOR_TEMPLATE(modable)
\r
840 BOOST_OPERATOR_TEMPLATE2(modable2_left)
\r
841 BOOST_OPERATOR_TEMPLATE(xorable)
\r
842 BOOST_OPERATOR_TEMPLATE(andable)
\r
843 BOOST_OPERATOR_TEMPLATE(orable)
\r
845 BOOST_OPERATOR_TEMPLATE1(incrementable)
\r
846 BOOST_OPERATOR_TEMPLATE1(decrementable)
\r
848 BOOST_OPERATOR_TEMPLATE2(dereferenceable)
\r
849 BOOST_OPERATOR_TEMPLATE3(indexable)
\r
851 BOOST_OPERATOR_TEMPLATE(left_shiftable)
\r
852 BOOST_OPERATOR_TEMPLATE(right_shiftable)
\r
853 BOOST_OPERATOR_TEMPLATE(equivalent)
\r
854 BOOST_OPERATOR_TEMPLATE(partially_ordered)
\r
856 BOOST_OPERATOR_TEMPLATE(totally_ordered)
\r
857 BOOST_OPERATOR_TEMPLATE(additive)
\r
858 BOOST_OPERATOR_TEMPLATE(multiplicative)
\r
859 BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
\r
860 BOOST_OPERATOR_TEMPLATE(arithmetic)
\r
861 BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
\r
862 BOOST_OPERATOR_TEMPLATE(bitwise)
\r
863 BOOST_OPERATOR_TEMPLATE1(unit_steppable)
\r
864 BOOST_OPERATOR_TEMPLATE(shiftable)
\r
865 BOOST_OPERATOR_TEMPLATE(ring_operators)
\r
866 BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
\r
867 BOOST_OPERATOR_TEMPLATE(field_operators)
\r
868 BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
\r
869 BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
\r
870 BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
\r
871 BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
\r
872 BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
\r
873 BOOST_OPERATOR_TEMPLATE2(input_iteratable)
\r
874 BOOST_OPERATOR_TEMPLATE1(output_iteratable)
\r
875 BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
\r
876 BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
\r
877 BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
\r
879 #undef BOOST_OPERATOR_TEMPLATE
\r
880 #undef BOOST_OPERATOR_TEMPLATE4
\r
881 #undef BOOST_OPERATOR_TEMPLATE3
\r
882 #undef BOOST_OPERATOR_TEMPLATE2
\r
883 #undef BOOST_OPERATOR_TEMPLATE1
\r
884 #undef BOOST_IMPORT_TEMPLATE1
\r
885 #undef BOOST_IMPORT_TEMPLATE2
\r
886 #undef BOOST_IMPORT_TEMPLATE3
\r
887 #undef BOOST_IMPORT_TEMPLATE4
\r
889 // The following 'operators' classes can only be used portably if the derived class
\r
890 // declares ALL of the required member operators.
\r
891 template <class T, class U>
\r
893 : totally_ordered2<T,U
\r
894 , integer_arithmetic2<T,U
\r
898 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
899 template <class T, class U = T>
\r
900 struct operators : operators2<T, U> {};
\r
902 template <class T> struct operators<T, T>
\r
904 template <class T> struct operators
\r
906 : totally_ordered<T
\r
907 , integer_arithmetic<T
\r
912 // Iterator helper classes (contributed by Jeremy Siek) -------------------//
\r
913 // (Input and output iterator helpers contributed by Daryle Walker) -------//
\r
914 // (Changed to use combined operator classes by Daryle Walker) ------------//
\r
917 class D = std::ptrdiff_t,
\r
918 class P = V const *,
\r
919 class R = V const &>
\r
920 struct input_iterator_helper
\r
921 : input_iteratable<T, P
\r
922 , boost::iterator<std::input_iterator_tag, V, D, P, R
\r
926 struct output_iterator_helper
\r
927 : output_iteratable<T
\r
928 , boost::iterator<std::output_iterator_tag, void, void, void, void
\r
931 T& operator*() { return static_cast<T&>(*this); }
\r
932 T& operator++() { return static_cast<T&>(*this); }
\r
937 class D = std::ptrdiff_t,
\r
940 struct forward_iterator_helper
\r
941 : forward_iteratable<T, P
\r
942 , boost::iterator<std::forward_iterator_tag, V, D, P, R
\r
947 class D = std::ptrdiff_t,
\r
950 struct bidirectional_iterator_helper
\r
951 : bidirectional_iteratable<T, P
\r
952 , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
\r
957 class D = std::ptrdiff_t,
\r
960 struct random_access_iterator_helper
\r
961 : random_access_iteratable<T, P, D, R
\r
962 , boost::iterator<std::random_access_iterator_tag, V, D, P, R
\r
965 friend D requires_difference_operator(const T& x, const T& y) {
\r
968 }; // random_access_iterator_helper
\r
970 } // namespace boost
\r
972 #if defined(__sgi) && !defined(__GNUC__)
\r
973 #pragma reset woff 1234
\r
976 #endif // BOOST_OPERATORS_HPP
\r