include/boost/url/impl/params_ref.hpp

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