GCC Code Coverage Report


Directory: libs/url/
File: include/boost/url/segments_ref.hpp
Date: 2025-11-13 05:23:43
Exec Total Coverage
Lines: 2 2 100.0%
Functions: 1 1 100.0%
Branches: 0 0 -%

Line Branch Exec Source
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_SEGMENTS_REF_HPP
12 #define BOOST_URL_SEGMENTS_REF_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/segments_base.hpp>
16 #include <initializer_list>
17 #include <iterator>
18
19 namespace boost {
20 namespace urls {
21
22 #ifndef BOOST_URL_DOCS
23 class url_base;
24 class segments_view;
25 #endif
26
27 /** Mutable decoded path segment proxy
28
29 Presents the decoded path segments of a
30 @ref url_base as a bidirectional range whose
31 modifiers update the underlying URL. The proxy
32 references the URL’s storage directly, so the
33 owning URL must remain alive while the proxy
34 is used.
35
36 @par Example
37 @code
38 url u( "/path/to/file.txt" );
39
40 segments_ref ps = u.segments();
41 @endcode
42
43 Percent escapes in strings returned when
44 dereferencing iterators are automatically
45 decoded.
46 Reserved characters in strings supplied
47 to modifier functions are automatically
48 percent-escaped.
49
50 @par Iterator Invalidation
51 Changes to the underlying character buffer
52 can invalidate iterators which reference it.
53 Modifications made through the container
54 invalidate some or all iterators:
55 <br>
56
57 @li @ref push_back : Only `end()`.
58
59 @li @ref assign, @ref clear,
60 @ref operator= : All elements.
61
62 @li @ref erase : Erased elements and all
63 elements after (including `end()`).
64
65 @li @ref insert : All elements at or after
66 the insertion point (including `end()`).
67
68 @li @ref replace : Modified
69 elements and all elements
70 after (including `end()`).
71
72 @see
73 @ref segments_encoded_ref,
74 @ref segments_encoded_view,
75 @ref segments_view.
76 */
77 class segments_ref
78 : public segments_base
79 {
80 url_base* u_ = nullptr;
81
82 friend class url_base;
83 friend class segments_encoded_ref;
84
85 segments_ref(url_base& u) noexcept;
86
87 public:
88 //--------------------------------------------
89 //
90 // Special Members
91 //
92 //--------------------------------------------
93
94 /** Constructor
95
96 After construction, both views
97 reference the same url. Ownership is not
98 transferred; the caller is responsible
99 for ensuring the lifetime of the url
100 extends until it is no longer
101 referenced.
102
103 @par Postconditions
104 @code
105 &this->url() == &other.url();
106 @endcode
107
108 @par Complexity
109 Constant.
110
111 @par Exception Safety
112 Throws nothing.
113
114 @param other The other view.
115 */
116 segments_ref(
117 segments_ref const& other) = default;
118
119 /** Assignment
120
121 The existing contents are replaced
122 by a copy of the other segments.
123
124 <br>
125 All iterators are invalidated.
126
127 @note
128 None of the character buffers referenced
129 by `other` may overlap the buffer of the
130 underlying url, or else the behavior
131 is undefined.
132
133 @par Effects
134 @code
135 this->assign( other.begin(), other.end() );
136 @endcode
137
138 @par Complexity
139 Linear in `other.buffer().size()`.
140
141 @par Exception Safety
142 Strong guarantee.
143 Calls to allocate may throw.
144
145 @param other The segments to assign.
146 @return A reference to this object.
147 */
148 BOOST_URL_DECL
149 segments_ref&
150 operator=(segments_ref const& other);
151
152 /// @copydoc segments_ref::operator=(segments_ref const&)
153 BOOST_URL_DECL
154 segments_ref&
155 operator=(segments_view const& other);
156
157 /** Assignment
158
159 The existing contents are replaced
160 by a copy of the contents of the
161 initializer list.
162 Reserved characters in the list are
163 automatically escaped.
164
165 <br>
166 All iterators are invalidated.
167
168 @par Example
169 @code
170 url u;
171
172 u.segments() = { "path", "to", "file.txt" };
173 @endcode
174
175 @par Preconditions
176 None of the character buffers referenced
177 by the list may overlap the character
178 buffer of the underlying url, or else
179 the behavior is undefined.
180
181 @par Effects
182 @code
183 this->assign( init.begin(), init.end() );
184 @endcode
185
186 @par Complexity
187 Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
188
189 @par Exception Safety
190 Strong guarantee.
191 Calls to allocate may throw.
192
193 @param init The list of segments to assign.
194 @return A reference to this object.
195 */
196 BOOST_URL_DECL
197 segments_ref&
198 operator=(std::initializer_list<
199 core::string_view> init);
200
201 /** Conversion
202
203 @see
204 @ref segments_view.
205
206 @return A view of the segments.
207 */
208 BOOST_URL_DECL
209 operator
210 segments_view() const noexcept;
211
212 //--------------------------------------------
213 //
214 // Observers
215 //
216 //--------------------------------------------
217
218 /** Return the referenced url
219
220 This function returns the url referenced
221 by the view.
222
223 @par Example
224 @code
225 url u( "/path/to/file.txt" );
226
227 assert( &u.segments().url() == &u );
228 @endcode
229
230 @par Exception Safety
231 Throws nothing.
232
233 @return A reference to the url.
234 */
235 url_base&
236 9 url() const noexcept
237 {
238 9 return *u_;
239 }
240
241 //--------------------------------------------
242 //
243 // Modifiers
244 //
245 //--------------------------------------------
246
247 /** Clear the contents of the container
248
249 <br>
250 All iterators are invalidated.
251
252 @par Effects
253 @code
254 this->url().set_encoded_path( "" );
255 @endcode
256
257 @par Postconditions
258 @code
259 this->empty() == true
260 @endcode
261
262 @par Complexity
263 Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
264
265 @par Exception Safety
266 Throws nothing.
267 */
268 void
269 clear() noexcept;
270
271 /** Assign segments
272
273 The existing contents are replaced
274 by a copy of the contents of the
275 initializer list.
276 Reserved characters in the list are
277 automatically escaped.
278
279 <br>
280 All iterators are invalidated.
281
282 @note
283 None of the character buffers referenced
284 by `init` may overlap the character buffer
285 of the underlying url, or else the behavior
286 is undefined.
287
288 @par Example
289 @code
290 url u;
291
292 u.segments().assign( { "path", "to", "file.txt" } );
293 @endcode
294
295 @par Complexity
296 Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
297
298 @par Exception Safety
299 Strong guarantee.
300 Calls to allocate may throw.
301
302 @param init The list of segments to assign.
303 */
304 BOOST_URL_DECL
305 void
306 assign(std::initializer_list<
307 core::string_view> init);
308
309 /** Assign segments
310
311 The existing contents are replaced
312 by a copy of the contents of the range.
313 Reserved characters in the range are
314 automatically escaped.
315
316 <br>
317 All iterators are invalidated.
318
319 @note
320 None of the character buffers referenced
321 by the range may overlap the character
322 buffer of the underlying url, or else
323 the behavior is undefined.
324
325 @par Mandates
326 @code
327 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
328 @endcode
329
330 @par Complexity
331 Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
332
333 @par Exception Safety
334 Strong guarantee.
335 Calls to allocate may throw.
336
337 @param first The beginning of the range of segments to assign.
338 @param last The end of the range of segments to assign.
339 */
340 template<class FwdIt>
341 void
342 assign(FwdIt first, FwdIt last);
343
344 //--------------------------------------------
345
346 /** Insert segments
347
348 This function inserts a segment
349 before the specified position.
350 Reserved characters in the segment are
351 automatically escaped.
352
353 <br>
354 All iterators that are equal to
355 `before` or come after are invalidated.
356
357 @par Complexity
358 Linear in `s.size() + this->url().encoded_resource().size()`.
359
360 @par Exception Safety
361 Strong guarantee.
362 Calls to allocate may throw.
363
364 @return An iterator to the inserted
365 segment.
366
367 @param before An iterator before which
368 the segment is inserted. This may
369 be equal to `end()`.
370
371 @param s The segment to insert.
372 */
373 BOOST_URL_DECL
374 iterator
375 insert(
376 iterator before,
377 core::string_view s);
378
379 /** Insert segments
380
381 This function inserts the segments
382 in an initializer list before the
383 specified position.
384 Reserved characters in the list are
385 percent-escaped in the result.
386
387 <br>
388 All iterators that are equal to
389 `before` or come after are invalidated.
390
391 @note
392 None of the character buffers referenced
393 by the list may overlap the character
394 buffer of the underlying url, or else
395 the behavior is undefined.
396
397 @par Example
398 @code
399 url u( "/file.txt" );
400
401 u.segments().insert( u.segments().begin(), { "path", "to" } );
402 @endcode
403
404 @par Complexity
405 Linear in `init.size() + this->url().encoded_resource().size()`.
406
407 @par Exception Safety
408 Strong guarantee.
409 Calls to allocate may throw.
410
411 @return An iterator to the first
412 element inserted, or `before` if
413 `init.size() == 0`.
414
415 @param before An iterator before which
416 the list is inserted. This may
417 be equal to `end()`.
418
419 @param init The list of segments to insert.
420 */
421 BOOST_URL_DECL
422 iterator
423 insert(
424 iterator before,
425 std::initializer_list<core::string_view> init);
426
427 /** Insert segments
428
429 This function inserts the segments in
430 a range before the specified position.
431 Reserved characters in the list are
432 automatically escaped.
433
434 <br>
435 All iterators that are equal to
436 `before` or come after are invalidated.
437
438 @note
439 None of the character buffers referenced
440 by the range may overlap the character
441 buffer of the underlying url, or else
442 the behavior is undefined.
443
444 @par Mandates
445 @code
446 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
447 @endcode
448
449 @par Complexity
450 Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
451
452 @par Exception Safety
453 Strong guarantee.
454 Calls to allocate may throw.
455
456 @return An iterator to the first
457 segment inserted, or `before` if
458 `init.empty()`.
459
460 @param before An iterator before which
461 the range is inserted. This may
462 be equal to `end()`.
463
464 @param first The beginning of the range of segments to insert.
465 @param last The end of the range of segments to insert.
466 */
467 template<class FwdIt>
468 iterator
469 insert(
470 iterator before,
471 FwdIt first,
472 FwdIt last);
473
474 //--------------------------------------------
475
476 /** Erase segments
477
478 This function removes a segment.
479
480 <br>
481 All iterators that are equal to
482 `pos` or come after are invalidated.
483
484 @par Complexity
485 Linear in `this->url().encoded_resource().size()`.
486
487 @par Exception Safety
488 Throws nothing.
489
490 @return An iterator to one past
491 the removed segment.
492
493 @param pos An iterator to the segment.
494 */
495 iterator
496 erase(
497 iterator pos) noexcept;
498
499 /** Erase segments
500
501 This function removes a range of segments.
502
503 <br>
504 All iterators that are equal to
505 `first` or come after are invalidated.
506
507 @par Complexity
508 Linear in `this->url().encoded_resource().size()`.
509
510 @par Exception Safety
511 Throws nothing.
512
513 @return An iterator to one past
514 the removed range.
515
516 @param first The beginning of the range to remove.
517 @param last The end of the range to remove.
518 */
519 BOOST_URL_DECL
520 iterator
521 erase(
522 iterator first,
523 iterator last) noexcept;
524
525 //--------------------------------------------
526
527 /** Replace segments
528
529 This function replaces the segment at
530 the specified position.
531 Reserved characters in the string are
532 automatically escaped.
533
534 <br>
535 All iterators that are equal to
536 `pos` or come after are invalidated.
537
538 @par Complexity
539 Linear in `s.size() + this->url().encoded_resouce().size()`.
540
541 @par Exception Safety
542 Strong guarantee.
543 Calls to allocate may throw.
544
545 @return An iterator to the replaced segment.
546
547 @param pos An iterator to the segment.
548
549 @param s The string to assign.
550 */
551 BOOST_URL_DECL
552 iterator
553 replace(
554 iterator pos,
555 core::string_view s);
556
557 /** Replace segments
558
559 This function replaces a range of
560 segments with one segment.
561 Reserved characters in the string are
562 automatically escaped.
563
564 <br>
565 All iterators that are equal to
566 `from` or come after are invalidated.
567
568 @par Complexity
569 Linear in `s.size() + this->url().encoded_resouce().size()`.
570
571 @par Exception Safety
572 Strong guarantee.
573 Calls to allocate may throw.
574
575 @return An iterator to the new segment.
576
577 @param from The beginning of the range of segments to replace.
578 @param to The end of the range of segments to replace.
579
580 @param s The string to assign.
581 */
582 BOOST_URL_DECL
583 iterator
584 replace(
585 iterator from,
586 iterator to,
587 core::string_view s);
588
589 /** Replace segments
590
591 This function replaces a range of
592 segments with a list of segments in
593 an initializer list.
594 Reserved characters in the list are
595 automatically escaped.
596
597 <br>
598 All iterators that are equal to
599 `from` or come after are invalidated.
600
601 @par Preconditions
602 None of the character buffers referenced
603 by the list may overlap the character
604 buffer of the underlying url, or else
605 the behavior is undefined.
606
607 @par Complexity
608 Linear in `init.size() + this->url().encoded_resouce().size()`.
609
610 @par Exception Safety
611 Strong guarantee.
612 Calls to allocate may throw.
613
614 @return An iterator to the first
615 segment inserted, or one past `to` if
616 `init.size() == 0`.
617
618 @param from The beginning of the range of segments to replace.
619 @param to The end of the range of segments to replace.
620
621 @param init The list of segments to assign.
622 */
623 BOOST_URL_DECL
624 iterator
625 replace(
626 iterator from,
627 iterator to,
628 std::initializer_list<
629 core::string_view> init);
630
631 /** Replace segments
632
633 This function replaces a range of
634 segments with annother range of segments.
635 Reserved characters in the new range are
636 automatically escaped.
637
638 <br>
639 All iterators that are equal to
640 `from` or come after are invalidated.
641
642 @par Preconditions
643 None of the character buffers referenced
644 by the new range may overlap the character
645 buffer of the underlying url, or else
646 the behavior is undefined.
647
648 @par Complexity
649 Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
650
651 @par Exception Safety
652 Strong guarantee.
653 Calls to allocate may throw.
654
655 @return An iterator to the first
656 segment inserted, or one past `to` if
657 `init.size() == 0`.
658
659 @param from The beginning of the range of segments to replace.
660 @param to The end of the range of segments to replace.
661 @param first The beginning of the range of segments to assign.
662 @param last The end of the range of segments to assign.
663 */
664 template<class FwdIt>
665 iterator
666 replace(
667 iterator from,
668 iterator to,
669 FwdIt first,
670 FwdIt last);
671
672 /** Append a segment
673
674 This function appends a segment to
675 the end of the path.
676 Reserved characters in the string are
677 automatically escaped.
678
679 <br>
680 All end iterators are invalidated.
681
682 @par Postconditions
683 @code
684 this->back() == s
685 @endcode
686
687 @par Exception Safety
688 Strong guarantee.
689 Calls to allocate may throw.
690
691 @param s The segment to append.
692 */
693 void
694 push_back(
695 core::string_view s);
696
697 /** Remove the last segment
698
699 This function removes the last segment
700 from the container.
701
702 <br>
703 Iterators to the last segment as well
704 as all end iterators are invalidated.
705
706 @par Preconditions
707 @code
708 not this->empty()
709 @endcode
710
711 @par Exception Safety
712 Throws nothing.
713 */
714 void
715 pop_back() noexcept;
716
717 private:
718 template<class FwdIt>
719 iterator
720 insert(
721 iterator before,
722 FwdIt first,
723 FwdIt last,
724 std::input_iterator_tag) = delete;
725
726 template<class FwdIt>
727 iterator
728 insert(
729 iterator before,
730 FwdIt first,
731 FwdIt last,
732 std::forward_iterator_tag);
733 };
734
735 } // urls
736 } // boost
737
738 // This include is at the bottom of
739 // url_base.hpp because of a circular dependency
740 //
741 // #include <boost/url/impl/segments_ref.hpp>
742
743 #endif
744