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