LCOV - code coverage report
Current view: top level - url/impl - params_ref.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 98.3 % 116 114 2
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 27 27

           TLA  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                 : #ifndef BOOST_URL_IMPL_PARAMS_REF_HPP
      12                 : #define BOOST_URL_IMPL_PARAMS_REF_HPP
      13                 : 
      14                 : #include <boost/url/params_view.hpp>
      15                 : #include <boost/url/url_base.hpp>
      16                 : #include <boost/url/detail/any_params_iter.hpp>
      17                 : #include <boost/url/detail/except.hpp>
      18                 : #include <boost/url/grammar/ci_string.hpp>
      19                 : #include <boost/url/grammar/recycled.hpp>
      20                 : #include <boost/assert.hpp>
      21                 : #include <utility>
      22                 : 
      23                 : namespace boost {
      24                 : namespace urls {
      25                 : 
      26                 : template<class FwdIt>
      27                 : void
      28 HIT           8 : params_ref::
      29                 : assign(FwdIt first, FwdIt last)
      30                 : {
      31                 : /*  If you get a compile error here, it
      32                 :     means that the iterators you passed
      33                 :     do not meet the requirements stated
      34                 :     in the documentation.
      35                 : */
      36                 :     static_assert(
      37                 :         std::is_convertible<
      38                 :             typename std::iterator_traits<
      39                 :                 FwdIt>::reference,
      40                 :             param_view>::value,
      41                 :         "Type requirements not met");
      42                 : 
      43               8 :     assign(first, last,
      44                 :         typename std::iterator_traits<
      45                 :             FwdIt>::iterator_category{});
      46               8 : }
      47                 : 
      48                 : template<class FwdIt>
      49                 : auto
      50               4 : params_ref::
      51                 : append(FwdIt first, FwdIt last) ->
      52                 :     iterator
      53                 : {
      54                 : /*  If you get a compile error here, it
      55                 :     means that the iterators you passed
      56                 :     do not meet the requirements stated
      57                 :     in the documentation.
      58                 : */
      59                 :     static_assert(
      60                 :         std::is_convertible<
      61                 :             typename std::iterator_traits<
      62                 :                 FwdIt>::reference,
      63                 :             param_view>::value,
      64                 :         "Type requirements not met");
      65                 : 
      66               4 :     return insert(
      67               4 :         end(), first, last);
      68                 : }
      69                 : 
      70                 : template<class FwdIt>
      71                 : auto
      72              20 : params_ref::
      73                 : insert(
      74                 :     iterator before,
      75                 :     FwdIt first,
      76                 :     FwdIt last) ->
      77                 :         iterator
      78                 : {
      79                 : /*  If you get a compile error here, it
      80                 :     means that the iterators you passed
      81                 :     do not meet the requirements stated
      82                 :     in the documentation.
      83                 : */
      84                 :     static_assert(
      85                 :         std::is_convertible<
      86                 :             typename std::iterator_traits<
      87                 :                 FwdIt>::reference,
      88                 :             param_view>::value,
      89                 :         "Type requirements not met");
      90                 : 
      91              40 :     return insert(
      92                 :         before,
      93                 :         first,
      94                 :         last,
      95                 :         typename std::iterator_traits<
      96              40 :             FwdIt>::iterator_category{});
      97                 : }
      98                 : 
      99                 : template<class FwdIt>
     100                 : auto
     101               4 : params_ref::
     102                 : replace(
     103                 :     iterator from,
     104                 :     iterator to,
     105                 :     FwdIt first,
     106                 :     FwdIt last) ->
     107                 :         iterator
     108                 : {
     109                 : /*  If you get a compile error here, it
     110                 :     means that the iterators you passed
     111                 :     do not meet the requirements stated
     112                 :     in the documentation.
     113                 : */
     114                 :     static_assert(
     115                 :         std::is_convertible<
     116                 :             typename std::iterator_traits<
     117                 :                 FwdIt>::reference,
     118                 :             param_view>::value,
     119                 :         "Type requirements not met");
     120                 : 
     121                 :     return iterator(
     122               8 :         u_->edit_params(
     123                 :             from.it_, to.it_,
     124                 :             detail::make_params_iter(
     125               4 :                 first, last, opt_.space_as_plus)),
     126               8 :         opt_);
     127                 : }
     128                 : 
     129                 : //------------------------------------------------
     130                 : //
     131                 : // implementation
     132                 : //
     133                 : //------------------------------------------------
     134                 : 
     135                 : template<class FwdIt>
     136                 : void
     137               8 : params_ref::
     138                 : assign(FwdIt first, FwdIt last,
     139                 :     std::forward_iterator_tag)
     140                 : {
     141               8 :     u_->edit_params(
     142               8 :         begin().it_,
     143              16 :         end().it_,
     144                 :         detail::make_params_iter(
     145               8 :             first, last, opt_.space_as_plus));
     146               8 : }
     147                 : 
     148                 : template<class FwdIt>
     149                 : auto
     150              20 : params_ref::
     151                 : insert(
     152                 :     iterator before,
     153                 :     FwdIt first,
     154                 :     FwdIt last,
     155                 :     std::forward_iterator_tag) ->
     156                 :         iterator
     157                 : {
     158                 :     return iterator(
     159              40 :         u_->edit_params(
     160                 :             before.it_,
     161                 :             before.it_,
     162                 :             detail::make_params_iter(
     163              20 :                 first, last, opt_.space_as_plus)),
     164              40 :         opt_);
     165                 : }
     166                 : 
     167                 : //------------------------------------------------
     168                 : //
     169                 : // Special Members
     170                 : //
     171                 : //------------------------------------------------
     172                 : 
     173                 : inline
     174             100 : params_ref::
     175                 : params_ref(
     176                 :     url_base& u,
     177             100 :     encoding_opts opt) noexcept
     178             100 :     : params_base(u.impl_, opt)
     179             100 :     , u_(&u)
     180                 : {
     181             100 : }
     182                 : 
     183                 : inline
     184               1 : params_ref::
     185                 : params_ref(
     186                 :     params_ref const& other,
     187               1 :     encoding_opts opt) noexcept
     188               1 :     : params_base(other.u_->impl_, opt)
     189               1 :     , u_(other.u_)
     190                 : {
     191               1 : }
     192                 : 
     193                 : inline
     194                 : auto
     195               1 : params_ref::
     196                 : operator=(params_ref const& other) ->
     197                 :     params_ref&
     198                 : {
     199               1 :     if (!ref_.alias_of(other.ref_))
     200               1 :         assign(other.begin(), other.end());
     201               1 :     return *this;
     202                 : }
     203                 : 
     204                 : inline
     205                 : auto
     206               1 : params_ref::
     207                 : operator=(std::initializer_list<
     208                 :     param_view> init) ->
     209                 :         params_ref&
     210                 : {
     211               1 :     assign(init);
     212               1 :     return *this;
     213                 : }
     214                 : 
     215                 : inline
     216              63 : params_ref::
     217                 : operator
     218                 : params_view() const noexcept
     219                 : {
     220              63 :     return { ref_, opt_ };
     221                 : }
     222                 : 
     223                 : //------------------------------------------------
     224                 : //
     225                 : // Modifiers
     226                 : //
     227                 : //------------------------------------------------
     228                 : 
     229                 : inline
     230                 : void
     231               3 : params_ref::
     232                 : clear() noexcept
     233                 : {
     234               3 :     u_->remove_query();
     235               3 : }
     236                 : 
     237                 : inline
     238                 : void
     239               5 : params_ref::
     240                 : assign(
     241                 :     std::initializer_list<
     242                 :         param_view> init)
     243                 : {
     244               5 :     assign(init.begin(), init.end());
     245               5 : }
     246                 : 
     247                 : inline
     248                 : auto
     249              16 : params_ref::
     250                 : insert(
     251                 :     iterator before,
     252                 :     param_view const& p) ->
     253                 :         iterator
     254                 : {
     255                 :     return {
     256              16 :         u_->edit_params(
     257                 :             before.it_,
     258                 :             before.it_,
     259              32 :             detail::single_param_iter(p, opt_.space_as_plus)),
     260              32 :         opt_};
     261                 : }
     262                 : 
     263                 : inline
     264                 : auto
     265              16 : params_ref::
     266                 : insert(
     267                 :     iterator before,
     268                 :     std::initializer_list<
     269                 :         param_view> init) ->
     270                 :     iterator
     271                 : {
     272              16 :     return insert(
     273                 :         before,
     274                 :         init.begin(),
     275              16 :         init.end());
     276                 : }
     277                 : 
     278                 : inline
     279                 : auto
     280              12 : params_ref::
     281                 : append(
     282                 :     param_view const& p) ->
     283                 :         iterator
     284                 : {
     285              12 :     return insert(end(), p);
     286                 : }
     287                 : 
     288                 : inline
     289                 : auto
     290               6 : params_ref::
     291                 : append(
     292                 :     std::initializer_list<
     293                 :         param_view> init) ->
     294                 :     iterator
     295                 : {
     296               6 :     return insert(end(), init);
     297                 : }
     298                 : 
     299                 : inline
     300                 : std::size_t
     301               2 : params_ref::
     302                 : erase(
     303                 :     core::string_view key,
     304                 :     ignore_case_param ic) noexcept
     305                 : {
     306                 :     // end() can't be fully cached,
     307                 :     // since erase invalidates it.
     308               2 :     iterator it;
     309                 :     {
     310               2 :         auto const end_ = end();
     311               2 :         it = find_last(end_, key, ic);
     312               2 :         if(it == end_)
     313 MIS           0 :             return 0;
     314                 :     }
     315 HIT           2 :     std::size_t n = 0;
     316                 :     for(;;)
     317                 :     {
     318               5 :         ++n;
     319                 :         // Use it->key instead of key,
     320                 :         // to handle self-intersection
     321               5 :         auto prev = find_last(it, (*it).key, ic);
     322               5 :         if(prev == end())
     323               2 :             break;
     324               3 :         erase(it);
     325               3 :         it = prev;
     326               3 :     }
     327               2 :     erase(it);
     328               2 :     return n;
     329                 : }
     330                 : 
     331                 : inline
     332                 : auto
     333               8 : params_ref::
     334                 : replace(
     335                 :     iterator pos,
     336                 :     param_view const& p) ->
     337                 :         iterator
     338                 : {
     339                 :     return iterator(
     340              24 :         u_->edit_params(
     341                 :             pos.it_,
     342               8 :             std::next(pos).it_,
     343              16 :             detail::single_param_iter(p, opt_.space_as_plus)),
     344              16 :         opt_);
     345                 : }
     346                 : 
     347                 : inline
     348                 : auto
     349               2 : params_ref::
     350                 : replace(
     351                 :     iterator from,
     352                 :     iterator to,
     353                 :     std::initializer_list<
     354                 :         param_view> init) ->
     355                 :     iterator
     356                 : {
     357               2 :     return replace(
     358                 :         from,
     359                 :         to,
     360                 :         init.begin(),
     361               2 :         init.end());
     362                 : }
     363                 : 
     364                 : inline
     365                 : auto
     366               4 : params_ref::
     367                 : unset(
     368                 :     iterator pos) noexcept ->
     369                 :         iterator
     370                 : {
     371               4 :     BOOST_ASSERT(pos.it_.nk > 0);
     372               4 :     core::string_view s;
     373                 :     return iterator(
     374               4 :         u_->edit_params(
     375                 :             pos.it_,
     376               4 :             pos.it_.next(),
     377               4 :             detail::param_value_iter(
     378               4 :                 pos.it_.nk - 1, s, false)),
     379               4 :         opt_);
     380                 : }
     381                 : 
     382                 : inline
     383                 : auto
     384               5 : params_ref::
     385                 : set(
     386                 :     iterator pos,
     387                 :     core::string_view value) ->
     388                 :         iterator
     389                 : {
     390               5 :     BOOST_ASSERT(pos.it_.nk > 0);
     391                 :     return iterator(
     392               5 :         u_->edit_params(
     393                 :             pos.it_,
     394               5 :             pos.it_.next(),
     395               5 :             detail::param_value_iter(
     396               5 :                 pos.it_.nk - 1, value, true)),
     397              10 :         opt_);
     398                 : }
     399                 : 
     400                 : inline
     401                 : auto
     402               1 : params_ref::
     403                 : set(
     404                 :     core::string_view key,
     405                 :     core::string_view value,
     406                 :     ignore_case_param ic) ->
     407                 :         iterator
     408                 : {
     409                 :     // VFALCO we can't cache end() here
     410                 :     // because it is invalidated
     411                 :     // every time we set or erase.
     412               1 :     auto it0 = find(key, ic);
     413               1 :     if(it0 == end())
     414 MIS           0 :         return append({key, value});
     415 HIT           1 :     it0 = set(it0, value);
     416               1 :     auto it = end();
     417                 :     for(;;)
     418                 :     {
     419               2 :         it = find_last(it, key, ic);
     420               2 :         if(it == it0)
     421               1 :             return it0;
     422               1 :         it = erase(it);
     423                 :     }
     424                 : }
     425                 : 
     426                 : inline
     427                 : auto
     428               9 : params_ref::
     429                 : erase(
     430                 :     iterator pos) noexcept ->
     431                 :     iterator
     432                 : {
     433               9 :     return erase(
     434                 :         pos,
     435               9 :         std::next(pos));
     436                 : }
     437                 : 
     438                 : inline
     439                 : auto
     440              11 : params_ref::
     441                 : erase(
     442                 :     iterator first,
     443                 :     iterator last) noexcept ->
     444                 :         iterator
     445                 : {
     446              11 :     core::string_view s("", 0);
     447                 :     return iterator(
     448              11 :         u_->edit_params(
     449                 :             first.it_,
     450                 :             last.it_,
     451              22 :             detail::query_string_iter(s)),
     452              11 :         opt_);
     453                 : }
     454                 : 
     455                 : } // urls
     456                 : } // boost
     457                 : 
     458                 : #endif
        

Generated by: LCOV version 2.3