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