GCC Code Coverage Report


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