File indexing completed on 2025-12-16 10:10:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP
0011 #define BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP
0012
0013 #include <boost/url/grammar/type_traits.hpp>
0014 #include <boost/static_assert.hpp>
0015
0016 namespace boost {
0017 namespace urls {
0018
0019 class decode_view::iterator
0020 {
0021 char const* begin_ = nullptr;
0022 char const* pos_ = nullptr;
0023 bool space_as_plus_ = true;
0024
0025 friend decode_view;
0026
0027 iterator(
0028 char const* str,
0029 bool space_as_plus) noexcept
0030 : begin_(str)
0031 , pos_(str)
0032 , space_as_plus_(
0033 space_as_plus)
0034 {
0035 }
0036
0037
0038 iterator(
0039 char const* str,
0040 size_type n,
0041 bool space_as_plus) noexcept
0042 : begin_(str)
0043 , pos_(str + n)
0044 , space_as_plus_(space_as_plus)
0045 {
0046 }
0047
0048 public:
0049 using value_type = char;
0050 using reference = char;
0051 using pointer = void const*;
0052 using const_reference = char;
0053 using size_type = std::size_t;
0054 using difference_type = std::ptrdiff_t;
0055 using iterator_category =
0056 std::bidirectional_iterator_tag;
0057
0058 iterator() = default;
0059
0060 iterator(iterator const&) = default;
0061
0062 iterator&
0063 operator=(iterator const&) = default;
0064
0065 BOOST_URL_DECL
0066 reference
0067 operator*() const noexcept;
0068
0069 iterator&
0070 operator++() noexcept
0071 {
0072 BOOST_ASSERT(pos_ != nullptr);
0073 if (*pos_ != '%')
0074 ++pos_;
0075 else
0076 pos_ += 3;
0077 return *this;
0078 }
0079
0080 iterator&
0081 operator--() noexcept
0082 {
0083 BOOST_ASSERT(pos_ != begin_);
0084 if (pos_ - begin_ < 3 ||
0085 pos_[-3] != '%')
0086 --pos_;
0087 else
0088 pos_ -= 3;
0089 return *this;
0090 }
0091
0092 iterator
0093 operator++(int) noexcept
0094 {
0095 auto tmp = *this;
0096 ++*this;
0097 return tmp;
0098 }
0099
0100 iterator
0101 operator--(int) noexcept
0102 {
0103 auto tmp = *this;
0104 --*this;
0105 return tmp;
0106 }
0107
0108 char const*
0109 base()
0110 {
0111 return pos_;
0112 }
0113
0114 bool
0115 operator==(
0116 iterator const& other) const noexcept
0117 {
0118 return pos_ == other.pos_;
0119 }
0120
0121 bool
0122 operator!=(
0123 iterator const& other) const noexcept
0124 {
0125 return !(*this == other);
0126 }
0127 };
0128
0129
0130
0131 inline
0132 auto
0133 decode_view::
0134 begin() const noexcept ->
0135 const_iterator
0136 {
0137 return {p_, space_as_plus_};
0138 }
0139
0140 inline
0141 auto
0142 decode_view::
0143 end() const noexcept ->
0144 const_iterator
0145 {
0146 return {p_, n_, space_as_plus_};
0147 }
0148
0149 inline
0150 auto
0151 decode_view::
0152 front() const noexcept ->
0153 const_reference
0154 {
0155 BOOST_ASSERT( !empty() );
0156 return *begin();
0157 }
0158
0159 inline
0160 auto
0161 decode_view::
0162 back() const noexcept ->
0163 const_reference
0164 {
0165 BOOST_ASSERT( !empty() );
0166 return *--end();
0167 }
0168
0169 namespace detail {
0170
0171 template <class T>
0172 BOOST_CXX14_CONSTEXPR
0173 int
0174 decoded_strcmp(decode_view s0, T s1)
0175 {
0176 auto const n0 = s0.size();
0177 auto const n1 = s1.size();
0178 auto n = (std::min)(n0, n1);
0179 auto it0 = s0.begin();
0180 auto it1 = s1.begin();
0181 while (n--)
0182 {
0183 const char c0 = *it0++;
0184 const char c1 = *it1++;
0185 if (c0 == c1)
0186 continue;
0187 return 1 - 2 * (static_cast<unsigned char>(c0)
0188 < static_cast<unsigned char>(c1));
0189 }
0190 return 1 - (n0 == n1) - 2 * (n0 < n1);
0191 }
0192
0193 }
0194
0195
0196 #if defined(BOOST_NO_CXX14_CONSTEXPR)
0197 inline
0198 #else
0199 BOOST_CXX14_CONSTEXPR
0200 #endif
0201 int
0202 decode_view::
0203 compare(core::string_view other) const noexcept
0204 {
0205 return detail::decoded_strcmp(*this, other);
0206 }
0207
0208 #if defined(BOOST_NO_CXX14_CONSTEXPR)
0209 inline
0210 #else
0211 BOOST_CXX14_CONSTEXPR
0212 #endif
0213 int
0214 decode_view::
0215 compare(decode_view other) const noexcept
0216 {
0217 return detail::decoded_strcmp(*this, other);
0218 }
0219
0220 }
0221 }
0222
0223 #endif