]> git.lyx.org Git - lyx.git/blob - boost/boost/operators.hpp
typos
[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 //  21 Oct 02 Modified implementation of operators to allow compilers with a
12 //            correct named return value optimization (NRVO) to produce optimal
13 //            code.  (Daniel Frey)
14 //  02 Dec 01 Bug fixed in random_access_iteratable.  (Helmut Zeisel)
15 //  28 Sep 01 Factored out iterator operator groups.  (Daryle Walker)
16 //  27 Aug 01 'left' form for non commutative operators added;
17 //            additional classes for groups of related operators added;
18 //            workaround for empty base class optimization
19 //            bug of GCC 3.0 (Helmut Zeisel)
20 //  25 Jun 01 output_iterator_helper changes: removed default template 
21 //            parameters, added support for self-proxying, additional 
22 //            documentation and tests (Aleksey Gurtovoy)
23 //  29 May 01 Added operator classes for << and >>.  Added input and output
24 //            iterator helper classes.  Added classes to connect equality and
25 //            relational operators.  Added classes for groups of related
26 //            operators.  Reimplemented example operator and iterator helper
27 //            classes in terms of the new groups.  (Daryle Walker, with help
28 //            from Alexy Gurtovoy)
29 //  11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
30 //            supplied arguments from actually being used (Dave Abrahams)
31 //  04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
32 //            refactoring of compiler workarounds, additional documentation
33 //            (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
34 //            Dave Abrahams) 
35 //  28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
36 //            Jeremy Siek (Dave Abrahams)
37 //  20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
38 //            (Mark Rodgers)
39 //  20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
40 //  10 Jun 00 Support for the base class chaining technique was added
41 //            (Aleksey Gurtovoy). See documentation and the comments below 
42 //            for the details. 
43 //  12 Dec 99 Initial version with iterator operators (Jeremy Siek)
44 //  18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
45 //            specializations of dividable, subtractable, modable (Ed Brey) 
46 //  17 Nov 99 Add comments (Beman Dawes)
47 //            Remove unnecessary specialization of operators<> (Ed Brey)
48 //  15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
49 //            operators.(Beman Dawes)
50 //  12 Nov 99 Add operators templates (Ed Brey)
51 //  11 Nov 99 Add single template parameter version for compilers without
52 //            partial specialization (Beman Dawes)
53 //  10 Nov 99 Initial version
54
55 // 10 Jun 00:
56 // An additional optional template parameter was added to most of 
57 // operator templates to support the base class chaining technique (see 
58 // documentation for the details). Unfortunately, a straightforward
59 // implementation of this change would have broken compatibility with the
60 // previous version of the library by making it impossible to use the same
61 // template name (e.g. 'addable') for both the 1- and 2-argument versions of
62 // an operator template. This implementation solves the backward-compatibility
63 // issue at the cost of some simplicity.
64 //
65 // One of the complications is an existence of special auxiliary class template
66 // 'is_chained_base<>' (see 'detail' namespace below), which is used
67 // to determine whether its template parameter is a library's operator template
68 // or not. You have to specialize 'is_chained_base<>' for each new 
69 // operator template you add to the library.
70 //
71 // However, most of the non-trivial implementation details are hidden behind 
72 // several local macros defined below, and as soon as you understand them,
73 // you understand the whole library implementation. 
74
75 #ifndef BOOST_OPERATORS_HPP
76 #define BOOST_OPERATORS_HPP
77
78 #include <boost/config.hpp>
79 #include <boost/iterator.hpp>
80 #include <boost/detail/workaround.hpp>
81
82 #if defined(__sgi) && !defined(__GNUC__)
83 #   pragma set woff 1234
84 #endif
85
86 #if defined(BOOST_MSVC)
87 #   pragma warning( disable : 4284 ) // complaint about return type of 
88 #endif                               // operator-> not begin a UDT
89
90 namespace boost {
91 namespace detail {
92
93 // Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
94 #if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
95 class empty_base {
96   bool dummy; 
97 };
98 #else
99 class empty_base {};
100 #endif
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>
123 struct less_than_comparable2 : B
124 {
125      friend bool operator<=(const T& x, const U& y) { return !(x > y); }
126      friend bool operator>=(const T& x, const U& y) { return !(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 !(y < x); }
130      friend bool operator>=(const U& x, const T& y) { return !(y > x); }
131 };
132
133 template <class T, class B = ::boost::detail::empty_base>
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 !(y < x); }
138      friend bool operator>=(const T& x, const T& y) { return !(x < y); }
139 };
140
141 template <class T, class U, class B = ::boost::detail::empty_base>
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 !(x == y); }
146      friend bool operator!=(const T& y, const U& x) { return !(y == x); }
147 };
148
149 template <class T, class B = ::boost::detail::empty_base>
150 struct equality_comparable1 : B
151 {
152      friend bool operator!=(const T& x, const T& y) { return !(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>            \
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>                     \
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>  \
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>  \
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>           \
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>            \
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>                     \
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>      \
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>      \
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>               \
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>
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>
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>
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>
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>            \
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>                     \
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>            \
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>                     \
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>
353 struct equivalent2 : B
354 {
355   friend bool operator==(const T& x, const U& y)
356   {
357     return !(x < y) && !(x > y);
358   }
359 };
360
361 template <class T, class B = ::boost::detail::empty_base>
362 struct equivalent1 : B
363 {
364   friend bool operator==(const T&x, const T&y)
365   {
366     return !(x < y) && !(y < x);
367   }
368 };
369
370 template <class T, class U, class B = ::boost::detail::empty_base>
371 struct partially_ordered2 : B
372 {
373   friend bool operator<=(const T& x, const U& y)
374     { return (x < y) || (x == y); }
375   friend bool operator>=(const T& x, const U& y)
376     { return (x > y) || (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 (y > x) || (y == x); }
383   friend bool operator>=(const U& x, const T& y)
384     { return (y < x) || (y == x); }
385 };
386
387 template <class T, class B = ::boost::detail::empty_base>
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 (x < y) || (x == y); }
394   friend bool operator>=(const T& x, const T& y)
395     { return (y < x) || (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>
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>
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>
413 struct additive2
414     : addable2<T, U
415     , subtractable2<T, U, B
416       > > {};
417
418 template <class T, class B = ::boost::detail::empty_base>
419 struct additive1
420     : addable1<T
421     , subtractable1<T, B
422       > > {};
423
424 template <class T, class U, class B = ::boost::detail::empty_base>
425 struct multiplicative2
426     : multipliable2<T, U
427     , dividable2<T, U, B
428       > > {};
429
430 template <class T, class B = ::boost::detail::empty_base>
431 struct multiplicative1
432     : multipliable1<T
433     , dividable1<T, B
434       > > {};
435
436 template <class T, class U, class B = ::boost::detail::empty_base>
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>
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>
449 struct arithmetic2
450     : additive2<T, U
451     , multiplicative2<T, U, B
452       > > {};
453
454 template <class T, class B = ::boost::detail::empty_base>
455 struct arithmetic1
456     : additive1<T
457     , multiplicative1<T, B
458       > > {};
459
460 template <class T, class U, class B = ::boost::detail::empty_base>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
577 struct ordered_euclidian_ring_operators1
578     : totally_ordered1<T
579     , euclidian_ring_operators1<T, B
580       > > {};
581       
582 template <class T, class P, class B = ::boost::detail::empty_base>
583 struct input_iteratable
584     : equality_comparable1<T
585     , incrementable<T
586     , dereferenceable<T, P, B
587       > > > {};
588
589 template <class T, class B = ::boost::detail::empty_base>
590 struct output_iteratable
591     : incrementable<T, B
592       > {};
593
594 template <class T, class P, class B = ::boost::detail::empty_base>
595 struct forward_iteratable
596     : input_iteratable<T, P, B
597       > {};
598
599 template <class T, class P, class B = ::boost::detail::empty_base>
600 struct bidirectional_iteratable
601     : forward_iteratable<T, P
602     , decrementable<T, B
603       > > {};
604
605 //  To avoid repeated derivation from equality_comparable,
606 //  which is an indirect base class of bidirectional_iterable,
607 //  random_access_iteratable must not be derived from totally_ordered1
608 //  but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
609 template <class T, class P, class D, class R, class B = ::boost::detail::empty_base>
610 struct random_access_iteratable
611     : bidirectional_iteratable<T, P
612     , less_than_comparable1<T
613     , additive2<T, D
614     , indexable<T, D, R, B
615       > > > > {};
616
617 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
618 } // namespace boost
619 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
620
621
622 // BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
623 //
624 // When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
625 // operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
626 // for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
627 // two-argument forms. Note that these macros expect to be invoked from within
628 // boost.
629
630 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
631
632   // The template is already in boost so we have nothing to do.
633 # define BOOST_IMPORT_TEMPLATE4(template_name)
634 # define BOOST_IMPORT_TEMPLATE3(template_name)
635 # define BOOST_IMPORT_TEMPLATE2(template_name)
636 # define BOOST_IMPORT_TEMPLATE1(template_name)
637
638 #else // BOOST_NO_OPERATORS_IN_NAMESPACE
639
640 #  ifndef BOOST_NO_USING_TEMPLATE
641
642      // Bring the names in with a using-declaration
643      // to avoid stressing the compiler.
644 #    define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
645 #    define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
646 #    define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
647 #    define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
648
649 #  else
650
651      // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
652      // from working, we are forced to use inheritance for that compiler.
653 #    define BOOST_IMPORT_TEMPLATE4(template_name)                                          \
654      template <class T, class U, class V, class W, class B = ::boost::detail::empty_base>  \
655      struct template_name : ::template_name<T, U, V, W, B> {};
656
657 #    define BOOST_IMPORT_TEMPLATE3(template_name)                                 \
658      template <class T, class U, class V, class B = ::boost::detail::empty_base>  \
659      struct template_name : ::template_name<T, U, V, B> {};
660
661 #    define BOOST_IMPORT_TEMPLATE2(template_name)                              \
662      template <class T, class U, class B = ::boost::detail::empty_base>        \
663      struct template_name : ::template_name<T, U, B> {};
664
665 #    define BOOST_IMPORT_TEMPLATE1(template_name)                              \
666      template <class T, class B = ::boost::detail::empty_base>                 \
667      struct template_name : ::template_name<T, B> {};
668
669 #  endif // BOOST_NO_USING_TEMPLATE
670
671 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
672
673 //
674 // Here's where we put it all together, defining the xxxx forms of the templates
675 // in namespace boost. We also define specializations of is_chained_base<> for
676 // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
677 // necessary.
678 //
679 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
680
681 // is_chained_base<> - a traits class used to distinguish whether an operator
682 // template argument is being used for base class chaining, or is specifying a
683 // 2nd argument type.
684
685 namespace boost {
686 // A type parameter is used instead of a plain bool because Borland's compiler
687 // didn't cope well with the more obvious non-type template parameter.
688 namespace detail {
689   struct true_t {};
690   struct false_t {};
691 } // namespace detail
692
693 // Unspecialized version assumes that most types are not being used for base
694 // class chaining. We specialize for the operator templates defined in this
695 // library.
696 template<class T> struct is_chained_base {
697   typedef ::boost::detail::false_t value;
698 };
699
700 } // namespace boost
701
702 // Import a 4-type-argument operator template into boost (if necessary) and
703 // provide a specialization of 'is_chained_base<>' for it.
704 # define BOOST_OPERATOR_TEMPLATE4(template_name4)                     \
705   BOOST_IMPORT_TEMPLATE4(template_name4)                              \
706   template<class T, class U, class V, class W, class B>               \
707   struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > {  \
708     typedef ::boost::detail::true_t value;                            \
709   };
710
711 // Import a 3-type-argument operator template into boost (if necessary) and
712 // provide a specialization of 'is_chained_base<>' for it.
713 # define BOOST_OPERATOR_TEMPLATE3(template_name3)                     \
714   BOOST_IMPORT_TEMPLATE3(template_name3)                              \
715   template<class T, class U, class V, class B>                        \
716   struct is_chained_base< ::boost::template_name3<T, U, V, B> > {     \
717     typedef ::boost::detail::true_t value;                            \
718   };
719
720 // Import a 2-type-argument operator template into boost (if necessary) and
721 // provide a specialization of 'is_chained_base<>' for it.
722 # define BOOST_OPERATOR_TEMPLATE2(template_name2)                  \
723   BOOST_IMPORT_TEMPLATE2(template_name2)                           \
724   template<class T, class U, class B>                              \
725   struct is_chained_base< ::boost::template_name2<T, U, B> > {     \
726     typedef ::boost::detail::true_t value;                         \
727   };
728
729 // Import a 1-type-argument operator template into boost (if necessary) and
730 // provide a specialization of 'is_chained_base<>' for it.
731 # define BOOST_OPERATOR_TEMPLATE1(template_name1)                  \
732   BOOST_IMPORT_TEMPLATE1(template_name1)                           \
733   template<class T, class B>                                       \
734   struct is_chained_base< ::boost::template_name1<T, B> > {        \
735     typedef ::boost::detail::true_t value;                         \
736   };
737
738 // BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
739 // can be used for specifying both 1-argument and 2-argument forms. Requires the
740 // existence of two previously defined class templates named '<template_name>1'
741 // and '<template_name>2' which must implement the corresponding 1- and 2-
742 // argument forms.
743 //
744 // The template type parameter O == is_chained_base<U>::value is used to
745 // distinguish whether the 2nd argument to <template_name> is being used for
746 // base class chaining from another boost operator template or is describing a
747 // 2nd operand type. O == true_t only when U is actually an another operator
748 // template from the library. Partial specialization is used to select an
749 // implementation in terms of either '<template_name>1' or '<template_name>2'.
750 //
751
752 # define BOOST_OPERATOR_TEMPLATE(template_name)                    \
753 template <class T                                                  \
754          ,class U = T                                              \
755          ,class B = ::boost::detail::empty_base                    \
756          ,class O = typename is_chained_base<U>::value             \
757          >                                                         \
758 struct template_name : template_name##2<T, U, B> {};               \
759                                                                    \
760 template<class T, class U, class B>                                \
761 struct template_name<T, U, B, ::boost::detail::true_t>             \
762   : template_name##1<T, U> {};                                     \
763                                                                    \
764 template <class T, class B>                                        \
765 struct template_name<T, T, B, ::boost::detail::false_t>            \
766   : template_name##1<T, B> {};                                     \
767                                                                    \
768 template<class T, class U, class B, class O>                       \
769 struct is_chained_base< ::boost::template_name<T, U, B, O> > {     \
770   typedef ::boost::detail::true_t value;                           \
771 };                                                                 \
772                                                                    \
773 BOOST_OPERATOR_TEMPLATE2(template_name##2)                         \
774 BOOST_OPERATOR_TEMPLATE1(template_name##1)
775
776
777 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
778
779 #  define BOOST_OPERATOR_TEMPLATE4(template_name4) \
780         BOOST_IMPORT_TEMPLATE4(template_name4)
781 #  define BOOST_OPERATOR_TEMPLATE3(template_name3) \
782         BOOST_IMPORT_TEMPLATE3(template_name3)
783 #  define BOOST_OPERATOR_TEMPLATE2(template_name2) \
784         BOOST_IMPORT_TEMPLATE2(template_name2)
785 #  define BOOST_OPERATOR_TEMPLATE1(template_name1) \
786         BOOST_IMPORT_TEMPLATE1(template_name1)
787
788    // In this case we can only assume that template_name<> is equivalent to the
789    // more commonly needed template_name1<> form.
790 #  define BOOST_OPERATOR_TEMPLATE(template_name)                   \
791    template <class T, class B = ::boost::detail::empty_base>       \
792    struct template_name : template_name##1<T, B> {};
793
794 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
795
796 namespace boost {
797     
798 BOOST_OPERATOR_TEMPLATE(less_than_comparable)
799 BOOST_OPERATOR_TEMPLATE(equality_comparable)
800 BOOST_OPERATOR_TEMPLATE(multipliable)
801 BOOST_OPERATOR_TEMPLATE(addable)
802 BOOST_OPERATOR_TEMPLATE(subtractable)
803 BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
804 BOOST_OPERATOR_TEMPLATE(dividable)
805 BOOST_OPERATOR_TEMPLATE2(dividable2_left)
806 BOOST_OPERATOR_TEMPLATE(modable)
807 BOOST_OPERATOR_TEMPLATE2(modable2_left)
808 BOOST_OPERATOR_TEMPLATE(xorable)
809 BOOST_OPERATOR_TEMPLATE(andable)
810 BOOST_OPERATOR_TEMPLATE(orable)
811
812 BOOST_OPERATOR_TEMPLATE1(incrementable)
813 BOOST_OPERATOR_TEMPLATE1(decrementable)
814
815 BOOST_OPERATOR_TEMPLATE2(dereferenceable)
816 BOOST_OPERATOR_TEMPLATE3(indexable)
817
818 BOOST_OPERATOR_TEMPLATE(left_shiftable)
819 BOOST_OPERATOR_TEMPLATE(right_shiftable)
820 BOOST_OPERATOR_TEMPLATE(equivalent)
821 BOOST_OPERATOR_TEMPLATE(partially_ordered)
822
823 BOOST_OPERATOR_TEMPLATE(totally_ordered)
824 BOOST_OPERATOR_TEMPLATE(additive)
825 BOOST_OPERATOR_TEMPLATE(multiplicative)
826 BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
827 BOOST_OPERATOR_TEMPLATE(arithmetic)
828 BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
829 BOOST_OPERATOR_TEMPLATE(bitwise)
830 BOOST_OPERATOR_TEMPLATE1(unit_steppable)
831 BOOST_OPERATOR_TEMPLATE(shiftable)
832 BOOST_OPERATOR_TEMPLATE(ring_operators)
833 BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
834 BOOST_OPERATOR_TEMPLATE(field_operators)
835 BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
836 BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
837 BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
838 BOOST_OPERATOR_TEMPLATE2(input_iteratable)
839 BOOST_OPERATOR_TEMPLATE1(output_iteratable)
840 BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
841 BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
842 BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
843
844 #undef BOOST_OPERATOR_TEMPLATE
845 #undef BOOST_OPERATOR_TEMPLATE4
846 #undef BOOST_OPERATOR_TEMPLATE3
847 #undef BOOST_OPERATOR_TEMPLATE2
848 #undef BOOST_OPERATOR_TEMPLATE1
849 #undef BOOST_IMPORT_TEMPLATE1
850 #undef BOOST_IMPORT_TEMPLATE2
851 #undef BOOST_IMPORT_TEMPLATE3
852 #undef BOOST_IMPORT_TEMPLATE4
853
854 // The following 'operators' classes can only be used portably if the derived class
855 // declares ALL of the required member operators.
856 template <class T, class U>
857 struct operators2
858     : totally_ordered2<T,U
859     , integer_arithmetic2<T,U
860     , bitwise2<T,U
861       > > > {};
862
863 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
864 template <class T, class U = T>
865 struct operators : operators2<T, U> {};
866
867 template <class T> struct operators<T, T>
868 #else
869 template <class T> struct operators
870 #endif
871     : totally_ordered<T
872     , integer_arithmetic<T
873     , bitwise<T
874     , unit_steppable<T
875       > > > > {};
876
877 //  Iterator helper classes (contributed by Jeremy Siek) -------------------//
878 //  (Input and output iterator helpers contributed by Daryle Walker) -------//
879 //  (Changed to use combined operator classes by Daryle Walker) ------------//
880 template <class T,
881           class V,
882           class D = std::ptrdiff_t,
883           class P = V const *,
884           class R = V const &>
885 struct input_iterator_helper
886   : input_iteratable<T, P
887   , boost::iterator<std::input_iterator_tag, V, D, P, R
888     > > {};
889
890 template<class T>
891 struct output_iterator_helper
892   : output_iteratable<T
893   , boost::iterator<std::output_iterator_tag, void, void, void, void
894   > >
895 {
896   T& operator*()  { return static_cast<T&>(*this); }
897   T& operator++() { return static_cast<T&>(*this); }
898 };
899
900 template <class T,
901           class V,
902           class D = std::ptrdiff_t,
903           class P = V*,
904           class R = V&>
905 struct forward_iterator_helper
906   : forward_iteratable<T, P
907   , boost::iterator<std::forward_iterator_tag, V, D, P, R
908     > > {};
909
910 template <class T,
911           class V,
912           class D = std::ptrdiff_t,
913           class P = V*,
914           class R = V&>
915 struct bidirectional_iterator_helper
916   : bidirectional_iteratable<T, P
917   , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
918     > > {};
919
920 template <class T,
921           class V, 
922           class D = std::ptrdiff_t,
923           class P = V*,
924           class R = V&>
925 struct random_access_iterator_helper
926   : random_access_iteratable<T, P, D, R
927   , boost::iterator<std::random_access_iterator_tag, V, D, P, R
928     > >
929 {
930   friend D requires_difference_operator(const T& x, const T& y) {
931     return x - y;
932   }
933 }; // random_access_iterator_helper
934
935 } // namespace boost
936
937 #if defined(__sgi) && !defined(__GNUC__)
938 #pragma reset woff 1234
939 #endif
940
941 #endif // BOOST_OPERATORS_HPP