LCOV - code coverage report
Current view: top level - boost/url/param.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 90 90
Test Date: 2025-04-22 15:26:24 Functions: 98.1 % 53 52

            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_PARAM_HPP
      12              : #define BOOST_URL_PARAM_HPP
      13              : 
      14              : #include <boost/url/detail/config.hpp>
      15              : #include <boost/url/detail/optional_string.hpp>
      16              : #include <boost/url/pct_string_view.hpp>
      17              : #include <cstddef>
      18              : #include <string>
      19              : 
      20              : namespace boost {
      21              : namespace urls {
      22              : 
      23              : #ifndef BOOST_URL_DOCS
      24              : struct param_pct_view;
      25              : struct param_view;
      26              : #endif
      27              : 
      28              : /** The type of @ref no_value
      29              : */
      30              : struct no_value_t
      31              : {
      32              : };
      33              : 
      34              : /** Constant indicating no value in a param
      35              : */
      36              : constexpr no_value_t no_value{};
      37              : 
      38              : //------------------------------------------------
      39              : 
      40              : /** A query parameter
      41              : 
      42              :     Objects of this type represent a single key
      43              :     and value pair in a query string where a key
      44              :     is always present and may be empty, while the
      45              :     presence of a value is indicated by
      46              :     @ref has_value equal to true.
      47              :     An empty value is distinct from no value.
      48              : 
      49              :     Depending on where the object was obtained,
      50              :     the strings may or may not contain percent
      51              :     escapes.
      52              : 
      53              :     For most usages, key comparisons are
      54              :     case-sensitive and duplicate keys in
      55              :     a query are possible. However, it is
      56              :     the authority that has final control
      57              :     over how the query is interpreted.
      58              : 
      59              :     @par BNF
      60              :     @code
      61              :     query-params    = query-param *( "&" query-param )
      62              :     query-param     = key [ "=" value ]
      63              :     key             = *qpchar
      64              :     value           = *( qpchar / "=" )
      65              :     @endcode
      66              : 
      67              :     @par Specification
      68              :     @li <a href="https://en.wikipedia.org/wiki/Query_string"
      69              :         >Query string (Wikipedia)</a>
      70              : 
      71              :     @see
      72              :         @ref param_view,
      73              :         @ref param_pct_view.
      74              : */
      75              : struct param
      76              : {
      77              :     /** The key
      78              : 
      79              :         For most usages, key comparisons are
      80              :         case-sensitive and duplicate keys in
      81              :         a query are possible. However, it is
      82              :         the authority that has final control
      83              :         over how the query is interpreted.
      84              :     */
      85              :     std::string key;
      86              : 
      87              :     /** The value
      88              : 
      89              :         The presence of a value is indicated by
      90              :         @ref has_value equal to true.
      91              :         An empty value is distinct from no value.
      92              :     */
      93              :     std::string value;
      94              : 
      95              :     /** True if a value is present
      96              : 
      97              :         The presence of a value is indicated by
      98              :         `has_value == true`.
      99              :         An empty value is distinct from no value.
     100              :     */
     101              :     bool has_value = false;
     102              : 
     103              :     /** Constructor
     104              : 
     105              :         Default constructed query parameters
     106              :         have an empty key and no value.
     107              : 
     108              :         @par Example
     109              :         @code
     110              :         param qp;
     111              :         @endcode
     112              : 
     113              :         @par Postconditions
     114              :         @code
     115              :         this->key == "" && this->value == "" && this->has_value == false
     116              :         @endcode
     117              : 
     118              :         @par Complexity
     119              :         Constant.
     120              : 
     121              :         @par Exception Safety
     122              :         Throws nothing.
     123              :     */
     124            6 :     param() = default;
     125              : 
     126              :     /** Constructor
     127              : 
     128              :         Upon construction, this acquires
     129              :         ownership of the members of other
     130              :         via move construction. The moved
     131              :         from object is as if default
     132              :         constructed.
     133              : 
     134              :         @par Complexity
     135              :         Constant.
     136              : 
     137              :         @par Exception Safety
     138              :         Throws nothing.
     139              : 
     140              :         @param other The object to construct from.
     141              :     */
     142            1 :     param(param&& other) noexcept
     143            1 :         : key(std::move(other.key))
     144            1 :         , value(std::move(other.value))
     145            1 :         , has_value(other.has_value)
     146              :     {
     147              :     #ifdef BOOST_URL_COW_STRINGS
     148              :         // for copy-on-write std::string
     149              :         other.key.clear();
     150              :         other.value.clear();
     151              :     #endif
     152            1 :         other.has_value = false;
     153            1 :     }
     154              : 
     155              :     /** Constructor
     156              : 
     157              :         Upon construction, this becomes a copy
     158              :         of `other`.
     159              : 
     160              :         @par Postconditions
     161              :         @code
     162              :         this->key == other.key && this->value == other.value && this->has_value == other.has_value
     163              :         @endcode
     164              : 
     165              :         @par Complexity
     166              :         Linear in `other.key.size() + other.value.size()`.
     167              : 
     168              :         @par Exception Safety
     169              :         Calls to allocate may throw.
     170              : 
     171              :         @param other The object to construct from.
     172              :         @return A reference to this object.
     173              :     */
     174            2 :     param(param const& other) = default;
     175              : 
     176              :     /** Assignment
     177              : 
     178              :         Upon assignment, this acquires
     179              :         ownership of the members of other
     180              :         via move assignment. The moved
     181              :         from object is as if default
     182              :         constructed.
     183              : 
     184              :         @par Complexity
     185              :         Constant.
     186              : 
     187              :         @par Exception Safety
     188              :         Throws nothing.
     189              : 
     190              : 
     191              :         @param other The object to assign from.
     192              :         @return A reference to this object.
     193              :     */
     194              :     param&
     195            3 :     operator=(param&& other) noexcept
     196              :     {
     197            3 :         key = std::move(other.key);
     198            3 :         value = std::move(other.value);
     199            3 :         has_value = other.has_value;
     200              :     #ifdef BOOST_URL_COW_STRINGS
     201              :         // for copy-on-write std::string
     202              :         other.key.clear();
     203              :         other.value.clear();
     204              :     #endif
     205            3 :         other.has_value = false;
     206            3 :         return *this;
     207              :     }
     208              : 
     209              :     /** Assignment
     210              : 
     211              :         Upon assignment, this becomes a copy
     212              :         of `other`.
     213              : 
     214              :         @par Postconditions
     215              :         @code
     216              :         this->key == other.key && this->value == other.value && this->has_value == other.has_value
     217              :         @endcode
     218              : 
     219              :         @par Complexity
     220              :         Linear in `other.key.size() + other.value.size()`.
     221              : 
     222              :         @par Exception Safety
     223              :         Calls to allocate may throw.
     224              : 
     225              : 
     226              :         @param other The object to assign from.
     227              :         @return A reference to this object.
     228              :     */
     229            1 :     param& operator=(
     230              :         param const& other) = default;
     231              : 
     232              :     //--------------------------------------------
     233              : 
     234              :     /** Constructor
     235              : 
     236              :         This constructs a parameter with a key
     237              :         and value.
     238              : 
     239              :         No validation is performed on the strings.
     240              :         Ownership of the key and value is acquired
     241              :         by making copies.
     242              : 
     243              :         @par Example
     244              :         @code
     245              :         param qp( "key", "value" );
     246              :         @endcode
     247              : 
     248              :         @code
     249              :         param qp( "key", optional<core::string_view>("value") );
     250              :         @endcode
     251              : 
     252              :         @code
     253              :         param qp( "key", boost::none );
     254              :         @endcode
     255              : 
     256              :         @code
     257              :         param qp( "key", nullptr );
     258              :         @endcode
     259              : 
     260              :         @code
     261              :         param qp( "key", no_value );
     262              :         @endcode
     263              : 
     264              :         @par Postconditions
     265              :         @code
     266              :         this->key == key && this->value == value && this->has_value == true
     267              :         @endcode
     268              : 
     269              :         @par Complexity
     270              :         Linear in `key.size() + value.size()`.
     271              : 
     272              :         @par Exception Safety
     273              :         Calls to allocate may throw.
     274              : 
     275              :         @tparam OptionalString An optional string
     276              :         type, such as `core::string_view`,
     277              :         `std::nullptr`, @ref no_value_t, or
     278              :         `optional<core::string_view>`.
     279              : 
     280              :         @param key The key to set.
     281              :         @param value The value to set.
     282              :     */
     283              :     template <class OptionalString>
     284           16 :     param(
     285              :         core::string_view key,
     286              :         OptionalString const& value)
     287           16 :         : param(key, detail::get_optional_string(value))
     288              :     {
     289           16 :     }
     290              : 
     291              :     /** Assignment
     292              : 
     293              :         The members of `other` are copied,
     294              :         re-using already existing string capacity.
     295              : 
     296              :         @par Postconditions
     297              :         @code
     298              :         this->key == other.key && this->value == other.value && this->has_value == other.has_value
     299              :         @endcode
     300              : 
     301              :         @par Complexity
     302              :         Linear in `other.key.size() + other.value.size()`.
     303              : 
     304              :         @par Exception Safety
     305              :         Calls to allocate may throw.
     306              : 
     307              :         @param other The parameter to copy.
     308              :         @return A reference to this object.
     309              :     */
     310              :     param&
     311              :     operator=(param_view const& other);
     312              : 
     313              :     /** Assignment
     314              : 
     315              :         The members of `other` are copied,
     316              :         re-using already existing string capacity.
     317              : 
     318              :         @par Postconditions
     319              :         @code
     320              :         this->key == other.key && this->value == other.value && this->has_value == other.has_value
     321              :         @endcode
     322              : 
     323              :         @par Complexity
     324              :         Linear in `other.key.size() + other.value.size()`.
     325              : 
     326              :         @par Exception Safety
     327              :         Calls to allocate may throw.
     328              : 
     329              :         @param other The parameter to copy.
     330              :         @return A reference to this object.
     331              :     */
     332              :     param&
     333              :     operator=(param_pct_view const& other);
     334              : 
     335              :     /** Arrow support
     336              : 
     337              :         This operator returns the address of the
     338              :         object so that it can be used in pointer
     339              :         contexts.
     340              : 
     341              :         @return A pointer to the object.
     342              : 
     343              :      */
     344              :     param const*
     345            1 :     operator->() const noexcept
     346              :     {
     347            1 :         return this;
     348              :     }
     349              : 
     350              :     /** Aggregate construction
     351              : 
     352              :         @param key The key to set.
     353              :         @param value The value to set.
     354              :         @param has_value True if a value is present.
     355              :      */
     356          794 :     param(
     357              :         core::string_view key,
     358              :         core::string_view value,
     359              :         bool has_value) noexcept
     360          794 :         : key(key)
     361          794 :         , value(has_value
     362          794 :             ? value
     363              :             : core::string_view())
     364          794 :         , has_value(has_value)
     365              :     {
     366          794 :     }
     367              : 
     368              : private:
     369           16 :     param(
     370              :         core::string_view key,
     371              :         detail::optional_string const& value)
     372           16 :         : param(key, value.s, value.b)
     373              :     {
     374           16 :     }
     375              : };
     376              : 
     377              : //------------------------------------------------
     378              : 
     379              : /** A view of a query parameter
     380              : 
     381              :     Objects of this type represent a single key
     382              :     and value pair in a query string where a key
     383              :     is always present and may be empty, while the
     384              :     presence of a value is indicated by
     385              :     @ref has_value equal to true.
     386              :     An empty value is distinct from no value.
     387              : 
     388              :     Depending on where the object was obtained,
     389              :     the strings may or may not contain percent
     390              :     escapes.
     391              : 
     392              :     For most usages, key comparisons are
     393              :     case-sensitive and duplicate keys in
     394              :     a query are possible. However, it is
     395              :     the authority that has final control
     396              :     over how the query is interpreted.
     397              : 
     398              :     <br>
     399              : 
     400              :     Keys and values in this object reference
     401              :     external character buffers.
     402              :     Ownership of the buffers is not transferred;
     403              :     the caller is responsible for ensuring that
     404              :     the assigned buffers remain valid until
     405              :     they are no longer referenced.
     406              : 
     407              :     @par BNF
     408              :     @code
     409              :     query-params    = query-param *( "&" query-param )
     410              :     query-param     = key [ "=" value ]
     411              :     key             = *qpchar
     412              :     value           = *( qpchar / "=" )
     413              :     @endcode
     414              : 
     415              :     @par Specification
     416              :     @li <a href="https://en.wikipedia.org/wiki/Query_string"
     417              :         >Query string (Wikipedia)</a>
     418              : 
     419              :     @see
     420              :         @ref param,
     421              :         @ref param_pct_view.
     422              : */
     423              : struct param_view
     424              : {
     425              :     /** The key
     426              : 
     427              :         For most usages, key comparisons are
     428              :         case-sensitive and duplicate keys in
     429              :         a query are possible. However, it is
     430              :         the authority that has final control
     431              :         over how the query is interpreted.
     432              :     */
     433              :     core::string_view key;
     434              : 
     435              :     /** The value
     436              : 
     437              :         The presence of a value is indicated by
     438              :         @ref has_value equal to true.
     439              :         An empty value is distinct from no value.
     440              :     */
     441              :     core::string_view value;
     442              : 
     443              :     /** True if a value is present
     444              : 
     445              :         The presence of a value is indicated by
     446              :         `has_value == true`.
     447              :         An empty value is distinct from no value.
     448              :     */
     449              :     bool has_value = false;
     450              : 
     451              :     //--------------------------------------------
     452              : 
     453              :     /** Constructor
     454              : 
     455              :         Default constructed query parameters
     456              :         have an empty key and no value.
     457              : 
     458              :         @par Example
     459              :         @code
     460              :         param_view qp;
     461              :         @endcode
     462              : 
     463              :         @par Postconditions
     464              :         @code
     465              :         this->key == "" && this->value == "" && this->has_value == false
     466              :         @endcode
     467              : 
     468              :         @par Complexity
     469              :         Constant.
     470              : 
     471              :         @par Exception Safety
     472              :         Throws nothing.
     473              :     */
     474              :     param_view() = default;
     475              : 
     476              :     /** Constructor
     477              : 
     478              :         This constructs a parameter with a key
     479              :         and value.
     480              :         No validation is performed on the strings.
     481              :         The new key and value reference
     482              :         the same corresponding underlying
     483              :         character buffers.
     484              :         Ownership of the buffers is not transferred;
     485              :         the caller is responsible for ensuring that
     486              :         the assigned buffers remain valid until
     487              :         they are no longer referenced.
     488              : 
     489              :         @par Example
     490              :         @code
     491              :         param_view qp( "key", "value" );
     492              :         @endcode
     493              : 
     494              :         @par Postconditions
     495              :         @code
     496              :         this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
     497              :         @endcode
     498              : 
     499              :         @par Complexity
     500              :         Constant.
     501              : 
     502              :         @par Exception Safety
     503              :         Throws nothing.
     504              : 
     505              :         @tparam OptionalString An optional string
     506              :         type, such as `core::string_view`,
     507              :         `std::nullptr`, @ref no_value_t, or
     508              :         `optional<core::string_view>`.
     509              : 
     510              :         @param key The key to set.
     511              :         @param value The value to set.
     512              :     */
     513              :     template <class OptionalString>
     514          167 :     param_view(
     515              :         core::string_view key,
     516              :         OptionalString const& value) noexcept
     517          167 :         : param_view(key, detail::get_optional_string(value))
     518              :     {
     519          167 :     }
     520              : 
     521              :     /** Constructor
     522              : 
     523              :         This function constructs a param
     524              :         which references the character buffers
     525              :         representing the key and value in another
     526              :         container.
     527              :         Ownership of the buffers is not transferred;
     528              :         the caller is responsible for ensuring that
     529              :         the assigned buffers remain valid until
     530              :         they are no longer referenced.
     531              : 
     532              :         @par Example
     533              :         @code
     534              :         param qp( "key", "value" );
     535              :         param_view qpv( qp );
     536              :         @endcode
     537              : 
     538              :         @par Postconditions
     539              :         @code
     540              :         this->key == key && this->value == value && this->has_value == other.has_value
     541              :         @endcode
     542              : 
     543              :         @par Complexity
     544              :         Constant.
     545              : 
     546              :         @par Exception Safety
     547              :         Throws nothing.
     548              : 
     549              :         @param other The param to reference
     550              :     */
     551          754 :     param_view(
     552              :         param const& other) noexcept
     553          754 :         : param_view(
     554          754 :             other.key,
     555          754 :             other.value,
     556          754 :             other.has_value)
     557              :     {
     558          754 :     }
     559              : 
     560              :     /** Conversion
     561              : 
     562              :         This function performs a conversion from
     563              :         a reference-like query parameter to one
     564              :         retaining ownership of the strings by
     565              :         making a copy.
     566              :         No validation is performed on the strings.
     567              : 
     568              :         @par Complexity
     569              :         Linear in `this->key.size() + this->value.size()`.
     570              : 
     571              :         @par Exception Safety
     572              :         Calls to allocate may throw.
     573              : 
     574              :         @return A new query parameter.
     575              :     */
     576              :     explicit
     577            4 :     operator
     578              :     param()
     579              :     {
     580            4 :         return { key, value, has_value };
     581              :     }
     582              : 
     583              :     /** Arrow support
     584              : 
     585              :         This operator returns the address of the
     586              :         object so that it can be used in pointer
     587              :         contexts.
     588              : 
     589              :         @return A pointer to the object.
     590              :      */
     591              :     param_view const*
     592              :     operator->() const noexcept
     593              :     {
     594              :         return this;
     595              :     }
     596              : 
     597              :     /** Aggregate construction
     598              : 
     599              :         @param key_ The key to set.
     600              :         @param value_ The value to set.
     601              :         @param has_value_ True if a value is present.
     602              :      */
     603         1718 :     param_view(
     604              :         core::string_view key_,
     605              :         core::string_view value_,
     606              :         bool has_value_) noexcept
     607         1718 :         : key(key_)
     608         1718 :         , value(has_value_
     609         1718 :             ? value_
     610              :             : core::string_view())
     611         1718 :         , has_value(has_value_)
     612              :     {
     613         1718 :     }
     614              : 
     615              : private:
     616          167 :     param_view(
     617              :         core::string_view key,
     618              :         detail::optional_string const& value)
     619          167 :         : param_view(key, value.s, value.b)
     620              :     {
     621          167 :     }
     622              : };
     623              : 
     624              : //------------------------------------------------
     625              : 
     626              : /** A view of a percent-encoded query parameter
     627              : 
     628              :     Objects of this type represent a single key
     629              :     and value pair in a query string where a key
     630              :     is always present and may be empty, while the
     631              :     presence of a value is indicated by
     632              :     @ref has_value equal to true.
     633              :     An empty value is distinct from no value.
     634              : 
     635              :     The strings may have percent escapes, and
     636              :     offer an additional invariant: they never
     637              :     contain an invalid percent-encoding.
     638              : 
     639              :     For most usages, key comparisons are
     640              :     case-sensitive and duplicate keys in
     641              :     a query are possible. However, it is
     642              :     the authority that has final control
     643              :     over how the query is interpreted.
     644              : 
     645              :     <br>
     646              : 
     647              :     Keys and values in this object reference
     648              :     external character buffers.
     649              :     Ownership of the buffers is not transferred;
     650              :     the caller is responsible for ensuring that
     651              :     the assigned buffers remain valid until
     652              :     they are no longer referenced.
     653              : 
     654              :     @par BNF
     655              :     @code
     656              :     query-params    = query-param *( "&" query-param )
     657              :     query-param     = key [ "=" value ]
     658              :     key             = *qpchar
     659              :     value           = *( qpchar / "=" )
     660              :     @endcode
     661              : 
     662              :     @par Specification
     663              :     @li <a href="https://en.wikipedia.org/wiki/Query_string"
     664              :         >Query string (Wikipedia)</a>
     665              : 
     666              :     @see
     667              :         @ref param,
     668              :         @ref param_view.
     669              : */
     670              : struct param_pct_view
     671              : {
     672              :     /** The key
     673              : 
     674              :         For most usages, key comparisons are
     675              :         case-sensitive and duplicate keys in
     676              :         a query are possible. However, it is
     677              :         the authority that has final control
     678              :         over how the query is interpreted.
     679              :     */
     680              :     pct_string_view key;
     681              : 
     682              :     /** The value
     683              : 
     684              :         The presence of a value is indicated by
     685              :         @ref has_value equal to true.
     686              :         An empty value is distinct from no value.
     687              :     */
     688              :     pct_string_view value;
     689              : 
     690              :     /** True if a value is present
     691              : 
     692              :         The presence of a value is indicated by
     693              :         `has_value == true`.
     694              :         An empty value is distinct from no value.
     695              :     */
     696              :     bool has_value = false;
     697              : 
     698              :     //--------------------------------------------
     699              : 
     700              :     /** Constructor
     701              : 
     702              :         Default constructed query parameters
     703              :         have an empty key and no value.
     704              : 
     705              :         @par Example
     706              :         @code
     707              :         param_pct_view qp;
     708              :         @endcode
     709              : 
     710              :         @par Postconditions
     711              :         @code
     712              :         this->key == "" && this->value == "" && this->has_value == false
     713              :         @endcode
     714              : 
     715              :         @par Complexity
     716              :         Constant.
     717              : 
     718              :         @par Exception Safety
     719              :         Throws nothing.
     720              :     */
     721              :     param_pct_view() = default;
     722              : 
     723              :     /** Constructor
     724              : 
     725              :         This constructs a parameter with a key
     726              :         and value, which may both contain percent
     727              :         escapes.
     728              :         The new key and value reference
     729              :         the same corresponding underlying
     730              :         character buffers.
     731              :         Ownership of the buffers is not transferred;
     732              :         the caller is responsible for ensuring that
     733              :         the assigned buffers remain valid until
     734              :         they are no longer referenced.
     735              : 
     736              :         @par Example
     737              :         @code
     738              :         param_pct_view qp( "key", "value" );
     739              :         @endcode
     740              : 
     741              :         @par Postconditions
     742              :         @code
     743              :         this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
     744              :         @endcode
     745              : 
     746              :         @par Complexity
     747              :         Linear in `key.size() + value.size()`.
     748              : 
     749              :         @par Exception Safety
     750              :         Exceptions thrown on invalid input.
     751              : 
     752              :         @throw system_error
     753              :         `key` or `value` contains an invalid percent-encoding.
     754              : 
     755              :         @param key The key to set.
     756              :         @param value The value to set.
     757              :     */
     758         1096 :     param_pct_view(
     759              :         pct_string_view key,
     760              :         pct_string_view value) noexcept
     761         1096 :         : key(key)
     762         1096 :         , value(value)
     763         1096 :         , has_value(true)
     764              :     {
     765         1096 :     }
     766              : 
     767              :     /** Constructor
     768              : 
     769              :         This constructs a parameter with a key
     770              :         and optional value, which may both
     771              :         contain percent escapes.
     772              : 
     773              :         The new key and value reference
     774              :         the same corresponding underlying
     775              :         character buffers.
     776              : 
     777              :         Ownership of the buffers is not transferred;
     778              :         the caller is responsible for ensuring that
     779              :         the assigned buffers remain valid until
     780              :         they are no longer referenced.
     781              : 
     782              :         @par Example
     783              :         @code
     784              :         param_pct_view qp( "key", optional<core::string_view>("value") );
     785              :         @endcode
     786              : 
     787              :         @par Postconditions
     788              :         @code
     789              :         this->key.data() == key.data() && this->value->data() == value->data() && this->has_value == true
     790              :         @endcode
     791              : 
     792              :         @par Complexity
     793              :         Linear in `key.size() + value->size()`.
     794              : 
     795              :         @par Exception Safety
     796              :         Exceptions thrown on invalid input.
     797              : 
     798              :         @throw system_error
     799              :         `key` or `value` contains an invalid percent-encoding.
     800              : 
     801              :         @tparam OptionalString An optional
     802              :         `core::string_view` type, such as
     803              :         `boost::optional<core::string_view>` or
     804              :         `std::optional<core::string_view>`.
     805              : 
     806              :         @param key The key to set.
     807              :         @param value The optional value to set.
     808              :         @return A param object
     809              :     */
     810              :     template <class OptionalString>
     811          649 :     param_pct_view(
     812              :         pct_string_view key,
     813              :         OptionalString const& value)
     814          649 :         : param_pct_view(key, detail::get_optional_string(value))
     815              :     {
     816          646 :     }
     817              : 
     818              :     /** Construction
     819              : 
     820              :         This converts a param which may
     821              :         contain unvalidated percent-escapes into
     822              :         a param whose key and value are
     823              :         guaranteed to contain strings with no
     824              :         invalid percent-escapes, otherwise
     825              :         an exception is thrown.
     826              : 
     827              :         The new key and value reference
     828              :         the same corresponding underlying
     829              :         character buffers.
     830              :         Ownership of the buffers is not transferred;
     831              :         the caller is responsible for ensuring that
     832              :         the assigned buffers remain valid until
     833              :         they are no longer referenced.
     834              : 
     835              :         @par Example
     836              :         @code
     837              :         param_pct_view qp( param_view( "key", "value" ) );
     838              :         @endcode
     839              : 
     840              :         @par Complexity
     841              :         Linear in `key.size() + value.size()`.
     842              : 
     843              :         @par Exception Safety
     844              :         Exceptions thrown on invalid input.
     845              : 
     846              :         @throw system_error
     847              :         `key` or `value` contains an invalid percent escape.
     848              : 
     849              :         @param p The param to construct from.
     850              :     */
     851              :     explicit
     852           56 :     param_pct_view(
     853              :         param_view const& p)
     854           56 :         : key(p.key)
     855           52 :         , value(p.has_value
     856           52 :             ? pct_string_view(p.value)
     857              :             : pct_string_view())
     858           51 :         , has_value(p.has_value)
     859              :     {
     860           51 :     }
     861              : 
     862              :     /** Conversion
     863              : 
     864              :         This function performs a conversion from
     865              :         a reference-like query parameter to one
     866              :         retaining ownership of the strings by
     867              :         making a copy.
     868              : 
     869              :         @par Complexity
     870              :         Linear in `this->key.size() + this->value.size()`.
     871              : 
     872              :         @par Exception Safety
     873              :         Calls to allocate may throw.
     874              : 
     875              :         @return A param object
     876              :     */
     877              :     explicit
     878            2 :     operator
     879              :     param() const
     880              :     {
     881              :         return param(
     882            4 :             static_cast<std::string>(key),
     883            6 :             static_cast<std::string>(value),
     884            6 :             has_value);
     885              :     }
     886              : 
     887              :     /** Conversion to param_view
     888              : 
     889              :         This function performs a conversion from
     890              :         a pct_string_view query parameter to one
     891              :         using a simple string_view.
     892              : 
     893              :         @par Exception Safety
     894              :         Calls to allocate may throw.
     895              : 
     896              :         @return A param_view object
     897              :     */
     898          797 :     operator
     899              :     param_view() const noexcept
     900              :     {
     901              :         return param_view(
     902          797 :             key, value, has_value);
     903              :     }
     904              : 
     905              :     /** Arrow support
     906              : 
     907              :         This operator returns the address of the
     908              :         object so that it can be used in pointer
     909              :         contexts.
     910              : 
     911              :         @return A pointer to this object
     912              :      */
     913              :     param_pct_view const*
     914           21 :     operator->() const noexcept
     915              :     {
     916           21 :         return this;
     917              :     }
     918              : 
     919              :     /** Aggregate construction
     920              : 
     921              :         @param key The key
     922              :         @param value The value
     923              :         @param has_value True if a value is present
     924              :      */
     925          646 :     param_pct_view(
     926              :         pct_string_view key,
     927              :         pct_string_view value,
     928              :         bool has_value) noexcept
     929          646 :         : key(key)
     930          646 :         , value(has_value
     931          646 :             ? value
     932              :             : pct_string_view())
     933          646 :         , has_value(has_value)
     934              :     {
     935          646 :     }
     936              : 
     937              : private:
     938          649 :     param_pct_view(
     939              :         pct_string_view key,
     940              :         detail::optional_string const& value)
     941          649 :         : param_pct_view(key, value.s, value.b)
     942              :     {
     943          646 :     }
     944              : };
     945              : 
     946              : //------------------------------------------------
     947              : 
     948              : inline
     949              : param&
     950            1 : param::
     951              : operator=(
     952              :     param_view const& other)
     953              : {
     954              :     // VFALCO operator= assignment
     955              :     // causes a loss of original capacity:
     956              :     // https://godbolt.org/z/nYef8445K
     957              :     //
     958              :     // key = other.key;
     959              :     // value = other.value;
     960              : 
     961              :     // preserve capacity
     962            1 :     key.assign(
     963              :         other.key.data(),
     964              :         other.key.size());
     965            1 :     value.assign(
     966              :         other.value.data(),
     967              :         other.value.size());
     968            1 :     has_value = other.has_value;
     969            1 :     return *this;
     970              : }
     971              : 
     972              : inline
     973              : param&
     974            1 : param::
     975              : operator=(
     976              :     param_pct_view const& other)
     977              : {
     978              :     // preserve capacity
     979            1 :     key.assign(
     980              :         other.key.data(),
     981              :         other.key.size());
     982            1 :     value.assign(
     983              :         other.value.data(),
     984              :         other.value.size());
     985            1 :     has_value = other.has_value;
     986            1 :     return *this;
     987              : }
     988              : 
     989              : } // urls
     990              : } // boost
     991              : 
     992              : #endif
        

Generated by: LCOV version 2.1