File indexing completed on 2025-09-18 08:53:49
0001
0002
0003
0004
0005
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
0060
0061
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
0165
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
0180
0181
0182 template<typename BidiIter>
0183 using reverse_iterator = std::reverse_iterator<BidiIter>;
0184
0185
0186
0187
0188
0189
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
0201
0202
0203 template<typename BidiIter>
0204 using reverse_iterator = std::reverse_iterator<BidiIter>;
0205
0206
0207
0208
0209
0210
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