LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/iterator - iterator_facade.hpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 17 23 73.9 %
Date: 2026-06-25 07:23:51 Functions: 70 141 49.6 %

          Line data    Source code
       1             : // (C) Copyright David Abrahams 2002.
       2             : // (C) Copyright Jeremy Siek    2002.
       3             : // (C) Copyright Thomas Witt    2002.
       4             : // Distributed under the Boost Software License, Version 1.0. (See
       5             : // accompanying file LICENSE_1_0.txt or copy at
       6             : // http://www.boost.org/LICENSE_1_0.txt)
       7             : #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
       8             : #define BOOST_ITERATOR_FACADE_23022003THW_HPP
       9             : 
      10             : #include <cstddef>
      11             : #include <memory>
      12             : #include <utility>
      13             : #include <type_traits>
      14             : 
      15             : #include <boost/config.hpp>
      16             : #include <boost/mp11/utility.hpp>
      17             : 
      18             : #include <boost/iterator/interoperable.hpp>
      19             : #include <boost/iterator/iterator_traits.hpp>
      20             : #include <boost/iterator/iterator_categories.hpp>
      21             : #include <boost/iterator/detail/facade_iterator_category.hpp>
      22             : #include <boost/iterator/detail/type_traits/conjunction.hpp>
      23             : #include <boost/iterator/detail/type_traits/negation.hpp>
      24             : 
      25             : namespace boost {
      26             : namespace iterators {
      27             : 
      28             : // This forward declaration is required for the friend declaration
      29             : // in iterator_core_access
      30             : template<
      31             :     typename Derived,
      32             :     typename Value,
      33             :     typename CategoryOrTraversal,
      34             :     typename Reference   = Value&,
      35             :     typename Difference  = std::ptrdiff_t
      36             : >
      37             : class iterator_facade;
      38             : 
      39             : namespace detail {
      40             : 
      41             : // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
      42             : template< typename CategoryOrTraversal, typename Required >
      43             : struct is_traversal_at_least :
      44             :     public std::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
      45             : {};
      46             : 
      47             : //
      48             : // enable if for use in operator implementation.
      49             : //
      50             : template<
      51             :     typename Facade1,
      52             :     typename Facade2,
      53             :     typename Return
      54             : >
      55             : struct enable_if_interoperable :
      56             :     public std::enable_if<
      57             :         is_interoperable< Facade1, Facade2 >::value,
      58             :         Return
      59             :     >
      60             : {};
      61             : 
      62             : //
      63             : // enable if for use in implementation of operators specific for random access traversal.
      64             : //
      65             : template<
      66             :     typename Facade1,
      67             :     typename Facade2,
      68             :     typename Return
      69             : >
      70             : struct enable_if_interoperable_and_random_access_traversal :
      71             :     public std::enable_if<
      72             :         detail::conjunction<
      73             :             is_interoperable< Facade1, Facade2 >,
      74             :             is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >,
      75             :             is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
      76             :         >::value,
      77             :         Return
      78             :     >
      79             : {};
      80             : 
      81             : //
      82             : // Generates associated types for an iterator_facade with the
      83             : // given parameters.
      84             : //
      85             : template<
      86             :     typename ValueParam,
      87             :     typename CategoryOrTraversal,
      88             :     typename Reference,
      89             :     typename Difference
      90             : >
      91             : struct iterator_facade_types
      92             : {
      93             :     using iterator_category = typename facade_iterator_category<
      94             :         CategoryOrTraversal, ValueParam, Reference
      95             :     >::type;
      96             : 
      97             :     using value_type = typename std::remove_const< ValueParam >::type;
      98             : 
      99             :     // Not the real associated pointer type
     100             :     using pointer = typename std::add_pointer<
     101             :         typename std::conditional<
     102             :             boost::iterators::detail::iterator_writability_disabled< ValueParam, Reference >::value,
     103             :             const value_type,
     104             :             value_type
     105             :         >::type
     106             :     >::type;
     107             : };
     108             : 
     109             : // iterators whose dereference operators reference the same value
     110             : // for all iterators into the same sequence (like many input
     111             : // iterators) need help with their postfix ++: the referenced
     112             : // value must be read and stored away before the increment occurs
     113             : // so that *a++ yields the originally referenced element and not
     114             : // the next one.
     115             : template< typename Iterator >
     116             : class postfix_increment_proxy
     117             : {
     118             :     using value_type = typename iterator_value< Iterator >::type;
     119             : 
     120             : public:
     121             :     explicit postfix_increment_proxy(Iterator const& x) :
     122             :         stored_iterator(x),
     123             :         stored_value(*x)
     124             :     {}
     125             : 
     126             :     // Returning a mutable reference allows nonsense like
     127             :     // (*r++).mutate(), but it imposes fewer assumptions about the
     128             :     // behavior of the value_type.  In particular, recall that
     129             :     // (*r).mutate() is legal if operator* returns by value.
     130             :     // Provides readability of *r++
     131             :     value_type& operator*() const
     132             :     {
     133             :         return stored_value;
     134             :     }
     135             : 
     136             :     // Provides X(r++)
     137             :     operator Iterator const&() const
     138             :     {
     139             :         return stored_iterator;
     140             :     }
     141             : 
     142             :     // Provides (r++)->foo()
     143             :     value_type* operator->() const
     144             :     {
     145             :         return std::addressof(stored_value);
     146             :     }
     147             : 
     148             : private:
     149             :     Iterator stored_iterator;
     150             :     mutable value_type stored_value;
     151             : };
     152             : 
     153             : 
     154             : template< typename Iterator >
     155             : class writable_postfix_increment_dereference_proxy;
     156             : 
     157             : template< typename T >
     158             : struct is_not_writable_postfix_increment_dereference_proxy :
     159             :     public std::true_type
     160             : {};
     161             : 
     162             : template< typename Iterator >
     163             : struct is_not_writable_postfix_increment_dereference_proxy<
     164             :     writable_postfix_increment_dereference_proxy< Iterator >
     165             : > :
     166             :     public std::false_type
     167             : {};
     168             : 
     169             : template< typename Iterator >
     170             : class writable_postfix_increment_proxy;
     171             : 
     172             : //
     173             : // In general, we can't determine that such an iterator isn't
     174             : // writable -- we also need to store a copy of the old iterator so
     175             : // that it can be written into.
     176             : template< typename Iterator >
     177             : class writable_postfix_increment_dereference_proxy
     178             : {
     179             :     friend class writable_postfix_increment_proxy< Iterator >;
     180             : 
     181             :     using value_type = typename iterator_value< Iterator >::type;
     182             : 
     183             : public:
     184             :     explicit writable_postfix_increment_dereference_proxy(Iterator const& x) :
     185             :         stored_iterator(x),
     186             :         stored_value(*x)
     187             :     {}
     188             : 
     189             :     // Provides readability of *r++
     190             :     operator value_type&() const
     191             :     {
     192             :         return this->stored_value;
     193             :     }
     194             : 
     195             :     template< typename OtherIterator >
     196             :     writable_postfix_increment_dereference_proxy const&
     197             :     operator=(writable_postfix_increment_dereference_proxy< OtherIterator > const& x) const
     198             :     {
     199             :         typedef typename iterator_value< OtherIterator >::type other_value_type;
     200             :         *this->stored_iterator = static_cast< other_value_type& >(x);
     201             :         return *this;
     202             :     }
     203             : 
     204             :     // Provides writability of *r++
     205             :     template< typename T >
     206             :     typename std::enable_if<
     207             :         is_not_writable_postfix_increment_dereference_proxy< T >::value,
     208             :         writable_postfix_increment_dereference_proxy const&
     209             :     >::type operator=(T&& x) const
     210             :     {
     211             :         *this->stored_iterator = static_cast< T&& >(x);
     212             :         return *this;
     213             :     }
     214             : 
     215             : private:
     216             :     Iterator stored_iterator;
     217             :     mutable value_type stored_value;
     218             : };
     219             : 
     220             : template< typename Iterator >
     221             : class writable_postfix_increment_proxy
     222             : {
     223             :     using value_type = typename iterator_value< Iterator >::type;
     224             : 
     225             : public:
     226             :     explicit writable_postfix_increment_proxy(Iterator const& x) :
     227             :         dereference_proxy(x)
     228             :     {}
     229             : 
     230             :     writable_postfix_increment_dereference_proxy< Iterator > const&
     231             :     operator*() const
     232             :     {
     233             :         return dereference_proxy;
     234             :     }
     235             : 
     236             :     // Provides X(r++)
     237             :     operator Iterator const&() const
     238             :     {
     239             :         return dereference_proxy.stored_iterator;
     240             :     }
     241             : 
     242             :     // Provides (r++)->foo()
     243             :     value_type* operator->() const
     244             :     {
     245             :         return std::addressof(dereference_proxy.stored_value);
     246             :     }
     247             : 
     248             : private:
     249             :     writable_postfix_increment_dereference_proxy< Iterator > dereference_proxy;
     250             : };
     251             : 
     252             : template< typename Reference, typename Value >
     253             : struct is_non_proxy_reference :
     254             :     public std::is_convertible<
     255             :         typename std::remove_reference< Reference >::type const volatile*,
     256             :         Value const volatile*
     257             :     >
     258             : {};
     259             : 
     260             : // A metafunction to choose the result type of postfix ++
     261             : //
     262             : // Because the C++98 input iterator requirements say that *r++ has
     263             : // type T (value_type), implementations of some standard
     264             : // algorithms like lexicographical_compare may use constructions
     265             : // like:
     266             : //
     267             : //          *r++ < *s++
     268             : //
     269             : // If *r++ returns a proxy (as required if r is writable but not
     270             : // multipass), this sort of expression will fail unless the proxy
     271             : // supports the operator<.  Since there are any number of such
     272             : // operations, we're not going to try to support them.  Therefore,
     273             : // even if r++ returns a proxy, *r++ will only return a proxy if
     274             : // *r also returns a proxy.
     275             : template< typename Iterator, typename Value, typename Reference, typename CategoryOrTraversal >
     276             : struct postfix_increment_result
     277             : {
     278             :     using type = mp11::mp_eval_if_not<
     279             :         detail::conjunction<
     280             :             // A proxy is only needed for readable iterators
     281             :             std::is_convertible<
     282             :                 Reference,
     283             :                 // Use add_lvalue_reference to form `reference to Value` due to
     284             :                 // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
     285             :                 // 'reference-to-reference' in the template which described in CWG
     286             :                 // DR106.
     287             :                 // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
     288             :                 typename std::add_lvalue_reference< Value const >::type
     289             :             >,
     290             : 
     291             :             // No multipass iterator can have values that disappear
     292             :             // before positions can be re-visited
     293             :             detail::negation<
     294             :                 detail::is_traversal_at_least< CategoryOrTraversal, forward_traversal_tag >
     295             :             >
     296             :         >,
     297             :         Iterator,
     298             :         mp11::mp_if,
     299             :             is_non_proxy_reference< Reference, Value >,
     300             :             postfix_increment_proxy< Iterator >,
     301             :             writable_postfix_increment_proxy< Iterator >
     302             :     >;
     303             : };
     304             : 
     305             : // operator->() needs special support for input iterators to strictly meet the
     306             : // standard's requirements. If *i is not a reference type, we must still
     307             : // produce an lvalue to which a pointer can be formed.  We do that by
     308             : // returning a proxy object containing an instance of the reference object.
     309             : template< typename Reference, typename Pointer >
     310             : struct operator_arrow_dispatch // proxy references
     311             : {
     312             :     struct proxy
     313             :     {
     314           0 :         explicit proxy(Reference const& x) : m_ref(x) {}
     315           0 :         Reference* operator->() { return std::addressof(m_ref); }
     316             :         // This function is needed for MWCW and BCC, which won't call
     317             :         // operator-> again automatically per 13.3.1.2 para 8
     318             :         operator Reference*() { return std::addressof(m_ref); }
     319             :         Reference m_ref;
     320             :     };
     321             : 
     322             :     using result_type = proxy;
     323             : 
     324           0 :     static result_type apply(Reference const& x)
     325             :     {
     326           0 :         return result_type(x);
     327             :     }
     328             : };
     329             : 
     330             : template< typename T, typename Pointer >
     331             : struct operator_arrow_dispatch< T&, Pointer > // "real" references
     332             : {
     333             :     using result_type = Pointer;
     334             : 
     335             :     static result_type apply(T& x)
     336             :     {
     337             :         return std::addressof(x);
     338             :     }
     339             : };
     340             : 
     341             : // A proxy return type for operator[], needed to deal with
     342             : // iterators that may invalidate referents upon destruction.
     343             : // Consider the temporary iterator in *(a + n)
     344             : template< typename Iterator >
     345             : class operator_brackets_proxy
     346             : {
     347             :     // Iterator is actually an iterator_facade, so we do not have to
     348             :     // go through iterator_traits to access the traits.
     349             :     using reference = typename Iterator::reference;
     350             : 
     351             : public:
     352             :     explicit operator_brackets_proxy(Iterator const& iter) noexcept(std::is_nothrow_copy_constructible< Iterator >::value) :
     353             :         m_iter(iter)
     354             :     {}
     355             : 
     356             :     operator reference() const noexcept(noexcept(*std::declval< Iterator const& >()))
     357             :     {
     358             :         return *m_iter;
     359             :     }
     360             : 
     361             :     template< typename T >
     362             :     typename std::enable_if<
     363             :         detail::conjunction<
     364             :             detail::negation<
     365             :                 std::is_same<
     366             :                     operator_brackets_proxy< Iterator >,
     367             :                     typename std::remove_cv< typename std::remove_reference< T >::type >::type
     368             :                 >
     369             :             >,
     370             :             std::is_assignable< reference, T&& >
     371             :         >::value,
     372             :         operator_brackets_proxy&
     373             :     >::type operator= (T&& val) noexcept(noexcept(*std::declval< Iterator& >() = std::declval< T&& >()))
     374             :     {
     375             :         *m_iter = static_cast< T&& >(val);
     376             :         return *this;
     377             :     }
     378             : 
     379             :     // Provides it[n]->foo(). Leverages chaining of operator->.
     380             :     reference operator->() const noexcept(noexcept(*std::declval< Iterator const& >()))
     381             :     {
     382             :         return *m_iter;
     383             :     }
     384             : 
     385             :     // Provides (*it[n]).foo()
     386             :     template< typename Ref = reference, typename Result = decltype(*std::declval< Ref >()) >
     387             :     Result operator*() const noexcept(noexcept(**std::declval< Iterator const& >()))
     388             :     {
     389             :         return **m_iter;
     390             :     }
     391             : 
     392             : private:
     393             :     Iterator m_iter;
     394             : };
     395             : 
     396             : // A binary metafunction class that always returns bool.
     397             : template< typename Iterator1, typename Iterator2 >
     398             : using always_bool_t = bool;
     399             : 
     400             : template< typename Iterator1, typename Iterator2 >
     401             : using choose_difference_type_t = typename std::conditional<
     402             :     std::is_convertible< Iterator2, Iterator1 >::value,
     403             :     iterator_difference< Iterator1 >,
     404             :     iterator_difference< Iterator2 >
     405             : >::type::type;
     406             : 
     407             : template<
     408             :     typename Derived,
     409             :     typename Value,
     410             :     typename CategoryOrTraversal,
     411             :     typename Reference,
     412             :     typename Difference,
     413             :     bool IsBidirectionalTraversal,
     414             :     bool IsRandomAccessTraversal
     415             : >
     416             : class iterator_facade_base;
     417             : 
     418             : } // namespace detail
     419             : 
     420             : 
     421             : // Macros which describe the declarations of binary operators
     422             : #define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)   \
     423             :     template<                                                           \
     424             :         typename Derived1, typename V1, typename TC1, typename Reference1, typename Difference1, \
     425             :         typename Derived2, typename V2, typename TC2, typename Reference2, typename Difference2  \
     426             :     >                                                                   \
     427             :     prefix typename enabler<                                            \
     428             :         Derived1, Derived2,                                             \
     429             :         result_type< Derived1, Derived2 >                               \
     430             :     >::type                                                             \
     431             :     operator op(                                                        \
     432             :         iterator_facade< Derived1, V1, TC1, Reference1, Difference1 > const& lhs,   \
     433             :         iterator_facade< Derived2, V2, TC2, Reference2, Difference2 > const& rhs)
     434             : 
     435             : #define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)       \
     436             :     BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
     437             : 
     438             : #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type)       \
     439             :     BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
     440             : 
     441             : #define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args)                \
     442             :     template< typename Derived, typename V, typename TC, typename R, typename D >   \
     443             :     prefix typename std::enable_if<                                 \
     444             :         boost::iterators::detail::is_traversal_at_least<            \
     445             :             TC,                                                     \
     446             :             boost::iterators::random_access_traversal_tag           \
     447             :         >::value,                                                   \
     448             :         Derived                                                     \
     449             :     >::type operator+ args
     450             : 
     451             : //
     452             : // Helper class for granting access to the iterator core interface.
     453             : //
     454             : // The simple core interface is used by iterator_facade. The core
     455             : // interface of a user/library defined iterator type should not be made public
     456             : // so that it does not clutter the public interface. Instead iterator_core_access
     457             : // should be made friend so that iterator_facade can access the core
     458             : // interface through iterator_core_access.
     459             : //
     460             : class iterator_core_access
     461             : {
     462             :     template< typename I, typename V, typename TC, typename R, typename D >
     463             :     friend class iterator_facade;
     464             :     template< typename I, typename V, typename TC, typename R, typename D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal >
     465             :     friend class detail::iterator_facade_base;
     466             : 
     467             : #define BOOST_ITERATOR_FACADE_RELATION(op)                                \
     468             :     BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend, op, boost::iterators::detail::always_bool_t);
     469             : 
     470             :     BOOST_ITERATOR_FACADE_RELATION(==)
     471             :     BOOST_ITERATOR_FACADE_RELATION(!=)
     472             : 
     473             : #undef BOOST_ITERATOR_FACADE_RELATION
     474             : 
     475             : #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op)                                \
     476             :     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, op, boost::iterators::detail::always_bool_t);
     477             : 
     478             :     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
     479             :     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
     480             :     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
     481             :     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
     482             : 
     483             : #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
     484             : 
     485             :     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, -, boost::iterators::detail::choose_difference_type_t);
     486             : 
     487             :     BOOST_ITERATOR_FACADE_PLUS_HEAD(
     488             :         friend inline,
     489             :         (iterator_facade< Derived, V, TC, R, D > const&, typename Derived::difference_type)
     490             :     );
     491             : 
     492             :     BOOST_ITERATOR_FACADE_PLUS_HEAD(
     493             :         friend inline,
     494             :         (typename Derived::difference_type, iterator_facade< Derived, V, TC, R, D > const&)
     495             :     );
     496             : 
     497             :     template< typename Facade >
     498        2031 :     static typename Facade::reference dereference(Facade const& f)
     499             :     {
     500        2031 :         return f.dereference();
     501             :     }
     502             : 
     503             :     template< typename Facade >
     504        1644 :     static void increment(Facade& f)
     505             :     {
     506        1644 :         f.increment();
     507        1644 :     }
     508             : 
     509             :     template< typename Facade >
     510             :     static void decrement(Facade& f)
     511             :     {
     512             :         f.decrement();
     513             :     }
     514             : 
     515             :     template< typename Facade1, typename Facade2 >
     516       84535 :     static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type)
     517             :     {
     518       84535 :         return f1.equal(f2);
     519             :     }
     520             : 
     521             :     template< typename Facade1, typename Facade2 >
     522             :     static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type)
     523             :     {
     524             :         return f2.equal(f1);
     525             :     }
     526             : 
     527             :     template< typename Facade >
     528             :     static void advance(Facade& f, typename Facade::difference_type n)
     529             :     {
     530             :         f.advance(n);
     531             :     }
     532             : 
     533             :     template< typename Facade1, typename Facade2 >
     534             :     static typename Facade1::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::true_type)
     535             :     {
     536             :         return -f1.distance_to(f2);
     537             :     }
     538             : 
     539             :     template< typename Facade1, typename Facade2 >
     540             :     static typename Facade2::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::false_type)
     541             :     {
     542             :         return f2.distance_to(f1);
     543             :     }
     544             : 
     545             :     //
     546             :     // Curiously Recurring Template interface.
     547             :     //
     548             :     template< typename I, typename V, typename TC, typename R, typename D >
     549             :     static I& derived(iterator_facade< I, V, TC, R, D >& facade)
     550             :     {
     551             :         return *static_cast< I* >(&facade);
     552             :     }
     553             : 
     554             :     template< typename I, typename V, typename TC, typename R, typename D >
     555             :     static I const& derived(iterator_facade< I, V, TC, R, D > const& facade)
     556             :     {
     557             :         return *static_cast< I const* >(&facade);
     558             :     }
     559             : 
     560             :     // objects of this class are useless
     561             :     iterator_core_access() = delete;
     562             : };
     563             : 
     564             : namespace detail {
     565             : 
     566             : // Implementation for forward traversal iterators
     567             : template<
     568             :     typename Derived,
     569             :     typename Value,
     570             :     typename CategoryOrTraversal,
     571             :     typename Reference,
     572             :     typename Difference
     573             : >
     574             : class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
     575             : {
     576             : private:
     577             :     using associated_types = boost::iterators::detail::iterator_facade_types<
     578             :         Value, CategoryOrTraversal, Reference, Difference
     579             :     >;
     580             : 
     581             :     using operator_arrow_dispatch_ = boost::iterators::detail::operator_arrow_dispatch<
     582             :         Reference,
     583             :         typename associated_types::pointer
     584             :     >;
     585             : 
     586             : public:
     587             :     using value_type = typename associated_types::value_type;
     588             :     using reference = Reference;
     589             :     using difference_type = Difference;
     590             : 
     591             :     using pointer = typename operator_arrow_dispatch_::result_type;
     592             : 
     593             :     using iterator_category = typename associated_types::iterator_category;
     594             : 
     595             : public:
     596        2031 :     reference operator*() const
     597             :     {
     598        2031 :         return iterator_core_access::dereference(this->derived());
     599             :     }
     600             : 
     601           0 :     pointer operator->() const
     602             :     {
     603           0 :         return operator_arrow_dispatch_::apply(*this->derived());
     604             :     }
     605             : 
     606        1644 :     Derived& operator++()
     607             :     {
     608        1644 :         iterator_core_access::increment(this->derived());
     609        1644 :         return this->derived();
     610             :     }
     611             : 
     612             : protected:
     613             :     //
     614             :     // Curiously Recurring Template interface.
     615             :     //
     616        3288 :     Derived& derived()
     617             :     {
     618        3288 :         return *static_cast< Derived* >(this);
     619             :     }
     620             : 
     621        2031 :     Derived const& derived() const
     622             :     {
     623        2031 :         return *static_cast< Derived const* >(this);
     624             :     }
     625             : };
     626             : 
     627             : // Implementation for bidirectional traversal iterators
     628             : template<
     629             :     typename Derived,
     630             :     typename Value,
     631             :     typename CategoryOrTraversal,
     632             :     typename Reference,
     633             :     typename Difference
     634             : >
     635             : class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
     636             :     public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
     637             : {
     638             : public:
     639             :     Derived& operator--()
     640             :     {
     641             :         iterator_core_access::decrement(this->derived());
     642             :         return this->derived();
     643             :     }
     644             : 
     645             :     Derived operator--(int)
     646             :     {
     647             :         Derived tmp(this->derived());
     648             :         --*this;
     649             :         return tmp;
     650             :     }
     651             : };
     652             : 
     653             : // Implementation for random access traversal iterators
     654             : template<
     655             :     typename Derived,
     656             :     typename Value,
     657             :     typename CategoryOrTraversal,
     658             :     typename Reference,
     659             :     typename Difference
     660             : >
     661             : class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
     662             :     public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
     663             : {
     664             : private:
     665             :     using base_type = iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >;
     666             : 
     667             : public:
     668             :     using reference = typename base_type::reference;
     669             :     using difference_type = typename base_type::difference_type;
     670             : 
     671             : public:
     672             :     operator_brackets_proxy< Derived > operator[](difference_type n) const
     673             :     {
     674             :         return operator_brackets_proxy< Derived >(this->derived() + n);
     675             :     }
     676             : 
     677             :     Derived& operator+=(difference_type n)
     678             :     {
     679             :         iterator_core_access::advance(this->derived(), n);
     680             :         return this->derived();
     681             :     }
     682             : 
     683             :     Derived& operator-=(difference_type n)
     684             :     {
     685             :         iterator_core_access::advance(this->derived(), -n);
     686             :         return this->derived();
     687             :     }
     688             : 
     689             :     Derived operator-(difference_type x) const
     690             :     {
     691             :         Derived result(this->derived());
     692             :         return result -= x;
     693             :     }
     694             : };
     695             : 
     696             : } // namespace detail
     697             : 
     698             : //
     699             : // iterator_facade - use as a public base class for defining new
     700             : // standard-conforming iterators.
     701             : //
     702             : template<
     703             :     typename Derived,             // The derived iterator type being constructed
     704             :     typename Value,
     705             :     typename CategoryOrTraversal,
     706             :     typename Reference,
     707             :     typename Difference
     708             : >
     709             : class iterator_facade :
     710             :     public detail::iterator_facade_base<
     711             :         Derived,
     712             :         Value,
     713             :         CategoryOrTraversal,
     714             :         Reference,
     715             :         Difference,
     716             :         detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
     717             :         detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
     718             :     >
     719             : {
     720             : protected:
     721             :     // For use by derived classes
     722             :     using iterator_facade_ = iterator_facade< Derived, Value, CategoryOrTraversal, Reference, Difference >;
     723             : };
     724             : 
     725             : template< typename I, typename V, typename TC, typename R, typename D >
     726             : inline typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
     727             : operator++(iterator_facade< I, V, TC, R, D >& i, int)
     728             : {
     729             :     typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
     730             :         tmp(*static_cast< I* >(&i));
     731             : 
     732             :     ++i;
     733             : 
     734             :     return tmp;
     735             : }
     736             : 
     737             : 
     738             : //
     739             : // Comparison operator implementation. The library supplied operators
     740             : // enables the user to provide fully interoperable constant/mutable
     741             : // iterator types. I.e. the library provides all operators
     742             : // for all mutable/constant iterator combinations.
     743             : //
     744             : // Note though that this kind of interoperability for constant/mutable
     745             : // iterators is not required by the standard for container iterators.
     746             : // All the standard asks for is a conversion mutable -> constant.
     747             : // Most standard library implementations nowadays provide fully interoperable
     748             : // iterator implementations, but there are still heavily used implementations
     749             : // that do not provide them. (Actually it's even worse, they do not provide
     750             : // them for only a few iterators.)
     751             : //
     752             : // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
     753             : //    enable the user to turn off mixed type operators
     754             : //
     755             : // The library takes care to provide only the right operator overloads.
     756             : // I.e.
     757             : //
     758             : // bool operator==(Iterator,      Iterator);
     759             : // bool operator==(ConstIterator, Iterator);
     760             : // bool operator==(Iterator,      ConstIterator);
     761             : // bool operator==(ConstIterator, ConstIterator);
     762             : //
     763             : //   ...
     764             : //
     765             : // In order to do so it uses c++ idioms that are not yet widely supported
     766             : // by current compiler releases. The library is designed to degrade gracefully
     767             : // in the face of compiler deficiencies. In general compiler
     768             : // deficiencies result in less strict error checking and more obscure
     769             : // error messages, functionality is not affected.
     770             : //
     771             : // For full operation compiler support for "Substitution Failure Is Not An Error"
     772             : // (aka. enable_if) and boost::is_convertible is required.
     773             : //
     774             : // The following problems occur if support is lacking.
     775             : //
     776             : // Pseudo code
     777             : //
     778             : // ---------------
     779             : // AdaptorA<Iterator1> a1;
     780             : // AdaptorA<Iterator2> a2;
     781             : //
     782             : // // This will result in a no such overload error in full operation
     783             : // // If enable_if or is_convertible is not supported
     784             : // // The instantiation will fail with an error hopefully indicating that
     785             : // // there is no operator== for Iterator1, Iterator2
     786             : // // The same will happen if no enable_if is used to remove
     787             : // // false overloads from the templated conversion constructor
     788             : // // of AdaptorA.
     789             : //
     790             : // a1 == a2;
     791             : // ----------------
     792             : //
     793             : // AdaptorA<Iterator> a;
     794             : // AdaptorB<Iterator> b;
     795             : //
     796             : // // This will result in a no such overload error in full operation
     797             : // // If enable_if is not supported the static assert used
     798             : // // in the operator implementation will fail.
     799             : // // This will accidently work if is_convertible is not supported.
     800             : //
     801             : // a == b;
     802             : // ----------------
     803             : //
     804             : 
     805             : #define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op)                 \
     806             :     BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type)                                \
     807             :     {                                                                                          \
     808             :         return_prefix iterator_core_access::base_op(                                           \
     809             :             *static_cast< Derived1 const* >(&lhs),                                             \
     810             :             *static_cast< Derived2 const* >(&rhs),                                             \
     811             :             std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
     812             :         );                                                                                     \
     813             :     }
     814             : 
     815             : #define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
     816             :     BOOST_ITERATOR_FACADE_INTEROP(                                 \
     817             :         op,                                                        \
     818             :         boost::iterators::detail::always_bool_t,                   \
     819             :         return_prefix,                                             \
     820             :         base_op                                                    \
     821             :     )
     822             : 
     823             : BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
     824       84535 : BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
     825             : 
     826             : #undef BOOST_ITERATOR_FACADE_RELATION
     827             : 
     828             : 
     829             : #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op)   \
     830             :     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type)                  \
     831             :     {                                                                                          \
     832             :         return_prefix iterator_core_access::base_op(                                           \
     833             :             *static_cast< Derived1 const* >(&lhs),                                             \
     834             :             *static_cast< Derived2 const* >(&rhs),                                             \
     835             :             std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
     836             :         );                                                                                     \
     837             :     }
     838             : 
     839             : #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
     840             :     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(                                 \
     841             :         op,                                                                      \
     842             :         boost::iterators::detail::always_bool_t,                                 \
     843             :         return_prefix,                                                           \
     844             :         base_op                                                                  \
     845             :     )
     846             : 
     847             : BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
     848             : BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
     849             : BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
     850             : BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
     851             : 
     852             : #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
     853             : 
     854             : // operator- requires an additional part in the static assertion
     855             : BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
     856             :     -,
     857             :     boost::iterators::detail::choose_difference_type_t,
     858             :     return,
     859             :     distance_from
     860             : )
     861             : 
     862             : #undef BOOST_ITERATOR_FACADE_INTEROP
     863             : #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
     864             : 
     865             : #define BOOST_ITERATOR_FACADE_PLUS(args)               \
     866             :     BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args)      \
     867             :     {                                                  \
     868             :         Derived tmp(static_cast< Derived const& >(i)); \
     869             :         return tmp += n;                               \
     870             :     }
     871             : 
     872             : BOOST_ITERATOR_FACADE_PLUS((iterator_facade< Derived, V, TC, R, D > const& i, typename Derived::difference_type n))
     873             : BOOST_ITERATOR_FACADE_PLUS((typename Derived::difference_type n, iterator_facade< Derived, V, TC, R, D > const& i))
     874             : 
     875             : #undef BOOST_ITERATOR_FACADE_PLUS
     876             : #undef BOOST_ITERATOR_FACADE_PLUS_HEAD
     877             : 
     878             : #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
     879             : #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
     880             : #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
     881             : 
     882             : } // namespace iterators
     883             : 
     884             : using iterators::iterator_core_access;
     885             : using iterators::iterator_facade;
     886             : 
     887             : } // namespace boost
     888             : 
     889             : #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP

Generated by: LCOV version 1.16