GCC Code Coverage Report


Directory: libs/url/
File: include/boost/url/url_view_base.hpp
Date: 2025-11-10 19:06:22
Exec Total Coverage
Lines: 84 84 100.0%
Functions: 29 30 96.7%
Branches: 15 28 53.6%

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_URL_VIEW_BASE_HPP
12 #define BOOST_URL_URL_VIEW_BASE_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/authority_view.hpp>
16 #include <boost/url/host_type.hpp>
17 #include <boost/url/ipv4_address.hpp>
18 #include <boost/url/ipv6_address.hpp>
19 #include <boost/url/params_view.hpp>
20 #include <boost/url/params_encoded_view.hpp>
21 #include <boost/url/pct_string_view.hpp>
22 #include <boost/url/scheme.hpp>
23 #include <boost/url/segments_encoded_view.hpp>
24 #include <boost/url/segments_view.hpp>
25 #include <boost/url/detail/url_impl.hpp>
26 #include <boost/url/grammar/string_token.hpp>
27 #include <boost/assert.hpp>
28 #include <cstddef>
29 #include <cstdint>
30 #include <iosfwd>
31 #include <memory>
32 #include <string>
33 #include <utility>
34
35 namespace boost {
36 namespace urls {
37
38 #ifndef BOOST_URL_DOCS
39 namespace detail {
40 struct pattern;
41 }
42 #endif
43
44
45 /** Common functionality for containers
46
47 This base class is used by the library
48 to provide common member functions for
49 containers. This cannot be instantiated
50 directly; Instead, use one of the
51 containers or functions:
52
53 @par Containers
54 @li @ref url
55 @li @ref url_view
56 @li @ref static_url
57
58 @par Functions
59 @li @ref parse_absolute_uri
60 @li @ref parse_origin_form
61 @li @ref parse_relative_ref
62 @li @ref parse_uri
63 @li @ref parse_uri_reference
64 */
65 class BOOST_URL_DECL
66 url_view_base
67 : private detail::parts_base
68 {
69 detail::url_impl impl_;
70 detail::url_impl const* pi_;
71
72 friend class url;
73 friend class url_base;
74 friend class url_view;
75 friend class static_url_base;
76 friend class params_base;
77 friend class params_encoded_base;
78 friend class params_encoded_ref;
79 friend class params_encoded_view;
80 friend class params_ref;
81 friend class params_view;
82 friend class segments_base;
83 friend class segments_encoded_base;
84 friend class segments_encoded_ref;
85 friend class segments_encoded_view;
86 friend class segments_ref;
87 friend class segments_view;
88 friend struct detail::pattern;
89
90 struct shared_impl;
91
92 url_view_base() noexcept;
93
94 explicit url_view_base(
95 detail::url_impl const&) noexcept;
96
97 ~url_view_base() = default;
98
99 url_view_base(
100 url_view_base const& o) noexcept
101 : impl_(o.impl_)
102 , pi_(o.pi_)
103 {
104 if (pi_ == &o.impl_)
105 pi_ = &impl_;
106 }
107
108 url_view_base& operator=(
109 url_view_base const&) = delete;
110
111 protected:
112 /** Calculate a hash of the url
113
114 This function calculates a hash of the
115 url as if it were always normalized.
116
117 @par Complexity
118 Linear in `this->size()`.
119
120 @par Exception Safety
121 Throws nothing.
122
123 @param salt An initial value to add to
124 the hash
125
126 @return A hash value suitable for use
127 in hash-based containers.
128 */
129 std::size_t
130 digest(std::size_t salt = 0) const noexcept;
131
132 public:
133 //--------------------------------------------
134 //
135 // Observers
136 //
137 //--------------------------------------------
138
139 /** Return the maximum number of characters possible
140
141 This represents the largest number
142 of characters that are theoretically
143 possible to represent in a url,
144 not including any null terminator.
145 In practice the actual possible size
146 may be lower than this number.
147
148 @par Complexity
149 Constant.
150
151 @par Exception Safety
152 Throws nothing.
153
154 @return The maximum number of characters.
155 */
156 static
157 constexpr
158 std::size_t
159 8451 max_size() noexcept
160 {
161 8451 return BOOST_URL_MAX_SIZE;
162 }
163
164 /** Return the number of characters in the url
165
166 This function returns the number of
167 characters in the url's encoded string,
168 not including any null terminator,
169 if present.
170
171 @par Example
172 @code
173 assert( url_view( "file:///Program%20Files" ).size() == 23 );
174 @endcode
175
176 @par Complexity
177 Constant.
178
179 @par Exception Safety
180 Throws nothing.
181
182 @return The number of characters in the url.
183 */
184 std::size_t
185 41086 size() const noexcept
186 {
187 41086 return pi_->offset(id_end);
188 }
189
190 /** Return true if the url is empty
191
192 The empty string matches the
193 <em>relative-ref</em> grammar.
194
195 @par Example
196 @code
197 assert( url_view( "" ).empty() );
198 @endcode
199
200 @par Complexity
201 Constant.
202
203 @par Exception Safety
204 Throws nothing.
205
206 @par BNF
207 @code
208 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
209
210 relative-part = "//" authority path-abempty
211 / path-absolute
212 / path-noscheme
213 / path-empty
214 @endcode
215
216 @par Specification
217 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2">4.2. Relative Reference (rfc3986)</a>
218
219 @return `true` if the url is empty.
220 */
221 bool
222 10 empty() const noexcept
223 {
224 10 return pi_->offset(id_end) == 0;
225 }
226
227 /** Return a pointer to the url's character buffer
228
229 This function returns a pointer to
230 the first character of the url, which
231 is not guaranteed to be null-terminated.
232
233 @par Complexity
234 Constant.
235
236 @par Exception Safety
237 Throws nothing.
238
239 @return A pointer to the first character.
240 */
241 char const*
242 4876 data() const noexcept
243 {
244 4876 return pi_->cs_;
245 }
246
247 /** Return the url string
248
249 This function returns the entire url,
250 which may contain percent escapes.
251
252 @par Example
253 @code
254 assert( url_view( "http://www.example.com" ).buffer() == "http://www.example.com" );
255 @endcode
256
257 @par Complexity
258 Constant.
259
260 @par Exception Safety
261 Throws nothing.
262
263 @return The url as a string.
264 */
265 core::string_view
266 1292 buffer() const noexcept
267 {
268 1292 return core::string_view(
269 1292 data(), size());
270 }
271
272 /** Return the URL as a core::string_view
273
274 @par Complexity
275 Constant.
276
277 @par Exception Safety
278 Throws nothing.
279
280 @return A string view of the URL.
281 */
282 250 operator core::string_view() const noexcept
283 {
284 250 return buffer();
285 }
286
287 /** Return a shared, persistent copy of the url
288
289 This function returns a read-only copy of
290 the url, with shared lifetime. The returned
291 value owns (persists) the underlying string.
292 The algorithm used to create the value
293 minimizes the number of individual memory
294 allocations, making it more efficient than
295 when using direct standard library functions.
296
297 @par Example
298 @code
299 std::shared_ptr< url_view const > sp;
300 {
301 std::string s( "http://example.com" );
302 url_view u( s ); // u references characters in s
303
304 assert( u.data() == s.data() ); // same buffer
305
306 sp = u.persist();
307
308 assert( sp->data() != s.data() ); // different buffer
309 assert( sp->buffer() == s); // same contents
310
311 // s is destroyed and thus u
312 // becomes invalid, but sp remains valid.
313 }
314 @endcode
315
316 @par Complexity
317 Linear in `this->size()`.
318
319 @par Exception Safety
320 Calls to allocate may throw.
321
322 @return A shared pointer to a read-only url_view.
323 */
324 std::shared_ptr<
325 url_view const> persist() const;
326
327 //--------------------------------------------
328 //
329 // Scheme
330 //
331 //--------------------------------------------
332
333 /** Return true a scheme is present
334
335 This function returns true if this
336 contains a scheme.
337
338 @par Example
339 @code
340 assert( url_view( "http://www.example.com" ).has_scheme() );
341 @endcode
342
343 @par Complexity
344 Constant.
345
346 @par Exception Safety
347 Throws nothing.
348
349 @par BNF
350 @code
351 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
352
353 absolute-URI = scheme ":" hier-part [ "?" query ]
354
355 scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
356 @endcode
357
358 @par Specification
359 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
360
361 @see
362 @ref scheme,
363 @ref scheme_id.
364
365 @return `true` if the url contains a scheme.
366 */
367 bool
368 has_scheme() const noexcept;
369
370 /** Return the scheme
371
372 This function returns the scheme if it
373 exists, without a trailing colon (':').
374 Otherwise it returns an empty string.
375 Note that schemes are case-insensitive,
376 and the canonical form is lowercased.
377
378 @par Example
379 @code
380 assert( url_view( "http://www.example.com" ).scheme() == "http" );
381 @endcode
382
383 @par Exception Safety
384 Throws nothing.
385
386 @par BNF
387 @code
388 scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
389
390 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
391
392 absolute-URI = scheme ":" hier-part [ "?" query ]
393 @endcode
394
395 @par Specification
396 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
397
398 @see
399 @ref has_scheme,
400 @ref scheme_id.
401
402 @return The scheme as a string.
403 */
404 core::string_view
405 scheme() const noexcept;
406
407 /** Return the scheme
408
409 This function returns a value which
410 depends on the scheme in the url:
411
412 @li If the scheme is a well-known
413 scheme, corresponding value from
414 the enumeration @ref urls::scheme
415 is returned.
416
417 @li If a scheme is present but is not
418 a well-known scheme, the value
419 returned is @ref urls::scheme::unknown.
420
421 @li Otherwise, if the scheme is absent
422 the value returned is
423 @ref urls::scheme::none.
424
425 @par Example
426 @code
427 assert( url_view( "wss://www.example.com/crypto.cgi" ).scheme_id() == scheme::wss );
428 @endcode
429
430 @par Complexity
431 Constant.
432
433 @par Exception Safety
434 Throws nothing.
435
436 @par BNF
437 @code
438 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
439
440 absolute-URI = scheme ":" hier-part [ "?" query ]
441
442 scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
443 @endcode
444
445 @par Specification
446 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
447
448 @see
449 @ref has_scheme,
450 @ref scheme.
451
452 @return The scheme as an enumeration value.
453 */
454 urls::scheme
455 scheme_id() const noexcept;
456
457 //--------------------------------------------
458 //
459 // Authority
460 //
461 //--------------------------------------------
462
463 /** Return true if an authority is present
464
465 This function returns true if the url
466 contains an authority. The presence of
467 an authority is denoted by a double
468 slash ("//") at the beginning or after
469 the scheme.
470
471 @par Example
472 @code
473 assert( url_view( "http://www.example.com/index.htm" ).has_authority() );
474 @endcode
475
476 @par Complexity
477 Constant.
478
479 @par Exception Safety
480 Throws nothing.
481
482 @par BNF
483 @code
484 authority = [ userinfo "@" ] host [ ":" port ]
485
486 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
487
488 absolute-URI = scheme ":" hier-part [ "?" query ]
489
490 URI-reference = URI / relative-ref
491
492 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
493
494 hier-part = "//" authority path-abempty
495 ; (more...)
496
497 relative-part = "//" authority path-abempty
498 ; (more...)
499
500 @endcode
501
502 @par Specification
503 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
504
505 @see
506 @ref authority,
507 @ref encoded_authority.
508
509 @return `true` if the url contains an authority.
510 */
511 bool
512 4861 has_authority() const noexcept
513 {
514 4861 return pi_->len(id_user) > 0;
515 }
516
517 /** Return the authority
518
519 This function returns the authority as
520 an @ref authority_view.
521
522 @par Example
523 @code
524 authority_view a = url_view( "https://www.example.com:8080/index.htm" ).authority();
525 @endcode
526
527 @par Complexity
528 Constant.
529
530 @par Exception Safety
531 Throws nothing.
532
533 @par BNF
534 @code
535 authority = [ userinfo "@" ] host [ ":" port ]
536 @endcode
537
538 @par Specification
539 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
540
541 @see
542 @ref encoded_authority,
543 @ref has_authority.
544
545 @return An authority_view representing the authority.
546 */
547 authority_view
548 authority() const noexcept;
549
550 /** Return the authority.
551
552 If present, this function returns a
553 string representing the authority (which
554 may be empty).
555 Otherwise it returns an empty string.
556 The returned string may contain
557 percent escapes.
558
559 @par Example
560 @code
561 assert( url_view( "file://Network%20Drive/My%2DFiles" ).encoded_authority() == "Network%20Drive" );
562 @endcode
563
564 @par Complexity
565 Constant.
566
567 @par Exception Safety
568 Throws nothing.
569
570 @par BNF
571 @code
572 authority = [ userinfo "@" ] host [ ":" port ]
573 @endcode
574
575 @par Specification
576 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
577
578 @see
579 @ref authority,
580 @ref has_authority.
581
582 @return The authority as a string.
583 */
584 pct_string_view
585 encoded_authority() const noexcept;
586
587 //--------------------------------------------
588 //
589 // Userinfo
590 //
591 //--------------------------------------------
592
593 /** Return true if a userinfo is present
594
595 This function returns true if this
596 contains a userinfo.
597
598 @par Example
599 @code
600 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_userinfo() );
601 @endcode
602
603 @par Complexity
604 Constant.
605
606 @par Exception Safety
607 Throws nothing.
608
609 @par BNF
610 @code
611 userinfo = user [ ":" [ password ] ]
612
613 authority = [ userinfo "@" ] host [ ":" port ]
614 @endcode
615
616 @par Specification
617 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
618
619 @see
620 @ref has_password,
621 @ref encoded_password,
622 @ref encoded_user,
623 @ref encoded_userinfo,
624 @ref password,
625 @ref user,
626 @ref userinfo.
627
628 @return `true` if the userinfo is present.
629 */
630 bool
631 has_userinfo() const noexcept;
632
633 /** Return true if a password is present
634
635 This function returns true if the
636 userinfo is present and contains
637 a password.
638
639 @par Example
640 @code
641 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_password() );
642 @endcode
643
644 @par Complexity
645 Constant.
646
647 @par Exception Safety
648 Throws nothing.
649
650 @par BNF
651 @code
652 userinfo = user [ ":" [ password ] ]
653
654 user = *( unreserved / pct-encoded / sub-delims )
655 password = *( unreserved / pct-encoded / sub-delims / ":" )
656 @endcode
657
658 @par Specification
659 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
660
661 @see
662 @ref has_userinfo,
663 @ref encoded_password,
664 @ref encoded_user,
665 @ref encoded_userinfo,
666 @ref password,
667 @ref user,
668 @ref userinfo.
669
670 @return `true` if the userinfo contains a password.
671 */
672 bool
673 has_password() const noexcept;
674
675 /** Return the userinfo
676
677 If present, this function returns a
678 string representing the userinfo (which
679 may be empty).
680 Otherwise it returns an empty string.
681 Any percent-escapes in the string are
682 decoded first.
683
684 @note
685 This function uses the string token
686 return type customization. Depending on
687 the token passed, the return type and
688 behavior of the function can be different.
689 See @ref string_token::return_string
690 for more information.
691
692 @par Example
693 @code
694 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" );
695 @endcode
696
697 @par Complexity
698 Linear in `this->userinfo().size()`.
699
700 @par Exception Safety
701 Calls to allocate may throw.
702
703 @return When called with no arguments,
704 a value of type `std::string` is
705 returned. Otherwise, the return type
706 and meaning depends on the string token
707 passed to the function.
708
709 @par BNF
710 @code
711 userinfo = user [ ":" [ password ] ]
712
713 authority = [ userinfo "@" ] host [ ":" port ]
714 @endcode
715
716 @par Specification
717 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
718
719 @see
720 @ref has_password,
721 @ref has_userinfo,
722 @ref encoded_password,
723 @ref encoded_user,
724 @ref encoded_userinfo,
725 @ref password,
726 @ref user.
727
728 @param token The string token to use.
729 @return The userinfo as a string.
730 */
731 template<BOOST_URL_STRTOK_TPARAM>
732 BOOST_URL_STRTOK_RETURN
733 34 userinfo(
734 StringToken&& token = {}) const
735 {
736 34 encoding_opts opt;
737 34 opt.space_as_plus = false;
738 68 return encoded_userinfo().decode(
739
1/2
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
68 opt, std::forward<StringToken>(token));
740 }
741
742 /** Return the userinfo
743
744 If present, this function returns a
745 string representing the userinfo (which
746 may be empty).
747 Otherwise it returns an empty string.
748 The returned string may contain
749 percent escapes.
750
751 @par Example
752 @code
753 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_userinfo() == "jane%2Ddoe:pass" );
754 @endcode
755
756 @par Complexity
757 Constant.
758
759 @par Exception Safety
760 Throws nothing
761
762 @par BNF
763 @code
764 userinfo = user [ ":" [ password ] ]
765
766 authority = [ userinfo "@" ] host [ ":" port ]
767 @endcode
768
769 @par Specification
770 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
771
772 @see
773 @ref has_password,
774 @ref has_userinfo,
775 @ref encoded_password,
776 @ref encoded_user,
777 @ref password,
778 @ref user,
779 @ref userinfo.
780
781 @return The userinfo as a string.
782 */
783 pct_string_view
784 encoded_userinfo() const noexcept;
785
786 //--------------------------------------------
787
788 /** Return the user
789
790 If present, this function returns a
791 string representing the user (which
792 may be empty).
793 Otherwise it returns an empty string.
794 Any percent-escapes in the string are
795 decoded first.
796
797 @par Example
798 @code
799 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).user() == "jane-doe" );
800 @endcode
801
802 @par Complexity
803 Linear in `this->user().size()`.
804
805 @par Exception Safety
806 Calls to allocate may throw.
807
808 @par BNF
809 @code
810 userinfo = user [ ":" [ password ] ]
811
812 user = *( unreserved / pct-encoded / sub-delims )
813 password = *( unreserved / pct-encoded / sub-delims / ":" )
814 @endcode
815
816 @par Specification
817 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
818
819 @see
820 @ref has_password,
821 @ref has_userinfo,
822 @ref encoded_password,
823 @ref encoded_user,
824 @ref encoded_userinfo,
825 @ref password,
826 @ref userinfo.
827
828 @param token The string token to use.
829 @return The user as a string.
830 */
831 template<BOOST_URL_STRTOK_TPARAM>
832 BOOST_URL_STRTOK_RETURN
833 55 user(
834 StringToken&& token = {}) const
835 {
836 55 encoding_opts opt;
837 55 opt.space_as_plus = false;
838 110 return encoded_user().decode(
839
1/2
✓ Branch 2 taken 55 times.
✗ Branch 3 not taken.
110 opt, std::forward<StringToken>(token));
840 }
841
842 /** Return the user
843
844 If present, this function returns a
845 string representing the user (which
846 may be empty).
847 Otherwise it returns an empty string.
848 The returned string may contain
849 percent escapes.
850
851 @par Example
852 @code
853 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_user() == "jane%2Ddoe" );
854 @endcode
855
856 @par Complexity
857 Constant.
858
859 @par Exception Safety
860 Throws nothing.
861
862 @par BNF
863 @code
864 userinfo = user [ ":" [ password ] ]
865
866 user = *( unreserved / pct-encoded / sub-delims )
867 password = *( unreserved / pct-encoded / sub-delims / ":" )
868 @endcode
869
870 @par Specification
871 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
872
873 @see
874 @ref has_password,
875 @ref has_userinfo,
876 @ref encoded_password,
877 @ref encoded_userinfo,
878 @ref password,
879 @ref user,
880 @ref userinfo.
881
882 @return The user as a string.
883 */
884 pct_string_view
885 encoded_user() const noexcept;
886
887 /** Return the password
888
889 If present, this function returns a
890 string representing the password (which
891 may be an empty string).
892 Otherwise it returns an empty string.
893 Any percent-escapes in the string are
894 decoded first.
895
896 @par Example
897 @code
898 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).password() == "pass" );
899 @endcode
900
901 @par Complexity
902 Linear in `this->password().size()`.
903
904 @par Exception Safety
905 Calls to allocate may throw.
906
907 @par BNF
908 @code
909 userinfo = user [ ":" [ password ] ]
910
911 user = *( unreserved / pct-encoded / sub-delims )
912 password = *( unreserved / pct-encoded / sub-delims / ":" )
913 @endcode
914
915 @par Specification
916 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
917
918 @see
919 @ref has_password,
920 @ref has_userinfo,
921 @ref encoded_password,
922 @ref encoded_user,
923 @ref encoded_userinfo,
924 @ref user,
925 @ref userinfo.
926
927 @param token The string token to use.
928 @return The password as a string.
929 */
930 template<BOOST_URL_STRTOK_TPARAM>
931 BOOST_URL_STRTOK_RETURN
932 25 password(
933 StringToken&& token = {}) const
934 {
935 25 encoding_opts opt;
936 25 opt.space_as_plus = false;
937 50 return encoded_password().decode(
938
1/2
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
50 opt, std::forward<StringToken>(token));
939 }
940
941 /** Return the password
942
943 This function returns the password portion
944 of the userinfo as a percent-encoded string.
945
946 @par Example
947 @code
948 assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_password() == "pass" );
949 @endcode
950
951 @par Complexity
952 Constant.
953
954 @par Exception Safety
955 Throws nothing.
956
957 @par BNF
958 @code
959 userinfo = user [ ":" [ password ] ]
960
961 user = *( unreserved / pct-encoded / sub-delims )
962 password = *( unreserved / pct-encoded / sub-delims / ":" )
963 @endcode
964
965 @par Specification
966 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
967
968 @see
969 @ref has_password,
970 @ref has_userinfo,
971 @ref encoded_user,
972 @ref encoded_userinfo,
973 @ref password,
974 @ref user,
975 @ref userinfo.
976
977 @return The password as a string.
978 */
979 pct_string_view
980 encoded_password() const noexcept;
981
982 //--------------------------------------------
983 //
984 // Host
985 //
986 //--------------------------------------------
987
988 /** Return the host type
989
990 This function returns one of the
991 following constants representing the
992 type of host present.
993
994 @li @ref host_type::ipv4
995 @li @ref host_type::ipv6
996 @li @ref host_type::ipvfuture
997 @li @ref host_type::name
998 @li @ref host_type::none
999
1000 When @ref has_authority is false, the
1001 host type is @ref host_type::none.
1002
1003 @par Example
1004 @code
1005 assert( url_view( "https://192.168.0.1/local.htm" ).host_type() == host_type::ipv4 );
1006 @endcode
1007
1008 @par Complexity
1009 Constant.
1010
1011 @par Exception Safety
1012 Throws nothing.
1013
1014 @par Specification
1015 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1016
1017 @return The type of host present.
1018 */
1019 urls::host_type
1020 443 host_type() const noexcept
1021 {
1022 443 return pi_->host_type_;
1023 }
1024
1025 /** Return the host
1026
1027 This function returns the host portion
1028 of the authority as a string, or the
1029 empty string if there is no authority.
1030 Any percent-escapes in the string are
1031 decoded first.
1032
1033 @par Example
1034 @code
1035 assert( url_view( "https://www%2droot.example.com/" ).host() == "www-root.example.com" );
1036 @endcode
1037
1038 @par Complexity
1039 Linear in `this->host().size()`.
1040
1041 @par Exception Safety
1042 Calls to allocate may throw.
1043
1044 @par BNF
1045 @code
1046 host = IP-literal / IPv4address / reg-name
1047
1048 IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1049
1050 reg-name = *( unreserved / pct-encoded / "-" / ".")
1051 @endcode
1052
1053 @par Specification
1054 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1055
1056 @param token A string token customization
1057 @return The host address as a string.
1058 */
1059 template<BOOST_URL_STRTOK_TPARAM>
1060 BOOST_URL_STRTOK_RETURN
1061 68 host(
1062 StringToken&& token = {}) const
1063 {
1064 68 encoding_opts opt;
1065 68 opt.space_as_plus = false;
1066
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
136 return encoded_host().decode(
1067
1/2
✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
136 opt, std::forward<StringToken>(token));
1068 }
1069
1070 /** Return the host
1071
1072 This function returns the host portion
1073 of the authority as a string, or the
1074 empty string if there is no authority.
1075 The returned string may contain
1076 percent escapes.
1077
1078 @par Example
1079 @code
1080 assert( url_view( "https://www%2droot.example.com/" ).encoded_host() == "www%2droot.example.com" );
1081 @endcode
1082
1083 @par Complexity
1084 Constant.
1085
1086 @par Exception Safety
1087 Throws nothing.
1088
1089 @par BNF
1090 @code
1091 host = IP-literal / IPv4address / reg-name
1092
1093 IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1094
1095 reg-name = *( unreserved / pct-encoded / "-" / ".")
1096 @endcode
1097
1098 @par Specification
1099 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1100
1101 @return The host address as a string.
1102 */
1103 pct_string_view
1104 encoded_host() const noexcept;
1105
1106 /** Return the host
1107
1108 The value returned by this function
1109 depends on the type of host returned
1110 from the function @ref host_type.
1111
1112 @li If the type is @ref host_type::ipv4,
1113 then the IPv4 address string is returned.
1114
1115 @li If the type is @ref host_type::ipv6,
1116 then the IPv6 address string is returned,
1117 without any enclosing brackets.
1118
1119 @li If the type is @ref host_type::ipvfuture,
1120 then the IPvFuture address string is returned,
1121 without any enclosing brackets.
1122
1123 @li If the type is @ref host_type::name,
1124 then the host name string is returned.
1125 Any percent-escapes in the string are
1126 decoded first.
1127
1128 @li If the type is @ref host_type::none,
1129 then an empty string is returned.
1130
1131 @par Example
1132 @code
1133 assert( url_view( "https://[1::6:c0a8:1]/" ).host_address() == "1::6:c0a8:1" );
1134 @endcode
1135
1136 @par Complexity
1137 Linear in `this->host_address().size()`.
1138
1139 @par Exception Safety
1140 Calls to allocate may throw.
1141
1142 @par BNF
1143 @code
1144 host = IP-literal / IPv4address / reg-name
1145
1146 IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1147
1148 reg-name = *( unreserved / pct-encoded / "-" / ".")
1149 @endcode
1150
1151 @par Specification
1152 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1153
1154 @param token A string token customization
1155 @return The host address as a string.
1156 */
1157 template<BOOST_URL_STRTOK_TPARAM>
1158 BOOST_URL_STRTOK_RETURN
1159 99 host_address(
1160 StringToken&& token = {}) const
1161 {
1162 99 encoding_opts opt;
1163 99 opt.space_as_plus = false;
1164 198 return encoded_host_address().decode(
1165
1/2
✓ Branch 2 taken 99 times.
✗ Branch 3 not taken.
198 opt, std::forward<StringToken>(token));
1166 }
1167
1168 /** Return the host
1169
1170 The value returned by this function
1171 depends on the type of host returned
1172 from the function @ref host_type.
1173
1174 @li If the type is @ref host_type::ipv4,
1175 then the IPv4 address string is returned.
1176
1177 @li If the type is @ref host_type::ipv6,
1178 then the IPv6 address string is returned,
1179 without any enclosing brackets.
1180
1181 @li If the type is @ref host_type::ipvfuture,
1182 then the IPvFuture address string is returned,
1183 without any enclosing brackets.
1184
1185 @li If the type is @ref host_type::name,
1186 then the host name string is returned.
1187 Any percent-escapes in the string are
1188 decoded first.
1189
1190 @li If the type is @ref host_type::none,
1191 then an empty string is returned.
1192 The returned string may contain
1193 percent escapes.
1194
1195 @par Example
1196 @code
1197 assert( url_view( "https://www%2droot.example.com/" ).encoded_host_address() == "www%2droot.example.com" );
1198 @endcode
1199
1200 @par Complexity
1201 Constant.
1202
1203 @par Exception Safety
1204 Throws nothing.
1205
1206 @par BNF
1207 @code
1208 host = IP-literal / IPv4address / reg-name
1209
1210 IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1211
1212 reg-name = *( unreserved / pct-encoded / "-" / ".")
1213 @endcode
1214
1215 @par Specification
1216 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1217
1218 @return The host address as a string.
1219 */
1220 pct_string_view
1221 encoded_host_address() const noexcept;
1222
1223 /** Return the host IPv4 address
1224
1225 If the host type is @ref host_type::ipv4,
1226 this function returns the address as
1227 a value of type @ref ipv4_address.
1228 Otherwise, if the host type is not an IPv4
1229 address, it returns a default-constructed
1230 value which is equal to the unspecified
1231 address "0.0.0.0".
1232
1233 @par Example
1234 @code
1235 assert( url_view( "http://127.0.0.1/index.htm?user=win95" ).host_ipv4_address() == ipv4_address( "127.0.0.1" ) );
1236 @endcode
1237
1238 @par Complexity
1239 Constant.
1240
1241 @par Exception Safety
1242 Throws nothing.
1243
1244 @par BNF
1245 @code
1246 IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1247
1248 dec-octet = DIGIT ; 0-9
1249 / %x31-39 DIGIT ; 10-99
1250 / "1" 2DIGIT ; 100-199
1251 / "2" %x30-34 DIGIT ; 200-249
1252 / "25" %x30-35 ; 250-255
1253 @endcode
1254
1255 @par Specification
1256 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1257
1258 @return The IPv4 address as a value of type @ref ipv4_address.
1259 */
1260 ipv4_address
1261 host_ipv4_address() const noexcept;
1262
1263 /** Return the host IPv6 address
1264
1265 If the host type is @ref host_type::ipv6,
1266 this function returns the address as
1267 a value of type @ref ipv6_address.
1268 Otherwise, if the host type is not an IPv6
1269 address, it returns a default-constructed
1270 value which is equal to the unspecified
1271 address "0:0:0:0:0:0:0:0".
1272
1273 @par Example
1274 @code
1275 assert( url_view( "ftp://[::1]/" ).host_ipv6_address() == ipv6_address( "::1" ) );
1276 @endcode
1277
1278 @par Complexity
1279 Constant.
1280
1281 @par Exception Safety
1282 Throws nothing.
1283
1284 @par BNF
1285 @code
1286 IPv6address = 6( h16 ":" ) ls32
1287 / "::" 5( h16 ":" ) ls32
1288 / [ h16 ] "::" 4( h16 ":" ) ls32
1289 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1290 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1291 / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1292 / [ *4( h16 ":" ) h16 ] "::" ls32
1293 / [ *5( h16 ":" ) h16 ] "::" h16
1294 / [ *6( h16 ":" ) h16 ] "::"
1295
1296 ls32 = ( h16 ":" h16 ) / IPv4address
1297 ; least-significant 32 bits of address
1298
1299 h16 = 1*4HEXDIG
1300 ; 16 bits of address represented in hexadecimal
1301 @endcode
1302
1303 @par Specification
1304 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1305
1306 @return The IPv6 address as a value of type @ref ipv6_address.
1307 */
1308 ipv6_address
1309 host_ipv6_address() const noexcept;
1310
1311 /** Return the host IPvFuture address
1312
1313 If the host type is @ref host_type::ipvfuture,
1314 this function returns the address as
1315 a string.
1316 Otherwise, if the host type is not an
1317 IPvFuture address, it returns an
1318 empty string.
1319
1320 @par Example
1321 @code
1322 assert( url_view( "http://[v1fe.d:9]/index.htm" ).host_ipvfuture() == "v1fe.d:9" );
1323 @endcode
1324
1325 @par Complexity
1326 Constant.
1327
1328 @par Exception Safety
1329 Throws nothing.
1330
1331 @par BNF
1332 @code
1333 IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1334 @endcode
1335
1336 @par Specification
1337 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1338
1339 @return The IPvFuture address as a string.
1340 */
1341 core::string_view
1342 host_ipvfuture() const noexcept;
1343
1344 /** Return the host name
1345
1346 If the host type is @ref host_type::name,
1347 this function returns the name as
1348 a string. Otherwise an empty string is returned.
1349 Any percent-escapes in the string are
1350 decoded first.
1351
1352 @par Example
1353 @code
1354 assert( url_view( "https://www%2droot.example.com/" ).host_name() == "www-root.example.com" );
1355 @endcode
1356
1357 @par Complexity
1358 Linear in `this->host_name().size()`.
1359
1360 @par Exception Safety
1361 Calls to allocate may throw.
1362
1363 @par BNF
1364 @code
1365 host = IP-literal / IPv4address / reg-name
1366
1367 IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1368
1369 reg-name = *( unreserved / pct-encoded / "-" / ".")
1370 @endcode
1371
1372 @par Specification
1373 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1374
1375 @param token A string token customization.
1376 @return The host name as a string.
1377 */
1378 template<BOOST_URL_STRTOK_TPARAM>
1379 BOOST_URL_STRTOK_RETURN
1380 93 host_name(
1381 StringToken&& token = {}) const
1382 {
1383 93 encoding_opts opt;
1384 93 opt.space_as_plus = false;
1385 186 return encoded_host_name().decode(
1386
1/2
✓ Branch 2 taken 93 times.
✗ Branch 3 not taken.
186 opt, std::forward<StringToken>(token));
1387 }
1388
1389 /** Return the host name
1390
1391 If the host type is @ref host_type::name,
1392 this function returns the name as
1393 a string.
1394 Otherwise, if the host type is not an
1395 name, it returns an empty string.
1396 The returned string may contain
1397 percent escapes.
1398
1399 @par Example
1400 @code
1401 assert( url_view( "https://www%2droot.example.com/" ).encoded_host_name() == "www%2droot.example.com" );
1402 @endcode
1403
1404 @par Complexity
1405 Constant.
1406
1407 @par Exception Safety
1408 Throws nothing.
1409
1410 @par BNF
1411 @code
1412 host = IP-literal / IPv4address / reg-name
1413
1414 IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1415
1416 reg-name = *( unreserved / pct-encoded / "-" / ".")
1417 @endcode
1418
1419 @par Specification
1420 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1421
1422 @return The host name as a percent-encoded string.
1423 */
1424 pct_string_view
1425 encoded_host_name() const noexcept;
1426
1427 /** Return the IPv6 Zone ID
1428
1429 If the host type is @ref host_type::ipv6,
1430 this function returns the Zone ID as
1431 a string. Otherwise an empty string is returned.
1432 Any percent-escapes in the string are
1433 decoded first.
1434
1435 @par Example
1436 @code
1437 assert( url_view( "http://[fe80::1%25eth0]/" ).zone_id() == "eth0" );
1438 @endcode
1439
1440 @par Complexity
1441 Linear in `this->encoded_zone_id().size()`.
1442
1443 @par Exception Safety
1444 Calls to allocate may throw.
1445
1446 @par BNF
1447 @code
1448 host = IP-literal / IPv4address / reg-name
1449
1450 IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]"
1451
1452 ZoneID = 1*( unreserved / pct-encoded )
1453
1454 IPv6addrz = IPv6address "%25" ZoneID
1455 @endcode
1456
1457 @par Specification
1458 @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a>
1459
1460 @param token A string token customization.
1461 @return The Zone ID as a string.
1462 */
1463 template<BOOST_URL_STRTOK_TPARAM>
1464 BOOST_URL_STRTOK_RETURN
1465 10 zone_id(
1466 StringToken&& token = {}) const
1467 {
1468 10 encoding_opts opt;
1469 10 opt.space_as_plus = false;
1470 20 return encoded_zone_id().decode(
1471
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
20 opt, std::forward<StringToken>(token));
1472 }
1473
1474 /** Return the IPv6 Zone ID
1475
1476 If the host type is @ref host_type::ipv6,
1477 this function returns the Zone ID as
1478 a string. Otherwise an empty string is returned.
1479 The returned string may contain
1480 percent escapes.
1481
1482 @par Example
1483 @code
1484 assert( url_view( "http://[fe80::1%25eth0]/" ).encoded_zone_id() == "eth0" );
1485 @endcode
1486
1487 @par Complexity
1488 Constant.
1489
1490 @par Exception Safety
1491 Throws nothing.
1492
1493 @par BNF
1494 @code
1495 host = IP-literal / IPv4address / reg-name
1496
1497 IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]"
1498
1499 ZoneID = 1*( unreserved / pct-encoded )
1500
1501 IPv6addrz = IPv6address "%25" ZoneID
1502 @endcode
1503
1504 @par Specification
1505 @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a>
1506
1507 @return The Zone ID as a percent-encoded string.
1508 */
1509 pct_string_view
1510 encoded_zone_id() const noexcept;
1511
1512 //--------------------------------------------
1513 //
1514 // Port
1515 //
1516 //--------------------------------------------
1517
1518 /** Return true if a port is present
1519
1520 This function returns true if an
1521 authority is present and contains a port.
1522
1523 @par Example
1524 @code
1525 assert( url_view( "wss://www.example.com:443" ).has_port() );
1526 @endcode
1527
1528 @par Complexity
1529 Constant.
1530
1531 @par Exception Safety
1532 Throws nothing.
1533
1534 @par BNF
1535 @code
1536 authority = [ userinfo "@" ] host [ ":" port ]
1537
1538 port = *DIGIT
1539 @endcode
1540
1541 @par Specification
1542 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1543
1544 @see
1545 @ref encoded_host_and_port,
1546 @ref port,
1547 @ref port_number.
1548
1549 @return `true` if a port is present, `false` otherwise.
1550 */
1551 bool
1552 has_port() const noexcept;
1553
1554 /** Return the port
1555
1556 If present, this function returns a
1557 string representing the port (which
1558 may be empty).
1559 Otherwise it returns an empty string.
1560
1561 @par Example
1562 @code
1563 assert( url_view( "http://localhost.com:8080" ).port() == "8080" );
1564 @endcode
1565
1566 @par Complexity
1567 Constant.
1568
1569 @par Exception Safety
1570 Throws nothing.
1571
1572 @par BNF
1573 @code
1574 port = *DIGIT
1575 @endcode
1576
1577 @par Specification
1578 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1579
1580 @see
1581 @ref encoded_host_and_port,
1582 @ref has_port,
1583 @ref port_number.
1584
1585 @return The port as a string.
1586 */
1587 core::string_view
1588 port() const noexcept;
1589
1590 /** Return the port
1591
1592 If a port is present and the numerical
1593 value is representable, it is returned
1594 as an unsigned integer. Otherwise, the
1595 number zero is returned.
1596
1597 @par Example
1598 @code
1599 assert( url_view( "http://localhost.com:8080" ).port_number() == 8080 );
1600 @endcode
1601
1602 @par Complexity
1603 Constant.
1604
1605 @par Exception Safety
1606 Throws nothing.
1607
1608 @par BNF
1609 @code
1610 port = *DIGIT
1611 @endcode
1612
1613 @par Specification
1614 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1615
1616 @see
1617 @ref encoded_host_and_port,
1618 @ref has_port,
1619 @ref port.
1620
1621 @return The port number as an unsigned integer.
1622 */
1623 std::uint16_t
1624 port_number() const noexcept;
1625
1626 //--------------------------------------------
1627 //
1628 // Path
1629 //
1630 //--------------------------------------------
1631
1632 /** Return true if the path is absolute
1633
1634 This function returns true if the path
1635 begins with a forward slash ('/').
1636
1637 @par Example
1638 @code
1639 assert( url_view( "/path/to/file.txt" ).is_path_absolute() );
1640 @endcode
1641
1642 @par Complexity
1643 Constant.
1644
1645 @par Exception Safety
1646 Throws nothing.
1647
1648 @par BNF
1649 @code
1650 path = path-abempty ; begins with "/" or is empty
1651 / path-absolute ; begins with "/" but not "//"
1652 / path-noscheme ; begins with a non-colon segment
1653 / path-rootless ; begins with a segment
1654 / path-empty ; zero characters
1655
1656 path-abempty = *( "/" segment )
1657 path-absolute = "/" [ segment-nz *( "/" segment ) ]
1658 path-noscheme = segment-nz-nc *( "/" segment )
1659 path-rootless = segment-nz *( "/" segment )
1660 path-empty = 0<pchar>
1661 @endcode
1662
1663 @par Specification
1664 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1665
1666 @see
1667 @ref encoded_path,
1668 @ref encoded_segments.
1669 @ref path,
1670 @ref segments.
1671
1672 @return `true` if the path is absolute, `false` otherwise.
1673 */
1674 bool
1675 1548 is_path_absolute() const noexcept
1676 {
1677 return
1678
2/2
✓ Branch 1 taken 1131 times.
✓ Branch 2 taken 417 times.
2679 pi_->len(id_path) > 0 &&
1679
2/2
✓ Branch 1 taken 711 times.
✓ Branch 2 taken 420 times.
2679 pi_->cs_[pi_->offset(id_path)] == '/';
1680 }
1681
1682 /** Return the path
1683
1684 This function returns the path as a
1685 string. The path may be empty.
1686 Any percent-escapes in the string are
1687 decoded first.
1688
1689 @par Example
1690 @code
1691 assert( url_view( "file:///Program%20Files/Games/config.ini" ).path() == "/Program Files/Games/config.ini" );
1692 @endcode
1693
1694 @par Complexity
1695 Linear in `this->path().size()`.
1696
1697 @par Exception Safety
1698 Calls to allocate may throw.
1699
1700 @par BNF
1701 @code
1702 path = path-abempty ; begins with "/" or is empty
1703 / path-absolute ; begins with "/" but not "//"
1704 / path-noscheme ; begins with a non-colon segment
1705 / path-rootless ; begins with a segment
1706 / path-empty ; zero characters
1707
1708 path-abempty = *( "/" segment )
1709 path-absolute = "/" [ segment-nz *( "/" segment ) ]
1710 path-noscheme = segment-nz-nc *( "/" segment )
1711 path-rootless = segment-nz *( "/" segment )
1712 path-empty = 0<pchar>
1713 @endcode
1714
1715 @par Specification
1716 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1717
1718 @see
1719 @ref is_path_absolute,
1720 @ref encoded_path,
1721 @ref encoded_segments.
1722 @ref segments.
1723
1724 @param token A string token to use for the result.
1725 @return The path as a string.
1726 */
1727 template<BOOST_URL_STRTOK_TPARAM>
1728 BOOST_URL_STRTOK_RETURN
1729 34 path(
1730 StringToken&& token = {}) const
1731 {
1732 34 encoding_opts opt;
1733 34 opt.space_as_plus = false;
1734
1/2
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
68 return encoded_path().decode(
1735
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
68 opt, std::forward<StringToken>(token));
1736 }
1737
1738 /** Return the path
1739
1740 This function returns the path as a
1741 string. The path may be empty.
1742 Any percent-escapes in the string are
1743 decoded first.
1744
1745 @par Example
1746 @code
1747 assert( url_view( "file:///Program%20Files/Games/config.ini" ).encoded_path() == "/Program%20Files/Games/config.ini" );
1748 @endcode
1749
1750 @par Complexity
1751 Constant.
1752
1753 @par Exception Safety
1754 Throws nothing.
1755
1756 @par BNF
1757 @code
1758 path = path-abempty ; begins with "/" or is empty
1759 / path-absolute ; begins with "/" but not "//"
1760 / path-noscheme ; begins with a non-colon segment
1761 / path-rootless ; begins with a segment
1762 / path-empty ; zero characters
1763
1764 path-abempty = *( "/" segment )
1765 path-absolute = "/" [ segment-nz *( "/" segment ) ]
1766 path-noscheme = segment-nz-nc *( "/" segment )
1767 path-rootless = segment-nz *( "/" segment )
1768 path-empty = 0<pchar>
1769 @endcode
1770
1771 @par Specification
1772 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1773
1774 @see
1775 @ref is_path_absolute,
1776 @ref encoded_segments.
1777 @ref path,
1778 @ref segments.
1779
1780 @return The path as a string.
1781 */
1782 pct_string_view
1783 encoded_path() const noexcept;
1784
1785 /** Return the path as a container of segments
1786
1787 This function returns a bidirectional
1788 view of strings over the path.
1789 The returned view references the same
1790 underlying character buffer; ownership
1791 is not transferred.
1792 Any percent-escapes in strings returned
1793 when iterating the view are decoded first.
1794
1795 @par Example
1796 @code
1797 segments_view sv = url_view( "/path/to/file.txt" ).segments();
1798 @endcode
1799
1800 @par Complexity
1801 Constant.
1802
1803 @par Exception Safety
1804 Throws nothing.
1805
1806 @par BNF
1807 @code
1808 path = [ "/" ] segment *( "/" segment )
1809 @endcode
1810
1811 @par Specification
1812 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1813
1814 @see
1815 @ref is_path_absolute,
1816 @ref encoded_path,
1817 @ref encoded_segments.
1818 @ref path,
1819 @ref segments_view.
1820
1821 @return A bidirectional view of segments.
1822 */
1823 segments_view
1824 segments() const noexcept;
1825
1826 /** Return the path as a container of segments
1827
1828 This function returns a bidirectional
1829 view of strings over the path.
1830 The returned view references the same
1831 underlying character buffer; ownership
1832 is not transferred.
1833 Strings returned when iterating the
1834 range may contain percent escapes.
1835
1836 @par Example
1837 @code
1838 segments_encoded_view sv = url_view( "/path/to/file.txt" ).encoded_segments();
1839 @endcode
1840
1841 @par Complexity
1842 Constant.
1843
1844 @par Exception Safety
1845 Throws nothing.
1846
1847 @par BNF
1848 @code
1849 path = path-abempty ; begins with "/" or is empty
1850 / path-absolute ; begins with "/" but not "//"
1851 / path-noscheme ; begins with a non-colon segment
1852 / path-rootless ; begins with a segment
1853 / path-empty ; zero characters
1854
1855 path-abempty = *( "/" segment )
1856 path-absolute = "/" [ segment-nz *( "/" segment ) ]
1857 path-noscheme = segment-nz-nc *( "/" segment )
1858 path-rootless = segment-nz *( "/" segment )
1859 path-empty = 0<pchar>
1860 @endcode
1861
1862 @par Specification
1863 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1864
1865 @see
1866 @ref is_path_absolute,
1867 @ref encoded_path,
1868 @ref path,
1869 @ref segments,
1870 @ref segments_encoded_view.
1871
1872 @return A bidirectional view of encoded segments.
1873 */
1874 segments_encoded_view
1875 encoded_segments() const noexcept;
1876
1877 //--------------------------------------------
1878 //
1879 // Query
1880 //
1881 //--------------------------------------------
1882
1883 /** Return true if a query is present
1884
1885 This function returns true if this
1886 contains a query. An empty query is
1887 distinct from having no query.
1888
1889 @par Example
1890 @code
1891 assert( url_view( "/sql?id=42&col=name&page-size=20" ).has_query() );
1892 @endcode
1893
1894 @par Complexity
1895 Constant.
1896
1897 @par Exception Safety
1898 Throws nothing.
1899
1900 @par BNF
1901 @code
1902 query = *( pchar / "/" / "?" )
1903
1904 query-param = key [ "=" value ]
1905 query-params = [ query-param ] *( "&" query-param )
1906 @endcode
1907
1908 @par Specification
1909 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
1910 @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
1911
1912 @see
1913 @ref encoded_params,
1914 @ref encoded_query,
1915 @ref params,
1916 @ref query.
1917
1918 @return `true` if a query is present.
1919 */
1920 bool
1921 has_query() const noexcept;
1922
1923 /** Return the query
1924
1925 If this contains a query, it is returned
1926 as a string (which may be empty).
1927 Otherwise, an empty string is returned.
1928 Any percent-escapes in the string are
1929 decoded first.
1930 <br>
1931 When plus signs appear in the query
1932 portion of the url, they are converted
1933 to spaces automatically upon decoding.
1934 This behavior can be changed by setting
1935 decode options.
1936
1937 @par Example
1938 @code
1939 assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).query() == "id=42&name=jane-doe&page size=20" );
1940 @endcode
1941
1942 @par Complexity
1943 Linear in `this->query().size()`.
1944
1945 @par Exception Safety
1946 Calls to allocate may throw.
1947
1948 @par BNF
1949 @code
1950 query = *( pchar / "/" / "?" )
1951
1952 query-param = key [ "=" value ]
1953 query-params = [ query-param ] *( "&" query-param )
1954 @endcode
1955
1956 @par Specification
1957 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
1958 @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
1959
1960 @see
1961 @ref encoded_params,
1962 @ref encoded_query,
1963 @ref has_query,
1964 @ref params.
1965
1966 @param token A token to use for the returned string.
1967 @return The query as a string.
1968 */
1969 template<BOOST_URL_STRTOK_TPARAM>
1970 BOOST_URL_STRTOK_RETURN
1971 29 query(
1972 StringToken&& token = {}) const
1973 {
1974 // When interacting with the query as
1975 // an intact string, we do not treat
1976 // the plus sign as an encoded space.
1977 29 encoding_opts opt;
1978 29 opt.space_as_plus = false;
1979 58 return encoded_query().decode(
1980
1/2
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
58 opt, std::forward<StringToken>(token));
1981 }
1982
1983 /** Return the query
1984
1985 If this contains a query, it is returned
1986 as a string (which may be empty).
1987 Otherwise, an empty string is returned.
1988 The returned string may contain
1989 percent escapes.
1990
1991 @par Example
1992 @code
1993 assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_query() == "id=42&name=jane%2Ddoe&page+size=20" );
1994 @endcode
1995
1996 @par Complexity
1997 Constant.
1998
1999 @par Exception Safety
2000 Throws nothing.
2001
2002 @par BNF
2003 @code
2004 query = *( pchar / "/" / "?" )
2005
2006 query-param = key [ "=" value ]
2007 query-params = [ query-param ] *( "&" query-param )
2008 @endcode
2009
2010 @par Specification
2011 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2012 @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2013
2014 @see
2015 @ref encoded_params,
2016 @ref has_query,
2017 @ref params,
2018 @ref query.
2019
2020 @return The query as a string.
2021 */
2022 pct_string_view
2023 encoded_query() const noexcept;
2024
2025 /** Return the query as a container of parameters
2026
2027 This function returns a bidirectional
2028 view of key/value pairs over the query.
2029 The returned view references the same
2030 underlying character buffer; ownership
2031 is not transferred.
2032 Any percent-escapes in strings returned
2033 when iterating the view are decoded first.
2034
2035 @par Example
2036 @code
2037 params_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
2038 @endcode
2039
2040 @par Complexity
2041 Constant.
2042
2043 @par Exception Safety
2044 Throws nothing.
2045
2046 @par BNF
2047 @code
2048 query = *( pchar / "/" / "?" )
2049
2050 query-param = key [ "=" value ]
2051 query-params = [ query-param ] *( "&" query-param )
2052 @endcode
2053
2054 @par Specification
2055 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2056 @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2057
2058 @see
2059 @ref encoded_params,
2060 @ref encoded_query,
2061 @ref has_query,
2062 @ref query.
2063
2064 @return A bidirectional view of key/value pairs.
2065 */
2066 params_view
2067 params() const noexcept;
2068
2069 params_view
2070 params(encoding_opts opt) const noexcept;
2071
2072 /** Return the query as a container of parameters
2073
2074 This function returns a bidirectional
2075 view of key/value pairs over the query.
2076 The returned view references the same
2077 underlying character buffer; ownership
2078 is not transferred.
2079 Strings returned when iterating the
2080 range may contain percent escapes.
2081
2082 @par Example
2083 @code
2084 params_encoded_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
2085 @endcode
2086
2087 @par Complexity
2088 Constant.
2089
2090 @par Exception Safety
2091 Throws nothing.
2092
2093 @par BNF
2094 @code
2095 query = *( pchar / "/" / "?" )
2096 query-param = key [ "=" value ]
2097 query-params = [ query-param ] *( "&" query-param )
2098 @endcode
2099
2100 @par Specification
2101 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2102 @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2103
2104 @see
2105 @ref encoded_query,
2106 @ref has_query,
2107 @ref params,
2108 @ref query.
2109
2110 @return A bidirectional view of key/value pairs.
2111 */
2112 params_encoded_view
2113 encoded_params() const noexcept;
2114
2115 //--------------------------------------------
2116 //
2117 // Fragment
2118 //
2119 //--------------------------------------------
2120
2121 /** Return true if a fragment is present
2122
2123 This function returns true if the url
2124 contains a fragment.
2125 An empty fragment is distinct from
2126 no fragment.
2127
2128 @par Example
2129 @code
2130 assert( url_view( "http://www.example.com/index.htm#anchor" ).has_fragment() );
2131 @endcode
2132
2133 @par Complexity
2134 Constant.
2135
2136 @par Exception Safety
2137 Throws nothing.
2138
2139 @par BNF
2140 @code
2141 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
2142
2143 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
2144 @endcode
2145
2146 @par Specification
2147 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2148
2149 @see
2150 @ref encoded_fragment,
2151 @ref fragment.
2152
2153 @return `true` if the url contains a fragment.
2154 */
2155 bool
2156 has_fragment() const noexcept;
2157
2158 /** Return the fragment
2159
2160 This function calculates the fragment
2161 of the url, with percent escapes decoded
2162 and without the leading pound sign ('#')
2163 whose presence indicates that the url
2164 contains a fragment.
2165
2166 <br>
2167
2168 This function accepts an optional
2169 <em>StringToken</em> parameter which
2170 controls the return type and behavior
2171 of the function:
2172
2173 @li When called with no arguments,
2174 the return type of the function is
2175 `std::string`. Otherwise
2176
2177 @li When called with a string token,
2178 the behavior and return type of the
2179 function depends on the type of string
2180 token being passed.
2181
2182 @par Example
2183 @code
2184 assert( url_view( "http://www.example.com/index.htm#a%2D1" ).fragment() == "a-1" );
2185 @endcode
2186
2187 @par Complexity
2188 Linear in `this->fragment().size()`.
2189
2190 @par Exception Safety
2191 Calls to allocate may throw.
2192 String tokens may throw exceptions.
2193
2194 @param token An optional string token to
2195 use. If this parameter is omitted, the
2196 function returns a new `std::string`.
2197
2198 @return The fragment portion of the url.
2199
2200 @par BNF
2201 @code
2202 fragment = *( pchar / "/" / "?" )
2203
2204 fragment-part = [ "#" fragment ]
2205 @endcode
2206
2207 @par Specification
2208 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2209
2210 @see
2211 @ref encoded_fragment,
2212 @ref has_fragment.
2213
2214 */
2215 template<BOOST_URL_STRTOK_TPARAM>
2216 BOOST_URL_STRTOK_RETURN
2217 17 fragment(
2218 StringToken&& token = {}) const
2219 {
2220 17 encoding_opts opt;
2221 17 opt.space_as_plus = false;
2222 34 return encoded_fragment().decode(
2223
1/2
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
34 opt, std::forward<StringToken>(token));
2224 }
2225
2226 /** Return the fragment
2227
2228 This function returns the fragment as a
2229 string with percent-escapes.
2230 Ownership is not transferred; the
2231 string returned references the underlying
2232 character buffer, which must remain valid
2233 or else undefined behavior occurs.
2234
2235 @par Example
2236 @code
2237 assert( url_view( "http://www.example.com/index.htm#a%2D1" ).encoded_fragment() == "a%2D1" );
2238 @endcode
2239
2240 @par Complexity
2241 Constant.
2242
2243 @par Exception Safety
2244 Throws nothing.
2245
2246 @par BNF
2247 @code
2248 fragment = *( pchar / "/" / "?" )
2249
2250 pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
2251 @endcode
2252
2253 @par Specification
2254 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2255
2256 @see
2257 @ref fragment,
2258 @ref has_fragment.
2259
2260 @return The fragment portion of the url.
2261 */
2262 pct_string_view
2263 encoded_fragment() const noexcept;
2264
2265 //--------------------------------------------
2266 //
2267 // Compound Fields
2268 //
2269 //--------------------------------------------
2270
2271 /** Return the host and port
2272
2273 If an authority is present, this
2274 function returns the host and optional
2275 port as a string, which may be empty.
2276 Otherwise it returns an empty string.
2277 The returned string may contain
2278 percent escapes.
2279
2280 @par Example
2281 @code
2282 assert( url_view( "http://www.example.com:8080/index.htm" ).encoded_host_and_port() == "www.example.com:8080" );
2283 @endcode
2284
2285 @par Complexity
2286 Constant.
2287
2288 @par Exception Safety
2289 Throws nothing.
2290
2291 @par BNF
2292 @code
2293 authority = [ userinfo "@" ] host [ ":" port ]
2294 @endcode
2295
2296 @par Specification
2297 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
2298 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
2299
2300 @see
2301 @ref has_port,
2302 @ref port,
2303 @ref port_number.
2304
2305 @return The host and port portion of the url.
2306 */
2307 pct_string_view
2308 encoded_host_and_port() const noexcept;
2309
2310 /** Return the origin
2311
2312 If an authority is present, this
2313 function returns the scheme and
2314 authority portion of the url.
2315 Otherwise, an empty string is
2316 returned.
2317 The returned string may contain
2318 percent escapes.
2319
2320 @par Example
2321 @code
2322 assert( url_view( "http://www.example.com:8080/index.htm?text=none#h1" ).encoded_origin() == "http://www.example.com:8080" );
2323 @endcode
2324
2325 @par Complexity
2326 Constant.
2327
2328 @par Exception Safety
2329 Throws nothing.
2330
2331 @see
2332 @ref encoded_resource,
2333 @ref encoded_target.
2334
2335 @return The origin portion of the url.
2336 */
2337 pct_string_view
2338 encoded_origin() const noexcept;
2339
2340 /** Return the resource
2341
2342 This function returns the resource, which
2343 is the portion of the url that includes
2344 only the path, query, and fragment.
2345 The returned string may contain
2346 percent escapes.
2347
2348 @par Example
2349 @code
2350 assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_resource() == "/index.html?query#frag" );
2351 @endcode
2352
2353 @par Complexity
2354 Constant.
2355
2356 @par Exception Safety
2357 Throws nothing.
2358
2359 @par Specification
2360 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
2361 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2362
2363 @see
2364 @ref encoded_origin,
2365 @ref encoded_target.
2366
2367 @return The resource portion of the url.
2368 */
2369 pct_string_view
2370 encoded_resource() const noexcept;
2371
2372 /** Return the target
2373
2374 This function returns the target, which
2375 is the portion of the url that includes
2376 only the path and query.
2377 The returned string may contain
2378 percent escapes.
2379
2380 @par Example
2381 @code
2382 assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_target() == "/index.html?query" );
2383 @endcode
2384
2385 @par Complexity
2386 Constant.
2387
2388 @par Exception Safety
2389 Throws nothing.
2390
2391 @par Specification
2392 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
2393 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2394
2395 @see
2396 @ref encoded_origin,
2397 @ref encoded_resource.
2398
2399 @return The target portion of the url.
2400 */
2401 pct_string_view
2402 encoded_target() const noexcept;
2403
2404 //--------------------------------------------
2405 //
2406 // Comparison
2407 //
2408 //--------------------------------------------
2409
2410 /** Return the result of comparing this with another url
2411
2412 This function compares two URLs
2413 according to Syntax-Based comparison
2414 algorithm.
2415
2416 @par Complexity
2417 Linear in `min( u0.size(), u1.size() )`
2418
2419 @par Exception Safety
2420 Throws nothing.
2421
2422 @par Specification
2423 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2424
2425 @param other The url to compare
2426 @return -1 if `*this < other`, 0 if `this == other`, and 1 if `this > other`.
2427 */
2428 int
2429 compare(url_view_base const& other) const noexcept;
2430
2431 /** Return the result of comparing two URLs
2432
2433 The URLs are compared component by
2434 component as if they were first
2435 normalized.
2436
2437 @par Example
2438 @code
2439 url_view u0( "http://www.a.com/index.htm" );
2440 url_view u1( "http://www.a.com/index.htm" );
2441 assert( u0 == u1 );
2442 @endcode
2443
2444 @par Effects
2445 @code
2446 url a(u0);
2447 a.normalize();
2448 url b(u1);
2449 b.normalize();
2450 return a.buffer() == b.buffer();
2451 @endcode
2452
2453 @par Complexity
2454 Linear in `min( u0.size(), u1.size() )`
2455
2456 @par Exception Safety
2457 Throws nothing
2458
2459 @param u0 The first url to compare
2460 @param u1 The second url to compare
2461 @return `true` if `u0 == u1`
2462
2463 @par Specification
2464 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2465 */
2466 friend
2467 bool
2468 81 operator==(
2469 url_view_base const& u0,
2470 url_view_base const& u1) noexcept
2471 {
2472 81 return u0.compare(u1) == 0;
2473 }
2474
2475 /** Return the result of comparing two URLs
2476
2477 The URLs are compared component by
2478 component as if they were first
2479 normalized.
2480
2481 @par Example
2482 @code
2483 url_view u0( "http://www.a.com/index.htm" );
2484 url_view u1( "http://www.b.com/index.htm" );
2485 assert( u0 != u1 );
2486 @endcode
2487
2488 @par Effects
2489 @code
2490 url a(u0);
2491 a.normalize();
2492 url b(u1);
2493 b.normalize();
2494 return a.buffer() != b.buffer();
2495 @endcode
2496
2497 @par Complexity
2498 Linear in `min( u0.size(), u1.size() )`
2499
2500 @par Exception Safety
2501 Throws nothing
2502
2503 @param u0 The first url to compare
2504 @param u1 The second url to compare
2505 @return `true` if `u0 != u1`
2506
2507 @par Specification
2508 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2509 */
2510 friend
2511 bool
2512 30 operator!=(
2513 url_view_base const& u0,
2514 url_view_base const& u1) noexcept
2515 {
2516 30 return ! (u0 == u1);
2517 }
2518
2519 /** Return the result of comparing two URLs
2520
2521 The URLs are compared component by
2522 component as if they were first
2523 normalized.
2524
2525 @par Example
2526 @code
2527 url_view u0( "http://www.a.com/index.htm" );
2528 url_view u1( "http://www.b.com/index.htm" );
2529 assert( u0 < u1 );
2530 @endcode
2531
2532 @par Effects
2533 @code
2534 url a(u0);
2535 a.normalize();
2536 url b(u1);
2537 b.normalize();
2538 return a.buffer() < b.buffer();
2539 @endcode
2540
2541 @par Complexity
2542 Linear in `min( u0.size(), u1.size() )`
2543
2544 @par Exception Safety
2545 Throws nothing
2546
2547 @param u0 The first url to compare
2548 @param u1 The second url to compare
2549 @return `true` if `u0 < u1`
2550
2551 @par Specification
2552 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2553 */
2554 friend
2555 bool
2556 23 operator<(
2557 url_view_base const& u0,
2558 url_view_base const& u1) noexcept
2559 {
2560 23 return u0.compare(u1) < 0;
2561 }
2562
2563 /** Return the result of comparing two URLs
2564
2565 The URLs are compared component by
2566 component as if they were first
2567 normalized.
2568
2569 @par Example
2570 @code
2571 url_view u0( "http://www.b.com/index.htm" );
2572 url_view u1( "http://www.b.com/index.htm" );
2573 assert( u0 <= u1 );
2574 @endcode
2575
2576 @par Effects
2577 @code
2578 url a(u0);
2579 a.normalize();
2580 url b(u1);
2581 b.normalize();
2582 return a.buffer() <= b.buffer();
2583 @endcode
2584
2585 @par Complexity
2586 Linear in `min( u0.size(), u1.size() )`
2587
2588 @par Exception Safety
2589 Throws nothing
2590
2591 @param u0 The first url to compare
2592 @param u1 The second url to compare
2593 @return `true` if `u0 <= u1`
2594
2595 @par Specification
2596 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2597 */
2598 friend
2599 bool
2600 23 operator<=(
2601 url_view_base const& u0,
2602 url_view_base const& u1) noexcept
2603 {
2604 23 return u0.compare(u1) <= 0;
2605 }
2606
2607 /** Return the result of comparing two URLs
2608
2609 The URLs are compared component by
2610 component as if they were first
2611 normalized.
2612
2613 @par Example
2614 @code
2615 url_view u0( "http://www.b.com/index.htm" );
2616 url_view u1( "http://www.a.com/index.htm" );
2617 assert( u0 > u1 );
2618 @endcode
2619
2620 @par Effects
2621 @code
2622 url a(u0);
2623 a.normalize();
2624 url b(u1);
2625 b.normalize();
2626 return a.buffer() > b.buffer();
2627 @endcode
2628
2629 @par Complexity
2630 Linear in `min( u0.size(), u1.size() )`
2631
2632 @par Exception Safety
2633 Throws nothing
2634
2635 @param u0 The first url to compare
2636 @param u1 The second url to compare
2637 @return `true` if `u0 > u1`
2638
2639 @par Specification
2640 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2641 */
2642 friend
2643 bool
2644 23 operator>(
2645 url_view_base const& u0,
2646 url_view_base const& u1) noexcept
2647 {
2648 23 return u0.compare(u1) > 0;
2649 }
2650
2651 /** Return the result of comparing two URLs
2652
2653 The URLs are compared component by
2654 component as if they were first
2655 normalized.
2656
2657 @par Example
2658 @code
2659 url_view u0( "http://www.a.com/index.htm" );
2660 url_view u1( "http://www.a.com/index.htm" );
2661 assert( u0 >= u1 );
2662 @endcode
2663
2664 @par Effects
2665 @code
2666 url a(u0);
2667 a.normalize();
2668 url b(u1);
2669 b.normalize();
2670 return a.buffer() >= b.buffer();
2671 @endcode
2672
2673 @par Complexity
2674 Linear in `min( u0.size(), u1.size() )`
2675
2676 @par Exception Safety
2677 Throws nothing
2678
2679 @param u0 The first url to compare
2680 @param u1 The second url to compare
2681 @return `true` if `u0 >= u1`
2682
2683 @par Specification
2684 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2685 */
2686 friend
2687 bool
2688 23 operator>=(
2689 url_view_base const& u0,
2690 url_view_base const& u1) noexcept
2691 {
2692 23 return u0.compare(u1) >= 0;
2693 }
2694
2695 /** Format the url to the output stream
2696
2697 This function serializes the url to
2698 the specified output stream. Any
2699 percent-escapes are emitted as-is;
2700 no decoding is performed.
2701
2702 @par Example
2703 @code
2704 url_view u( "http://www.example.com/index.htm" );
2705 std::stringstream ss;
2706 ss << u;
2707 assert( ss.str() == "http://www.example.com/index.htm" );
2708 @endcode
2709
2710 @par Effects
2711 @code
2712 return os << u.buffer();
2713 @endcode
2714
2715 @par Complexity
2716 Linear in `u.buffer().size()`
2717
2718 @par Exception Safety
2719 Basic guarantee.
2720
2721 @return A reference to the output stream, for chaining
2722
2723 @param os The output stream to write to.
2724
2725 @param u The url to write.
2726 */
2727 friend
2728 std::ostream&
2729 5 operator<<(
2730 std::ostream& os,
2731 url_view_base const& u)
2732 {
2733 5 return os << u.buffer();
2734 }
2735
2736 private:
2737 //--------------------------------------------
2738 //
2739 // implementation
2740 //
2741 //--------------------------------------------
2742 static
2743 int
2744 segments_compare(
2745 segments_encoded_view seg0,
2746 segments_encoded_view seg1) noexcept;
2747 };
2748
2749 //------------------------------------------------
2750
2751 /** Format the url to the output stream
2752
2753 This function serializes the url to
2754 the specified output stream. Any
2755 percent-escapes are emitted as-is;
2756 no decoding is performed.
2757
2758 @par Example
2759 @code
2760 url_view u( "http://www.example.com/index.htm" );
2761 std::stringstream ss;
2762 ss << u;
2763 assert( ss.str() == "http://www.example.com/index.htm" );
2764 @endcode
2765
2766 @par Effects
2767 @code
2768 return os << u.buffer();
2769 @endcode
2770
2771 @par Complexity
2772 Linear in `u.buffer().size()`
2773
2774 @par Exception Safety
2775 Basic guarantee.
2776
2777 @return A reference to the output stream, for chaining
2778
2779 @param os The output stream to write to.
2780
2781 @param u The url to write.
2782 */
2783 std::ostream&
2784 operator<<(
2785 std::ostream& os,
2786 url_view_base const& u);
2787
2788 } // urls
2789 } // boost
2790
2791 #endif
2792