Ticket #979: operators.hpp.diff

File operators.hpp.diff, 25.5 KB (added by Thomas Witt, 15 years ago)
  • boost/operators.hpp

    RCS file: /cvsroot/boost/boost/boost/operators.hpp,v
    retrieving revision 1.23
    retrieving revision 1.24
    diff -u -r1.23 -r1.24
     
    88//  See http://www.boost.org/libs/utility/operators.htm for documentation.
    99
    1010//  Revision History
     11//  24 May 07 Changed empty_base to depend on T, see
     12//            http://svn.boost.org/trac/boost/ticket/979
    1113//  21 Oct 02 Modified implementation of operators to allow compilers with a
    1214//            correct named return value optimization (NRVO) to produce optimal
    1315//            code.  (Daniel Frey)
     
    9092namespace boost {
    9193namespace detail {
    9294
     95template <typename T> class empty_base {
     96
    9397// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
    9498#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
    95 class empty_base {
    9699  bool dummy;
    97 };
    98 #else
    99 class empty_base {};
    100100#endif
    101101
     102};
     103
    102104} // namespace detail
    103105} // namespace boost
    104106
     
    119121//  Note that friend functions defined in a class are implicitly inline.
    120122//  See the C++ std, 11.4 [class.friend] paragraph 5
    121123
    122 template <class T, class U, class B = ::boost::detail::empty_base>
     124template <class T, class U, class B = ::boost::detail::empty_base<T> >
    123125struct less_than_comparable2 : B
    124126{
    125127     friend bool operator<=(const T& x, const U& y) { return !(x > y); }
     
    130132     friend bool operator>=(const U& x, const T& y) { return !(y > x); }
    131133};
    132134
    133 template <class T, class B = ::boost::detail::empty_base>
     135template <class T, class B = ::boost::detail::empty_base<T> >
    134136struct less_than_comparable1 : B
    135137{
    136138     friend bool operator>(const T& x, const T& y)  { return y < x; }
     
    138140     friend bool operator>=(const T& x, const T& y) { return !(x < y); }
    139141};
    140142
    141 template <class T, class U, class B = ::boost::detail::empty_base>
     143template <class T, class U, class B = ::boost::detail::empty_base<T> >
    142144struct equality_comparable2 : B
    143145{
    144146     friend bool operator==(const U& y, const T& x) { return x == y; }
     
    146148     friend bool operator!=(const T& y, const U& x) { return !(y == x); }
    147149};
    148150
    149 template <class T, class B = ::boost::detail::empty_base>
     151template <class T, class B = ::boost::detail::empty_base<T> >
    150152struct equality_comparable1 : B
    151153{
    152154     friend bool operator!=(const T& x, const T& y) { return !(x == y); }
     
    165167// implementation available.
    166168
    167169#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                         \
    168 template <class T, class U, class B = ::boost::detail::empty_base>            \
     170template <class T, class U, class B = ::boost::detail::empty_base<T> >        \
    169171struct NAME##2 : B                                                            \
    170172{                                                                             \
    171173  friend T operator OP( const T& lhs, const U& rhs )                          \
     
    174176    { T nrv( rhs ); nrv OP##= lhs; return nrv; }                              \
    175177};                                                                            \
    176178                                                                              \
    177 template <class T, class B = ::boost::detail::empty_base>                     \
     179template <class T, class B = ::boost::detail::empty_base<T> >                 \
    178180struct NAME##1 : B                                                            \
    179181{                                                                             \
    180182  friend T operator OP( const T& lhs, const T& rhs )                          \
    181183    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
    182184};
    183185
    184 #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )           \
    185 template <class T, class U, class B = ::boost::detail::empty_base>  \
    186 struct NAME##2 : B                                                  \
    187 {                                                                   \
    188   friend T operator OP( const T& lhs, const U& rhs )                \
    189     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                    \
    190 };                                                                  \
    191                                                                     \
    192 template <class T, class U, class B = ::boost::detail::empty_base>  \
    193 struct BOOST_OPERATOR2_LEFT(NAME) : B                               \
    194 {                                                                   \
    195   friend T operator OP( const U& lhs, const T& rhs )                \
    196     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                    \
    197 };                                                                  \
    198                                                                     \
    199 template <class T, class B = ::boost::detail::empty_base>           \
    200 struct NAME##1 : B                                                  \
    201 {                                                                   \
    202   friend T operator OP( const T& lhs, const T& rhs )                \
    203     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                    \
     186#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
     187template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
     188struct 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                                                                        \
     194template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
     195struct 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                                                                        \
     201template <class T, class B = ::boost::detail::empty_base<T> >           \
     202struct NAME##1 : B                                                      \
     203{                                                                       \
     204  friend T operator OP( const T& lhs, const T& rhs )                    \
     205    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
    204206};
    205207
    206208#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
     
    210212// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
    211213// optimization opportunities to the compiler :)
    212214
    213 #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                         \
    214 template <class T, class U, class B = ::boost::detail::empty_base>            \
    215 struct NAME##2 : B                                                            \
    216 {                                                                             \
    217   friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \
    218   friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; }       \
    219 };                                                                            \
    220                                                                               \
    221 template <class T, class B = ::boost::detail::empty_base>                     \
    222 struct NAME##1 : B                                                            \
    223 {                                                                             \
    224   friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; }       \
     215#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                   \
     216template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
     217struct 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                                                                        \
     223template <class T, class B = ::boost::detail::empty_base<T> >           \
     224struct NAME##1 : B                                                      \
     225{                                                                       \
     226  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
    225227};
    226228
    227229#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
    228 template <class T, class U, class B = ::boost::detail::empty_base>      \
     230template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
    229231struct NAME##2 : B                                                      \
    230232{                                                                       \
    231233  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
    232234};                                                                      \
    233235                                                                        \
    234 template <class T, class U, class B = ::boost::detail::empty_base>      \
     236template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
    235237struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \
    236238{                                                                       \
    237239  friend T operator OP( const U& lhs, const T& rhs )                    \
    238240    { return T( lhs ) OP##= rhs; }                                      \
    239241};                                                                      \
    240242                                                                        \
    241 template <class T, class B = ::boost::detail::empty_base>               \
     243template <class T, class B = ::boost::detail::empty_base<T> >           \
    242244struct NAME##1 : B                                                      \
    243245{                                                                       \
    244246  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
     
    261263
    262264//  incrementable and decrementable contributed by Jeremy Siek
    263265
    264 template <class T, class B = ::boost::detail::empty_base>
     266template <class T, class B = ::boost::detail::empty_base<T> >
    265267struct incrementable : B
    266268{
    267269  friend T operator++(T& x, int)
     
    274276  typedef T incrementable_type;
    275277};
    276278
    277 template <class T, class B = ::boost::detail::empty_base>
     279template <class T, class B = ::boost::detail::empty_base<T> >
    278280struct decrementable : B
    279281{
    280282  friend T operator--(T& x, int)
     
    289291
    290292//  Iterator operator classes (contributed by Jeremy Siek) ------------------//
    291293
    292 template <class T, class P, class B = ::boost::detail::empty_base>
     294template <class T, class P, class B = ::boost::detail::empty_base<T> >
    293295struct dereferenceable : B
    294296{
    295297  P operator->() const
     
    298300  }
    299301};
    300302
    301 template <class T, class I, class R, class B = ::boost::detail::empty_base>
     303template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
    302304struct indexable : B
    303305{
    304306  R operator[](I n) const
     
    313315#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
    314316
    315317#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
    316 template <class T, class U, class B = ::boost::detail::empty_base>            \
     318template <class T, class U, class B = ::boost::detail::empty_base<T> >        \
    317319struct NAME##2 : B                                                            \
    318320{                                                                             \
    319321  friend T operator OP( const T& lhs, const U& rhs )                          \
    320322    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
    321323};                                                                            \
    322324                                                                              \
    323 template <class T, class B = ::boost::detail::empty_base>                     \
     325template <class T, class B = ::boost::detail::empty_base<T> >                 \
    324326struct NAME##1 : B                                                            \
    325327{                                                                             \
    326328  friend T operator OP( const T& lhs, const T& rhs )                          \
     
    330332#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
    331333
    332334#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
    333 template <class T, class U, class B = ::boost::detail::empty_base>            \
     335template <class T, class U, class B = ::boost::detail::empty_base<T> >        \
    334336struct NAME##2 : B                                                            \
    335337{                                                                             \
    336338  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \
    337339};                                                                            \
    338340                                                                              \
    339 template <class T, class B = ::boost::detail::empty_base>                     \
     341template <class T, class B = ::boost::detail::empty_base<T> >                 \
    340342struct NAME##1 : B                                                            \
    341343{                                                                             \
    342344  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; }       \
     
    349351
    350352#undef BOOST_BINARY_OPERATOR
    351353
    352 template <class T, class U, class B = ::boost::detail::empty_base>
     354template <class T, class U, class B = ::boost::detail::empty_base<T> >
    353355struct equivalent2 : B
    354356{
    355357  friend bool operator==(const T& x, const U& y)
     
    358360  }
    359361};
    360362
    361 template <class T, class B = ::boost::detail::empty_base>
     363template <class T, class B = ::boost::detail::empty_base<T> >
    362364struct equivalent1 : B
    363365{
    364366  friend bool operator==(const T&x, const T&y)
     
    367369  }
    368370};
    369371
    370 template <class T, class U, class B = ::boost::detail::empty_base>
     372template <class T, class U, class B = ::boost::detail::empty_base<T> >
    371373struct partially_ordered2 : B
    372374{
    373375  friend bool operator<=(const T& x, const U& y)
     
    384386    { return (y < x) || (y == x); }
    385387};
    386388
    387 template <class T, class B = ::boost::detail::empty_base>
     389template <class T, class B = ::boost::detail::empty_base<T> >
    388390struct partially_ordered1 : B
    389391{
    390392  friend bool operator>(const T& x, const T& y)
     
    397399
    398400//  Combined operator classes (contributed by Daryle Walker) ----------------//
    399401
    400 template <class T, class U, class B = ::boost::detail::empty_base>
     402template <class T, class U, class B = ::boost::detail::empty_base<T> >
    401403struct totally_ordered2
    402404    : less_than_comparable2<T, U
    403405    , equality_comparable2<T, U, B
    404406      > > {};
    405407
    406 template <class T, class B = ::boost::detail::empty_base>
     408template <class T, class B = ::boost::detail::empty_base<T> >
    407409struct totally_ordered1
    408410    : less_than_comparable1<T
    409411    , equality_comparable1<T, B
    410412      > > {};
    411413
    412 template <class T, class U, class B = ::boost::detail::empty_base>
     414template <class T, class U, class B = ::boost::detail::empty_base<T> >
    413415struct additive2
    414416    : addable2<T, U
    415417    , subtractable2<T, U, B
    416418      > > {};
    417419
    418 template <class T, class B = ::boost::detail::empty_base>
     420template <class T, class B = ::boost::detail::empty_base<T> >
    419421struct additive1
    420422    : addable1<T
    421423    , subtractable1<T, B
    422424      > > {};
    423425
    424 template <class T, class U, class B = ::boost::detail::empty_base>
     426template <class T, class U, class B = ::boost::detail::empty_base<T> >
    425427struct multiplicative2
    426428    : multipliable2<T, U
    427429    , dividable2<T, U, B
    428430      > > {};
    429431
    430 template <class T, class B = ::boost::detail::empty_base>
     432template <class T, class B = ::boost::detail::empty_base<T> >
    431433struct multiplicative1
    432434    : multipliable1<T
    433435    , dividable1<T, B
    434436      > > {};
    435437
    436 template <class T, class U, class B = ::boost::detail::empty_base>
     438template <class T, class U, class B = ::boost::detail::empty_base<T> >
    437439struct integer_multiplicative2
    438440    : multiplicative2<T, U
    439441    , modable2<T, U, B
    440442      > > {};
    441443
    442 template <class T, class B = ::boost::detail::empty_base>
     444template <class T, class B = ::boost::detail::empty_base<T> >
    443445struct integer_multiplicative1
    444446    : multiplicative1<T
    445447    , modable1<T, B
    446448      > > {};
    447449
    448 template <class T, class U, class B = ::boost::detail::empty_base>
     450template <class T, class U, class B = ::boost::detail::empty_base<T> >
    449451struct arithmetic2
    450452    : additive2<T, U
    451453    , multiplicative2<T, U, B
    452454      > > {};
    453455
    454 template <class T, class B = ::boost::detail::empty_base>
     456template <class T, class B = ::boost::detail::empty_base<T> >
    455457struct arithmetic1
    456458    : additive1<T
    457459    , multiplicative1<T, B
    458460      > > {};
    459461
    460 template <class T, class U, class B = ::boost::detail::empty_base>
     462template <class T, class U, class B = ::boost::detail::empty_base<T> >
    461463struct integer_arithmetic2
    462464    : additive2<T, U
    463465    , integer_multiplicative2<T, U, B
    464466      > > {};
    465467
    466 template <class T, class B = ::boost::detail::empty_base>
     468template <class T, class B = ::boost::detail::empty_base<T> >
    467469struct integer_arithmetic1
    468470    : additive1<T
    469471    , integer_multiplicative1<T, B
    470472      > > {};
    471473
    472 template <class T, class U, class B = ::boost::detail::empty_base>
     474template <class T, class U, class B = ::boost::detail::empty_base<T> >
    473475struct bitwise2
    474476    : xorable2<T, U
    475477    , andable2<T, U
    476478    , orable2<T, U, B
    477479      > > > {};
    478480
    479 template <class T, class B = ::boost::detail::empty_base>
     481template <class T, class B = ::boost::detail::empty_base<T> >
    480482struct bitwise1
    481483    : xorable1<T
    482484    , andable1<T
    483485    , orable1<T, B
    484486      > > > {};
    485487
    486 template <class T, class B = ::boost::detail::empty_base>
     488template <class T, class B = ::boost::detail::empty_base<T> >
    487489struct unit_steppable
    488490    : incrementable<T
    489491    , decrementable<T, B
    490492      > > {};
    491493
    492 template <class T, class U, class B = ::boost::detail::empty_base>
     494template <class T, class U, class B = ::boost::detail::empty_base<T> >
    493495struct shiftable2
    494496    : left_shiftable2<T, U
    495497    , right_shiftable2<T, U, B
    496498      > > {};
    497499
    498 template <class T, class B = ::boost::detail::empty_base>
     500template <class T, class B = ::boost::detail::empty_base<T> >
    499501struct shiftable1
    500502    : left_shiftable1<T
    501503    , right_shiftable1<T, B
    502504      > > {};
    503505
    504 template <class T, class U, class B = ::boost::detail::empty_base>
     506template <class T, class U, class B = ::boost::detail::empty_base<T> >
    505507struct ring_operators2
    506508    : additive2<T, U
    507509    , subtractable2_left<T, U
    508510    , multipliable2<T, U, B
    509511      > > > {};
    510512
    511 template <class T, class B = ::boost::detail::empty_base>
     513template <class T, class B = ::boost::detail::empty_base<T> >
    512514struct ring_operators1
    513515    : additive1<T
    514516    , multipliable1<T, B
    515517      > > {};
    516518
    517 template <class T, class U, class B = ::boost::detail::empty_base>
     519template <class T, class U, class B = ::boost::detail::empty_base<T> >
    518520struct ordered_ring_operators2
    519521    : ring_operators2<T, U
    520522    , totally_ordered2<T, U, B
    521523      > > {};
    522524
    523 template <class T, class B = ::boost::detail::empty_base>
     525template <class T, class B = ::boost::detail::empty_base<T> >
    524526struct ordered_ring_operators1
    525527    : ring_operators1<T
    526528    , totally_ordered1<T, B
    527529      > > {};
    528530
    529 template <class T, class U, class B = ::boost::detail::empty_base>
     531template <class T, class U, class B = ::boost::detail::empty_base<T> >
    530532struct field_operators2
    531533    : ring_operators2<T, U
    532534    , dividable2<T, U
    533535    , dividable2_left<T, U, B
    534536      > > > {};
    535537
    536 template <class T, class B = ::boost::detail::empty_base>
     538template <class T, class B = ::boost::detail::empty_base<T> >
    537539struct field_operators1
    538540    : ring_operators1<T
    539541    , dividable1<T, B
    540542      > > {};
    541543
    542 template <class T, class U, class B = ::boost::detail::empty_base>
     544template <class T, class U, class B = ::boost::detail::empty_base<T> >
    543545struct ordered_field_operators2
    544546    : field_operators2<T, U
    545547    , totally_ordered2<T, U, B
    546548      > > {};
    547549
    548 template <class T, class B = ::boost::detail::empty_base>
     550template <class T, class B = ::boost::detail::empty_base<T> >
    549551struct ordered_field_operators1
    550552    : field_operators1<T
    551553    , totally_ordered1<T, B
    552554      > > {};
    553555
    554 template <class T, class U, class B = ::boost::detail::empty_base>
     556template <class T, class U, class B = ::boost::detail::empty_base<T> >
    555557struct euclidian_ring_operators2
    556558    : ring_operators2<T, U
    557559    , dividable2<T, U
     
    560562    , modable2_left<T, U, B
    561563      > > > > > {};
    562564
    563 template <class T, class B = ::boost::detail::empty_base>
     565template <class T, class B = ::boost::detail::empty_base<T> >
    564566struct euclidian_ring_operators1
    565567    : ring_operators1<T
    566568    , dividable1<T
    567569    , modable1<T, B
    568570      > > > {};
    569571
    570 template <class T, class U, class B = ::boost::detail::empty_base>
     572template <class T, class U, class B = ::boost::detail::empty_base<T> >
    571573struct ordered_euclidian_ring_operators2
    572574    : totally_ordered2<T, U
    573575    , euclidian_ring_operators2<T, U, B
    574576      > > {};
    575577
    576 template <class T, class B = ::boost::detail::empty_base>
     578template <class T, class B = ::boost::detail::empty_base<T> >
    577579struct ordered_euclidian_ring_operators1
    578580    : totally_ordered1<T
    579581    , euclidian_ring_operators1<T, B
    580582      > > {};
    581583     
    582 template <class T, class P, class B = ::boost::detail::empty_base>
     584template <class T, class P, class B = ::boost::detail::empty_base<T> >
    583585struct input_iteratable
    584586    : equality_comparable1<T
    585587    , incrementable<T
    586588    , dereferenceable<T, P, B
    587589      > > > {};
    588590
    589 template <class T, class B = ::boost::detail::empty_base>
     591template <class T, class B = ::boost::detail::empty_base<T> >
    590592struct output_iteratable
    591593    : incrementable<T, B
    592594      > {};
    593595
    594 template <class T, class P, class B = ::boost::detail::empty_base>
     596template <class T, class P, class B = ::boost::detail::empty_base<T> >
    595597struct forward_iteratable
    596598    : input_iteratable<T, P, B
    597599      > {};
    598600
    599 template <class T, class P, class B = ::boost::detail::empty_base>
     601template <class T, class P, class B = ::boost::detail::empty_base<T> >
    600602struct bidirectional_iteratable
    601603    : forward_iteratable<T, P
    602604    , decrementable<T, B
     
    606608//  which is an indirect base class of bidirectional_iterable,
    607609//  random_access_iteratable must not be derived from totally_ordered1
    608610//  but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
    609 template <class T, class P, class D, class R, class B = ::boost::detail::empty_base>
     611template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
    610612struct random_access_iteratable
    611613    : bidirectional_iteratable<T, P
    612614    , less_than_comparable1<T
     
    650652
    651653     // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
    652654     // from working, we are forced to use inheritance for that compiler.
    653 #    define BOOST_IMPORT_TEMPLATE4(template_name)                                          \
    654      template <class T, class U, class V, class W, class B = ::boost::detail::empty_base> \
     655#    define BOOST_IMPORT_TEMPLATE4(template_name)                                             \
     656     template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
    655657     struct template_name : ::template_name<T, U, V, W, B> {};
    656658
    657 #    define BOOST_IMPORT_TEMPLATE3(template_name)                                 \
    658      template <class T, class U, class V, class B = ::boost::detail::empty_base> \
     659#    define BOOST_IMPORT_TEMPLATE3(template_name)                                    \
     660     template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
    659661     struct template_name : ::template_name<T, U, V, B> {};
    660662
    661 #    define BOOST_IMPORT_TEMPLATE2(template_name)                              \
    662      template <class T, class U, class B = ::boost::detail::empty_base>        \
     663#    define BOOST_IMPORT_TEMPLATE2(template_name)                           \
     664     template <class T, class U, class B = ::boost::detail::empty_base<T> > \
    663665     struct template_name : ::template_name<T, U, B> {};
    664666
    665 #    define BOOST_IMPORT_TEMPLATE1(template_name)                              \
    666      template <class T, class B = ::boost::detail::empty_base>                \
     667#    define BOOST_IMPORT_TEMPLATE1(template_name)                  \
     668     template <class T, class B = ::boost::detail::empty_base<T> > \
    667669     struct template_name : ::template_name<T, B> {};
    668670
    669671#  endif // BOOST_NO_USING_TEMPLATE
     
    752754# define BOOST_OPERATOR_TEMPLATE(template_name)                    \
    753755template <class T                                                  \
    754756         ,class U = T                                              \
    755          ,class B = ::boost::detail::empty_base                    \
     757         ,class B = ::boost::detail::empty_base<T>                 \
    756758         ,class O = typename is_chained_base<U>::value             \
    757759         >                                                         \
    758760struct template_name : template_name##2<T, U, B> {};               \
     
    788790   // In this case we can only assume that template_name<> is equivalent to the
    789791   // more commonly needed template_name1<> form.
    790792#  define BOOST_OPERATOR_TEMPLATE(template_name)                   \
    791    template <class T, class B = ::boost::detail::empty_base>       \
     793   template <class T, class B = ::boost::detail::empty_base<T> >   \
    792794   struct template_name : template_name##1<T, B> {};
    793795
    794796#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION