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-11-10 19:06:20 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          797 :     param(
     357              :         core::string_view key,
     358              :         core::string_view value,
     359              :         bool has_value) noexcept
     360          797 :         : key(key)
     361          797 :         , value(has_value
     362          797 :             ? value
     363              :             : core::string_view())
     364          797 :         , has_value(has_value)
     365              :     {
     366          797 :     }
     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. Some functions and objects might
     391              :     expect encoded strings in this view, while
     392              :     others expect decoded strings. The caller
     393              :     should be aware of the context in which
     394              :     the object will be used.
     395              : 
     396              :     For most usages, key comparisons are
     397              :     case-sensitive and duplicate keys in
     398              :     a query are possible. However, it is
     399              :     the authority that has final control
     400              :     over how the query is interpreted.
     401              : 
     402              :     <br>
     403              : 
     404              :     Keys and values in this object reference
     405              :     external character buffers.
     406              :     Ownership of the buffers is not transferred;
     407              :     the caller is responsible for ensuring that
     408              :     the assigned buffers remain valid until
     409              :     they are no longer referenced.
     410              : 
     411              :     @par BNF
     412              :     @code
     413              :     query-params    = query-param *( "&" query-param )
     414              :     query-param     = key [ "=" value ]
     415              :     key             = *qpchar
     416              :     value           = *( qpchar / "=" )
     417              :     @endcode
     418              : 
     419              :     @par Specification
     420              :     @li <a href="https://en.wikipedia.org/wiki/Query_string"
     421              :         >Query string (Wikipedia)</a>
     422              : 
     423              :     @see
     424              :         @ref param,
     425              :         @ref param_pct_view.
     426              : */
     427              : struct param_view
     428              : {
     429              :     /** The key
     430              : 
     431              :         For most usages, key comparisons are
     432              :         case-sensitive and duplicate keys in
     433              :         a query are possible. However, it is
     434              :         the authority that has final control
     435              :         over how the query is interpreted.
     436              :     */
     437              :     core::string_view key;
     438              : 
     439              :     /** The value
     440              : 
     441              :         The presence of a value is indicated by
     442              :         @ref has_value equal to true.
     443              :         An empty value is distinct from no value.
     444              :     */
     445              :     core::string_view value;
     446              : 
     447              :     /** True if a value is present
     448              : 
     449              :         The presence of a value is indicated by
     450              :         `has_value == true`.
     451              :         An empty value is distinct from no value.
     452              :     */
     453              :     bool has_value = false;
     454              : 
     455              :     //--------------------------------------------
     456              : 
     457              :     /** Constructor
     458              : 
     459              :         Default constructed query parameters
     460              :         have an empty key and no value.
     461              : 
     462              :         @par Example
     463              :         @code
     464              :         param_view qp;
     465              :         @endcode
     466              : 
     467              :         @par Postconditions
     468              :         @code
     469              :         this->key == "" && this->value == "" && this->has_value == false
     470              :         @endcode
     471              : 
     472              :         @par Complexity
     473              :         Constant.
     474              : 
     475              :         @par Exception Safety
     476              :         Throws nothing.
     477              :     */
     478              :     param_view() = default;
     479              : 
     480              :     /** Constructor
     481              : 
     482              :         This constructs a parameter with a key
     483              :         and value.
     484              :         No validation is performed on the strings.
     485              :         The new key and value reference
     486              :         the same corresponding underlying
     487              :         character buffers.
     488              :         Ownership of the buffers is not transferred;
     489              :         the caller is responsible for ensuring that
     490              :         the assigned buffers remain valid until
     491              :         they are no longer referenced.
     492              : 
     493              :         @par Example
     494              :         @code
     495              :         param_view qp( "key", "value" );
     496              :         @endcode
     497              : 
     498              :         @par Postconditions
     499              :         @code
     500              :         this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
     501              :         @endcode
     502              : 
     503              :         @par Complexity
     504              :         Constant.
     505              : 
     506              :         @par Exception Safety
     507              :         Throws nothing.
     508              : 
     509              :         @tparam OptionalString An optional string
     510              :         type, such as `core::string_view`,
     511              :         `std::nullptr`, @ref no_value_t, or
     512              :         `optional<core::string_view>`.
     513              : 
     514              :         @param key The key to set.
     515              :         @param value The value to set.
     516              :     */
     517              :     template <class OptionalString>
     518          173 :     param_view(
     519              :         core::string_view key,
     520              :         OptionalString const& value) noexcept
     521          173 :         : param_view(key, detail::get_optional_string(value))
     522              :     {
     523          173 :     }
     524              : 
     525              :     /** Constructor
     526              : 
     527              :         This function constructs a param
     528              :         which references the character buffers
     529              :         representing the key and value in another
     530              :         container.
     531              :         Ownership of the buffers is not transferred;
     532              :         the caller is responsible for ensuring that
     533              :         the assigned buffers remain valid until
     534              :         they are no longer referenced.
     535              : 
     536              :         @par Example
     537              :         @code
     538              :         param qp( "key", "value" );
     539              :         param_view qpv( qp );
     540              :         @endcode
     541              : 
     542              :         @par Postconditions
     543              :         @code
     544              :         this->key == key && this->value == value && this->has_value == other.has_value
     545              :         @endcode
     546              : 
     547              :         @par Complexity
     548              :         Constant.
     549              : 
     550              :         @par Exception Safety
     551              :         Throws nothing.
     552              : 
     553              :         @param other The param to reference
     554              :     */
     555          754 :     param_view(
     556              :         param const& other) noexcept
     557          754 :         : param_view(
     558          754 :             other.key,
     559          754 :             other.value,
     560          754 :             other.has_value)
     561              :     {
     562          754 :     }
     563              : 
     564              :     /** Conversion
     565              : 
     566              :         This function performs a conversion from
     567              :         a reference-like query parameter to one
     568              :         retaining ownership of the strings by
     569              :         making a copy.
     570              :         No validation is performed on the strings.
     571              : 
     572              :         @par Complexity
     573              :         Linear in `this->key.size() + this->value.size()`.
     574              : 
     575              :         @par Exception Safety
     576              :         Calls to allocate may throw.
     577              : 
     578              :         @return A new query parameter.
     579              :     */
     580              :     explicit
     581            4 :     operator
     582              :     param()
     583              :     {
     584            4 :         return { key, value, has_value };
     585              :     }
     586              : 
     587              :     /** Arrow support
     588              : 
     589              :         This operator returns the address of the
     590              :         object so that it can be used in pointer
     591              :         contexts.
     592              : 
     593              :         @return A pointer to the object.
     594              :      */
     595              :     param_view const*
     596              :     operator->() const noexcept
     597              :     {
     598              :         return this;
     599              :     }
     600              : 
     601              :     /** Aggregate construction
     602              : 
     603              :         @param key_ The key to set.
     604              :         @param value_ The value to set.
     605              :         @param has_value_ True if a value is present.
     606              :      */
     607         1724 :     param_view(
     608              :         core::string_view key_,
     609              :         core::string_view value_,
     610              :         bool has_value_) noexcept
     611         1724 :         : key(key_)
     612         1724 :         , value(has_value_
     613         1724 :             ? value_
     614              :             : core::string_view())
     615         1724 :         , has_value(has_value_)
     616              :     {
     617         1724 :     }
     618              : 
     619              : private:
     620          173 :     param_view(
     621              :         core::string_view key,
     622              :         detail::optional_string const& value)
     623          173 :         : param_view(key, value.s, value.b)
     624              :     {
     625          173 :     }
     626              : };
     627              : 
     628              : //------------------------------------------------
     629              : 
     630              : /** A view of a percent-encoded query parameter
     631              : 
     632              :     Objects of this type represent a single key
     633              :     and value pair in a query string where a key
     634              :     is always present and may be empty, while the
     635              :     presence of a value is indicated by
     636              :     @ref has_value equal to true.
     637              :     An empty value is distinct from no value.
     638              : 
     639              :     The strings may have percent escapes, and
     640              :     offer an additional invariant: they never
     641              :     contain an invalid percent-encoding.
     642              : 
     643              :     For most usages, key comparisons are
     644              :     case-sensitive and duplicate keys in
     645              :     a query are possible. However, it is
     646              :     the authority that has final control
     647              :     over how the query is interpreted.
     648              : 
     649              :     <br>
     650              : 
     651              :     Keys and values in this object reference
     652              :     external character buffers.
     653              :     Ownership of the buffers is not transferred;
     654              :     the caller is responsible for ensuring that
     655              :     the assigned buffers remain valid until
     656              :     they are no longer referenced.
     657              : 
     658              :     @par BNF
     659              :     @code
     660              :     query-params    = query-param *( "&" query-param )
     661              :     query-param     = key [ "=" value ]
     662              :     key             = *qpchar
     663              :     value           = *( qpchar / "=" )
     664              :     @endcode
     665              : 
     666              :     @par Specification
     667              :     @li <a href="https://en.wikipedia.org/wiki/Query_string"
     668              :         >Query string (Wikipedia)</a>
     669              : 
     670              :     @see
     671              :         @ref param,
     672              :         @ref param_view.
     673              : */
     674              : struct param_pct_view
     675              : {
     676              :     /** The key
     677              : 
     678              :         For most usages, key comparisons are
     679              :         case-sensitive and duplicate keys in
     680              :         a query are possible. However, it is
     681              :         the authority that has final control
     682              :         over how the query is interpreted.
     683              :     */
     684              :     pct_string_view key;
     685              : 
     686              :     /** The value
     687              : 
     688              :         The presence of a value is indicated by
     689              :         @ref has_value equal to true.
     690              :         An empty value is distinct from no value.
     691              :     */
     692              :     pct_string_view value;
     693              : 
     694              :     /** True if a value is present
     695              : 
     696              :         The presence of a value is indicated by
     697              :         `has_value == true`.
     698              :         An empty value is distinct from no value.
     699              :     */
     700              :     bool has_value = false;
     701              : 
     702              :     //--------------------------------------------
     703              : 
     704              :     /** Constructor
     705              : 
     706              :         Default constructed query parameters
     707              :         have an empty key and no value.
     708              : 
     709              :         @par Example
     710              :         @code
     711              :         param_pct_view qp;
     712              :         @endcode
     713              : 
     714              :         @par Postconditions
     715              :         @code
     716              :         this->key == "" && this->value == "" && this->has_value == false
     717              :         @endcode
     718              : 
     719              :         @par Complexity
     720              :         Constant.
     721              : 
     722              :         @par Exception Safety
     723              :         Throws nothing.
     724              :     */
     725              :     param_pct_view() = default;
     726              : 
     727              :     /** Constructor
     728              : 
     729              :         This constructs a parameter with a key
     730              :         and value, which may both contain percent
     731              :         escapes.
     732              :         The new key and value reference
     733              :         the same corresponding underlying
     734              :         character buffers.
     735              :         Ownership of the buffers is not transferred;
     736              :         the caller is responsible for ensuring that
     737              :         the assigned buffers remain valid until
     738              :         they are no longer referenced.
     739              : 
     740              :         @par Example
     741              :         @code
     742              :         param_pct_view qp( "key", "value" );
     743              :         @endcode
     744              : 
     745              :         @par Postconditions
     746              :         @code
     747              :         this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
     748              :         @endcode
     749              : 
     750              :         @par Complexity
     751              :         Linear in `key.size() + value.size()`.
     752              : 
     753              :         @par Exception Safety
     754              :         Exceptions thrown on invalid input.
     755              : 
     756              :         @throw system_error
     757              :         `key` or `value` contains an invalid percent-encoding.
     758              : 
     759              :         @param key The key to set.
     760              :         @param value The value to set.
     761              :     */
     762         1099 :     param_pct_view(
     763              :         pct_string_view key,
     764              :         pct_string_view value) noexcept
     765         1099 :         : key(key)
     766         1099 :         , value(value)
     767         1099 :         , has_value(true)
     768              :     {
     769         1099 :     }
     770              : 
     771              :     /** Constructor
     772              : 
     773              :         This constructs a parameter with a key
     774              :         and optional value, which may both
     775              :         contain percent escapes.
     776              : 
     777              :         The new key and value reference
     778              :         the same corresponding underlying
     779              :         character buffers.
     780              : 
     781              :         Ownership of the buffers is not transferred;
     782              :         the caller is responsible for ensuring that
     783              :         the assigned buffers remain valid until
     784              :         they are no longer referenced.
     785              : 
     786              :         @par Example
     787              :         @code
     788              :         param_pct_view qp( "key", optional<core::string_view>("value") );
     789              :         @endcode
     790              : 
     791              :         @par Postconditions
     792              :         @code
     793              :         this->key.data() == key.data() && this->value->data() == value->data() && this->has_value == true
     794              :         @endcode
     795              : 
     796              :         @par Complexity
     797              :         Linear in `key.size() + value->size()`.
     798              : 
     799              :         @par Exception Safety
     800              :         Exceptions thrown on invalid input.
     801              : 
     802              :         @throw system_error
     803              :         `key` or `value` contains an invalid percent-encoding.
     804              : 
     805              :         @tparam OptionalString An optional
     806              :         `core::string_view` type, such as
     807              :         `boost::optional<core::string_view>` or
     808              :         `std::optional<core::string_view>`.
     809              : 
     810              :         @param key The key to set.
     811              :         @param value The optional value to set.
     812              :         @return A param object
     813              :     */
     814              :     template <class OptionalString>
     815          649 :     param_pct_view(
     816              :         pct_string_view key,
     817              :         OptionalString const& value)
     818          649 :         : param_pct_view(key, detail::get_optional_string(value))
     819              :     {
     820          646 :     }
     821              : 
     822              :     /** Construction
     823              : 
     824              :         This converts a param which may
     825              :         contain unvalidated percent-escapes into
     826              :         a param whose key and value are
     827              :         guaranteed to contain strings with no
     828              :         invalid percent-escapes, otherwise
     829              :         an exception is thrown.
     830              : 
     831              :         The new key and value reference
     832              :         the same corresponding underlying
     833              :         character buffers.
     834              :         Ownership of the buffers is not transferred;
     835              :         the caller is responsible for ensuring that
     836              :         the assigned buffers remain valid until
     837              :         they are no longer referenced.
     838              : 
     839              :         @par Example
     840              :         @code
     841              :         param_pct_view qp( param_view( "key", "value" ) );
     842              :         @endcode
     843              : 
     844              :         @par Complexity
     845              :         Linear in `key.size() + value.size()`.
     846              : 
     847              :         @par Exception Safety
     848              :         Exceptions thrown on invalid input.
     849              : 
     850              :         @throw system_error
     851              :         `key` or `value` contains an invalid percent escape.
     852              : 
     853              :         @param p The param to construct from.
     854              :     */
     855              :     explicit
     856           56 :     param_pct_view(
     857              :         param_view const& p)
     858           56 :         : key(p.key)
     859           52 :         , value(p.has_value
     860           52 :             ? pct_string_view(p.value)
     861              :             : pct_string_view())
     862           51 :         , has_value(p.has_value)
     863              :     {
     864           51 :     }
     865              : 
     866              :     /** Conversion
     867              : 
     868              :         This function performs a conversion from
     869              :         a reference-like query parameter to one
     870              :         retaining ownership of the strings by
     871              :         making a copy.
     872              : 
     873              :         @par Complexity
     874              :         Linear in `this->key.size() + this->value.size()`.
     875              : 
     876              :         @par Exception Safety
     877              :         Calls to allocate may throw.
     878              : 
     879              :         @return A param object
     880              :     */
     881              :     explicit
     882            2 :     operator
     883              :     param() const
     884              :     {
     885              :         return param(
     886            4 :             static_cast<std::string>(key),
     887            6 :             static_cast<std::string>(value),
     888            6 :             has_value);
     889              :     }
     890              : 
     891              :     /** Conversion to param_view
     892              : 
     893              :         This function performs a conversion from
     894              :         a pct_string_view query parameter to one
     895              :         using a simple string_view.
     896              : 
     897              :         @par Exception Safety
     898              :         Calls to allocate may throw.
     899              : 
     900              :         @return A param_view object
     901              :     */
     902          797 :     operator
     903              :     param_view() const noexcept
     904              :     {
     905              :         return param_view(
     906          797 :             key, value, has_value);
     907              :     }
     908              : 
     909              :     /** Arrow support
     910              : 
     911              :         This operator returns the address of the
     912              :         object so that it can be used in pointer
     913              :         contexts.
     914              : 
     915              :         @return A pointer to this object
     916              :      */
     917              :     param_pct_view const*
     918           21 :     operator->() const noexcept
     919              :     {
     920           21 :         return this;
     921              :     }
     922              : 
     923              :     /** Aggregate construction
     924              : 
     925              :         @param key The key
     926              :         @param value The value
     927              :         @param has_value True if a value is present
     928              :      */
     929          646 :     param_pct_view(
     930              :         pct_string_view key,
     931              :         pct_string_view value,
     932              :         bool has_value) noexcept
     933          646 :         : key(key)
     934          646 :         , value(has_value
     935          646 :             ? value
     936              :             : pct_string_view())
     937          646 :         , has_value(has_value)
     938              :     {
     939          646 :     }
     940              : 
     941              : private:
     942          649 :     param_pct_view(
     943              :         pct_string_view key,
     944              :         detail::optional_string const& value)
     945          649 :         : param_pct_view(key, value.s, value.b)
     946              :     {
     947          646 :     }
     948              : };
     949              : 
     950              : //------------------------------------------------
     951              : 
     952              : inline
     953              : param&
     954            1 : param::
     955              : operator=(
     956              :     param_view const& other)
     957              : {
     958              :     // VFALCO operator= assignment
     959              :     // causes a loss of original capacity:
     960              :     // https://godbolt.org/z/nYef8445K
     961              :     //
     962              :     // key = other.key;
     963              :     // value = other.value;
     964              : 
     965              :     // preserve capacity
     966            1 :     key.assign(
     967              :         other.key.data(),
     968              :         other.key.size());
     969            1 :     value.assign(
     970              :         other.value.data(),
     971              :         other.value.size());
     972            1 :     has_value = other.has_value;
     973            1 :     return *this;
     974              : }
     975              : 
     976              : inline
     977              : param&
     978            1 : param::
     979              : operator=(
     980              :     param_pct_view const& other)
     981              : {
     982              :     // preserve capacity
     983            1 :     key.assign(
     984              :         other.key.data(),
     985              :         other.key.size());
     986            1 :     value.assign(
     987              :         other.value.data(),
     988              :         other.value.size());
     989            1 :     has_value = other.has_value;
     990            1 :     return *this;
     991              : }
     992              : 
     993              : } // urls
     994              : } // boost
     995              : 
     996              : #endif
        

Generated by: LCOV version 2.1