TLA Line data Source code
1 : //
2 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 : #ifndef BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP
11 : #define BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP
12 :
13 : #include <boost/url/grammar/type_traits.hpp>
14 : #include <boost/core/detail/static_assert.hpp>
15 :
16 : namespace boost {
17 : namespace urls {
18 :
19 : class decode_view::iterator
20 : {
21 : char const* begin_ = nullptr;
22 : char const* pos_ = nullptr;
23 : bool space_as_plus_ = true;
24 :
25 : friend decode_view;
26 :
27 HIT 17855 : iterator(
28 : char const* str,
29 : bool space_as_plus) noexcept
30 17855 : : begin_(str)
31 17855 : , pos_(str)
32 17855 : , space_as_plus_(
33 : space_as_plus)
34 : {
35 17855 : }
36 :
37 : // end ctor
38 7534 : iterator(
39 : char const* str,
40 : size_type n,
41 : bool space_as_plus) noexcept
42 7534 : : begin_(str)
43 7534 : , pos_(str + n)
44 7534 : , space_as_plus_(space_as_plus)
45 : {
46 7534 : }
47 :
48 : public:
49 : using value_type = char;
50 : using reference = char;
51 : using pointer = void const*;
52 : using const_reference = char;
53 : using size_type = std::size_t;
54 : using difference_type = std::ptrdiff_t;
55 : using iterator_category =
56 : std::bidirectional_iterator_tag;
57 :
58 2 : iterator() = default;
59 :
60 : iterator(iterator const&) = default;
61 :
62 : iterator&
63 : operator=(iterator const&) = default;
64 :
65 : BOOST_URL_DECL
66 : reference
67 : operator*() const noexcept;
68 :
69 : iterator&
70 1178835 : operator++() noexcept
71 : {
72 1178835 : BOOST_ASSERT(pos_ != nullptr);
73 1178835 : if (*pos_ != '%')
74 956387 : ++pos_;
75 : else
76 222448 : pos_ += 3;
77 1178835 : return *this;
78 : }
79 :
80 : iterator&
81 3601 : operator--() noexcept
82 : {
83 3601 : BOOST_ASSERT(pos_ != begin_);
84 3601 : if (pos_ - begin_ < 3 ||
85 3593 : pos_[-3] != '%')
86 2958 : --pos_;
87 : else
88 643 : pos_ -= 3;
89 3601 : return *this;
90 : }
91 :
92 : iterator
93 11371 : operator++(int) noexcept
94 : {
95 11371 : auto tmp = *this;
96 11371 : ++*this;
97 11371 : return tmp;
98 : }
99 :
100 : iterator
101 : operator--(int) noexcept
102 : {
103 : auto tmp = *this;
104 : --*this;
105 : return tmp;
106 : }
107 :
108 : char const*
109 22 : base()
110 : {
111 22 : return pos_;
112 : }
113 :
114 : bool
115 1171656 : operator==(
116 : iterator const& other) const noexcept
117 : {
118 1171656 : return pos_ == other.pos_;
119 : }
120 :
121 : bool
122 1171106 : operator!=(
123 : iterator const& other) const noexcept
124 : {
125 1171106 : return !(*this == other);
126 : }
127 : };
128 :
129 : //------------------------------------------------
130 :
131 : inline
132 : auto
133 17855 : decode_view::
134 : begin() const noexcept ->
135 : const_iterator
136 : {
137 17855 : return {p_, space_as_plus_};
138 : }
139 :
140 : inline
141 : auto
142 7534 : decode_view::
143 : end() const noexcept ->
144 : const_iterator
145 : {
146 7534 : return {p_, n_, space_as_plus_};
147 : }
148 :
149 : inline
150 : auto
151 3552 : decode_view::
152 : front() const noexcept ->
153 : const_reference
154 : {
155 3552 : BOOST_ASSERT( !empty() );
156 3552 : return *begin();
157 : }
158 :
159 : inline
160 : auto
161 3533 : decode_view::
162 : back() const noexcept ->
163 : const_reference
164 : {
165 3533 : BOOST_ASSERT( !empty() );
166 3533 : return *--end();
167 : }
168 :
169 : namespace detail {
170 :
171 : template <class T>
172 : BOOST_CXX14_CONSTEXPR
173 : int
174 9975 : decoded_strcmp(decode_view s0, T s1)
175 : {
176 9975 : auto const n0 = s0.size();
177 9975 : auto const n1 = s1.size();
178 9975 : auto n = (std::min)(n0, n1);
179 9975 : auto it0 = s0.begin();
180 9975 : auto it1 = s1.begin();
181 13767 : while (n != 0)
182 : {
183 10708 : --n;
184 10708 : const char c0 = *it0++;
185 10708 : const char c1 = *it1++;
186 10708 : if (c0 == c1)
187 3792 : continue;
188 6916 : return 1 - 2 * (static_cast<unsigned char>(c0)
189 13832 : < static_cast<unsigned char>(c1));
190 : }
191 3059 : return 1 - (n0 == n1) - 2 * (n0 < n1);
192 : }
193 :
194 : } // detail
195 :
196 :
197 : #if defined(BOOST_NO_CXX14_CONSTEXPR)
198 : inline
199 : #else
200 : BOOST_CXX14_CONSTEXPR
201 : #endif
202 : int
203 9643 : decode_view::
204 : compare(core::string_view other) const noexcept
205 : {
206 9643 : return detail::decoded_strcmp(*this, other);
207 : }
208 :
209 : #if defined(BOOST_NO_CXX14_CONSTEXPR)
210 : inline
211 : #else
212 : BOOST_CXX14_CONSTEXPR
213 : #endif
214 : int
215 332 : decode_view::
216 : compare(decode_view other) const noexcept
217 : {
218 332 : return detail::decoded_strcmp(*this, other);
219 : }
220 :
221 : } // urls
222 : } // boost
223 :
224 : #endif
|