LCOV - code coverage report
Current view: top level - usr/include/boost - operators.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 4 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14