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