GCC Code Coverage Report


Directory: libs/url/
File: boost/url/segments_ref.hpp
Date: 2024-02-29 20:02:56
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 */
155 /** @{ */
156 BOOST_URL_DECL
157 segments_ref&
158 operator=(segments_ref const& other);
159
160 BOOST_URL_DECL
161 segments_ref&
162 operator=(segments_view const& other);
163 /** @} */
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 */
203 BOOST_URL_DECL
204 segments_ref&
205 operator=(std::initializer_list<
206 core::string_view> init);
207
208 /** Conversion
209
210 @see
211 @ref segments_view.
212 */
213 BOOST_URL_DECL
214 operator
215 segments_view() const noexcept;
216
217 //--------------------------------------------
218 //
219 // Observers
220 //
221 //--------------------------------------------
222
223 /** Return the referenced url
224
225 This function returns the url referenced
226 by the view.
227
228 @par Example
229 @code
230 url u( "/path/to/file.txt" );
231
232 assert( &u.segments().url() == &u );
233 @endcode
234
235 @par Exception Safety
236 Throws nothing.
237 */
238 url_base&
239 9 url() const noexcept
240 {
241 9 return *u_;
242 }
243
244 //--------------------------------------------
245 //
246 // Modifiers
247 //
248 //--------------------------------------------
249
250 /** Clear the contents of the container
251
252 <br>
253 All iterators are invalidated.
254
255 @par Effects
256 @code
257 this->url().set_encoded_path( "" );
258 @endcode
259
260 @par Postconditions
261 @code
262 this->empty() == true
263 @endcode
264
265 @par Complexity
266 Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
267
268 @par Exception Safety
269 Throws nothing.
270 */
271 void
272 clear() noexcept;
273
274 /** Assign segments
275
276 The existing contents are replaced
277 by a copy of the contents of the
278 initializer list.
279 Reserved characters in the list are
280 automatically escaped.
281
282 <br>
283 All iterators are invalidated.
284
285 @note
286 None of the character buffers referenced
287 by `init` may overlap the character buffer
288 of the underlying url, or else the behavior
289 is undefined.
290
291 @par Example
292 @code
293 url u;
294
295 u.segments().assign( { "path", "to", "file.txt" } );
296 @endcode
297
298 @par Complexity
299 Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
300
301 @par Exception Safety
302 Strong guarantee.
303 Calls to allocate may throw.
304
305 @param init The list of segments to assign.
306 */
307 BOOST_URL_DECL
308 void
309 assign(std::initializer_list<
310 core::string_view> init);
311
312 /** Assign segments
313
314 The existing contents are replaced
315 by a copy of the contents of the range.
316 Reserved characters in the range are
317 automatically escaped.
318
319 <br>
320 All iterators are invalidated.
321
322 @note
323 None of the character buffers referenced
324 by the range may overlap the character
325 buffer of the underlying url, or else
326 the behavior is undefined.
327
328 @par Mandates
329 @code
330 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
331 @endcode
332
333 @par Complexity
334 Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
335
336 @par Exception Safety
337 Strong guarantee.
338 Calls to allocate may throw.
339
340 @param first, last The range of segments
341 to assign.
342 */
343 template<class FwdIt>
344 void
345 assign(FwdIt first, FwdIt last);
346
347 //--------------------------------------------
348
349 /** Insert segments
350
351 This function inserts a segment
352 before the specified position.
353 Reserved characters in the segment are
354 automatically escaped.
355
356 <br>
357 All iterators that are equal to
358 `before` or come after are invalidated.
359
360 @par Complexity
361 Linear in `s.size() + this->url().encoded_resource().size()`.
362
363 @par Exception Safety
364 Strong guarantee.
365 Calls to allocate may throw.
366
367 @return An iterator to the inserted
368 segment.
369
370 @param before An iterator before which
371 the segment is inserted. This may
372 be equal to `end()`.
373
374 @param s The segment to insert.
375 */
376 BOOST_URL_DECL
377 iterator
378 insert(
379 iterator before,
380 core::string_view s);
381
382 /** Insert segments
383
384 This function inserts the segments
385 in an initializer list before the
386 specified position.
387 Reserved characters in the list are
388 percent-escaped in the result.
389
390 <br>
391 All iterators that are equal to
392 `before` or come after are invalidated.
393
394 @note
395 None of the character buffers referenced
396 by the list may overlap the character
397 buffer of the underlying url, or else
398 the behavior is undefined.
399
400 @par Example
401 @code
402 url u( "/file.txt" );
403
404 u.segments().insert( u.segments().begin(), { "path", "to" } );
405 @endcode
406
407 @par Complexity
408 Linear in `init.size() + this->url().encoded_resource().size()`.
409
410 @par Exception Safety
411 Strong guarantee.
412 Calls to allocate may throw.
413
414 @return An iterator to the first
415 element inserted, or `before` if
416 `init.size() == 0`.
417
418 @param before An iterator before which
419 the list is inserted. This may
420 be equal to `end()`.
421
422 @param init The list of segments to insert.
423 */
424 BOOST_URL_DECL
425 iterator
426 insert(
427 iterator before,
428 std::initializer_list<core::string_view> init);
429
430 /** Insert segments
431
432 This function inserts the segments in
433 a range before the specified position.
434 Reserved characters in the list are
435 automatically escaped.
436
437 <br>
438 All iterators that are equal to
439 `before` or come after are invalidated.
440
441 @note
442 None of the character buffers referenced
443 by the range may overlap the character
444 buffer of the underlying url, or else
445 the behavior is undefined.
446
447 @par Mandates
448 @code
449 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
450 @endcode
451
452 @par Complexity
453 Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
454
455 @par Exception Safety
456 Strong guarantee.
457 Calls to allocate may throw.
458
459 @return An iterator to the first
460 segment inserted, or `before` if
461 `init.empty()`.
462
463 @param before An iterator before which
464 the range is inserted. This may
465 be equal to `end()`.
466
467 @param first, last The range of segments
468 to insert.
469 */
470 template<class FwdIt>
471 iterator
472 insert(
473 iterator before,
474 FwdIt first,
475 FwdIt last);
476
477 //--------------------------------------------
478
479 /** Erase segments
480
481 This function removes a segment.
482
483 <br>
484 All iterators that are equal to
485 `pos` or come after are invalidated.
486
487 @par Complexity
488 Linear in `this->url().encoded_resource().size()`.
489
490 @par Exception Safety
491 Throws nothing.
492
493 @return An iterator to one past
494 the removed segment.
495
496 @param pos An iterator to the segment.
497 */
498 iterator
499 erase(
500 iterator pos) noexcept;
501
502 /** Erase segments
503
504 This function removes a range of segments.
505
506 <br>
507 All iterators that are equal to
508 `first` or come after are invalidated.
509
510 @par Complexity
511 Linear in `this->url().encoded_resource().size()`.
512
513 @par Exception Safety
514 Throws nothing.
515
516 @return An iterator to one past
517 the removed range.
518
519 @param first, last The range of
520 segments to erase.
521 */
522 BOOST_URL_DECL
523 iterator
524 erase(
525 iterator first,
526 iterator last) noexcept;
527
528 //--------------------------------------------
529
530 /** Replace segments
531
532 This function replaces the segment at
533 the specified position.
534 Reserved characters in the string are
535 automatically escaped.
536
537 <br>
538 All iterators that are equal to
539 `pos` or come after are invalidated.
540
541 @par Complexity
542 Linear in `s.size() + this->url().encoded_resouce().size()`.
543
544 @par Exception Safety
545 Strong guarantee.
546 Calls to allocate may throw.
547
548 @return An iterator to the replaced segment.
549
550 @param pos An iterator to the segment.
551
552 @param s The string to assign.
553 */
554 BOOST_URL_DECL
555 iterator
556 replace(
557 iterator pos,
558 core::string_view s);
559
560 /** Replace segments
561
562 This function replaces a range of
563 segments with one segment.
564 Reserved characters in the string are
565 automatically escaped.
566
567 <br>
568 All iterators that are equal to
569 `from` or come after are invalidated.
570
571 @par Complexity
572 Linear in `s.size() + this->url().encoded_resouce().size()`.
573
574 @par Exception Safety
575 Strong guarantee.
576 Calls to allocate may throw.
577
578 @return An iterator to the new segment.
579
580 @param from, to The range of segments to replace.
581
582 @param s The string to assign.
583 */
584 BOOST_URL_DECL
585 iterator
586 replace(
587 iterator from,
588 iterator to,
589 core::string_view s);
590
591 /** Replace segments
592
593 This function replaces a range of
594 segments with a list of segments in
595 an initializer list.
596 Reserved characters in the list are
597 automatically escaped.
598
599 <br>
600 All iterators that are equal to
601 `from` or come after are invalidated.
602
603 @par Preconditions
604 None of the character buffers referenced
605 by the list may overlap the character
606 buffer of the underlying url, or else
607 the behavior is undefined.
608
609 @par Complexity
610 Linear in `init.size() + this->url().encoded_resouce().size()`.
611
612 @par Exception Safety
613 Strong guarantee.
614 Calls to allocate may throw.
615
616 @return An iterator to the first
617 segment inserted, or one past `to` if
618 `init.size() == 0`.
619
620 @param from, to The range of segments to replace.
621
622 @param init The list of segments to assign.
623 */
624 BOOST_URL_DECL
625 iterator
626 replace(
627 iterator from,
628 iterator to,
629 std::initializer_list<
630 core::string_view> init);
631
632 /** Replace segments
633
634 This function replaces a range of
635 segments with annother range of segments.
636 Reserved characters in the new range are
637 automatically escaped.
638
639 <br>
640 All iterators that are equal to
641 `from` or come after are invalidated.
642
643 @par Preconditions
644 None of the character buffers referenced
645 by the new range may overlap the character
646 buffer of the underlying url, or else
647 the behavior is undefined.
648
649 @par Complexity
650 Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
651
652 @par Exception Safety
653 Strong guarantee.
654 Calls to allocate may throw.
655
656 @return An iterator to the first
657 segment inserted, or one past `to` if
658 `init.size() == 0`.
659
660 @param from, to The range of segments to replace.
661
662 @param first, last 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