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