LCOV - code coverage report
Current view: top level - boost/url - param.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 83 83 100.0 %
Date: 2024-03-12 19:37:18 Functions: 52 53 98.1 %

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

Generated by: LCOV version 1.15