include/boost/url/segments_encoded_ref.hpp

100.0% Lines (2/2) 100.0% Functions (1/1) -% Branches (0/0)
include/boost/url/segments_encoded_ref.hpp
Line 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_SEGMENTS_ENCODED_REF_HPP
12 #define BOOST_URL_SEGMENTS_ENCODED_REF_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/segments_encoded_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_encoded_view;
25 #endif
26
27 /** Mutable encoded path segment proxy
28
29 Exposes the percent-encoded segments of a
30 @ref url_base as a bidirectional range that
31 can modify the underlying URL. The proxy uses
32 the URL’s storage directly, so the url must
33 outlive any references.
34
35 @par Example
36 @code
37 url u( "/path/to/file.txt" );
38
39 segments_encoded_ref ps = u.encoded_segments();
40 @endcode
41
42 The strings returned when iterators are
43 dereferenced have type @ref pct_string_view
44 and may contain percent-escapes.
45
46 Reserved characters in inputs are
47 automatically escaped.
48 Escapes in inputs are preserved.
49
50 Exceptions are thrown on invalid inputs.
51
52 @par Iterator Invalidation
53 Changes to the underlying character buffer
54 can invalidate iterators which reference it.
55 Modifications made through the container
56 invalidate some or all iterators:
57 <br>
58
59 @li @ref push_back : Only `end()`.
60
61 @li @ref assign, @ref clear,
62 @ref operator= : All elements.
63
64 @li @ref erase : Erased elements and all
65 elements after (including `end()`).
66
67 @li @ref insert : All elements at or after
68 the insertion point (including `end()`).
69
70 @li @ref replace : Modified
71 elements and all elements
72 after (including `end()`).
73
74 @see
75 @ref segments_encoded_view,
76 @ref segments_view,
77 @ref segments_ref.
78 */
79 class BOOST_URL_DECL segments_encoded_ref
80 : public segments_encoded_base
81 {
82 friend class url_base;
83
84 url_base* u_ = nullptr;
85
86 segments_encoded_ref(
87 url_base& u) noexcept;
88
89 public:
90 //--------------------------------------------
91 //
92 // Special Members
93 //
94 //--------------------------------------------
95
96 /** Constructor
97
98 After construction, both views
99 reference the same url. Ownership is not
100 transferred; the caller is responsible
101 for ensuring the lifetime of the url
102 extends until it is no longer
103 referenced.
104
105 @par Postconditions
106 @code
107 &this->url() == &other.url();
108 @endcode
109
110 @par Complexity
111 Constant.
112
113 @par Exception Safety
114 Throws nothing.
115
116 @param other The other view.
117 */
118 segments_encoded_ref(
119 segments_encoded_ref const& other) = default;
120
121 /** Assignment
122
123 The existing contents are replaced
124 by a copy of the other segments.
125
126 <br>
127 All iterators are invalidated.
128
129 @note
130 None of the character buffers referenced
131 by `other` may overlap the buffer of the
132 underlying url, or else the behavior
133 is undefined.
134
135 @par Effects
136 @code
137 this->assign( other.begin(), other.end() );
138 @endcode
139
140 @par Complexity
141 Linear in `other.buffer().size()`.
142
143 @par Exception Safety
144 Strong guarantee.
145 Calls to allocate may throw.
146
147 @param other The segments to assign.
148 @return A reference to this object.
149 */
150 segments_encoded_ref&
151 operator=(segments_encoded_ref const& other);
152
153 /// @copydoc operator=(segments_encoded_ref const&)
154 segments_encoded_ref&
155 operator=(segments_encoded_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 Escapes in the list are preserved.
165
166 <br>
167 All iterators are invalidated.
168
169 @par Example
170 @code
171 url u;
172
173 u.encoded_segments() = {"path", "to", "file.txt"};
174 @endcode
175
176 @par Preconditions
177 None of the character buffers referenced
178 by the list may overlap the character buffer
179 of the underlying url, or else the behavior
180 is undefined.
181
182 @par Effects
183 @code
184 this->assign( init.begin(), init.end() );
185 @endcode
186
187 @par Complexity
188 Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
189
190 @par Exception Safety
191 Strong guarantee.
192 Calls to allocate may throw.
193 Exceptions thrown on invalid input.
194
195 @throw system_error
196 The list contains an invalid percent-encoding.
197
198 @param init The list of segments to assign.
199 @return A reference to this.
200 */
201 segments_encoded_ref&
202 operator=(std::initializer_list<
203 pct_string_view> init);
204
205 /** Conversion
206
207 @see
208 @ref segments_encoded_view.
209
210 @return A view of the segments.
211 */
212 operator
213 segments_encoded_view() const noexcept;
214
215 //--------------------------------------------
216 //
217 // Observers
218 //
219 //--------------------------------------------
220
221 /** Return the referenced url
222
223 This function returns the url referenced
224 by the view.
225
226 @par Example
227 @code
228 url u( "/path/to/file.txt" );
229
230 assert( &u.encoded_segments().url() == &u );
231 @endcode
232
233 @par Exception Safety
234 Throws nothing.
235
236 @return A reference to the url.
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 Escapes in the list are preserved.
282
283 <br>
284 All iterators are invalidated.
285
286 @note
287 None of the character buffers referenced
288 by the list may overlap the character
289 buffer of the underlying url, or else
290 the behavior is undefined.
291
292 @par Example
293 @code
294 url u;
295
296 u.segments().assign( {"path", "to", "file.txt"} );
297 @endcode
298
299 @par Complexity
300 Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
301
302 @par Exception Safety
303 Strong guarantee.
304 Calls to allocate may throw.
305 Exceptions thrown on invalid input.
306
307 @throw system_error
308 The list contains an invalid percent-encoding.
309
310 @param init The list of segments to assign.
311 */
312 void
313 assign(std::initializer_list<
314 pct_string_view> init);
315
316 /** Assign segments
317
318 The existing contents are replaced
319 by a copy of the contents of the range.
320 Reserved characters in the range are
321 automatically escaped.
322 Escapes in the range are preserved.
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, pct_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 Exceptions thrown on invalid input.
345
346 @throw system_error
347 The range contains an invalid percent-encoding.
348
349 @param first The first element in the range.
350 @param last One past the last element in the range.
351 */
352 template<class FwdIt>
353 void
354 assign(FwdIt first, FwdIt last);
355
356 //--------------------------------------------
357
358 /** Insert segments
359
360 This function inserts a segment
361 before the specified position.
362 Reserved characters in the segment are
363 automatically escaped.
364 Escapes in the segment are preserved.
365
366 <br>
367 All iterators that are equal to
368 `before` or come after are invalidated.
369
370 @par Complexity
371 Linear in `s.size() + this->url().encoded_resource().size()`.
372
373 @par Exception Safety
374 Strong guarantee.
375 Calls to allocate may throw.
376 Exceptions thrown on invalid input.
377
378 @throw system_error
379 The segment contains an invalid percent-encoding.
380
381 @return An iterator to the inserted
382 segment.
383
384 @param before An iterator before which
385 the segment is inserted. This may
386 be equal to `end()`.
387
388 @param s The segment to insert.
389 */
390 iterator
391 insert(
392 iterator before,
393 pct_string_view s);
394
395 /** Insert segments
396
397 This function inserts the segments
398 in an initializer list before the
399 specified position.
400 Reserved characters in the list are
401 automatically escaped.
402 Escapes in the list are preserved.
403
404 <br>
405 All iterators that are equal to
406 `before` or come after are invalidated.
407
408 @note
409 None of the character buffers referenced
410 by the list may overlap the character
411 buffer of the underlying url, or else
412 the behavior is undefined.
413
414 @par Example
415 @code
416 url u( "/file.txt" );
417
418 u.encoded_segments().insert( u.encoded_segments().begin(), { "path", "to" } );
419 @endcode
420
421 @par Complexity
422 Linear in `init.size() + this->url().encoded_resource().size()`.
423
424 @par Exception Safety
425 Strong guarantee.
426 Calls to allocate may throw.
427 Exceptions thrown on invalid input.
428
429 @throw system_error
430 The list contains an invalid percent-encoding.
431
432 @return An iterator to the first
433 element inserted, or `before` if
434 `init.size() == 0`.
435
436 @param before An iterator before which
437 the list is inserted. This may
438 be equal to `end()`.
439
440 @param init The list of segments to insert.
441 */
442 iterator
443 insert(
444 iterator before,
445 std::initializer_list<
446 pct_string_view> init);
447
448 /** Insert segments
449
450 This function inserts the segments in
451 a range before the specified position.
452 Reserved characters in the range are
453 automatically escaped.
454 Escapes in the range are preserved.
455
456 <br>
457 All iterators that are equal to
458 `before` or come after are invalidated.
459
460 @note
461 None of the character buffers referenced
462 by the range may overlap the character
463 buffer of the underlying url, or else
464 the behavior is undefined.
465
466 @par Mandates
467 @code
468 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, pct_string_view >::value == true
469 @endcode
470
471 @par Complexity
472 Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
473
474 @par Exception Safety
475 Strong guarantee.
476 Calls to allocate may throw.
477 Exceptions thrown on invalid input.
478
479 @throw system_error
480 The range contains an invalid percent-encoding.
481
482 @return An iterator to the first
483 segment inserted, or `before` if
484 `init.empty()`.
485
486 @param before An iterator before which
487 the range is inserted. This may
488 be equal to `end()`.
489
490 @param first The first element in the range to insert.
491 @param last One past the last element in the range to insert.
492 */
493 template<class FwdIt>
494 iterator
495 insert(
496 iterator before,
497 FwdIt first,
498 FwdIt last);
499
500 //--------------------------------------------
501
502 /** Erase segments
503
504 This function removes a segment.
505
506 <br>
507 All iterators that are equal to
508 `pos` 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 segment.
518
519 @param pos An iterator to the element.
520 */
521 iterator
522 erase(
523 iterator pos) noexcept;
524
525 /** Erase segments
526
527 This function removes a range of segments
528 from the container.
529
530 <br>
531 All iterators that are equal to
532 `first` or come after are invalidated.
533
534 @par Complexity
535 Linear in `this->url().encoded_resource().size()`.
536
537 @par Exception Safety
538 Throws nothing.
539
540 @param first The first element in the range to erase.
541 @param last One past the last element in the range to erase.
542 @return An iterator to one past the removed range.
543 */
544 iterator
545 erase(
546 iterator first,
547 iterator last) noexcept;
548
549 //--------------------------------------------
550
551 /** Replace segments
552
553 This function replaces the segment at
554 the specified position.
555 Reserved characters in the string are
556 automatically escaped.
557 Escapes in the string are preserved.
558
559 <br>
560 All iterators that are equal to
561 `pos` or come after are invalidated.
562
563 @par Complexity
564 Linear in `s.size() + this->url().encoded_resouce().size()`.
565
566 @par Exception Safety
567 Strong guarantee.
568 Calls to allocate may throw.
569
570 @return An iterator to the replaced segment.
571
572 @param pos An iterator to the segment.
573
574 @param s The string to assign.
575 */
576 iterator
577 replace(
578 iterator pos,
579 pct_string_view s);
580
581 /** Replace segments
582
583 This function replaces a range of
584 segments with one segment.
585 Reserved characters in the string are
586 automatically escaped.
587 Escapes in the string are preserved.
588
589 <br>
590 All iterators that are equal to
591 `from` or come after are invalidated.
592
593 @par Complexity
594 Linear in `s.size() + this->url().encoded_resouce().size()`.
595
596 @par Exception Safety
597 Strong guarantee.
598 Calls to allocate may throw.
599 Exceptions thrown on invalid input.
600
601 @throw system_error
602 The string contains an invalid percent-encoding.
603
604 @return An iterator to the new segment.
605
606 @param from The first element in the range of segments to replace.
607 @param to One past the last element in the range of segments to replace.
608
609 @param s The string to assign.
610 */
611 iterator
612 replace(
613 iterator from,
614 iterator to,
615 pct_string_view s);
616
617 /** Replace segments
618
619 This function replaces a range of
620 segments with a list of segments in
621 an initializer list.
622 Reserved characters in the list are
623 automatically escaped.
624 Escapes in the list are preserved.
625
626 <br>
627 All iterators that are equal to
628 `from` or come after are invalidated.
629
630 @par Preconditions
631 None of the character buffers referenced
632 by the list may overlap the character
633 buffer of the underlying url, or else
634 the behavior is undefined.
635
636 @par Complexity
637 Linear in `init.size() + this->url().encoded_resouce().size()`.
638
639 @par Exception Safety
640 Strong guarantee.
641 Calls to allocate may throw.
642 Exceptions thrown on invalid input.
643
644 @throw system_error
645 The list contains an invalid percent-encoding.
646
647 @return An iterator to the first
648 segment inserted, or one past `to` if
649 `init.size() == 0`.
650
651 @param from The first element in the range of segments to replace.
652 @param to One past the last element in the range of segments to replace.
653
654 @param init The list of segments to assign.
655 */
656 iterator
657 replace(
658 iterator from,
659 iterator to,
660 std::initializer_list<
661 pct_string_view> init);
662
663 /** Replace segments
664
665 This function replaces a range of
666 segments with annother range of segments.
667 Reserved characters in the new range are
668 automatically escaped.
669 Escapes in the new range are preserved.
670
671 <br>
672 All iterators that are equal to
673 `from` or come after are invalidated.
674
675 @par Preconditions
676 None of the character buffers referenced
677 by the new range may overlap the character
678 buffer of the underlying url, or else
679 the behavior is undefined.
680
681 @par Complexity
682 Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
683
684 @par Exception Safety
685 Strong guarantee.
686 Calls to allocate may throw.
687 Exceptions thrown on invalid input.
688
689 @throw system_error
690 The range contains an invalid percent-encoding.
691
692 @return An iterator to the first
693 segment inserted, or one past `to` if
694 `init.size() == 0`.
695
696 @param from The first element in the range of segments to replace.
697 @param to One past the last element in the range of segments to replace.
698 @param first The first element in the new range of segments.
699 @param last One past the last element in the new range of segments.
700 */
701 template<class FwdIt>
702 iterator
703 replace(
704 iterator from,
705 iterator to,
706 FwdIt first,
707 FwdIt last);
708
709 //--------------------------------------------
710
711 /** Append a segment
712
713 This function appends a segment to
714 the end of the path.
715 Reserved characters in the string are
716 automatically escaped.
717 Escapes in the string are preserved.
718
719 <br>
720 All end iterators are invalidated.
721
722 @par Postconditions
723 @code
724 this->back() == s
725 @endcode
726
727 @par Exception Safety
728 Strong guarantee.
729 Calls to allocate may throw.
730 Exceptions thrown on invalid input.
731
732 @throw system_error
733 The string contains an invalid percent-encoding.
734
735 @param s The segment to append.
736 */
737 void
738 push_back(
739 pct_string_view s);
740
741 /** Remove the last segment
742
743 This function removes the last segment
744 from the container.
745
746 <br>
747 Iterators to the last segment as well
748 as all end iterators are invalidated.
749
750 @par Preconditions
751 @code
752 !this->empty()
753 @endcode
754
755 @par Exception Safety
756 Throws nothing.
757 */
758 void
759 pop_back() noexcept;
760
761 private:
762 template<class FwdIt>
763 iterator
764 insert(
765 iterator before,
766 FwdIt first,
767 FwdIt last,
768 std::input_iterator_tag) = delete;
769
770 template<class FwdIt>
771 iterator
772 insert(
773 iterator before,
774 FwdIt first,
775 FwdIt last,
776 std::forward_iterator_tag);
777 };
778
779 } // urls
780 } // boost
781
782 // This is in <boost/url/url_base.hpp>
783 //
784 // #include <boost/url/impl/segments_encoded_ref.hpp>
785
786 //------------------------------------------------
787 //
788 // std::ranges::enable_borrowed_range
789 //
790 //------------------------------------------------
791
792 #ifdef BOOST_URL_HAS_CONCEPTS
793 #include <ranges>
794 namespace std::ranges {
795 template<>
796 inline constexpr bool
797 enable_borrowed_range<
798 boost::urls::segments_encoded_ref> = true;
799 } // std::ranges
800 #endif
801
802 #endif
803