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: 2026-01-20 15:14:25 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              : #if defined(_MSC_VER)
     602              : #pragma warning(push)
     603              : #pragma warning(disable: 4458) // declaration hides class member
     604              : #endif
     605              : #if defined(__clang__)
     606              : #pragma clang diagnostic push
     607              : #pragma clang diagnostic ignored "-Wshadow"
     608              : #elif defined(__GNUC__)
     609              : #pragma GCC diagnostic push
     610              : #pragma GCC diagnostic ignored "-Wshadow"
     611              : #endif
     612              : 
     613              :     /** Aggregate construction
     614              : 
     615              :         @param key The key to set.
     616              :         @param value The value to set.
     617              :         @param has_value True if a value is present.
     618              :      */
     619         1724 :     param_view(
     620              :         core::string_view key,
     621              :         core::string_view value,
     622              :         bool has_value) noexcept
     623         1724 :         : key(key)
     624         1724 :         , value(has_value
     625         1724 :             ? value
     626              :             : core::string_view())
     627         1724 :         , has_value(has_value)
     628              :     {
     629         1724 :     }
     630              : 
     631              : #if defined(__clang__)
     632              : #pragma clang diagnostic pop
     633              : #elif defined(__GNUC__)
     634              : #pragma GCC diagnostic pop
     635              : #endif
     636              : #if defined(_MSC_VER)
     637              : #pragma warning(pop)
     638              : #endif
     639              : 
     640              : private:
     641          173 :     param_view(
     642              :         core::string_view key,
     643              :         detail::optional_string const& value)
     644          173 :         : param_view(key, value.s, value.b)
     645              :     {
     646          173 :     }
     647              : };
     648              : 
     649              : //------------------------------------------------
     650              : 
     651              : /** A view of a percent-encoded query parameter
     652              : 
     653              :     Objects of this type represent a single key
     654              :     and value pair in a query string where a key
     655              :     is always present and may be empty, while the
     656              :     presence of a value is indicated by
     657              :     @ref has_value equal to true.
     658              :     An empty value is distinct from no value.
     659              : 
     660              :     The strings may have percent escapes, and
     661              :     offer an additional invariant: they never
     662              :     contain an invalid percent-encoding.
     663              : 
     664              :     For most usages, key comparisons are
     665              :     case-sensitive and duplicate keys in
     666              :     a query are possible. However, it is
     667              :     the authority that has final control
     668              :     over how the query is interpreted.
     669              : 
     670              :     <br>
     671              : 
     672              :     Keys and values in this object reference
     673              :     external character buffers.
     674              :     Ownership of the buffers is not transferred;
     675              :     the caller is responsible for ensuring that
     676              :     the assigned buffers remain valid until
     677              :     they are no longer referenced.
     678              : 
     679              :     @par BNF
     680              :     @code
     681              :     query-params    = query-param *( "&" query-param )
     682              :     query-param     = key [ "=" value ]
     683              :     key             = *qpchar
     684              :     value           = *( qpchar / "=" )
     685              :     @endcode
     686              : 
     687              :     @par Specification
     688              :     @li <a href="https://en.wikipedia.org/wiki/Query_string"
     689              :         >Query string (Wikipedia)</a>
     690              : 
     691              :     @see
     692              :         @ref param,
     693              :         @ref param_view.
     694              : */
     695              : struct param_pct_view
     696              : {
     697              :     /** The key
     698              : 
     699              :         For most usages, key comparisons are
     700              :         case-sensitive and duplicate keys in
     701              :         a query are possible. However, it is
     702              :         the authority that has final control
     703              :         over how the query is interpreted.
     704              :     */
     705              :     pct_string_view key;
     706              : 
     707              :     /** The value
     708              : 
     709              :         The presence of a value is indicated by
     710              :         @ref has_value equal to true.
     711              :         An empty value is distinct from no value.
     712              :     */
     713              :     pct_string_view value;
     714              : 
     715              :     /** True if a value is present
     716              : 
     717              :         The presence of a value is indicated by
     718              :         `has_value == true`.
     719              :         An empty value is distinct from no value.
     720              :     */
     721              :     bool has_value = false;
     722              : 
     723              :     //--------------------------------------------
     724              : 
     725              :     /** Constructor
     726              : 
     727              :         Default constructed query parameters
     728              :         have an empty key and no value.
     729              : 
     730              :         @par Example
     731              :         @code
     732              :         param_pct_view qp;
     733              :         @endcode
     734              : 
     735              :         @par Postconditions
     736              :         @code
     737              :         this->key == "" && this->value == "" && this->has_value == false
     738              :         @endcode
     739              : 
     740              :         @par Complexity
     741              :         Constant.
     742              : 
     743              :         @par Exception Safety
     744              :         Throws nothing.
     745              :     */
     746              :     param_pct_view() = default;
     747              : 
     748              :     /** Constructor
     749              : 
     750              :         This constructs a parameter with a key
     751              :         and value, which may both contain percent
     752              :         escapes.
     753              :         The new key and value reference
     754              :         the same corresponding underlying
     755              :         character buffers.
     756              :         Ownership of the buffers is not transferred;
     757              :         the caller is responsible for ensuring that
     758              :         the assigned buffers remain valid until
     759              :         they are no longer referenced.
     760              : 
     761              :         @par Example
     762              :         @code
     763              :         param_pct_view qp( "key", "value" );
     764              :         @endcode
     765              : 
     766              :         @par Postconditions
     767              :         @code
     768              :         this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
     769              :         @endcode
     770              : 
     771              :         @par Complexity
     772              :         Linear in `key.size() + value.size()`.
     773              : 
     774              :         @par Exception Safety
     775              :         Exceptions thrown on invalid input.
     776              : 
     777              :         @throw system_error
     778              :         `key` or `value` contains an invalid percent-encoding.
     779              : 
     780              :         @param key The key to set.
     781              :         @param value The value to set.
     782              :     */
     783         1108 :     param_pct_view(
     784              :         pct_string_view key,
     785              :         pct_string_view value) noexcept
     786         1108 :         : key(key)
     787         1108 :         , value(value)
     788         1108 :         , has_value(true)
     789              :     {
     790         1108 :     }
     791              : 
     792              :     /** Constructor
     793              : 
     794              :         This constructs a parameter with a key
     795              :         and optional value, which may both
     796              :         contain percent escapes.
     797              : 
     798              :         The new key and value reference
     799              :         the same corresponding underlying
     800              :         character buffers.
     801              : 
     802              :         Ownership of the buffers is not transferred;
     803              :         the caller is responsible for ensuring that
     804              :         the assigned buffers remain valid until
     805              :         they are no longer referenced.
     806              : 
     807              :         @par Example
     808              :         @code
     809              :         param_pct_view qp( "key", optional<core::string_view>("value") );
     810              :         @endcode
     811              : 
     812              :         @par Postconditions
     813              :         @code
     814              :         this->key.data() == key.data() && this->value->data() == value->data() && this->has_value == true
     815              :         @endcode
     816              : 
     817              :         @par Complexity
     818              :         Linear in `key.size() + value->size()`.
     819              : 
     820              :         @par Exception Safety
     821              :         Exceptions thrown on invalid input.
     822              : 
     823              :         @throw system_error
     824              :         `key` or `value` contains an invalid percent-encoding.
     825              : 
     826              :         @tparam OptionalString An optional
     827              :         `core::string_view` type, such as
     828              :         `boost::optional<core::string_view>` or
     829              :         `std::optional<core::string_view>`.
     830              : 
     831              :         @param key The key to set.
     832              :         @param value The optional value to set.
     833              :         @return A param object
     834              :     */
     835              :     template <class OptionalString>
     836          651 :     param_pct_view(
     837              :         pct_string_view key,
     838              :         OptionalString const& value)
     839          651 :         : param_pct_view(key, detail::get_optional_string(value))
     840              :     {
     841          648 :     }
     842              : 
     843              :     /** Construction
     844              : 
     845              :         This converts a param which may
     846              :         contain unvalidated percent-escapes into
     847              :         a param whose key and value are
     848              :         guaranteed to contain strings with no
     849              :         invalid percent-escapes, otherwise
     850              :         an exception is thrown.
     851              : 
     852              :         The new key and value reference
     853              :         the same corresponding underlying
     854              :         character buffers.
     855              :         Ownership of the buffers is not transferred;
     856              :         the caller is responsible for ensuring that
     857              :         the assigned buffers remain valid until
     858              :         they are no longer referenced.
     859              : 
     860              :         @par Example
     861              :         @code
     862              :         param_pct_view qp( param_view( "key", "value" ) );
     863              :         @endcode
     864              : 
     865              :         @par Complexity
     866              :         Linear in `key.size() + value.size()`.
     867              : 
     868              :         @par Exception Safety
     869              :         Exceptions thrown on invalid input.
     870              : 
     871              :         @throw system_error
     872              :         `key` or `value` contains an invalid percent escape.
     873              : 
     874              :         @param p The param to construct from.
     875              :     */
     876              :     explicit
     877           56 :     param_pct_view(
     878              :         param_view const& p)
     879           56 :         : key(p.key)
     880           52 :         , value(p.has_value
     881           52 :             ? pct_string_view(p.value)
     882              :             : pct_string_view())
     883           51 :         , has_value(p.has_value)
     884              :     {
     885           51 :     }
     886              : 
     887              :     /** Conversion
     888              : 
     889              :         This function performs a conversion from
     890              :         a reference-like query parameter to one
     891              :         retaining ownership of the strings by
     892              :         making a copy.
     893              : 
     894              :         @par Complexity
     895              :         Linear in `this->key.size() + this->value.size()`.
     896              : 
     897              :         @par Exception Safety
     898              :         Calls to allocate may throw.
     899              : 
     900              :         @return A param object
     901              :     */
     902              :     explicit
     903            2 :     operator
     904              :     param() const
     905              :     {
     906              :         return param(
     907            4 :             static_cast<std::string>(key),
     908            6 :             static_cast<std::string>(value),
     909            6 :             has_value);
     910              :     }
     911              : 
     912              :     /** Conversion to param_view
     913              : 
     914              :         This function performs a conversion from
     915              :         a pct_string_view query parameter to one
     916              :         using a simple string_view.
     917              : 
     918              :         @par Exception Safety
     919              :         Calls to allocate may throw.
     920              : 
     921              :         @return A param_view object
     922              :     */
     923          797 :     operator
     924              :     param_view() const noexcept
     925              :     {
     926              :         return param_view(
     927          797 :             key, value, has_value);
     928              :     }
     929              : 
     930              :     /** Arrow support
     931              : 
     932              :         This operator returns the address of the
     933              :         object so that it can be used in pointer
     934              :         contexts.
     935              : 
     936              :         @return A pointer to this object
     937              :      */
     938              :     param_pct_view const*
     939           21 :     operator->() const noexcept
     940              :     {
     941           21 :         return this;
     942              :     }
     943              : 
     944              :     /** Aggregate construction
     945              : 
     946              :         @param key The key
     947              :         @param value The value
     948              :         @param has_value True if a value is present
     949              :      */
     950          648 :     param_pct_view(
     951              :         pct_string_view key,
     952              :         pct_string_view value,
     953              :         bool has_value) noexcept
     954          648 :         : key(key)
     955          648 :         , value(has_value
     956          648 :             ? value
     957              :             : pct_string_view())
     958          648 :         , has_value(has_value)
     959              :     {
     960          648 :     }
     961              : 
     962              : private:
     963          651 :     param_pct_view(
     964              :         pct_string_view key,
     965              :         detail::optional_string const& value)
     966          651 :         : param_pct_view(key, value.s, value.b)
     967              :     {
     968          648 :     }
     969              : };
     970              : 
     971              : //------------------------------------------------
     972              : 
     973              : inline
     974              : param&
     975            1 : param::
     976              : operator=(
     977              :     param_view const& other)
     978              : {
     979              :     // VFALCO operator= assignment
     980              :     // causes a loss of original capacity:
     981              :     // https://godbolt.org/z/nYef8445K
     982              :     //
     983              :     // key = other.key;
     984              :     // value = other.value;
     985              : 
     986              :     // preserve capacity
     987            1 :     key.assign(
     988              :         other.key.data(),
     989              :         other.key.size());
     990            1 :     value.assign(
     991              :         other.value.data(),
     992              :         other.value.size());
     993            1 :     has_value = other.has_value;
     994            1 :     return *this;
     995              : }
     996              : 
     997              : inline
     998              : param&
     999            1 : param::
    1000              : operator=(
    1001              :     param_pct_view const& other)
    1002              : {
    1003              :     // preserve capacity
    1004            1 :     key.assign(
    1005              :         other.key.data(),
    1006              :         other.key.size());
    1007            1 :     value.assign(
    1008              :         other.value.data(),
    1009              :         other.value.size());
    1010            1 :     has_value = other.has_value;
    1011            1 :     return *this;
    1012              : }
    1013              : 
    1014              : } // urls
    1015              : } // boost
    1016              : 
    1017              : #endif
        

Generated by: LCOV version 2.3