LCOV - code coverage report
Current view: top level - libs/url/src - url_view_base.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 304 314 96.8 %
Date: 2024-04-08 19:38:36 Functions: 40 42 95.2 %

          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        4090 : url_view_base::
      24        4090 : url_view_base() noexcept
      25             :     : impl_(from::url)
      26        4090 :     , pi_(&impl_)
      27             : {
      28        4090 : }
      29             : 
      30             : // construct reference
      31       20785 : url_view_base::
      32             : url_view_base(
      33       20785 :     detail::url_impl const& impl) noexcept
      34             :     : impl_(impl)
      35       20785 :     , pi_(&impl_)
      36             : {
      37       20785 : }
      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           4 :     Alloc a;
      88             :     auto p = std::allocate_shared<T>(
      89           2 :         detail::over_allocator<T, Alloc>(
      90           6 :             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             : }
      96             : 
      97             : //------------------------------------------------
      98             : //
      99             : // Scheme
     100             : //
     101             : //------------------------------------------------
     102             : 
     103             : bool
     104        2836 : url_view_base::
     105             : has_scheme() const noexcept
     106             : {
     107        2836 :     auto const n = pi_->len(
     108             :         id_scheme);
     109        2836 :     if(n == 0)
     110         579 :         return false;
     111        2257 :     BOOST_ASSERT(n > 1);
     112        2257 :     BOOST_ASSERT(
     113             :         pi_->get(id_scheme
     114             :             ).ends_with(':'));
     115        2257 :     return true;
     116             : }
     117             : 
     118             : core::string_view
     119        1432 : url_view_base::
     120             : scheme() const noexcept
     121             : {
     122        1432 :     auto s = pi_->get(id_scheme);
     123        1432 :     if(! s.empty())
     124             :     {
     125        1336 :         BOOST_ASSERT(s.size() > 1);
     126        1336 :         BOOST_ASSERT(s.ends_with(':'));
     127        1336 :         s.remove_suffix(1);
     128             :     }
     129        1432 :     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         479 : url_view_base::
     147             : authority() const noexcept
     148             : {
     149         479 :     detail::url_impl u(from::authority);
     150         479 :     u.cs_ = encoded_authority().data();
     151         479 :     if(has_authority())
     152             :     {
     153         479 :         u.set_size(id_user, pi_->len(id_user) - 2);
     154         479 :         u.set_size(id_pass, pi_->len(id_pass));
     155         479 :         u.set_size(id_host, pi_->len(id_host));
     156         479 :         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         479 :     u.decoded_[id_user] = pi_->decoded_[id_user];
     166         479 :     u.decoded_[id_pass] = pi_->decoded_[id_pass];
     167         479 :     u.decoded_[id_host] = pi_->decoded_[id_host];
     168        8143 :     for (int i = 0; i < 16; ++i)
     169        7664 :         u.ip_addr_[i] = pi_->ip_addr_[i];
     170         479 :     u.port_number_ = pi_->port_number_;
     171         479 :     u.host_type_ = pi_->host_type_;
     172         479 :     return u.construct_authority();
     173             : }
     174             : 
     175             : pct_string_view
     176         637 : url_view_base::
     177             : encoded_authority() const noexcept
     178             : {
     179         637 :     auto s = pi_->get(id_user, id_path);
     180         637 :     if(! s.empty())
     181             :     {
     182         597 :         BOOST_ASSERT(has_authority());
     183         597 :         s.remove_prefix(2);
     184             :     }
     185             :     return make_pct_string_view_unsafe(
     186             :         s.data(),
     187             :         s.size(),
     188         637 :         pi_->decoded_[id_user] +
     189         637 :             pi_->decoded_[id_pass] +
     190         637 :             pi_->decoded_[id_host] +
     191         637 :             pi_->decoded_[id_port] +
     192         637 :             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         772 : url_view_base::
     216             : has_password() const noexcept
     217             : {
     218         772 :     auto const n = pi_->len(id_pass);
     219         772 :     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         658 :     BOOST_ASSERT(n == 0 || pi_->get(
     228             :         id_pass).ends_with('@'));
     229         658 :     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         119 :         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             :     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          77 :             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             :     return make_pct_string_view_unsafe(
     268             :         s.data(),
     269             :         s.size(),
     270         131 :         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             :         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             :     return make_pct_string_view_unsafe(
     294          52 :         s.data() + 1,
     295          52 :         s.size() - 2,
     296          52 :         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         521 : url_view_base::
     321             : encoded_host() const noexcept
     322             : {
     323         521 :     return pi_->pct_get(id_host);
     324             : }
     325             : 
     326             : pct_string_view
     327         117 : url_view_base::
     328             : encoded_host_address() const noexcept
     329             : {
     330         117 :     core::string_view s = pi_->get(id_host);
     331             :     std::size_t n;
     332         117 :     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          23 :     case urls::host_type::ipv6:
     346             :     case urls::host_type::ipvfuture:
     347             :     {
     348          23 :         BOOST_ASSERT(
     349             :             pi_->decoded_[id_host] ==
     350             :                 s.size());
     351          23 :         BOOST_ASSERT(s.size() >= 2);
     352          23 :         BOOST_ASSERT(s.front() == '[');
     353          23 :         BOOST_ASSERT(s.back() == ']');
     354          23 :         s = s.substr(1, s.size() - 2);
     355          23 :         n = pi_->decoded_[id_host] - 2;
     356          23 :         break;
     357             :     }
     358             :     }
     359             :     return make_pct_string_view_unsafe(
     360             :         s.data(),
     361             :         s.size(),
     362         117 :         n);
     363             : }
     364             : 
     365             : urls::ipv4_address
     366          51 : url_view_base::
     367             : host_ipv4_address() const noexcept
     368             : {
     369          51 :     if(pi_->host_type_ !=
     370             :             urls::host_type::ipv4)
     371          35 :         return {};
     372          16 :     ipv4_address::bytes_type b{{}};
     373          16 :     std::memcpy(
     374          16 :         &b[0], &pi_->ip_addr_[0], b.size());
     375          16 :     return urls::ipv4_address(b);
     376             : }
     377             : 
     378             : urls::ipv6_address
     379          51 : url_view_base::
     380             : host_ipv6_address() const noexcept
     381             : {
     382          51 :     if(pi_->host_type_ !=
     383             :             urls::host_type::ipv6)
     384          43 :         return {};
     385           8 :     ipv6_address::bytes_type b{{}};
     386           8 :     std::memcpy(
     387           8 :         &b[0], &pi_->ip_addr_[0], b.size());
     388           8 :     return urls::ipv6_address(b);
     389             : }
     390             : 
     391             : core::string_view
     392          51 : url_view_base::
     393             : host_ipvfuture() const noexcept
     394             : {
     395          51 :     if(pi_->host_type_ !=
     396             :             urls::host_type::ipvfuture)
     397          44 :         return {};
     398           7 :     core::string_view s = pi_->get(id_host);
     399           7 :     BOOST_ASSERT(s.size() >= 6);
     400           7 :     BOOST_ASSERT(s.front() == '[');
     401           7 :     BOOST_ASSERT(s.back() == ']');
     402           7 :     s = s.substr(1, s.size() - 2);
     403           7 :     return s;
     404             : }
     405             : 
     406             : pct_string_view
     407         146 : url_view_base::
     408             : encoded_host_name() const noexcept
     409             : {
     410         146 :     if(pi_->host_type_ !=
     411             :             urls::host_type::name)
     412          78 :         return {};
     413          68 :     core::string_view s = pi_->get(id_host);
     414             :     return make_pct_string_view_unsafe(
     415             :         s.data(),
     416             :         s.size(),
     417          68 :         pi_->decoded_[id_host]);
     418             : }
     419             : 
     420             : pct_string_view
     421          10 : url_view_base::
     422             : encoded_zone_id() const noexcept
     423             : {
     424          10 :     if(pi_->host_type_ !=
     425             :         urls::host_type::ipv6)
     426           2 :         return {};
     427           8 :     core::string_view s = pi_->get(id_host);
     428           8 :     BOOST_ASSERT(s.front() == '[');
     429           8 :     BOOST_ASSERT(s.back() == ']');
     430           8 :     s = s.substr(1, s.size() - 2);
     431           8 :     auto pos = s.find("%25");
     432           8 :     if (pos == core::string_view::npos)
     433           2 :         return {};
     434           6 :     s.remove_prefix(pos + 3);
     435           6 :     return *make_pct_string_view(s);
     436             : }
     437             : 
     438             : //------------------------------------------------
     439             : 
     440             : bool
     441         364 : url_view_base::
     442             : has_port() const noexcept
     443             : {
     444         364 :     auto const n = pi_->len(id_port);
     445         364 :     if(n == 0)
     446          87 :         return false;
     447         277 :     BOOST_ASSERT(
     448             :         pi_->get(id_port).starts_with(':'));
     449         277 :     return true;
     450             : }
     451             : 
     452             : core::string_view
     453         179 : url_view_base::
     454             : port() const noexcept
     455             : {
     456         179 :     auto s = pi_->get(id_port);
     457         179 :     if(s.empty())
     458          58 :         return s;
     459         121 :     BOOST_ASSERT(has_port());
     460         121 :     return s.substr(1);
     461             : }
     462             : 
     463             : std::uint16_t
     464         101 : url_view_base::
     465             : port_number() const noexcept
     466             : {
     467         101 :     BOOST_ASSERT(
     468             :         has_port() ||
     469             :         pi_->port_number_ == 0);
     470         101 :     return pi_->port_number_;
     471             : }
     472             : 
     473             : //------------------------------------------------
     474             : //
     475             : // Path
     476             : //
     477             : //------------------------------------------------
     478             : 
     479             : pct_string_view
     480        1314 : url_view_base::
     481             : encoded_path() const noexcept
     482             : {
     483        1314 :     return pi_->pct_get(id_path);
     484             : }
     485             : 
     486             : segments_view
     487          45 : url_view_base::
     488             : segments() const noexcept
     489             : {
     490          45 :     return {detail::path_ref(*pi_)};
     491             : }
     492             : 
     493             : segments_encoded_view
     494         659 : url_view_base::
     495             : encoded_segments() const noexcept
     496             : {
     497             :     return segments_encoded_view(
     498         659 :         detail::path_ref(*pi_));
     499             : }
     500             : 
     501             : //------------------------------------------------
     502             : //
     503             : // Query
     504             : //
     505             : //------------------------------------------------
     506             : 
     507             : bool
     508         731 : url_view_base::
     509             : has_query() const noexcept
     510             : {
     511         731 :     auto const n = pi_->len(
     512             :         id_query);
     513         731 :     if(n == 0)
     514         613 :         return false;
     515         118 :     BOOST_ASSERT(
     516             :         pi_->get(id_query).
     517             :             starts_with('?'));
     518         118 :     return true;
     519             : }
     520             : 
     521             : pct_string_view
     522         274 : url_view_base::
     523             : encoded_query() const noexcept
     524             : {
     525         274 :     auto s = pi_->get(id_query);
     526         274 :     if(s.empty())
     527          10 :         return s;
     528         264 :     BOOST_ASSERT(
     529             :         s.starts_with('?'));
     530         264 :     return s.substr(1);
     531             : }
     532             : 
     533             : params_encoded_view
     534          55 : url_view_base::
     535             : encoded_params() const noexcept
     536             : {
     537          55 :     return params_encoded_view(*pi_);
     538             : }
     539             : 
     540             : params_view
     541          46 : url_view_base::
     542             : params() const noexcept
     543             : {
     544             :     return params_view(
     545          46 :         *pi_,
     546             :         encoding_opts{
     547          46 :             true,false,false});
     548             : }
     549             : 
     550             : params_view
     551           0 : url_view_base::
     552             : params(encoding_opts opt) const noexcept
     553             : {
     554           0 :     return params_view(*pi_, opt);
     555             : }
     556             : 
     557             : //------------------------------------------------
     558             : //
     559             : // Fragment
     560             : //
     561             : //------------------------------------------------
     562             : 
     563             : bool
     564         639 : url_view_base::
     565             : has_fragment() const noexcept
     566             : {
     567         639 :     auto const n = pi_->len(id_frag);
     568         639 :     if(n == 0)
     569         514 :         return false;
     570         125 :     BOOST_ASSERT(
     571             :         pi_->get(id_frag).
     572             :             starts_with('#'));
     573         125 :     return true;
     574             : }
     575             : 
     576             : pct_string_view
     577         155 : url_view_base::
     578             : encoded_fragment() const noexcept
     579             : {
     580         155 :     auto s = pi_->get(id_frag);
     581         155 :     if(! s.empty())
     582             :     {
     583         153 :         BOOST_ASSERT(
     584             :             s.starts_with('#'));
     585         153 :         s.remove_prefix(1);
     586             :     }
     587             :     return make_pct_string_view_unsafe(
     588             :         s.data(),
     589             :         s.size(),
     590         155 :         pi_->decoded_[id_frag]);
     591             : }
     592             : 
     593             : //------------------------------------------------
     594             : //
     595             : // Compound Fields
     596             : //
     597             : //------------------------------------------------
     598             : 
     599             : pct_string_view
     600         120 : url_view_base::
     601             : encoded_host_and_port() const noexcept
     602             : {
     603         120 :     return pi_->pct_get(id_host, id_path);
     604             : }
     605             : 
     606             : pct_string_view
     607          16 : url_view_base::
     608             : encoded_origin() const noexcept
     609             : {
     610          16 :     if(pi_->len(id_user) < 2)
     611          14 :         return {};
     612           2 :     return pi_->get(id_scheme, id_path);
     613             : }
     614             : 
     615             : pct_string_view
     616           1 : url_view_base::
     617             : encoded_resource() const noexcept
     618             : {
     619           1 :     auto n =
     620           1 :         pi_->decoded_[id_path] +
     621           1 :         pi_->decoded_[id_query] +
     622           1 :         pi_->decoded_[id_frag];
     623           1 :     if(has_query())
     624           1 :         ++n;
     625           1 :     if(has_fragment())
     626           1 :         ++n;
     627           1 :     BOOST_ASSERT(pct_string_view(
     628             :         pi_->get(id_path, id_end)
     629             :             ).decoded_size() == n);
     630           1 :     auto s = pi_->get(id_path, id_end);
     631             :     return make_pct_string_view_unsafe(
     632           1 :         s.data(), s.size(), n);
     633             : }
     634             : 
     635             : pct_string_view
     636           2 : url_view_base::
     637             : encoded_target() const noexcept
     638             : {
     639           2 :     auto n =
     640           2 :         pi_->decoded_[id_path] +
     641           2 :         pi_->decoded_[id_query];
     642           2 :     if(has_query())
     643           1 :         ++n;
     644           2 :     BOOST_ASSERT(pct_string_view(
     645             :         pi_->get(id_path, id_frag)
     646             :             ).decoded_size() == n);
     647           2 :     auto s = pi_->get(id_path, id_frag);
     648             :     return make_pct_string_view_unsafe(
     649           2 :         s.data(), s.size(), n);
     650             : }
     651             : 
     652             : //------------------------------------------------
     653             : //
     654             : // Comparisons
     655             : //
     656             : //------------------------------------------------
     657             : 
     658             : int
     659         276 : url_view_base::
     660             : compare(const url_view_base& other) const noexcept
     661             : {
     662             :     int comp =
     663         276 :         static_cast<int>(has_scheme()) -
     664         276 :         static_cast<int>(other.has_scheme());
     665         276 :     if ( comp != 0 )
     666           0 :         return comp;
     667             : 
     668         276 :     if (has_scheme())
     669             :     {
     670         196 :         comp = detail::ci_compare(
     671             :             scheme(),
     672             :             other.scheme());
     673         196 :         if ( comp != 0 )
     674          14 :             return comp;
     675             :     }
     676             : 
     677         262 :     comp =
     678         262 :         static_cast<int>(has_authority()) -
     679         262 :         static_cast<int>(other.has_authority());
     680         262 :     if ( comp != 0 )
     681           0 :         return comp;
     682             : 
     683         262 :     if (has_authority())
     684             :     {
     685         182 :         comp = authority().compare(other.authority());
     686         182 :         if ( comp != 0 )
     687          89 :             return comp;
     688             :     }
     689             : 
     690         173 :     comp = detail::segments_compare(
     691             :         encoded_segments(),
     692             :         other.encoded_segments());
     693         173 :     if ( comp != 0 )
     694          43 :         return comp;
     695             : 
     696         130 :     comp =
     697         130 :         static_cast<int>(has_query()) -
     698         130 :         static_cast<int>(other.has_query());
     699         130 :     if ( comp != 0 )
     700           0 :         return comp;
     701             : 
     702         130 :     if (has_query())
     703             :     {
     704          34 :         comp = detail::compare_encoded(
     705          17 :             encoded_query(),
     706          17 :             other.encoded_query());
     707          17 :         if ( comp != 0 )
     708          14 :             return comp;
     709             :     }
     710             : 
     711         116 :     comp =
     712         116 :         static_cast<int>(has_fragment()) -
     713         116 :         static_cast<int>(other.has_fragment());
     714         116 :     if ( comp != 0 )
     715           0 :         return comp;
     716             : 
     717         116 :     if (has_fragment())
     718             :     {
     719          44 :         comp = detail::compare_encoded(
     720          22 :             encoded_fragment(),
     721          22 :             other.encoded_fragment());
     722          22 :         if ( comp != 0 )
     723          21 :             return comp;
     724             :     }
     725             : 
     726          95 :     return 0;
     727             : }
     728             : 
     729             : } // urls
     730             : } // boost
     731             : 

Generated by: LCOV version 1.15