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