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