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