param.hpp 24 KB

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