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