ossrv_pub/boost_apis/boost/operators.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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