include/boost/url/impl/params_encoded_ref.hpp

98.1% Lines (101/103) 100.0% Functions (31/31)
include/boost/url/impl/params_encoded_ref.hpp
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/boostorg/url
9 //
10
11 #ifndef BOOST_URL_IMPL_PARAMS_ENCODED_REF_HPP
12 #define BOOST_URL_IMPL_PARAMS_ENCODED_REF_HPP
13
14 #include <boost/url/params_encoded_view.hpp>
15 #include <boost/url/url_base.hpp>
16 #include <boost/url/detail/except.hpp>
17 #include <boost/url/grammar/ci_string.hpp>
18 #include <boost/assert.hpp>
19 #include <utility>
20
21 namespace boost {
22 namespace urls {
23
24 //------------------------------------------------
25 //
26 // Special Members
27 //
28 //------------------------------------------------
29
30 inline
31 77 params_encoded_ref::
32 params_encoded_ref(
33 77 url_base& u) noexcept
34 77 : params_encoded_base(u.impl_)
35 77 , u_(&u)
36 {
37 77 }
38
39 inline
40 params_encoded_ref&
41 1 params_encoded_ref::
42 operator=(
43 params_encoded_ref const& other)
44 {
45 1 if (!ref_.alias_of( other.ref_ ))
46 1 assign(other.begin(), other.end());
47 1 return *this;
48 }
49
50 inline
51 params_encoded_ref&
52 2 params_encoded_ref::
53 operator=(std::initializer_list<
54 param_pct_view> init)
55 {
56 2 assign(init.begin(), init.end());
57 2 return *this;
58 }
59
60 inline
61 58 params_encoded_ref::
62 operator
63 params_encoded_view() const noexcept
64 {
65 58 return {ref_};
66 }
67
68 //------------------------------------------------
69 //
70 // Modifiers
71 //
72 //------------------------------------------------
73
74 inline
75 void
76 3 params_encoded_ref::
77 assign(
78 std::initializer_list<
79 param_pct_view> init)
80 {
81 3 assign(init.begin(), init.end());
82 3 }
83
84 inline
85 void
86 3 params_encoded_ref::
87 clear() noexcept
88 {
89 3 u_->remove_query();
90 3 }
91
92 template<class FwdIt>
93 void
94 7 params_encoded_ref::
95 assign(FwdIt first, FwdIt last)
96 {
97 /* If you get a compile error here, it
98 means that the iterators you passed
99 do not meet the requirements stated
100 in the documentation.
101 */
102 static_assert(
103 std::is_convertible<
104 typename std::iterator_traits<
105 FwdIt>::reference,
106 param_view>::value,
107 "Type requirements not met");
108
109 7 assign(first, last,
110 typename std::iterator_traits<
111 FwdIt>::iterator_category{});
112 7 }
113
114 inline
115 auto
116 4 params_encoded_ref::
117 append(
118 param_pct_view const& p) ->
119 iterator
120 {
121 4 return insert(end(), p);
122 }
123
124 inline
125 auto
126 4 params_encoded_ref::
127 append(
128 std::initializer_list<
129 param_pct_view> init) ->
130 iterator
131 {
132 4 return insert(end(), init);
133 }
134
135 template<class FwdIt>
136 auto
137 6 params_encoded_ref::
138 append(
139 FwdIt first, FwdIt last) ->
140 iterator
141 {
142 /* If you get a compile error here, it
143 means that the iterators you passed
144 do not meet the requirements stated
145 in the documentation.
146 */
147 static_assert(
148 std::is_convertible<
149 typename std::iterator_traits<
150 FwdIt>::reference,
151 param_view>::value,
152 "Type requirements not met");
153
154 6 return insert(
155 3 end(), first, last);
156 }
157
158 template<class FwdIt>
159 auto
160 19 params_encoded_ref::
161 insert(
162 iterator before,
163 FwdIt first,
164 FwdIt last) ->
165 iterator
166 {
167 /* If you get a compile error here, it
168 means that the iterators you passed
169 do not meet the requirements stated
170 in the documentation.
171 */
172 static_assert(
173 std::is_convertible<
174 typename std::iterator_traits<
175 FwdIt>::reference,
176 param_view>::value,
177 "Type requirements not met");
178
179 34 return insert(
180 before,
181 first,
182 last,
183 typename std::iterator_traits<
184 30 FwdIt>::iterator_category{});
185 }
186
187 template<class FwdIt>
188 auto
189 3 params_encoded_ref::
190 replace(
191 iterator from,
192 iterator to,
193 FwdIt first,
194 FwdIt last) ->
195 iterator
196 {
197 /* If you get a compile error here, it
198 means that the iterators you passed
199 do not meet the requirements stated
200 in the documentation.
201 */
202 static_assert(
203 std::is_convertible<
204 typename std::iterator_traits<
205 FwdIt>::reference,
206 param_view>::value,
207 "Type requirements not met");
208
209 6 return u_->edit_params(
210 from.it_, to.it_,
211 detail::make_params_encoded_iter(
212 4 first, last));
213 }
214
215 //------------------------------------------------
216 //
217 // implementation
218 //
219 //------------------------------------------------
220
221 template<class FwdIt>
222 void
223 7 params_encoded_ref::
224 assign(FwdIt first, FwdIt last,
225 std::forward_iterator_tag)
226 {
227 14 u_->edit_params(
228 7 begin().it_,
229 14 end().it_,
230 detail::make_params_encoded_iter(
231 first, last));
232 7 }
233
234 template<class FwdIt>
235 auto
236 19 params_encoded_ref::
237 insert(
238 iterator before,
239 FwdIt first,
240 FwdIt last,
241 std::forward_iterator_tag) ->
242 iterator
243 {
244 38 return u_->edit_params(
245 before.it_,
246 before.it_,
247 detail::make_params_encoded_iter(
248 30 first, last));
249 }
250
251 inline
252 auto
253 7 params_encoded_ref::
254 insert(
255 iterator before,
256 param_pct_view const& p) ->
257 iterator
258 {
259 7 return u_->edit_params(
260 before.it_,
261 before.it_,
262 14 detail::param_encoded_iter(p));
263 }
264
265 inline
266 auto
267 12 params_encoded_ref::
268 insert(
269 iterator before,
270 std::initializer_list<
271 param_pct_view> init) ->
272 iterator
273 {
274 12 return insert(
275 before,
276 init.begin(),
277 12 init.end());
278 }
279
280 inline
281 std::size_t
282 2 params_encoded_ref::
283 erase(
284 pct_string_view key,
285 ignore_case_param ic) noexcept
286 {
287 // end() can't be fully cached,
288 // since erase invalidates it.
289 2 iterator it;
290 {
291 2 auto const end_ = end();
292 2 it = find_last(end_, key, ic);
293 2 if(it == end_)
294 return 0;
295 }
296 2 std::size_t n = 0;
297 for(;;)
298 {
299 5 ++n;
300 // Use it->key instead of key,
301 // to handle self-intersection
302 5 auto prev = find_last(it, it->key, ic);
303 5 if(prev == end())
304 2 break;
305 3 erase(it);
306 3 it = prev;
307 3 }
308 2 erase(it);
309 2 return n;
310 }
311
312 inline
313 auto
314 5 params_encoded_ref::
315 replace(
316 iterator pos,
317 param_pct_view const& p) ->
318 iterator
319 {
320 15 return u_->edit_params(
321 pos.it_,
322 5 std::next(pos).it_,
323 10 detail::param_encoded_iter(p));
324 }
325
326 inline
327 auto
328 1 params_encoded_ref::
329 replace(
330 iterator from,
331 iterator to,
332 std::initializer_list<
333 param_pct_view> init) ->
334 iterator
335 {
336 1 return replace(
337 from,
338 to,
339 init.begin(),
340 1 init.end());
341 }
342
343 inline
344 auto
345 4 params_encoded_ref::
346 unset(
347 iterator pos) noexcept ->
348 iterator
349 {
350 4 BOOST_ASSERT(pos.it_.nk > 0);
351 4 pct_string_view s;
352 4 return u_->edit_params(
353 4 pos.it_, pos.it_.next(),
354 4 detail::param_encoded_value_iter(
355 8 pos.it_.nk - 1, s, false));
356 }
357
358 inline
359 auto
360 4 params_encoded_ref::
361 set(
362 iterator pos,
363 pct_string_view value) ->
364 iterator
365 {
366 4 BOOST_ASSERT(pos.it_.nk > 0);
367 4 return u_->edit_params(
368 pos.it_,
369 4 pos.it_.next(),
370 4 detail::param_encoded_value_iter(
371 12 pos.it_.nk - 1, value, true));
372 }
373
374 inline
375 auto
376 1 params_encoded_ref::
377 set(
378 pct_string_view key,
379 pct_string_view value,
380 ignore_case_param ic) ->
381 iterator
382 {
383 // VFALCO we can't cache end() here
384 // because it is invalidated
385 // every time we set or erase.
386 1 auto it0 = find(key, ic);
387 1 if(it0 == end())
388 return append({key, value});
389 1 it0 = set(it0, value);
390 1 auto it = end();
391 for(;;)
392 {
393 2 it = find_last(it, key, ic);
394 2 if(it == it0)
395 1 return it0;
396 1 it = erase(it);
397 }
398 }
399
400 inline
401 auto
402 9 params_encoded_ref::
403 erase(
404 iterator pos) noexcept ->
405 iterator
406 {
407 9 return erase(
408 pos,
409 9 std::next(pos));
410 }
411
412 inline
413 auto
414 11 params_encoded_ref::
415 erase(
416 iterator first,
417 iterator last) noexcept ->
418 iterator
419 {
420 11 core::string_view s("", 0);
421 11 return u_->edit_params(
422 first.it_,
423 last.it_,
424 22 detail::query_string_iter(s));
425 }
426
427 } // urls
428 } // boost
429
430 #endif
431