LCOV - code coverage report
Current view: top level - libs/url/src/url_view_base.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 96.9 % 325 315
Test Date: 2025-11-10 19:06:20 Functions: 95.2 % 42 40

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/url
       9              : //
      10              : 
      11              : 
      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            2 :     ~shared_impl()
      69            2 :     {
      70            2 :     }
      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            4 :         detail::over_allocator<T, Alloc>(
      90            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         2878 :     if(n == 0)
     110          582 :         return false;
     111         2296 :     BOOST_ASSERT(n > 1);
     112         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         1448 :     if(! s.empty())
     124              :     {
     125         1352 :         BOOST_ASSERT(s.size() > 1);
     126         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          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            0 :         u.set_size(id_user, pi_->len(id_user));
     161            0 :         BOOST_ASSERT(pi_->len(id_pass) == 0);
     162            0 :         BOOST_ASSERT(pi_->len(id_host) == 0);
     163            0 :         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         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          653 :     if(! s.empty())
     181              :     {
     182          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          261 :     if(n == 0)
     207           97 :         return false;
     208          164 :     BOOST_ASSERT(has_authority());
     209          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          788 :     if(n > 1)
     220              :     {
     221          114 :         BOOST_ASSERT(pi_->get(id_pass
     222              :             ).starts_with(':'));
     223          114 :         BOOST_ASSERT(pi_->get(id_pass
     224              :             ).ends_with('@'));
     225          114 :         return true;
     226              :     }
     227          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          119 :     if(s.empty())
     239            8 :         return s;
     240          111 :     BOOST_ASSERT(
     241              :         has_authority());
     242          111 :     s.remove_prefix(2);
     243          111 :     if(s.empty())
     244           34 :         return s;
     245           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          131 :     if(! s.empty())
     262              :     {
     263          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           94 :     switch(s.size())
     279              :     {
     280           24 :     case 1:
     281           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           52 :     BOOST_ASSERT(s.ends_with('@'));
     292           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          119 :     switch(pi_->host_type_)
     333              :     {
     334           41 :     default:
     335              :     case urls::host_type::none:
     336           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           25 :         BOOST_ASSERT(
     349              :             pi_->decoded_[id_host] ==
     350              :                 s.size() ||
     351              :             !this->encoded_zone_id().empty());
     352           25 :         BOOST_ASSERT(s.size() >= 2);
     353           25 :         BOOST_ASSERT(s.front() == '[');
     354           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           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           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           51 :     if(pi_->host_type_ !=
     397              :             urls::host_type::ipvfuture)
     398           44 :         return {};
     399            7 :     core::string_view s = pi_->get(id_host);
     400            7 :     BOOST_ASSERT(s.size() >= 6);
     401            7 :     BOOST_ASSERT(s.front() == '[');
     402            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          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           24 :     if(pi_->host_type_ !=
     426              :         urls::host_type::ipv6)
     427            6 :         return {};
     428           18 :     core::string_view s = pi_->get(id_host);
     429           18 :     BOOST_ASSERT(s.front() == '[');
     430           18 :     BOOST_ASSERT(s.back() == ']');
     431           18 :     s = s.substr(1, s.size() - 2);
     432           18 :     auto pos = s.find("%25");
     433           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          364 :     if(n == 0)
     447           87 :         return false;
     448          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          179 :     if(s.empty())
     459           58 :         return s;
     460          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          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          758 :     if(n == 0)
     515          618 :         return false;
     516          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          289 :     if(s.empty())
     528           10 :         return s;
     529          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            0 : url_view_base::
     553              : params(encoding_opts opt) const noexcept
     554              : {
     555            0 :     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          652 :     if(n == 0)
     570          527 :         return false;
     571          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          155 :     if(! s.empty())
     583              :     {
     584          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           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 :     if(has_query())
     625            1 :         ++n;
     626            1 :     if(has_fragment())
     627            1 :         ++n;
     628            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 :     if(has_query())
     644            1 :         ++n;
     645            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          284 :     if ( comp != 0 )
     667            0 :         return comp;
     668              : 
     669          284 :     if (has_scheme())
     670              :     {
     671          204 :         comp = detail::ci_compare(
     672              :             scheme(),
     673              :             other.scheme());
     674          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          270 :     if ( comp != 0 )
     682            0 :         return comp;
     683              : 
     684          270 :     if (has_authority())
     685              :     {
     686          190 :         comp = authority().compare(other.authority());
     687          190 :         if ( comp != 0 )
     688           89 :             return comp;
     689              :     }
     690              : 
     691          181 :     comp = detail::segments_compare(
     692              :         encoded_segments(),
     693              :         other.encoded_segments());
     694          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          138 :     if ( comp != 0 )
     701            0 :         return comp;
     702              : 
     703          138 :     if (has_query())
     704              :     {
     705           48 :         comp = detail::compare_encoded_query(
     706           24 :             encoded_query(),
     707           24 :             other.encoded_query());
     708           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          119 :     if ( comp != 0 )
     716            0 :         return comp;
     717              : 
     718          119 :     if (has_fragment())
     719              :     {
     720           44 :         comp = detail::compare_encoded(
     721           22 :             encoded_fragment(),
     722           22 :             other.encoded_fragment());
     723           22 :         if ( comp != 0 )
     724           21 :             return comp;
     725              :     }
     726              : 
     727           98 :     return 0;
     728              : }
     729              : 
     730              : } // urls
     731              : } // boost
     732              : 
        

Generated by: LCOV version 2.1