1 // Boost operators.hpp header file ----------------------------------------//
3 // (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001.
4 // Permission to copy, use, modify, sell and distribute this software is
5 // granted provided this copyright notice appears in all copies. This
6 // software is provided "as is" without express or implied warranty, and
7 // with no claim as to its suitability for any purpose.
9 // See http://www.boost.org for most recent version including documentation.
12 // 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
13 // 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
14 // 27 Aug 01 'left' form for non commutative operators added;
15 // additional classes for groups of related operators added;
16 // workaround for empty base class optimization
17 // bug of GCC 3.0 (Helmut Zeisel)
18 // 25 Jun 01 output_iterator_helper changes: removed default template
19 // parameters, added support for self-proxying, additional
20 // documentation and tests (Aleksey Gurtovoy)
21 // 29 May 01 Added operator classes for << and >>. Added input and output
22 // iterator helper classes. Added classes to connect equality and
23 // relational operators. Added classes for groups of related
24 // operators. Reimplemented example operator and iterator helper
25 // classes in terms of the new groups. (Daryle Walker, with help
26 // from Alexy Gurtovoy)
27 // 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
28 // supplied arguments from actually being used (Dave Abrahams)
29 // 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
30 // refactoring of compiler workarounds, additional documentation
31 // (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
33 // 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
34 // Jeremy Siek (Dave Abrahams)
35 // 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
37 // 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
38 // 10 Jun 00 Support for the base class chaining technique was added
39 // (Aleksey Gurtovoy). See documentation and the comments below
41 // 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
42 // 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
43 // specializations of dividable, subtractable, modable (Ed Brey)
44 // 17 Nov 99 Add comments (Beman Dawes)
45 // Remove unnecessary specialization of operators<> (Ed Brey)
46 // 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
47 // operators.(Beman Dawes)
48 // 12 Nov 99 Add operators templates (Ed Brey)
49 // 11 Nov 99 Add single template parameter version for compilers without
50 // partial specialization (Beman Dawes)
51 // 10 Nov 99 Initial version
54 // An additional optional template parameter was added to most of
55 // operator templates to support the base class chaining technique (see
56 // documentation for the details). Unfortunately, a straightforward
57 // implementation of this change would have broken compatibility with the
58 // previous version of the library by making it impossible to use the same
59 // template name (e.g. 'addable') for both the 1- and 2-argument versions of
60 // an operator template. This implementation solves the backward-compatibility
61 // issue at the cost of some simplicity.
63 // One of the complications is an existence of special auxiliary class template
64 // 'is_chained_base<>' (see 'detail' namespace below), which is used
65 // to determine whether its template parameter is a library's operator template
66 // or not. You have to specialize 'is_chained_base<>' for each new
67 // operator template you add to the library.
69 // However, most of the non-trivial implementation details are hidden behind
70 // several local macros defined below, and as soon as you understand them,
71 // you understand the whole library implementation.
73 #ifndef BOOST_OPERATORS_HPP
74 #define BOOST_OPERATORS_HPP
76 #include <boost/config.hpp>
77 #include <boost/iterator.hpp>
79 #if defined(__sgi) && !defined(__GNUC__)
83 #if defined(BOOST_MSVC)
84 # pragma warning( disable : 4284 ) // complaint about return type of
85 #endif // operator-> not begin a UDT
90 // Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
91 #if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
102 // In this section we supply the xxxx1 and xxxx2 forms of the operator
103 // templates, which are explicitly targeted at the 1-type-argument and
104 // 2-type-argument operator forms, respectively. Some compilers get confused
105 // when inline friend functions are overloaded in namespaces other than the
106 // global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
107 // these templates must go in the global namespace.
109 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
114 // Basic operator classes (contributed by Dave Abrahams) ------------------//
116 // Note that friend functions defined in a class are implicitly inline.
117 // See the C++ std, 11.4 [class.friend] paragraph 5
119 template <class T, class U, class B = ::boost::detail::empty_base>
120 struct less_than_comparable2 : B
122 friend bool operator<=(const T& x, const U& y) { return !(x > y); }
123 friend bool operator>=(const T& x, const U& y) { return !(x < y); }
124 friend bool operator>(const U& x, const T& y) { return y < x; }
125 friend bool operator<(const U& x, const T& y) { return y > x; }
126 friend bool operator<=(const U& x, const T& y) { return !(y < x); }
127 friend bool operator>=(const U& x, const T& y) { return !(y > x); }
130 template <class T, class B = ::boost::detail::empty_base>
131 struct less_than_comparable1 : B
133 friend bool operator>(const T& x, const T& y) { return y < x; }
134 friend bool operator<=(const T& x, const T& y) { return !(y < x); }
135 friend bool operator>=(const T& x, const T& y) { return !(x < y); }
138 template <class T, class U, class B = ::boost::detail::empty_base>
139 struct equality_comparable2 : B
141 friend bool operator==(const U& y, const T& x) { return x == y; }
142 friend bool operator!=(const U& y, const T& x) { return !(x == y); }
143 friend bool operator!=(const T& y, const U& x) { return !(y == x); }
146 template <class T, class B = ::boost::detail::empty_base>
147 struct equality_comparable1 : B
149 friend bool operator!=(const T& x, const T& y) { return !(x == y); }
152 template <class T, class U, class B = ::boost::detail::empty_base>
153 struct multipliable2 : B
155 friend T operator*(T x, const U& y) { return x *= y; }
156 friend T operator*(const U& y, T x) { return x *= y; }
159 template <class T, class B = ::boost::detail::empty_base>
160 struct multipliable1 : B
162 friend T operator*(T x, const T& y) { return x *= y; }
165 template <class T, class U, class B = ::boost::detail::empty_base>
168 friend T operator+(T x, const U& y) { return x += y; }
169 friend T operator+(const U& y, T x) { return x += y; }
172 template <class T, class B = ::boost::detail::empty_base>
175 friend T operator+(T x, const T& y) { return x += y; }
178 template <class T, class U, class B = ::boost::detail::empty_base>
179 struct subtractable2 : B
181 friend T operator-(T x, const U& y) { return x -= y; }
184 template <class T, class U, class B = ::boost::detail::empty_base>
185 struct subtractable2_left : B
187 friend T operator-(const U& x, const T& y)
188 { T result(x); return result -= y; }
191 template <class T, class B = ::boost::detail::empty_base>
192 struct subtractable1 : B
194 friend T operator-(T x, const T& y) { return x -= y; }
197 template <class T, class U, class B = ::boost::detail::empty_base>
198 struct dividable2 : B
200 friend T operator/(T x, const U& y) { return x /= y; }
203 template <class T, class U, class B = ::boost::detail::empty_base>
204 struct dividable2_left : B
206 friend T operator/(const U& x, const T& y)
207 { T result(x); return result /= y; }
210 template <class T, class B = ::boost::detail::empty_base>
211 struct dividable1 : B
213 friend T operator/(T x, const T& y) { return x /= y; }
216 template <class T, class U, class B = ::boost::detail::empty_base>
219 friend T operator%(T x, const U& y) { return x %= y; }
222 template <class T, class U, class B = ::boost::detail::empty_base>
223 struct modable2_left : B
225 friend T operator%(const U& x, const T& y)
226 { T result(x); return result %= y; }
229 template <class T, class B = ::boost::detail::empty_base>
232 friend T operator%(T x, const T& y) { return x %= y; }
235 template <class T, class U, class B = ::boost::detail::empty_base>
238 friend T operator^(T x, const U& y) { return x ^= y; }
239 friend T operator^(const U& y, T x) { return x ^= y; }
242 template <class T, class B = ::boost::detail::empty_base>
245 friend T operator^(T x, const T& y) { return x ^= y; }
248 template <class T, class U, class B = ::boost::detail::empty_base>
251 friend T operator&(T x, const U& y) { return x &= y; }
252 friend T operator&(const U& y, T x) { return x &= y; }
255 template <class T, class B = ::boost::detail::empty_base>
258 friend T operator&(T x, const T& y) { return x &= y; }
261 template <class T, class U, class B = ::boost::detail::empty_base>
264 friend T operator|(T x, const U& y) { return x |= y; }
265 friend T operator|(const U& y, T x) { return x |= y; }
268 template <class T, class B = ::boost::detail::empty_base>
271 friend T operator|(T x, const T& y) { return x |= y; }
274 // incrementable and decrementable contributed by Jeremy Siek
276 template <class T, class B = ::boost::detail::empty_base>
277 struct incrementable : B
279 friend T operator++(T& x, int)
281 incrementable_type tmp(x);
285 private: // The use of this typedef works around a Borland bug
286 typedef T incrementable_type;
289 template <class T, class B = ::boost::detail::empty_base>
290 struct decrementable : B
292 friend T operator--(T& x, int)
294 decrementable_type tmp(x);
298 private: // The use of this typedef works around a Borland bug
299 typedef T decrementable_type;
302 // Iterator operator classes (contributed by Jeremy Siek) ------------------//
304 template <class T, class P, class B = ::boost::detail::empty_base>
305 struct dereferenceable : B
309 return &*static_cast<const T&>(*this);
313 template <class T, class I, class R, class B = ::boost::detail::empty_base>
316 R operator[](I n) const
318 return *(static_cast<const T&>(*this) + n);
322 // More operator classes (contributed by Daryle Walker) --------------------//
324 template <class T, class U, class B = ::boost::detail::empty_base>
325 struct left_shiftable2 : B
327 friend T operator<<(T x, const U& y) { return x <<= y; }
330 template <class T, class B = ::boost::detail::empty_base>
331 struct left_shiftable1 : B
333 friend T operator<<(T x, const T& y) { return x <<= y; }
336 template <class T, class U, class B = ::boost::detail::empty_base>
337 struct right_shiftable2 : B
339 friend T operator>>(T x, const U& y) { return x >>= y; }
342 template <class T, class B = ::boost::detail::empty_base>
343 struct right_shiftable1 : B
345 friend T operator>>(T x, const T& y) { return x >>= y; }
348 template <class T, class U, class B = ::boost::detail::empty_base>
349 struct equivalent2 : B
351 friend bool operator==(const T& x, const U& y)
353 return !(x < y) && !(x > y);
357 template <class T, class B = ::boost::detail::empty_base>
358 struct equivalent1 : B
360 friend bool operator==(const T&x, const T&y)
362 return !(x < y) && !(y < x);
366 template <class T, class U, class B = ::boost::detail::empty_base>
367 struct partially_ordered2 : B
369 friend bool operator<=(const T& x, const U& y)
370 { return (x < y) || (x == y); }
371 friend bool operator>=(const T& x, const U& y)
372 { return (x > y) || (x == y); }
373 friend bool operator>(const U& x, const T& y)
375 friend bool operator<(const U& x, const T& y)
377 friend bool operator<=(const U& x, const T& y)
378 { return (y > x) || (y == x); }
379 friend bool operator>=(const U& x, const T& y)
380 { return (y < x) || (y == x); }
383 template <class T, class B = ::boost::detail::empty_base>
384 struct partially_ordered1 : B
386 friend bool operator>(const T& x, const T& y)
388 friend bool operator<=(const T& x, const T& y)
389 { return (x < y) || (x == y); }
390 friend bool operator>=(const T& x, const T& y)
391 { return (y < x) || (x == y); }
394 // Combined operator classes (contributed by Daryle Walker) ----------------//
396 template <class T, class U, class B = ::boost::detail::empty_base>
397 struct totally_ordered2
398 : less_than_comparable2<T, U
399 , equality_comparable2<T, U, B
402 template <class T, class B = ::boost::detail::empty_base>
403 struct totally_ordered1
404 : less_than_comparable1<T
405 , equality_comparable1<T, B
408 template <class T, class U, class B = ::boost::detail::empty_base>
411 , subtractable2<T, U, B
414 template <class T, class B = ::boost::detail::empty_base>
420 template <class T, class U, class B = ::boost::detail::empty_base>
421 struct multiplicative2
426 template <class T, class B = ::boost::detail::empty_base>
427 struct multiplicative1
432 template <class T, class U, class B = ::boost::detail::empty_base>
433 struct integer_multiplicative2
434 : multiplicative2<T, U
438 template <class T, class B = ::boost::detail::empty_base>
439 struct integer_multiplicative1
444 template <class T, class U, class B = ::boost::detail::empty_base>
447 , multiplicative2<T, U, B
450 template <class T, class B = ::boost::detail::empty_base>
453 , multiplicative1<T, B
456 template <class T, class U, class B = ::boost::detail::empty_base>
457 struct integer_arithmetic2
459 , integer_multiplicative2<T, U, B
462 template <class T, class B = ::boost::detail::empty_base>
463 struct integer_arithmetic1
465 , integer_multiplicative1<T, B
468 template <class T, class U, class B = ::boost::detail::empty_base>
475 template <class T, class B = ::boost::detail::empty_base>
482 template <class T, class B = ::boost::detail::empty_base>
483 struct unit_steppable
488 template <class T, class U, class B = ::boost::detail::empty_base>
490 : left_shiftable2<T, U
491 , right_shiftable2<T, U, B
494 template <class T, class B = ::boost::detail::empty_base>
497 , right_shiftable1<T, B
500 template <class T, class U, class B = ::boost::detail::empty_base>
501 struct ring_operators2
503 , subtractable2_left<T, U
504 , multipliable2<T, U, B
507 template <class T, class B = ::boost::detail::empty_base>
508 struct ring_operators1
513 template <class T, class U, class B = ::boost::detail::empty_base>
514 struct ordered_ring_operators2
515 : ring_operators2<T, U
516 , totally_ordered2<T, U, B
519 template <class T, class B = ::boost::detail::empty_base>
520 struct ordered_ring_operators1
522 , totally_ordered1<T, B
525 template <class T, class U, class B = ::boost::detail::empty_base>
526 struct field_operators2
527 : ring_operators2<T, U
529 , dividable2_left<T, U, B
532 template <class T, class B = ::boost::detail::empty_base>
533 struct field_operators1
538 template <class T, class U, class B = ::boost::detail::empty_base>
539 struct ordered_field_operators2
540 : field_operators2<T, U
541 , totally_ordered2<T, U, B
544 template <class T, class B = ::boost::detail::empty_base>
545 struct ordered_field_operators1
547 , totally_ordered1<T, B
550 template <class T, class U, class B = ::boost::detail::empty_base>
551 struct euclidian_ring_operators2
552 : ring_operators2<T, U
554 , dividable2_left<T, U
556 , modable2_left<T, U, B
559 template <class T, class B = ::boost::detail::empty_base>
560 struct euclidian_ring_operators1
566 template <class T, class U, class B = ::boost::detail::empty_base>
567 struct ordered_euclidian_ring_operators2
568 : totally_ordered2<T, U
569 , euclidian_ring_operators2<T, U, B
572 template <class T, class B = ::boost::detail::empty_base>
573 struct ordered_euclidian_ring_operators1
575 , euclidian_ring_operators1<T, B
578 template <class T, class P, class B = ::boost::detail::empty_base>
579 struct input_iteratable
580 : equality_comparable1<T
582 , dereferenceable<T, P, B
585 template <class T, class B = ::boost::detail::empty_base>
586 struct output_iteratable
590 template <class T, class P, class B = ::boost::detail::empty_base>
591 struct forward_iteratable
592 : input_iteratable<T, P, B
595 template <class T, class P, class B = ::boost::detail::empty_base>
596 struct bidirectional_iteratable
597 : forward_iteratable<T, P
601 // To avoid repeated derivation from equality_comparable,
602 // which is an indirect base class of bidirectional_iterable,
603 // random_access_iteratable must not be derived from totally_ordered1
604 // but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
605 template <class T, class P, class D, class R, class B = ::boost::detail::empty_base>
606 struct random_access_iteratable
607 : bidirectional_iteratable<T, P
608 , less_than_comparable1<T
610 , indexable<T, D, R, B
613 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
615 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
618 // BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
620 // When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
621 // operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
622 // for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
623 // two-argument forms. Note that these macros expect to be invoked from within
626 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
628 // The template is already in boost so we have nothing to do.
629 # define BOOST_IMPORT_TEMPLATE4(template_name)
630 # define BOOST_IMPORT_TEMPLATE3(template_name)
631 # define BOOST_IMPORT_TEMPLATE2(template_name)
632 # define BOOST_IMPORT_TEMPLATE1(template_name)
634 #else // BOOST_NO_OPERATORS_IN_NAMESPACE
636 # ifndef BOOST_NO_USING_TEMPLATE
638 // Bring the names in with a using-declaration
639 // to avoid stressing the compiler.
640 # define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
641 # define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
642 # define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
643 # define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
647 // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
648 // from working, we are forced to use inheritance for that compiler.
649 # define BOOST_IMPORT_TEMPLATE4(template_name) \
650 template <class T, class U, class V, class W, class B = ::boost::detail::empty_base> \
651 struct template_name : ::template_name<T, U, V, W, B> {};
653 # define BOOST_IMPORT_TEMPLATE3(template_name) \
654 template <class T, class U, class V, class B = ::boost::detail::empty_base> \
655 struct template_name : ::template_name<T, U, V, B> {};
657 # define BOOST_IMPORT_TEMPLATE2(template_name) \
658 template <class T, class U, class B = ::boost::detail::empty_base> \
659 struct template_name : ::template_name<T, U, B> {};
661 # define BOOST_IMPORT_TEMPLATE1(template_name) \
662 template <class T, class B = ::boost::detail::empty_base> \
663 struct template_name : ::template_name<T, B> {};
665 # endif // BOOST_NO_USING_TEMPLATE
667 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
670 // Here's where we put it all together, defining the xxxx forms of the templates
671 // in namespace boost. We also define specializations of is_chained_base<> for
672 // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
675 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
677 // is_chained_base<> - a traits class used to distinguish whether an operator
678 // template argument is being used for base class chaining, or is specifying a
679 // 2nd argument type.
682 // A type parameter is used instead of a plain bool because Borland's compiler
683 // didn't cope well with the more obvious non-type template parameter.
687 } // namespace detail
689 // Unspecialized version assumes that most types are not being used for base
690 // class chaining. We specialize for the operator templates defined in this
692 template<class T> struct is_chained_base {
693 typedef ::boost::detail::false_t value;
698 // Import a 4-type-argument operator template into boost (if neccessary) and
699 // provide a specialization of 'is_chained_base<>' for it.
700 # define BOOST_OPERATOR_TEMPLATE4(template_name4) \
701 BOOST_IMPORT_TEMPLATE4(template_name4) \
702 template<class T, class U, class V, class W, class B> \
703 struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
704 typedef ::boost::detail::true_t value; \
707 // Import a 3-type-argument operator template into boost (if neccessary) and
708 // provide a specialization of 'is_chained_base<>' for it.
709 # define BOOST_OPERATOR_TEMPLATE3(template_name3) \
710 BOOST_IMPORT_TEMPLATE3(template_name3) \
711 template<class T, class U, class V, class B> \
712 struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
713 typedef ::boost::detail::true_t value; \
716 // Import a 2-type-argument operator template into boost (if neccessary) and
717 // provide a specialization of 'is_chained_base<>' for it.
718 # define BOOST_OPERATOR_TEMPLATE2(template_name2) \
719 BOOST_IMPORT_TEMPLATE2(template_name2) \
720 template<class T, class U, class B> \
721 struct is_chained_base< ::boost::template_name2<T, U, B> > { \
722 typedef ::boost::detail::true_t value; \
725 // Import a 1-type-argument operator template into boost (if neccessary) and
726 // provide a specialization of 'is_chained_base<>' for it.
727 # define BOOST_OPERATOR_TEMPLATE1(template_name1) \
728 BOOST_IMPORT_TEMPLATE1(template_name1) \
729 template<class T, class B> \
730 struct is_chained_base< ::boost::template_name1<T, B> > { \
731 typedef ::boost::detail::true_t value; \
734 // BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
735 // can be used for specifying both 1-argument and 2-argument forms. Requires the
736 // existence of two previously defined class templates named '<template_name>1'
737 // and '<template_name>2' which must implement the corresponding 1- and 2-
740 // The template type parameter O == is_chained_base<U>::value is used to
741 // distinguish whether the 2nd argument to <template_name> is being used for
742 // base class chaining from another boost operator template or is describing a
743 // 2nd operand type. O == true_t only when U is actually an another operator
744 // template from the library. Partial specialization is used to select an
745 // implementation in terms of either '<template_name>1' or '<template_name>2'.
748 # define BOOST_OPERATOR_TEMPLATE(template_name) \
751 ,class B = ::boost::detail::empty_base \
752 ,class O = typename is_chained_base<U>::value \
754 struct template_name : template_name##2<T, U, B> {}; \
756 template<class T, class U, class B> \
757 struct template_name<T, U, B, ::boost::detail::true_t> \
758 : template_name##1<T, U> {}; \
760 template <class T, class B> \
761 struct template_name<T, T, B, ::boost::detail::false_t> \
762 : template_name##1<T, B> {}; \
764 template<class T, class U, class B, class O> \
765 struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
766 typedef ::boost::detail::true_t value; \
769 BOOST_OPERATOR_TEMPLATE2(template_name##2) \
770 BOOST_OPERATOR_TEMPLATE1(template_name##1)
773 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
775 # define BOOST_OPERATOR_TEMPLATE4(template_name4) \
776 BOOST_IMPORT_TEMPLATE4(template_name4)
777 # define BOOST_OPERATOR_TEMPLATE3(template_name3) \
778 BOOST_IMPORT_TEMPLATE3(template_name3)
779 # define BOOST_OPERATOR_TEMPLATE2(template_name2) \
780 BOOST_IMPORT_TEMPLATE2(template_name2)
781 # define BOOST_OPERATOR_TEMPLATE1(template_name1) \
782 BOOST_IMPORT_TEMPLATE1(template_name1)
784 // In this case we can only assume that template_name<> is equivalent to the
785 // more commonly needed template_name1<> form.
786 # define BOOST_OPERATOR_TEMPLATE(template_name) \
787 template <class T, class B = ::boost::detail::empty_base> \
788 struct template_name : template_name##1<T, B> {};
790 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
794 BOOST_OPERATOR_TEMPLATE(less_than_comparable)
795 BOOST_OPERATOR_TEMPLATE(equality_comparable)
796 BOOST_OPERATOR_TEMPLATE(multipliable)
797 BOOST_OPERATOR_TEMPLATE(addable)
798 BOOST_OPERATOR_TEMPLATE(subtractable)
799 BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
800 BOOST_OPERATOR_TEMPLATE(dividable)
801 BOOST_OPERATOR_TEMPLATE2(dividable2_left)
802 BOOST_OPERATOR_TEMPLATE(modable)
803 BOOST_OPERATOR_TEMPLATE2(modable2_left)
804 BOOST_OPERATOR_TEMPLATE(xorable)
805 BOOST_OPERATOR_TEMPLATE(andable)
806 BOOST_OPERATOR_TEMPLATE(orable)
808 BOOST_OPERATOR_TEMPLATE1(incrementable)
809 BOOST_OPERATOR_TEMPLATE1(decrementable)
811 BOOST_OPERATOR_TEMPLATE2(dereferenceable)
812 BOOST_OPERATOR_TEMPLATE3(indexable)
814 BOOST_OPERATOR_TEMPLATE(left_shiftable)
815 BOOST_OPERATOR_TEMPLATE(right_shiftable)
816 BOOST_OPERATOR_TEMPLATE(equivalent)
817 BOOST_OPERATOR_TEMPLATE(partially_ordered)
819 BOOST_OPERATOR_TEMPLATE(totally_ordered)
820 BOOST_OPERATOR_TEMPLATE(additive)
821 BOOST_OPERATOR_TEMPLATE(multiplicative)
822 BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
823 BOOST_OPERATOR_TEMPLATE(arithmetic)
824 BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
825 BOOST_OPERATOR_TEMPLATE(bitwise)
826 BOOST_OPERATOR_TEMPLATE1(unit_steppable)
827 BOOST_OPERATOR_TEMPLATE(shiftable)
828 BOOST_OPERATOR_TEMPLATE(ring_operators)
829 BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
830 BOOST_OPERATOR_TEMPLATE(field_operators)
831 BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
832 BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
833 BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
834 BOOST_OPERATOR_TEMPLATE2(input_iteratable)
835 BOOST_OPERATOR_TEMPLATE1(output_iteratable)
836 BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
837 BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
838 BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
840 #undef BOOST_OPERATOR_TEMPLATE
841 #undef BOOST_OPERATOR_TEMPLATE4
842 #undef BOOST_OPERATOR_TEMPLATE3
843 #undef BOOST_OPERATOR_TEMPLATE2
844 #undef BOOST_OPERATOR_TEMPLATE1
845 #undef BOOST_IMPORT_TEMPLATE1
846 #undef BOOST_IMPORT_TEMPLATE2
847 #undef BOOST_IMPORT_TEMPLATE3
848 #undef BOOST_IMPORT_TEMPLATE4
850 // The following 'operators' classes can only be used portably if the derived class
851 // declares ALL of the required member operators.
852 template <class T, class U>
854 : totally_ordered2<T,U
855 , integer_arithmetic2<T,U
859 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
860 template <class T, class U = T>
861 struct operators : operators2<T, U> {};
863 template <class T> struct operators<T, T>
865 template <class T> struct operators
868 , integer_arithmetic<T
873 // Iterator helper classes (contributed by Jeremy Siek) -------------------//
874 // (Input and output iterator helpers contributed by Daryle Walker) -------//
875 // (Changed to use combined operator classes by Daryle Walker) ------------//
878 class D = std::ptrdiff_t,
881 struct input_iterator_helper
882 : input_iteratable<T, P
883 , boost::iterator<std::input_iterator_tag, V, D, P, R
887 struct output_iterator_helper
888 : output_iteratable<T
889 , boost::iterator<std::output_iterator_tag, void, void, void, void
892 T& operator*() { return static_cast<T&>(*this); }
893 T& operator++() { return static_cast<T&>(*this); }
898 class D = std::ptrdiff_t,
901 struct forward_iterator_helper
902 : forward_iteratable<T, P
903 , boost::iterator<std::forward_iterator_tag, V, D, P, R
908 class D = std::ptrdiff_t,
911 struct bidirectional_iterator_helper
912 : bidirectional_iteratable<T, P
913 , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
918 class D = std::ptrdiff_t,
921 struct random_access_iterator_helper
922 : random_access_iteratable<T, P, D, R
923 , boost::iterator<std::random_access_iterator_tag, V, D, P, R
926 friend D requires_difference_operator(const T& x, const T& y) {
929 }; // random_access_iterator_helper
933 #if defined(__sgi) && !defined(__GNUC__)
934 #pragma reset woff 1234
937 #endif // BOOST_OPERATORS_HPP