GCC Code Coverage Report


Directory: libs/url/
File: src/url_view_base.cpp
Date: 2025-11-10 19:06:22
Exec Total Coverage
Lines: 315 325 96.9%
Functions: 40 41 97.6%
Branches: 120 170 70.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
12 #include <boost/url/detail/config.hpp>
13 #include <boost/url/url_view_base.hpp>
14 #include <boost/url/url_view.hpp>
15 #include <boost/url/detail/except.hpp>
16 #include "detail/normalize.hpp"
17 #include "detail/over_allocator.hpp"
18
19 namespace boost {
20 namespace urls {
21
22 // construct empty view
23 4116 url_view_base::
24 4116 url_view_base() noexcept
25 4116 : impl_(from::url)
26 4116 , pi_(&impl_)
27 {
28 4116 }
29
30 // construct reference
31 20989 url_view_base::
32 url_view_base(
33 20989 detail::url_impl const& impl) noexcept
34 20989 : impl_(impl)
35 20989 , pi_(&impl_)
36 {
37 20989 }
38
39 //------------------------------------------------
40
41 std::size_t
42 304 url_view_base::
43 digest(std::size_t salt) const noexcept
44 {
45 304 detail::fnv_1a h(salt);
46 304 detail::ci_digest(pi_->get(id_scheme), h);
47 304 detail::digest_encoded(pi_->get(id_user), h);
48 304 detail::digest_encoded(pi_->get(id_pass), h);
49 304 detail::ci_digest_encoded(pi_->get(id_host), h);
50 304 h.put(pi_->get(id_port));
51 304 detail::normalized_path_digest(
52 304 pi_->get(id_path), is_path_absolute(), h);
53 304 detail::digest_encoded(pi_->get(id_query), h);
54 304 detail::digest_encoded(pi_->get(id_frag), h);
55 304 return h.digest();
56 }
57
58 //------------------------------------------------
59 //
60 // Observers
61 //
62 //------------------------------------------------
63
64 struct url_view_base::shared_impl
65 : url_view
66 {
67 virtual
68 4 ~shared_impl()
69 4 {
70 4 }
71
72 2 shared_impl(
73 url_view const& u) noexcept
74 2 : url_view(u)
75 {
76 2 impl_.cs_ = reinterpret_cast<
77 char const*>(this + 1);
78 2 }
79 };
80
81 std::shared_ptr<url_view const>
82 2 url_view_base::
83 persist() const
84 {
85 using T = shared_impl;
86 using Alloc = std::allocator<char>;
87 Alloc a;
88 auto p = std::allocate_shared<T>(
89
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 detail::over_allocator<T, Alloc>(
90
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 size(), a), url_view(*pi_));
91 2 std::memcpy(
92 reinterpret_cast<char*>(
93 2 p.get() + 1), data(), size());
94 4 return p;
95 2 }
96
97 //------------------------------------------------
98 //
99 // Scheme
100 //
101 //------------------------------------------------
102
103 bool
104 2878 url_view_base::
105 has_scheme() const noexcept
106 {
107 2878 auto const n = pi_->len(
108 id_scheme);
109
2/2
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 2296 times.
2878 if(n == 0)
110 582 return false;
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2296 times.
2296 BOOST_ASSERT(n > 1);
112
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2296 times.
2296 BOOST_ASSERT(
113 pi_->get(id_scheme
114 ).ends_with(':'));
115 2296 return true;
116 }
117
118 core::string_view
119 1448 url_view_base::
120 scheme() const noexcept
121 {
122 1448 auto s = pi_->get(id_scheme);
123
2/2
✓ Branch 1 taken 1352 times.
✓ Branch 2 taken 96 times.
1448 if(! s.empty())
124 {
125
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1352 times.
1352 BOOST_ASSERT(s.size() > 1);
126
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1352 times.
1352 BOOST_ASSERT(s.ends_with(':'));
127 1352 s.remove_suffix(1);
128 }
129 1448 return s;
130 }
131
132 urls::scheme
133 44 url_view_base::
134 scheme_id() const noexcept
135 {
136 44 return pi_->scheme_;
137 }
138
139 //------------------------------------------------
140 //
141 // Authority
142 //
143 //------------------------------------------------
144
145 authority_view
146 495 url_view_base::
147 authority() const noexcept
148 {
149 495 detail::url_impl u(from::authority);
150 495 u.cs_ = encoded_authority().data();
151
1/2
✓ Branch 1 taken 495 times.
✗ Branch 2 not taken.
495 if(has_authority())
152 {
153 495 u.set_size(id_user, pi_->len(id_user) - 2);
154 495 u.set_size(id_pass, pi_->len(id_pass));
155 495 u.set_size(id_host, pi_->len(id_host));
156 495 u.set_size(id_port, pi_->len(id_port));
157 }
158 else
159 {
160 u.set_size(id_user, pi_->len(id_user));
161 BOOST_ASSERT(pi_->len(id_pass) == 0);
162 BOOST_ASSERT(pi_->len(id_host) == 0);
163 BOOST_ASSERT(pi_->len(id_port) == 0);
164 }
165 495 u.decoded_[id_user] = pi_->decoded_[id_user];
166 495 u.decoded_[id_pass] = pi_->decoded_[id_pass];
167 495 u.decoded_[id_host] = pi_->decoded_[id_host];
168
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 495 times.
8415 for (int i = 0; i < 16; ++i)
169 7920 u.ip_addr_[i] = pi_->ip_addr_[i];
170 495 u.port_number_ = pi_->port_number_;
171 495 u.host_type_ = pi_->host_type_;
172 495 return u.construct_authority();
173 }
174
175 pct_string_view
176 653 url_view_base::
177 encoded_authority() const noexcept
178 {
179 653 auto s = pi_->get(id_user, id_path);
180
2/2
✓ Branch 1 taken 613 times.
✓ Branch 2 taken 40 times.
653 if(! s.empty())
181 {
182
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 613 times.
613 BOOST_ASSERT(has_authority());
183 613 s.remove_prefix(2);
184 }
185 653 return make_pct_string_view_unsafe(
186 s.data(),
187 s.size(),
188 653 pi_->decoded_[id_user] +
189 653 pi_->decoded_[id_pass] +
190 653 pi_->decoded_[id_host] +
191 653 pi_->decoded_[id_port] +
192 1306 has_password());
193 }
194
195 //------------------------------------------------
196 //
197 // Userinfo
198 //
199 //------------------------------------------------
200
201 bool
202 261 url_view_base::
203 has_userinfo() const noexcept
204 {
205 261 auto n = pi_->len(id_pass);
206
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 164 times.
261 if(n == 0)
207 97 return false;
208
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 164 times.
164 BOOST_ASSERT(has_authority());
209
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 164 times.
164 BOOST_ASSERT(pi_->get(
210 id_pass).ends_with('@'));
211 164 return true;
212 }
213
214 bool
215 788 url_view_base::
216 has_password() const noexcept
217 {
218 788 auto const n = pi_->len(id_pass);
219
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 674 times.
788 if(n > 1)
220 {
221
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
114 BOOST_ASSERT(pi_->get(id_pass
222 ).starts_with(':'));
223
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
114 BOOST_ASSERT(pi_->get(id_pass
224 ).ends_with('@'));
225 114 return true;
226 }
227
3/4
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 561 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 113 times.
674 BOOST_ASSERT(n == 0 || pi_->get(
228 id_pass).ends_with('@'));
229 674 return false;
230 }
231
232 pct_string_view
233 119 url_view_base::
234 encoded_userinfo() const noexcept
235 {
236 119 auto s = pi_->get(
237 id_user, id_host);
238
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 111 times.
119 if(s.empty())
239 8 return s;
240
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
111 BOOST_ASSERT(
241 has_authority());
242 111 s.remove_prefix(2);
243
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 77 times.
111 if(s.empty())
244 34 return s;
245
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
77 BOOST_ASSERT(
246 s.ends_with('@'));
247 77 s.remove_suffix(1);
248 77 return make_pct_string_view_unsafe(
249 s.data(),
250 s.size(),
251 77 pi_->decoded_[id_user] +
252 77 pi_->decoded_[id_pass] +
253 154 has_password());
254 }
255
256 pct_string_view
257 131 url_view_base::
258 encoded_user() const noexcept
259 {
260 131 auto s = pi_->get(id_user);
261
2/2
✓ Branch 1 taken 130 times.
✓ Branch 2 taken 1 times.
131 if(! s.empty())
262 {
263
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 130 times.
130 BOOST_ASSERT(
264 has_authority());
265 130 s.remove_prefix(2);
266 }
267 131 return make_pct_string_view_unsafe(
268 s.data(),
269 s.size(),
270 262 pi_->decoded_[id_user]);
271 }
272
273 pct_string_view
274 94 url_view_base::
275 encoded_password() const noexcept
276 {
277 94 auto s = pi_->get(id_pass);
278
3/3
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 52 times.
94 switch(s.size())
279 {
280 24 case 1:
281
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
24 BOOST_ASSERT(
282 s.starts_with('@'));
283 24 s.remove_prefix(1);
284 BOOST_FALLTHROUGH;
285 42 case 0:
286 42 return make_pct_string_view_unsafe(
287 42 s.data(), s.size(), 0);
288 52 default:
289 52 break;
290 }
291
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
52 BOOST_ASSERT(s.ends_with('@'));
292
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
52 BOOST_ASSERT(s.starts_with(':'));
293 52 return make_pct_string_view_unsafe(
294 52 s.data() + 1,
295 52 s.size() - 2,
296 104 pi_->decoded_[id_pass]);
297 }
298
299 //------------------------------------------------
300 //
301 // Host
302 //
303 //------------------------------------------------
304 /*
305 host_type host_type() // ipv4, ipv6, ipvfuture, name
306
307 std::string host() // return encoded_host().decode()
308 pct_string_view encoded_host() // return host part, as-is
309 std::string host_address() // return encoded_host_address().decode()
310 pct_string_view encoded_host_address() // ipv4, ipv6, ipvfut, or encoded name, no brackets
311
312 ipv4_address host_ipv4_address() // return ipv4_address or {}
313 ipv6_address host_ipv6_address() // return ipv6_address or {}
314 core::string_view host_ipvfuture() // return ipvfuture or {}
315 std::string host_name() // return decoded name or ""
316 pct_string_view encoded_host_name() // return encoded host name or ""
317 */
318
319 pct_string_view
320 523 url_view_base::
321 encoded_host() const noexcept
322 {
323 523 return pi_->pct_get(id_host);
324 }
325
326 pct_string_view
327 119 url_view_base::
328 encoded_host_address() const noexcept
329 {
330 119 core::string_view s = pi_->get(id_host);
331 std::size_t n;
332
3/3
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 25 times.
119 switch(pi_->host_type_)
333 {
334 41 default:
335 case urls::host_type::none:
336
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
41 BOOST_ASSERT(s.empty());
337 41 n = 0;
338 41 break;
339
340 53 case urls::host_type::name:
341 case urls::host_type::ipv4:
342 53 n = pi_->decoded_[id_host];
343 53 break;
344
345 25 case urls::host_type::ipv6:
346 case urls::host_type::ipvfuture:
347 {
348
3/4
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
25 BOOST_ASSERT(
349 pi_->decoded_[id_host] ==
350 s.size() ||
351 !this->encoded_zone_id().empty());
352
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 BOOST_ASSERT(s.size() >= 2);
353
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 BOOST_ASSERT(s.front() == '[');
354
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 BOOST_ASSERT(s.back() == ']');
355 25 s = s.substr(1, s.size() - 2);
356 25 n = pi_->decoded_[id_host] - 2;
357 25 break;
358 }
359 }
360 119 return make_pct_string_view_unsafe(
361 s.data(),
362 s.size(),
363 119 n);
364 }
365
366 urls::ipv4_address
367 51 url_view_base::
368 host_ipv4_address() const noexcept
369 {
370
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 16 times.
51 if(pi_->host_type_ !=
371 urls::host_type::ipv4)
372 35 return {};
373 16 ipv4_address::bytes_type b{{}};
374 32 std::memcpy(
375 16 &b[0], &pi_->ip_addr_[0], b.size());
376 16 return urls::ipv4_address(b);
377 }
378
379 urls::ipv6_address
380 59 url_view_base::
381 host_ipv6_address() const noexcept
382 {
383
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 14 times.
59 if(pi_->host_type_ !=
384 urls::host_type::ipv6)
385 45 return {};
386 14 ipv6_address::bytes_type b{{}};
387 28 std::memcpy(
388 14 &b[0], &pi_->ip_addr_[0], b.size());
389 14 return {b};
390 }
391
392 core::string_view
393 51 url_view_base::
394 host_ipvfuture() const noexcept
395 {
396
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 7 times.
51 if(pi_->host_type_ !=
397 urls::host_type::ipvfuture)
398 44 return {};
399 7 core::string_view s = pi_->get(id_host);
400
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 BOOST_ASSERT(s.size() >= 6);
401
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 BOOST_ASSERT(s.front() == '[');
402
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 BOOST_ASSERT(s.back() == ']');
403 7 s = s.substr(1, s.size() - 2);
404 7 return s;
405 }
406
407 pct_string_view
408 146 url_view_base::
409 encoded_host_name() const noexcept
410 {
411
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 68 times.
146 if(pi_->host_type_ !=
412 urls::host_type::name)
413 78 return {};
414 68 core::string_view s = pi_->get(id_host);
415 68 return make_pct_string_view_unsafe(
416 s.data(),
417 s.size(),
418 136 pi_->decoded_[id_host]);
419 }
420
421 pct_string_view
422 24 url_view_base::
423 encoded_zone_id() const noexcept
424 {
425
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 18 times.
24 if(pi_->host_type_ !=
426 urls::host_type::ipv6)
427 6 return {};
428 18 core::string_view s = pi_->get(id_host);
429
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
18 BOOST_ASSERT(s.front() == '[');
430
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
18 BOOST_ASSERT(s.back() == ']');
431 18 s = s.substr(1, s.size() - 2);
432 18 auto pos = s.find("%25");
433
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 if (pos == core::string_view::npos)
434 2 return {};
435 16 s.remove_prefix(pos + 3);
436 16 return *make_pct_string_view(s);
437 }
438
439 //------------------------------------------------
440
441 bool
442 364 url_view_base::
443 has_port() const noexcept
444 {
445 364 auto const n = pi_->len(id_port);
446
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 277 times.
364 if(n == 0)
447 87 return false;
448
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 277 times.
277 BOOST_ASSERT(
449 pi_->get(id_port).starts_with(':'));
450 277 return true;
451 }
452
453 core::string_view
454 179 url_view_base::
455 port() const noexcept
456 {
457 179 auto s = pi_->get(id_port);
458
2/2
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 121 times.
179 if(s.empty())
459 58 return s;
460
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 121 times.
121 BOOST_ASSERT(has_port());
461 121 return s.substr(1);
462 }
463
464 std::uint16_t
465 101 url_view_base::
466 port_number() const noexcept
467 {
468
3/4
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 79 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
101 BOOST_ASSERT(
469 has_port() ||
470 pi_->port_number_ == 0);
471 101 return pi_->port_number_;
472 }
473
474 //------------------------------------------------
475 //
476 // Path
477 //
478 //------------------------------------------------
479
480 pct_string_view
481 1332 url_view_base::
482 encoded_path() const noexcept
483 {
484 1332 return pi_->pct_get(id_path);
485 }
486
487 segments_view
488 46 url_view_base::
489 segments() const noexcept
490 {
491 46 return {detail::path_ref(*pi_)};
492 }
493
494 segments_encoded_view
495 675 url_view_base::
496 encoded_segments() const noexcept
497 {
498 return segments_encoded_view(
499 675 detail::path_ref(*pi_));
500 }
501
502 //------------------------------------------------
503 //
504 // Query
505 //
506 //------------------------------------------------
507
508 bool
509 758 url_view_base::
510 has_query() const noexcept
511 {
512 758 auto const n = pi_->len(
513 id_query);
514
2/2
✓ Branch 0 taken 618 times.
✓ Branch 1 taken 140 times.
758 if(n == 0)
515 618 return false;
516
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 140 times.
140 BOOST_ASSERT(
517 pi_->get(id_query).
518 starts_with('?'));
519 140 return true;
520 }
521
522 pct_string_view
523 289 url_view_base::
524 encoded_query() const noexcept
525 {
526 289 auto s = pi_->get(id_query);
527
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 279 times.
289 if(s.empty())
528 10 return s;
529
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 279 times.
279 BOOST_ASSERT(
530 s.starts_with('?'));
531 279 return s.substr(1);
532 }
533
534 params_encoded_view
535 55 url_view_base::
536 encoded_params() const noexcept
537 {
538 55 return params_encoded_view(*pi_);
539 }
540
541 params_view
542 62 url_view_base::
543 params() const noexcept
544 {
545 return params_view(
546 62 *pi_,
547 encoding_opts{
548 62 true,false,false});
549 }
550
551 params_view
552 url_view_base::
553 params(encoding_opts opt) const noexcept
554 {
555 return params_view(*pi_, opt);
556 }
557
558 //------------------------------------------------
559 //
560 // Fragment
561 //
562 //------------------------------------------------
563
564 bool
565 652 url_view_base::
566 has_fragment() const noexcept
567 {
568 652 auto const n = pi_->len(id_frag);
569
2/2
✓ Branch 0 taken 527 times.
✓ Branch 1 taken 125 times.
652 if(n == 0)
570 527 return false;
571
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 125 times.
125 BOOST_ASSERT(
572 pi_->get(id_frag).
573 starts_with('#'));
574 125 return true;
575 }
576
577 pct_string_view
578 155 url_view_base::
579 encoded_fragment() const noexcept
580 {
581 155 auto s = pi_->get(id_frag);
582
2/2
✓ Branch 1 taken 153 times.
✓ Branch 2 taken 2 times.
155 if(! s.empty())
583 {
584
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 153 times.
153 BOOST_ASSERT(
585 s.starts_with('#'));
586 153 s.remove_prefix(1);
587 }
588 155 return make_pct_string_view_unsafe(
589 s.data(),
590 s.size(),
591 310 pi_->decoded_[id_frag]);
592 }
593
594 //------------------------------------------------
595 //
596 // Compound Fields
597 //
598 //------------------------------------------------
599
600 pct_string_view
601 120 url_view_base::
602 encoded_host_and_port() const noexcept
603 {
604 120 return pi_->pct_get(id_host, id_path);
605 }
606
607 pct_string_view
608 16 url_view_base::
609 encoded_origin() const noexcept
610 {
611
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
16 if(pi_->len(id_user) < 2)
612 14 return {};
613 2 return pi_->get(id_scheme, id_path);
614 }
615
616 pct_string_view
617 1 url_view_base::
618 encoded_resource() const noexcept
619 {
620 1 auto n =
621 1 pi_->decoded_[id_path] +
622 1 pi_->decoded_[id_query] +
623 1 pi_->decoded_[id_frag];
624
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(has_query())
625 1 ++n;
626
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(has_fragment())
627 1 ++n;
628
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 BOOST_ASSERT(pct_string_view(
629 pi_->get(id_path, id_end)
630 ).decoded_size() == n);
631 1 auto s = pi_->get(id_path, id_end);
632 1 return make_pct_string_view_unsafe(
633 1 s.data(), s.size(), n);
634 }
635
636 pct_string_view
637 2 url_view_base::
638 encoded_target() const noexcept
639 {
640 2 auto n =
641 2 pi_->decoded_[id_path] +
642 2 pi_->decoded_[id_query];
643
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if(has_query())
644 1 ++n;
645
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 BOOST_ASSERT(pct_string_view(
646 pi_->get(id_path, id_frag)
647 ).decoded_size() == n);
648 2 auto s = pi_->get(id_path, id_frag);
649 2 return make_pct_string_view_unsafe(
650 2 s.data(), s.size(), n);
651 }
652
653 //------------------------------------------------
654 //
655 // Comparisons
656 //
657 //------------------------------------------------
658
659 int
660 284 url_view_base::
661 compare(const url_view_base& other) const noexcept
662 {
663 int comp =
664 284 static_cast<int>(has_scheme()) -
665 284 static_cast<int>(other.has_scheme());
666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 284 times.
284 if ( comp != 0 )
667 return comp;
668
669
2/2
✓ Branch 1 taken 204 times.
✓ Branch 2 taken 80 times.
284 if (has_scheme())
670 {
671 204 comp = detail::ci_compare(
672 scheme(),
673 other.scheme());
674
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 190 times.
204 if ( comp != 0 )
675 14 return comp;
676 }
677
678 270 comp =
679 270 static_cast<int>(has_authority()) -
680 270 static_cast<int>(other.has_authority());
681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 if ( comp != 0 )
682 return comp;
683
684
2/2
✓ Branch 1 taken 190 times.
✓ Branch 2 taken 80 times.
270 if (has_authority())
685 {
686 190 comp = authority().compare(other.authority());
687
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 101 times.
190 if ( comp != 0 )
688 89 return comp;
689 }
690
691 181 comp = detail::segments_compare(
692 encoded_segments(),
693 other.encoded_segments());
694
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 138 times.
181 if ( comp != 0 )
695 43 return comp;
696
697 138 comp =
698 138 static_cast<int>(has_query()) -
699 138 static_cast<int>(other.has_query());
700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138 times.
138 if ( comp != 0 )
701 return comp;
702
703
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 114 times.
138 if (has_query())
704 {
705 48 comp = detail::compare_encoded_query(
706 24 encoded_query(),
707 24 other.encoded_query());
708
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 5 times.
24 if ( comp != 0 )
709 19 return comp;
710 }
711
712 119 comp =
713 119 static_cast<int>(has_fragment()) -
714 119 static_cast<int>(other.has_fragment());
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 119 times.
119 if ( comp != 0 )
716 return comp;
717
718
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 97 times.
119 if (has_fragment())
719 {
720 44 comp = detail::compare_encoded(
721 22 encoded_fragment(),
722 22 other.encoded_fragment());
723
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 times.
22 if ( comp != 0 )
724 21 return comp;
725 }
726
727 98 return 0;
728 }
729
730 } // urls
731 } // boost
732
733