Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:53:49

0001 // Copyright (C) 2019 T. Zachary Laine
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 #ifndef BOOST_PARSER_DETAIL_STL_INTERFACES_REVERSE_ITERATOR_HPP
0007 #define BOOST_PARSER_DETAIL_STL_INTERFACES_REVERSE_ITERATOR_HPP
0008 
0009 #include <boost/parser/detail/stl_interfaces/iterator_interface.hpp>
0010 
0011 
0012 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
0013 
0014     namespace v1_dtl {
0015         template<typename Iter>
0016         constexpr auto ce_dist(Iter f, Iter l, std::random_access_iterator_tag)
0017             -> decltype(l - f)
0018         {
0019             return l - f;
0020         }
0021         template<typename Iter, typename Tag>
0022         constexpr auto ce_dist(Iter f, Iter l, Tag)
0023             -> decltype(std::distance(f, l))
0024         {
0025             decltype(std::distance(f, l)) retval = 0;
0026             for (; f != l; ++f) {
0027                 ++retval;
0028             }
0029             return retval;
0030         }
0031 
0032         template<typename Iter>
0033         constexpr Iter ce_prev(Iter it)
0034         {
0035             return --it;
0036         }
0037 
0038         template<typename Iter, typename Offset>
0039         constexpr void
0040         ce_adv(Iter & f, Offset n, std::random_access_iterator_tag)
0041         {
0042             f += n;
0043         }
0044         template<typename Iter, typename Offset, typename Tag>
0045         constexpr void ce_adv(Iter & f, Offset n, Tag)
0046         {
0047             if (0 < n) {
0048                 for (Offset i = 0; i < n; ++i) {
0049                     ++f;
0050                 }
0051             } else {
0052                 for (Offset i = 0; i < -n; ++i) {
0053                     --f;
0054                 }
0055             }
0056         }
0057     }
0058 
0059     /** This type is very similar to the C++20 version of
0060         `std::reverse_iterator`; it is `constexpr`-, `noexcept`-, and
0061         proxy-friendly. */
0062     template<typename BidiIter>
0063     struct reverse_iterator
0064         : iterator_interface<
0065 #if !BOOST_PARSER_USE_DEDUCED_THIS
0066               reverse_iterator<BidiIter>,
0067 #endif
0068 #if BOOST_PARSER_DETAIL_STL_INTERFACES_USE_CONCEPTS
0069               typename boost::parser::detail::stl_interfaces::v2::v2_dtl::iter_concept_t<
0070                   BidiIter>,
0071 #else
0072               typename std::iterator_traits<BidiIter>::iterator_category,
0073 #endif
0074               typename std::iterator_traits<BidiIter>::value_type,
0075               typename std::iterator_traits<BidiIter>::reference,
0076               typename std::iterator_traits<BidiIter>::pointer,
0077               typename std::iterator_traits<BidiIter>::difference_type>
0078     {
0079         constexpr reverse_iterator() noexcept(noexcept(BidiIter())) : it_() {}
0080         constexpr reverse_iterator(BidiIter it) noexcept(
0081             noexcept(BidiIter(it))) :
0082             it_(it)
0083         {}
0084         template<
0085             typename BidiIter2,
0086             typename E = std::enable_if_t<
0087                 std::is_convertible<BidiIter2, BidiIter>::value>>
0088         reverse_iterator(reverse_iterator<BidiIter2> const & it) : it_(it.it_)
0089         {}
0090 
0091         friend constexpr auto
0092         operator-(reverse_iterator lhs, reverse_iterator rhs) noexcept(
0093             noexcept(v1_dtl::ce_dist(
0094                 lhs.it_,
0095                 rhs.it_,
0096                 typename std::iterator_traits<BidiIter>::iterator_category{})))
0097         {
0098             return -v1_dtl::ce_dist(
0099                 rhs.it_,
0100                 lhs.it_,
0101                 typename std::iterator_traits<BidiIter>::iterator_category{});
0102         }
0103 
0104         constexpr typename std::iterator_traits<BidiIter>::reference
0105         operator*() const noexcept(
0106             noexcept(std::prev(v1_dtl::ce_prev(std::declval<BidiIter &>()))))
0107         {
0108             return *v1_dtl::ce_prev(it_);
0109         }
0110 
0111         constexpr reverse_iterator & operator+=(
0112             typename std::iterator_traits<BidiIter>::difference_type
0113                 n) noexcept(noexcept(v1_dtl::
0114                                          ce_adv(
0115                                              std::declval<BidiIter &>(),
0116                                              -n,
0117                                              typename std::iterator_traits<
0118                                                  BidiIter>::
0119                                                  iterator_category{})))
0120         {
0121             v1_dtl::ce_adv(
0122                 it_,
0123                 -n,
0124                 typename std::iterator_traits<BidiIter>::iterator_category{});
0125             return *this;
0126         }
0127 
0128         constexpr BidiIter base() const noexcept { return it_; }
0129 
0130     private:
0131         friend access;
0132         constexpr BidiIter & base_reference() noexcept { return it_; }
0133         constexpr BidiIter const & base_reference() const noexcept
0134         {
0135             return it_;
0136         }
0137 
0138         template<typename BidiIter2>
0139         friend struct reverse_iterator;
0140 
0141         BidiIter it_;
0142     };
0143 
0144     template<typename BidiIter>
0145     constexpr auto operator==(
0146         reverse_iterator<BidiIter> lhs,
0147         reverse_iterator<BidiIter>
0148             rhs) noexcept(noexcept(lhs.base() == rhs.base()))
0149         -> decltype(rhs.base() == lhs.base())
0150     {
0151         return lhs.base() == rhs.base();
0152     }
0153 
0154     template<typename BidiIter1, typename BidiIter2>
0155     constexpr auto operator==(
0156         reverse_iterator<BidiIter1> lhs,
0157         reverse_iterator<BidiIter2>
0158             rhs) noexcept(noexcept(lhs.base() == rhs.base()))
0159         -> decltype(rhs.base() == lhs.base())
0160     {
0161         return lhs.base() == rhs.base();
0162     }
0163 
0164     /** Makes a `reverse_iterator<BidiIter>` from an iterator of type
0165         `BidiIter`. */
0166     template<typename BidiIter>
0167     auto make_reverse_iterator(BidiIter it)
0168     {
0169         return reverse_iterator<BidiIter>(it);
0170     }
0171 
0172 }}}
0173 
0174 
0175 #if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_PARSER_DETAIL_STL_INTERFACES_USE_CONCEPTS
0176 
0177 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V2 {
0178 
0179     /** A template alias for `std::reverse_iterator`.  This only exists to
0180         make migration from Boost.STLInterfaces to C++20 easier; switch to the
0181         one in `std` as soon as you can. */
0182     template<typename BidiIter>
0183     using reverse_iterator = std::reverse_iterator<BidiIter>;
0184 
0185 
0186     /** Makes a `reverse_iterator<BidiIter>` from an iterator of type
0187         `BidiIter`.  This only exists to make migration from
0188         Boost.STLInterfaces to C++20 easier; switch to the one in `std` as
0189         soon as you can. */
0190     template<typename BidiIter>
0191     auto make_reverse_iterator(BidiIter it)
0192     {
0193         return reverse_iterator<BidiIter>(it);
0194     }
0195 
0196 }}}
0197 
0198 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V3 {
0199 
0200     /** A template alias for `std::reverse_iterator`.  This only exists to
0201         make migration from Boost.STLInterfaces to C++20 easier; switch to the
0202         one in `std` as soon as you can. */
0203     template<typename BidiIter>
0204     using reverse_iterator = std::reverse_iterator<BidiIter>;
0205 
0206 
0207     /** Makes a `reverse_iterator<BidiIter>` from an iterator of type
0208         `BidiIter`.  This only exists to make migration from
0209         Boost.STLInterfaces to C++20 easier; switch to the one in `std` as
0210         soon as you can. */
0211     template<typename BidiIter>
0212     auto make_reverse_iterator(BidiIter it)
0213     {
0214         return reverse_iterator<BidiIter>(it);
0215     }
0216 
0217 }}}
0218 
0219 #endif
0220 
0221 #endif