epoc32/include/stdapis/boost/lambda/detail/operators.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
parent 2 epoc32/include/stdapis/boost/operators.hpp@2fe1408b6811
child 4 837f303aceeb
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     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