LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost - operators.hpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 8 8 100.0 %
Date: 2026-06-25 07:23:43 Functions: 19 19 100.0 %

          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             : // Define BOOST_OPERATORS_CONSTEXPR to be like BOOST_CONSTEXPR but empty under MSVC < v19.22
     113             : #if BOOST_WORKAROUND(BOOST_MSVC, < 1922)
     114             : #define BOOST_OPERATORS_CONSTEXPR
     115             : #elif defined __sun
     116             : #define BOOST_OPERATORS_CONSTEXPR
     117             : #else
     118             : #define BOOST_OPERATORS_CONSTEXPR BOOST_CONSTEXPR
     119             : #endif
     120             : 
     121             : // In this section we supply the xxxx1 and xxxx2 forms of the operator
     122             : // templates, which are explicitly targeted at the 1-type-argument and
     123             : // 2-type-argument operator forms, respectively.
     124             : 
     125             : namespace boost
     126             : {
     127             : namespace operators_impl
     128             : {
     129             : namespace operators_detail
     130             : {
     131             : 
     132             : template <typename T> class empty_base {};
     133             : 
     134             : } // namespace operators_detail
     135             : 
     136             : //  Basic operator classes (contributed by Dave Abrahams) ------------------//
     137             : 
     138             : //  Note that friend functions defined in a class are implicitly inline.
     139             : //  See the C++ std, 11.4 [class.friend] paragraph 5
     140             : 
     141             : template <class T, class U, class B = operators_detail::empty_base<T> >
     142             : struct less_than_comparable2 : B
     143             : {
     144             :      friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
     145             :      friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
     146             :      friend BOOST_OPERATORS_CONSTEXPR bool operator>(const U& x, const T& y)  { return y < x; }
     147             :      friend BOOST_OPERATORS_CONSTEXPR bool operator<(const U& x, const T& y)  { return y > x; }
     148             :      friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
     149             :      friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
     150             : };
     151             : 
     152             : template <class T, class B = operators_detail::empty_base<T> >
     153             : struct less_than_comparable1 : B
     154             : {
     155        2500 :      friend BOOST_OPERATORS_CONSTEXPR bool operator>(const T& x, const T& y)  { return y < x; }
     156             :      friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
     157             :      friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
     158             : };
     159             : 
     160             : template <class T, class U, class B = operators_detail::empty_base<T> >
     161             : struct equality_comparable2 : B
     162             : {
     163             :      friend BOOST_OPERATORS_CONSTEXPR bool operator==(const U& y, const T& x) { return x == y; }
     164             :      friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
     165             :      friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
     166             : };
     167             : 
     168             : template <class T, class B = operators_detail::empty_base<T> >
     169             : struct equality_comparable1 : B
     170             : {
     171    46541230 :      friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
     172             : };
     173             : 
     174             : // A macro which produces "name_2left" from "name".
     175             : #define BOOST_OPERATOR2_LEFT(name) name##2##_##left
     176             : 
     177             : //  NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
     178             : 
     179             : #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
     180             : 
     181             : // This is the optimal implementation for ISO/ANSI C++,
     182             : // but it requires the compiler to implement the NRVO.
     183             : // If the compiler has no NRVO, this is the best symmetric
     184             : // implementation available.
     185             : 
     186             : #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                   \
     187             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     188             : struct NAME##2 : B                                                      \
     189             : {                                                                       \
     190             :   friend T operator OP( const T& lhs, const U& rhs )                    \
     191             :     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
     192             :   friend T operator OP( const U& lhs, const T& rhs )                    \
     193             :     { T nrv( rhs ); nrv OP##= lhs; return nrv; }                        \
     194             : };                                                                      \
     195             :                                                                         \
     196             : template <class T, class B = operators_detail::empty_base<T> >          \
     197             : struct NAME##1 : B                                                      \
     198             : {                                                                       \
     199             :   friend T operator OP( const T& lhs, const T& rhs )                    \
     200             :     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
     201             : };
     202             : 
     203             : #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
     204             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     205             : struct NAME##2 : B                                                      \
     206             : {                                                                       \
     207             :   friend T operator OP( const T& lhs, const U& rhs )                    \
     208             :     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
     209             : };                                                                      \
     210             :                                                                         \
     211             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     212             : struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \
     213             : {                                                                       \
     214             :   friend T operator OP( const U& lhs, const T& rhs )                    \
     215             :     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
     216             : };                                                                      \
     217             :                                                                         \
     218             : template <class T, class B = operators_detail::empty_base<T> >          \
     219             : struct NAME##1 : B                                                      \
     220             : {                                                                       \
     221             :   friend T operator OP( const T& lhs, const T& rhs )                    \
     222             :     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
     223             : };
     224             : 
     225             : #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
     226             : 
     227             : // For compilers without NRVO the following code is optimal, but not
     228             : // symmetric!  Note that the implementation of
     229             : // BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
     230             : // optimization opportunities to the compiler :)
     231             : 
     232             : #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                   \
     233             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     234             : struct NAME##2 : B                                                      \
     235             : {                                                                       \
     236             :   friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
     237             :   friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
     238             : };                                                                      \
     239             :                                                                         \
     240             : template <class T, class B = operators_detail::empty_base<T> >          \
     241             : struct NAME##1 : B                                                      \
     242             : {                                                                       \
     243             :   friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
     244             : };
     245             : 
     246             : #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
     247             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     248             : struct NAME##2 : B                                                      \
     249             : {                                                                       \
     250             :   friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
     251             : };                                                                      \
     252             :                                                                         \
     253             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     254             : struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \
     255             : {                                                                       \
     256             :   friend T operator OP( const U& lhs, const T& rhs )                    \
     257             :     { return T( lhs ) OP##= rhs; }                                      \
     258             : };                                                                      \
     259             :                                                                         \
     260             : template <class T, class B = operators_detail::empty_base<T> >          \
     261             : struct NAME##1 : B                                                      \
     262             : {                                                                       \
     263             :   friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
     264             : };
     265             : 
     266             : #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
     267             : 
     268             : BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
     269             : BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
     270             : BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
     271             : BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
     272             : BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
     273             : BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
     274             : BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
     275             : BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
     276             : 
     277             : #undef BOOST_BINARY_OPERATOR_COMMUTATIVE
     278             : #undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
     279             : #undef BOOST_OPERATOR2_LEFT
     280             : 
     281             : //  incrementable and decrementable contributed by Jeremy Siek
     282             : 
     283             : template <class T, class B = operators_detail::empty_base<T> >
     284             : struct incrementable : B
     285             : {
     286       76481 :   friend T operator++(T& x, int)
     287             :   {
     288       76481 :     incrementable_type nrv(x);
     289       76481 :     ++x;
     290       76481 :     return nrv;
     291             :   }
     292             : private: // The use of this typedef works around a Borland bug
     293             :   typedef T incrementable_type;
     294             : };
     295             : 
     296             : template <class T, class B = operators_detail::empty_base<T> >
     297             : struct decrementable : B
     298             : {
     299             :   friend T operator--(T& x, int)
     300             :   {
     301             :     decrementable_type nrv(x);
     302             :     --x;
     303             :     return nrv;
     304             :   }
     305             : private: // The use of this typedef works around a Borland bug
     306             :   typedef T decrementable_type;
     307             : };
     308             : 
     309             : //  Iterator operator classes (contributed by Jeremy Siek) ------------------//
     310             : 
     311             : template <class T, class P, class B = operators_detail::empty_base<T> >
     312             : struct dereferenceable : B
     313             : {
     314   536130283 :   P operator->() const
     315             :   {
     316   536130283 :     return ::boost::addressof(*static_cast<const T&>(*this));
     317             :   }
     318             : };
     319             : 
     320             : template <class T, class I, class R, class B = operators_detail::empty_base<T> >
     321             : struct indexable : B
     322             : {
     323             :   R operator[](I n) const
     324             :   {
     325             :     return *(static_cast<const T&>(*this) + n);
     326             :   }
     327             : };
     328             : 
     329             : //  More operator classes (contributed by Daryle Walker) --------------------//
     330             : //  (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
     331             : 
     332             : #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
     333             : 
     334             : #define BOOST_BINARY_OPERATOR( NAME, OP )                               \
     335             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     336             : struct NAME##2 : B                                                      \
     337             : {                                                                       \
     338             :   friend T operator OP( const T& lhs, const U& rhs )                    \
     339             :     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
     340             : };                                                                      \
     341             :                                                                         \
     342             : template <class T, class B = operators_detail::empty_base<T> >          \
     343             : struct NAME##1 : B                                                      \
     344             : {                                                                       \
     345             :   friend T operator OP( const T& lhs, const T& rhs )                    \
     346             :     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
     347             : };
     348             : 
     349             : #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
     350             : 
     351             : #define BOOST_BINARY_OPERATOR( NAME, OP )                               \
     352             : template <class T, class U, class B = operators_detail::empty_base<T> > \
     353             : struct NAME##2 : B                                                      \
     354             : {                                                                       \
     355             :   friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
     356             : };                                                                      \
     357             :                                                                         \
     358             : template <class T, class B = operators_detail::empty_base<T> >          \
     359             : struct NAME##1 : B                                                      \
     360             : {                                                                       \
     361             :   friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
     362             : };
     363             : 
     364             : #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
     365             : 
     366             : BOOST_BINARY_OPERATOR( left_shiftable, << )
     367             : BOOST_BINARY_OPERATOR( right_shiftable, >> )
     368             : 
     369             : #undef BOOST_BINARY_OPERATOR
     370             : 
     371             : template <class T, class U, class B = operators_detail::empty_base<T> >
     372             : struct equivalent2 : B
     373             : {
     374             :   friend BOOST_OPERATORS_CONSTEXPR bool operator==(const T& x, const U& y)
     375             :   {
     376             :     return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
     377             :   }
     378             : };
     379             : 
     380             : template <class T, class B = operators_detail::empty_base<T> >
     381             : struct equivalent1 : B
     382             : {
     383             :   friend BOOST_OPERATORS_CONSTEXPR bool operator==(const T&x, const T&y)
     384             :   {
     385             :     return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
     386             :   }
     387             : };
     388             : 
     389             : template <class T, class U, class B = operators_detail::empty_base<T> >
     390             : struct partially_ordered2 : B
     391             : {
     392             :   friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const U& y)
     393             :     { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
     394             :   friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const U& y)
     395             :     { return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
     396             :   friend BOOST_OPERATORS_CONSTEXPR bool operator>(const U& x, const T& y)
     397             :     { return y < x; }
     398             :   friend BOOST_OPERATORS_CONSTEXPR bool operator<(const U& x, const T& y)
     399             :     { return y > x; }
     400             :   friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const U& x, const T& y)
     401             :     { return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
     402             :   friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const U& x, const T& y)
     403             :     { return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
     404             : };
     405             : 
     406             : template <class T, class B = operators_detail::empty_base<T> >
     407             : struct partially_ordered1 : B
     408             : {
     409             :   friend BOOST_OPERATORS_CONSTEXPR bool operator>(const T& x, const T& y)
     410             :     { return y < x; }
     411             :   friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const T& y)
     412             :     { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
     413             :   friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const T& y)
     414             :     { return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
     415             : };
     416             : 
     417             : //  Combined operator classes (contributed by Daryle Walker) ----------------//
     418             : 
     419             : template <class T, class U, class B = operators_detail::empty_base<T> >
     420             : struct totally_ordered2
     421             :     : less_than_comparable2<T, U
     422             :     , equality_comparable2<T, U, B
     423             :       > > {};
     424             : 
     425             : template <class T, class B = operators_detail::empty_base<T> >
     426             : struct totally_ordered1
     427             :     : less_than_comparable1<T
     428             :     , equality_comparable1<T, B
     429             :       > > {};
     430             : 
     431             : template <class T, class U, class B = operators_detail::empty_base<T> >
     432             : struct additive2
     433             :     : addable2<T, U
     434             :     , subtractable2<T, U, B
     435             :       > > {};
     436             : 
     437             : template <class T, class B = operators_detail::empty_base<T> >
     438             : struct additive1
     439             :     : addable1<T
     440             :     , subtractable1<T, B
     441             :       > > {};
     442             : 
     443             : template <class T, class U, class B = operators_detail::empty_base<T> >
     444             : struct multiplicative2
     445             :     : multipliable2<T, U
     446             :     , dividable2<T, U, B
     447             :       > > {};
     448             : 
     449             : template <class T, class B = operators_detail::empty_base<T> >
     450             : struct multiplicative1
     451             :     : multipliable1<T
     452             :     , dividable1<T, B
     453             :       > > {};
     454             : 
     455             : template <class T, class U, class B = operators_detail::empty_base<T> >
     456             : struct integer_multiplicative2
     457             :     : multiplicative2<T, U
     458             :     , modable2<T, U, B
     459             :       > > {};
     460             : 
     461             : template <class T, class B = operators_detail::empty_base<T> >
     462             : struct integer_multiplicative1
     463             :     : multiplicative1<T
     464             :     , modable1<T, B
     465             :       > > {};
     466             : 
     467             : template <class T, class U, class B = operators_detail::empty_base<T> >
     468             : struct arithmetic2
     469             :     : additive2<T, U
     470             :     , multiplicative2<T, U, B
     471             :       > > {};
     472             : 
     473             : template <class T, class B = operators_detail::empty_base<T> >
     474             : struct arithmetic1
     475             :     : additive1<T
     476             :     , multiplicative1<T, B
     477             :       > > {};
     478             : 
     479             : template <class T, class U, class B = operators_detail::empty_base<T> >
     480             : struct integer_arithmetic2
     481             :     : additive2<T, U
     482             :     , integer_multiplicative2<T, U, B
     483             :       > > {};
     484             : 
     485             : template <class T, class B = operators_detail::empty_base<T> >
     486             : struct integer_arithmetic1
     487             :     : additive1<T
     488             :     , integer_multiplicative1<T, B
     489             :       > > {};
     490             : 
     491             : template <class T, class U, class B = operators_detail::empty_base<T> >
     492             : struct bitwise2
     493             :     : xorable2<T, U
     494             :     , andable2<T, U
     495             :     , orable2<T, U, B
     496             :       > > > {};
     497             : 
     498             : template <class T, class B = operators_detail::empty_base<T> >
     499             : struct bitwise1
     500             :     : xorable1<T
     501             :     , andable1<T
     502             :     , orable1<T, B
     503             :       > > > {};
     504             : 
     505             : template <class T, class B = operators_detail::empty_base<T> >
     506             : struct unit_steppable
     507             :     : incrementable<T
     508             :     , decrementable<T, B
     509             :       > > {};
     510             : 
     511             : template <class T, class U, class B = operators_detail::empty_base<T> >
     512             : struct shiftable2
     513             :     : left_shiftable2<T, U
     514             :     , right_shiftable2<T, U, B
     515             :       > > {};
     516             : 
     517             : template <class T, class B = operators_detail::empty_base<T> >
     518             : struct shiftable1
     519             :     : left_shiftable1<T
     520             :     , right_shiftable1<T, B
     521             :       > > {};
     522             : 
     523             : template <class T, class U, class B = operators_detail::empty_base<T> >
     524             : struct ring_operators2
     525             :     : additive2<T, U
     526             :     , subtractable2_left<T, U
     527             :     , multipliable2<T, U, B
     528             :       > > > {};
     529             : 
     530             : template <class T, class B = operators_detail::empty_base<T> >
     531             : struct ring_operators1
     532             :     : additive1<T
     533             :     , multipliable1<T, B
     534             :       > > {};
     535             : 
     536             : template <class T, class U, class B = operators_detail::empty_base<T> >
     537             : struct ordered_ring_operators2
     538             :     : ring_operators2<T, U
     539             :     , totally_ordered2<T, U, B
     540             :       > > {};
     541             : 
     542             : template <class T, class B = operators_detail::empty_base<T> >
     543             : struct ordered_ring_operators1
     544             :     : ring_operators1<T
     545             :     , totally_ordered1<T, B
     546             :       > > {};
     547             : 
     548             : template <class T, class U, class B = operators_detail::empty_base<T> >
     549             : struct field_operators2
     550             :     : ring_operators2<T, U
     551             :     , dividable2<T, U
     552             :     , dividable2_left<T, U, B
     553             :       > > > {};
     554             : 
     555             : template <class T, class B = operators_detail::empty_base<T> >
     556             : struct field_operators1
     557             :     : ring_operators1<T
     558             :     , dividable1<T, B
     559             :       > > {};
     560             : 
     561             : template <class T, class U, class B = operators_detail::empty_base<T> >
     562             : struct ordered_field_operators2
     563             :     : field_operators2<T, U
     564             :     , totally_ordered2<T, U, B
     565             :       > > {};
     566             : 
     567             : template <class T, class B = operators_detail::empty_base<T> >
     568             : struct ordered_field_operators1
     569             :     : field_operators1<T
     570             :     , totally_ordered1<T, B
     571             :       > > {};
     572             : 
     573             : template <class T, class U, class B = operators_detail::empty_base<T> >
     574             : struct euclidian_ring_operators2
     575             :     : ring_operators2<T, U
     576             :     , dividable2<T, U
     577             :     , dividable2_left<T, U
     578             :     , modable2<T, U
     579             :     , modable2_left<T, U, B
     580             :       > > > > > {};
     581             : 
     582             : template <class T, class B = operators_detail::empty_base<T> >
     583             : struct euclidian_ring_operators1
     584             :     : ring_operators1<T
     585             :     , dividable1<T
     586             :     , modable1<T, B
     587             :       > > > {};
     588             : 
     589             : template <class T, class U, class B = operators_detail::empty_base<T> >
     590             : struct ordered_euclidian_ring_operators2
     591             :     : totally_ordered2<T, U
     592             :     , euclidian_ring_operators2<T, U, B
     593             :       > > {};
     594             : 
     595             : template <class T, class B = operators_detail::empty_base<T> >
     596             : struct ordered_euclidian_ring_operators1
     597             :     : totally_ordered1<T
     598             :     , euclidian_ring_operators1<T, B
     599             :       > > {};
     600             : 
     601             : template <class T, class U, class B = operators_detail::empty_base<T> >
     602             : struct euclidean_ring_operators2
     603             :     : ring_operators2<T, U
     604             :     , dividable2<T, U
     605             :     , dividable2_left<T, U
     606             :     , modable2<T, U
     607             :     , modable2_left<T, U, B
     608             :       > > > > > {};
     609             : 
     610             : template <class T, class B = operators_detail::empty_base<T> >
     611             : struct euclidean_ring_operators1
     612             :     : ring_operators1<T
     613             :     , dividable1<T
     614             :     , modable1<T, B
     615             :       > > > {};
     616             : 
     617             : template <class T, class U, class B = operators_detail::empty_base<T> >
     618             : struct ordered_euclidean_ring_operators2
     619             :     : totally_ordered2<T, U
     620             :     , euclidean_ring_operators2<T, U, B
     621             :       > > {};
     622             : 
     623             : template <class T, class B = operators_detail::empty_base<T> >
     624             : struct ordered_euclidean_ring_operators1
     625             :     : totally_ordered1<T
     626             :     , euclidean_ring_operators1<T, B
     627             :       > > {};
     628             : 
     629             : template <class T, class P, class B = operators_detail::empty_base<T> >
     630             : struct input_iteratable
     631             :     : equality_comparable1<T
     632             :     , incrementable<T
     633             :     , dereferenceable<T, P, B
     634             :       > > > {};
     635             : 
     636             : template <class T, class B = operators_detail::empty_base<T> >
     637             : struct output_iteratable
     638             :     : incrementable<T, B
     639             :       > {};
     640             : 
     641             : template <class T, class P, class B = operators_detail::empty_base<T> >
     642             : struct forward_iteratable
     643             :     : input_iteratable<T, P, B
     644             :       > {};
     645             : 
     646             : template <class T, class P, class B = operators_detail::empty_base<T> >
     647             : struct bidirectional_iteratable
     648             :     : forward_iteratable<T, P
     649             :     , decrementable<T, B
     650             :       > > {};
     651             : 
     652             : //  To avoid repeated derivation from equality_comparable,
     653             : //  which is an indirect base class of bidirectional_iterable,
     654             : //  random_access_iteratable must not be derived from totally_ordered1
     655             : //  but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
     656             : template <class T, class P, class D, class R, class B = operators_detail::empty_base<T> >
     657             : struct random_access_iteratable
     658             :     : bidirectional_iteratable<T, P
     659             :     , less_than_comparable1<T
     660             :     , additive2<T, D
     661             :     , indexable<T, D, R, B
     662             :       > > > > {};
     663             : 
     664             : 
     665             : //
     666             : // Here's where we put it all together, defining the xxxx forms of the templates.
     667             : // We also define specializations of is_chained_base<> for
     668             : // the xxxx, xxxx1, and xxxx2 templates.
     669             : //
     670             : 
     671             : namespace operators_detail
     672             : {
     673             : 
     674             : // A type parameter is used instead of a plain bool because Borland's compiler
     675             : // didn't cope well with the more obvious non-type template parameter.
     676             : struct true_t {};
     677             : struct false_t {};
     678             : 
     679             : } // namespace operators_detail
     680             : 
     681             : // is_chained_base<> - a traits class used to distinguish whether an operator
     682             : // template argument is being used for base class chaining, or is specifying a
     683             : // 2nd argument type.
     684             : 
     685             : // Unspecialized version assumes that most types are not being used for base
     686             : // class chaining. We specialize for the operator templates defined in this
     687             : // library.
     688             : template<class T> struct is_chained_base {
     689             :   typedef operators_detail::false_t value;
     690             : };
     691             : 
     692             : // Provide a specialization of 'is_chained_base<>'
     693             : // for a 4-type-argument operator template.
     694             : # define BOOST_OPERATOR_TEMPLATE4(template_name4)           \
     695             :   template<class T, class U, class V, class W, class B>     \
     696             :   struct is_chained_base< template_name4<T, U, V, W, B> > { \
     697             :     typedef operators_detail::true_t value;                 \
     698             :   };
     699             : 
     700             : // Provide a specialization of 'is_chained_base<>'
     701             : // for a 3-type-argument operator template.
     702             : # define BOOST_OPERATOR_TEMPLATE3(template_name3)        \
     703             :   template<class T, class U, class V, class B>           \
     704             :   struct is_chained_base< template_name3<T, U, V, B> > { \
     705             :     typedef operators_detail::true_t value;              \
     706             :   };
     707             : 
     708             : // Provide a specialization of 'is_chained_base<>'
     709             : // for a 2-type-argument operator template.
     710             : # define BOOST_OPERATOR_TEMPLATE2(template_name2)     \
     711             :   template<class T, class U, class B>                 \
     712             :   struct is_chained_base< template_name2<T, U, B> > { \
     713             :     typedef operators_detail::true_t value;           \
     714             :   };
     715             : 
     716             : // Provide a specialization of 'is_chained_base<>'
     717             : // for a 1-type-argument operator template.
     718             : # define BOOST_OPERATOR_TEMPLATE1(template_name1)  \
     719             :   template<class T, class B>                       \
     720             :   struct is_chained_base< template_name1<T, B> > { \
     721             :     typedef operators_detail::true_t value;        \
     722             :   };
     723             : 
     724             : // BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
     725             : // can be used for specifying both 1-argument and 2-argument forms. Requires the
     726             : // existence of two previously defined class templates named '<template_name>1'
     727             : // and '<template_name>2' which must implement the corresponding 1- and 2-
     728             : // argument forms.
     729             : //
     730             : // The template type parameter O == is_chained_base<U>::value is used to
     731             : // distinguish whether the 2nd argument to <template_name> is being used for
     732             : // base class chaining from another boost operator template or is describing a
     733             : // 2nd operand type. O == true_t only when U is actually an another operator
     734             : // template from the library. Partial specialization is used to select an
     735             : // implementation in terms of either '<template_name>1' or '<template_name>2'.
     736             : //
     737             : 
     738             : # define BOOST_OPERATOR_TEMPLATE(template_name)                                       \
     739             : template <class T                                                                     \
     740             :          ,class U = T                                                                 \
     741             :          ,class B = operators_detail::empty_base<T>                                   \
     742             :          ,class O = typename is_chained_base<U>::value                                \
     743             :          >                                                                            \
     744             : struct template_name;                                                                 \
     745             :                                                                                       \
     746             : template<class T, class U, class B>                                                   \
     747             : struct template_name<T, U, B, operators_detail::false_t>                              \
     748             :   : template_name##2<T, U, B> {};                                                     \
     749             :                                                                                       \
     750             : template<class T, class U>                                                            \
     751             : struct template_name<T, U, operators_detail::empty_base<T>, operators_detail::true_t> \
     752             :   : template_name##1<T, U> {};                                                        \
     753             :                                                                                       \
     754             : template <class T, class B>                                                           \
     755             : struct template_name<T, T, B, operators_detail::false_t>                              \
     756             :   : template_name##1<T, B> {};                                                        \
     757             :                                                                                       \
     758             : template<class T, class U, class B, class O>                                          \
     759             : struct is_chained_base< template_name<T, U, B, O> > {                                 \
     760             :   typedef operators_detail::true_t value;                                             \
     761             : };                                                                                    \
     762             :                                                                                       \
     763             : BOOST_OPERATOR_TEMPLATE2(template_name##2)                                            \
     764             : BOOST_OPERATOR_TEMPLATE1(template_name##1)
     765             : 
     766             : BOOST_OPERATOR_TEMPLATE(less_than_comparable)
     767             : BOOST_OPERATOR_TEMPLATE(equality_comparable)
     768             : BOOST_OPERATOR_TEMPLATE(multipliable)
     769             : BOOST_OPERATOR_TEMPLATE(addable)
     770             : BOOST_OPERATOR_TEMPLATE(subtractable)
     771             : BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
     772             : BOOST_OPERATOR_TEMPLATE(dividable)
     773             : BOOST_OPERATOR_TEMPLATE2(dividable2_left)
     774             : BOOST_OPERATOR_TEMPLATE(modable)
     775             : BOOST_OPERATOR_TEMPLATE2(modable2_left)
     776             : BOOST_OPERATOR_TEMPLATE(xorable)
     777             : BOOST_OPERATOR_TEMPLATE(andable)
     778             : BOOST_OPERATOR_TEMPLATE(orable)
     779             : 
     780             : BOOST_OPERATOR_TEMPLATE1(incrementable)
     781             : BOOST_OPERATOR_TEMPLATE1(decrementable)
     782             : 
     783             : BOOST_OPERATOR_TEMPLATE2(dereferenceable)
     784             : BOOST_OPERATOR_TEMPLATE3(indexable)
     785             : 
     786             : BOOST_OPERATOR_TEMPLATE(left_shiftable)
     787             : BOOST_OPERATOR_TEMPLATE(right_shiftable)
     788             : BOOST_OPERATOR_TEMPLATE(equivalent)
     789             : BOOST_OPERATOR_TEMPLATE(partially_ordered)
     790             : 
     791             : BOOST_OPERATOR_TEMPLATE(totally_ordered)
     792             : BOOST_OPERATOR_TEMPLATE(additive)
     793             : BOOST_OPERATOR_TEMPLATE(multiplicative)
     794             : BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
     795             : BOOST_OPERATOR_TEMPLATE(arithmetic)
     796             : BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
     797             : BOOST_OPERATOR_TEMPLATE(bitwise)
     798             : BOOST_OPERATOR_TEMPLATE1(unit_steppable)
     799             : BOOST_OPERATOR_TEMPLATE(shiftable)
     800             : BOOST_OPERATOR_TEMPLATE(ring_operators)
     801             : BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
     802             : BOOST_OPERATOR_TEMPLATE(field_operators)
     803             : BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
     804             : BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
     805             : BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
     806             : BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
     807             : BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
     808             : BOOST_OPERATOR_TEMPLATE2(input_iteratable)
     809             : BOOST_OPERATOR_TEMPLATE1(output_iteratable)
     810             : BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
     811             : BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
     812             : BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
     813             : 
     814             : #undef BOOST_OPERATOR_TEMPLATE
     815             : #undef BOOST_OPERATOR_TEMPLATE4
     816             : #undef BOOST_OPERATOR_TEMPLATE3
     817             : #undef BOOST_OPERATOR_TEMPLATE2
     818             : #undef BOOST_OPERATOR_TEMPLATE1
     819             : 
     820             : template <class T, class U>
     821             : struct operators2
     822             :     : totally_ordered2<T,U
     823             :     , integer_arithmetic2<T,U
     824             :     , bitwise2<T,U
     825             :       > > > {};
     826             : 
     827             : template <class T, class U = T>
     828             : struct operators : operators2<T, U> {};
     829             : 
     830             : template <class T> struct operators<T, T>
     831             :     : totally_ordered<T
     832             :     , integer_arithmetic<T
     833             :     , bitwise<T
     834             :     , unit_steppable<T
     835             :       > > > > {};
     836             : 
     837             : //  Iterator helper classes (contributed by Jeremy Siek) -------------------//
     838             : //  (Input and output iterator helpers contributed by Daryle Walker) -------//
     839             : //  (Changed to use combined operator classes by Daryle Walker) ------------//
     840             : //  (Adapted to C++17 by Daniel Frey) --------------------------------------//
     841             : template <class Category,
     842             :           class T,
     843             :           class Distance = std::ptrdiff_t,
     844             :           class Pointer = T*,
     845             :           class Reference = T&>
     846             : struct iterator_helper
     847             : {
     848             :   typedef Category iterator_category;
     849             :   typedef T value_type;
     850             :   typedef Distance difference_type;
     851             :   typedef Pointer pointer;
     852             :   typedef Reference reference;
     853             : };
     854             : 
     855             : template <class T,
     856             :           class V,
     857             :           class D = std::ptrdiff_t,
     858             :           class P = V const *,
     859             :           class R = V const &>
     860             : struct input_iterator_helper
     861             :   : input_iteratable<T, P
     862             :   , iterator_helper<std::input_iterator_tag, V, D, P, R
     863             :     > > {};
     864             : 
     865             : template<class T>
     866             : struct output_iterator_helper
     867             :   : output_iteratable<T
     868             :   , iterator_helper<std::output_iterator_tag, void, void, void, void
     869             :   > >
     870             : {
     871             :   T& operator*()  { return static_cast<T&>(*this); }
     872             :   T& operator++() { return static_cast<T&>(*this); }
     873             : };
     874             : 
     875             : template <class T,
     876             :           class V,
     877             :           class D = std::ptrdiff_t,
     878             :           class P = V*,
     879             :           class R = V&>
     880             : struct forward_iterator_helper
     881             :   : forward_iteratable<T, P
     882             :   , iterator_helper<std::forward_iterator_tag, V, D, P, R
     883             :     > > {};
     884             : 
     885             : template <class T,
     886             :           class V,
     887             :           class D = std::ptrdiff_t,
     888             :           class P = V*,
     889             :           class R = V&>
     890             : struct bidirectional_iterator_helper
     891             :   : bidirectional_iteratable<T, P
     892             :   , iterator_helper<std::bidirectional_iterator_tag, V, D, P, R
     893             :     > > {};
     894             : 
     895             : template <class T,
     896             :           class V,
     897             :           class D = std::ptrdiff_t,
     898             :           class P = V*,
     899             :           class R = V&>
     900             : struct random_access_iterator_helper
     901             :   : random_access_iteratable<T, P, D, R
     902             :   , iterator_helper<std::random_access_iterator_tag, V, D, P, R
     903             :     > >
     904             : {
     905             :   friend D requires_difference_operator(const T& x, const T& y) {
     906             :     return x - y;
     907             :   }
     908             : }; // random_access_iterator_helper
     909             : 
     910             : } // namespace operators_impl
     911             : using namespace operators_impl;
     912             : 
     913             : } // namespace boost
     914             : 
     915             : #if defined(__sgi) && !defined(__GNUC__)
     916             : #pragma reset woff 1234
     917             : #endif
     918             : 
     919             : #endif // BOOST_NO_OPERATORS_IN_NAMESPACE
     920             : #endif // BOOST_OPERATORS_HPP

Generated by: LCOV version 1.16