Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@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/json
9 : //
10 :
11 : #ifndef BOOST_JSON_STRING_HPP
12 : #define BOOST_JSON_STRING_HPP
13 :
14 : #include <boost/json/detail/config.hpp>
15 : #include <boost/json/pilfer.hpp>
16 : #include <boost/json/storage_ptr.hpp>
17 : #include <boost/json/string_view.hpp>
18 : #include <boost/json/detail/digest.hpp>
19 : #include <boost/json/detail/except.hpp>
20 : #include <boost/json/detail/string_impl.hpp>
21 : #include <boost/json/detail/value.hpp>
22 : #include <boost/system/result.hpp>
23 : #include <cstring>
24 : #include <iosfwd>
25 : #include <iterator>
26 : #include <new>
27 : #include <type_traits>
28 : #include <utility>
29 :
30 : namespace boost {
31 : namespace json {
32 :
33 : class value;
34 :
35 : /** The native type of string values.
36 :
37 : Instances of string store and manipulate sequences of `char` using the
38 : UTF-8 encoding. The elements of a string are stored contiguously. A pointer
39 : to any character in a string may be passed to functions that expect
40 : a pointer to the first element of a null-terminated `char` array. The type
41 : uses small buffer optimisation to avoid allocations for small strings.
42 :
43 : String iterators are regular `char` pointers.
44 :
45 : @attention `string` member functions do not validate any UTF-8 byte sequences
46 : passed to them.
47 :
48 : @par Thread Safety
49 : Non-const member functions may not be called concurrently with any other
50 : member functions.
51 :
52 : @par Satisfies
53 : [_ContiguousContainer_](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
54 : [_ReversibleContainer_](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer),
55 : and {req_SequenceContainer}.
56 : */
57 : class string
58 : {
59 : friend class value;
60 : #ifndef BOOST_JSON_DOCS
61 : // VFALCO doc toolchain shouldn't show this but does
62 : friend struct detail::access;
63 : #endif
64 :
65 : using string_impl = detail::string_impl;
66 :
67 : inline
68 : string(
69 : detail::key_t const&,
70 : string_view s,
71 : storage_ptr sp);
72 :
73 : inline
74 : string(
75 : detail::key_t const&,
76 : string_view s1,
77 : string_view s2,
78 : storage_ptr sp);
79 :
80 : public:
81 : /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
82 : using allocator_type = container::pmr::polymorphic_allocator<value>;
83 :
84 : /// The type of a character
85 : using value_type = char;
86 :
87 : /// The type used to represent unsigned integers
88 : using size_type = std::size_t;
89 :
90 : /// The type used to represent signed integers
91 : using difference_type = std::ptrdiff_t;
92 :
93 : /// A pointer to an element
94 : using pointer = char*;
95 :
96 : /// A const pointer to an element
97 : using const_pointer = char const*;
98 :
99 : /// A reference to an element
100 : using reference = char&;
101 :
102 : /// A const reference to an element
103 : using const_reference = const char&;
104 :
105 : /// A random access iterator to an element
106 : using iterator = char*;
107 :
108 : /// A random access const iterator to an element
109 : using const_iterator = char const*;
110 :
111 : /// A reverse random access iterator to an element
112 : using reverse_iterator =
113 : std::reverse_iterator<iterator>;
114 :
115 : /// A reverse random access const iterator to an element
116 : using const_reverse_iterator =
117 : std::reverse_iterator<const_iterator>;
118 :
119 : /** A special index
120 :
121 : Represents the end of the string.
122 : */
123 : static constexpr std::size_t npos =
124 : string_view::npos;
125 :
126 : private:
127 : template<class T>
128 : using is_inputit = typename std::enable_if<
129 : std::is_convertible<typename
130 : std::iterator_traits<T>::reference,
131 : char>::value>::type;
132 :
133 : storage_ptr sp_; // must come first
134 : string_impl impl_;
135 :
136 : public:
137 : /** Destructor.
138 :
139 : Any dynamically allocated internal storage is freed.
140 :
141 : @par Complexity
142 : Constant.
143 :
144 : @par Exception Safety
145 : No-throw guarantee.
146 : */
147 30659 : ~string() noexcept
148 : {
149 30659 : impl_.destroy(sp_);
150 30659 : }
151 :
152 : //------------------------------------------------------
153 : //
154 : // Construction
155 : //
156 : //------------------------------------------------------
157 :
158 : /** Constructors.
159 :
160 : Construct a string.
161 :
162 : @li **(1)**, **(2)** the string is empty with a non-zero,
163 : unspecified capacity.
164 :
165 : @li **(3)** the string is filled with `count` copies of character `ch`.
166 :
167 : @li **(4)** the string will contain a copy of the characters of `s`.
168 :
169 : @li **(5)** the string will contain a copy of the characters of the
170 : null-terminated string `s`.
171 :
172 : @li **(6)** the string will contain a copy of the characters in the
173 : range `[s, s + count)`.
174 :
175 : @li **(7)** the string will contain a copy of the characters in the
176 : range `[first, last)`.
177 :
178 : @li **(8)**, **(9)** the string contains a copy of the characters of
179 : `other`.
180 :
181 : @li **(10)** the string acquires ownership of the contents of `other`.
182 :
183 : @li **(11)** equivalent to **(10)** if `*sp == *other.storage()`;
184 : otherwise equivalent to **(9)**.
185 :
186 : @li **(12)** the string is acquires ownership of the contents of
187 : `other` using pilfer semantics. This is more efficient than move
188 : construction, when it is known that the moved-from object
189 : will be immediately destroyed afterwards.
190 :
191 : With **(2)**--**(7)**, **(9)**, **(11)** the constructed string uses
192 : memory resource of `sp`. With **(8)**, **(10)**, and **(12)** it uses
193 : `other`'s memory resource. In either case the string will share the
194 : ownership of the memory resource. With **(1)** it uses the
195 : \<\<default_memory_resource, default memory resource\>\>.
196 :
197 : After **(10)** `other` behaves as if newly constructed with its
198 : current storage pointer.
199 :
200 : After **(12)** `other` is not in a usable state and may only be
201 : destroyed.
202 :
203 : @par Constraints
204 : `InputIt` satisfies {req_InputIterator}.
205 :
206 : @par Complexity
207 : @li **(1)**, **(2)**, **(10)**, **(12)** constant.
208 : @li **(3)** linear in `count`.
209 : @li **(4)** linear in `s.size()`.
210 : @li **(5)** linear in `std::strlen(s)`.
211 : @li **(6)** linear in `count`.
212 : @li **(7)** linear in `std::distance(first, last)`.
213 : @li **(8)**, **(9)** linear in `other.size()`.
214 : @li **(11)** constant if `*sp == *other.storage()`; otherwise linear in
215 : `other.size()`.
216 :
217 : @par Exception Safety
218 : @li **(1)**, **(2)**, **(10)**, **(12)** no-throw guarantee.
219 : @li **(3)**--**(6)**, **(8)**, **(9)**, **(11)** strong guarantee.
220 : @li **(7)** strong guarantee if `InputIt` satisfies
221 : {req_ForwardIterator}, basic guarantee otherwise.
222 :
223 : Calls to `memory_resource::allocate` may throw.
224 :
225 : @throw boost::system::system_error The constructed string's size would
226 : have exceeded @ref max_size().
227 :
228 : @see @ref pilfer,
229 : [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
230 :
231 : @{
232 : */
233 2456 : string() = default;
234 :
235 : /** Overload
236 :
237 : @param sp A pointer to the @ref boost::container::pmr::memory_resource
238 : to use. The container will acquire shared ownership of the memory
239 : resource.
240 : */
241 : explicit
242 9103 : string(storage_ptr sp)
243 9103 : : sp_(std::move(sp))
244 : {
245 9103 : }
246 :
247 : /** Overload
248 :
249 : @param count The size of the resulting string.
250 : @param ch The value to initialize characters of the string with.
251 : @param sp
252 : */
253 : BOOST_JSON_DECL
254 : explicit
255 : string(
256 : std::size_t count,
257 : char ch,
258 : storage_ptr sp = {});
259 :
260 : /** Overload
261 :
262 : @param s The string to copy from.
263 : @param sp
264 : */
265 : BOOST_JSON_DECL
266 : string(
267 : string_view s,
268 : storage_ptr sp = {});
269 :
270 : /// Overload
271 : BOOST_JSON_DECL
272 : string(
273 : char const* s,
274 : storage_ptr sp = {});
275 :
276 : /// Overload
277 : BOOST_JSON_DECL
278 : explicit
279 : string(
280 : char const* s,
281 : std::size_t count,
282 : storage_ptr sp = {});
283 :
284 : /** Overload
285 :
286 : @tparam InputIt The type of the iterators.
287 :
288 : @param first An input iterator pointing to the first character to
289 : insert, or pointing to the end of the range.
290 : @param last An input iterator pointing to the end of the range.
291 : @param sp
292 : */
293 : template<class InputIt
294 : #ifndef BOOST_JSON_DOCS
295 : ,class = is_inputit<InputIt>
296 : #endif
297 : >
298 : explicit
299 : string(
300 : InputIt first,
301 : InputIt last,
302 : storage_ptr sp = {});
303 :
304 : /** Overload
305 : @param other The source string.
306 : */
307 : BOOST_JSON_DECL
308 : string(string const& other);
309 :
310 : /// Overload
311 : BOOST_JSON_DECL
312 : explicit
313 : string(
314 : string const& other,
315 : storage_ptr sp);
316 :
317 : /// Overload
318 415 : string(string&& other) noexcept
319 415 : : sp_(other.sp_)
320 415 : , impl_(other.impl_)
321 : {
322 415 : ::new(&other.impl_) string_impl();
323 415 : }
324 :
325 : /// Overload
326 : BOOST_JSON_DECL
327 : explicit
328 : string(
329 : string&& other,
330 : storage_ptr sp);
331 :
332 : /// Overload
333 5 : string(pilfered<string> other) noexcept
334 5 : : sp_(std::move(other.get().sp_))
335 5 : , impl_(other.get().impl_)
336 : {
337 5 : ::new(&other.get().impl_) string_impl();
338 5 : }
339 : /// @}
340 :
341 : //------------------------------------------------------
342 : //
343 : // Assignment
344 : //
345 : //------------------------------------------------------
346 :
347 : /** Assignment operators.
348 :
349 : @li **(1)**, **(4)** the contents are replaced with an element-wise
350 : copy of `other`.
351 : @li **(2)** takes ownership of `other`'s element storage if
352 : `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
353 : @li **(3)** the contents are replaced with an element-wise copy of
354 : null-terminated string `s`.
355 :
356 : After **(2)**, the moved-from array behaves as if newly constructed
357 : with its current storage pointer.
358 :
359 : @par Complexity
360 : @li **(1)**, **(4)** linear in `other.size()`.
361 : @li **(2)** constant if `*storage() == *other.storage()`; otherwise
362 : linear in `other.size()`.
363 : @li **(3)** linear in `std::strlen(s)`.
364 :
365 : @par Exception Safety
366 : {sp} **(2)** provides strong guarantee if
367 : `*storage() != *other.storage()` and no-throw guarantee otherwise.
368 : Other overloads provide strong guarantee.
369 : Calls to `memory_resource::allocate` may throw.
370 :
371 : @param other The string to copy.
372 :
373 : @return `*this`
374 :
375 : @{
376 : */
377 : BOOST_JSON_DECL
378 : string&
379 : operator=(string const& other);
380 :
381 : BOOST_JSON_DECL
382 : string&
383 : operator=(string&& other);
384 :
385 : /** Overload
386 :
387 : @param s The null-terminated character string.
388 :
389 : @throw boost::system::system_error `std::strlen(s) >` @ref max_size().
390 : */
391 : BOOST_JSON_DECL
392 : string&
393 : operator=(char const* s);
394 :
395 : /** Overload
396 :
397 : @throw `boost::system::system_error` `other.size() >` @ref max_size().
398 : */
399 : BOOST_JSON_DECL
400 : string&
401 : operator=(string_view other);
402 : /// @}
403 :
404 : /** Assign characters to a string.
405 :
406 : @li **(1)** replaces the contents with `count` copies of character
407 : `ch`.
408 :
409 : @li **(2)** replaces the contents with copies of the characters in the
410 : range `[s, s + count)`. This range can contain null characters.
411 :
412 : @li **(3)** replaces the contents with those of the null terminated
413 : string `s`. The length of the string is determined by the first null
414 : character.
415 :
416 : @li **(4)** replaces the contents with copies of characters in the
417 : range `[first, last)`.
418 :
419 : @li **(5)** Replaces the contents with those of string view `s`. This
420 : view can contain null characters.
421 :
422 : @li **(6)** replaces the contents with a copy of the characters of
423 : `other`.
424 :
425 : @li **(7)** if `*storage() == *other.storage()` takes ownership of the
426 : element storage of `other`; otherwise equivalent to **(6)**.
427 :
428 : Self-assignment using **(7)** does nothing.
429 :
430 : After **(7)** `other` is left in valid but unspecified state.
431 :
432 : @par Constraints
433 : `InputIt` satisfies {req_InputIterator}.
434 :
435 : @par Complexity
436 : @li **(1)**, **(2)** linear in `count`.
437 : @li **(3)** linear in `std::strlen(s)`.
438 : @li **(4)** linear in `std::distance(first, last)`.
439 : @li **(5)** linear in `s.size()`.
440 : @li **(6)** linear in `other.size()`.
441 : @li **(7)** constant if `*storage() == *other.storage()`, otherwise
442 : linear in `other.size()`.
443 :
444 : @par Exception Safety
445 : {sp} **(7)** provides strong guarantee if
446 : `*storage() != *other.storage()` and no-throw guarantee otherwise.
447 : Other overloads provide strong guarantee. Calls to
448 : `memory_resource::allocate` may throw.
449 :
450 : @return `*this`.
451 :
452 : @param count The number of the characters to use.
453 :
454 : @param ch The character to fill the string with.
455 :
456 : @throw boost::system::system_error The size of the string after the
457 : operation would exceed @ref max_size().
458 :
459 : @{
460 : */
461 : BOOST_JSON_DECL
462 : string&
463 : assign(
464 : std::size_t count,
465 : char ch);
466 :
467 : /** Overload
468 : @param s A pointer to a character string used to copy from.
469 : @param count
470 : */
471 : BOOST_JSON_DECL
472 : string&
473 : assign(
474 : char const* s,
475 : std::size_t count);
476 :
477 : /** Overload
478 : @param s
479 : */
480 : BOOST_JSON_DECL
481 : string&
482 : assign(
483 : char const* s);
484 :
485 : /** Overload
486 :
487 : @tparam InputIt The type of the iterators.
488 :
489 : @param first An input iterator pointing to the first character to
490 : insert, or pointing to the end of the range.
491 : @param last An input iterator pointing to the end of the range.
492 : */
493 : template<class InputIt
494 : #ifndef BOOST_JSON_DOCS
495 : ,class = is_inputit<InputIt>
496 : #endif
497 : >
498 : string&
499 : assign(
500 : InputIt first,
501 : InputIt last);
502 :
503 : /** Overload
504 : @param s The string view to copy from.
505 : */
506 : string&
507 17970 : assign(string_view s)
508 : {
509 17970 : return assign(s.data(), s.size());
510 : }
511 :
512 : /** Overload
513 : @param other Another string.
514 : */
515 : BOOST_JSON_DECL
516 : string&
517 : assign(
518 : string const& other);
519 :
520 : /** Overload
521 : @param other
522 : */
523 : BOOST_JSON_DECL
524 : string&
525 : assign(string&& other);
526 : /// @}
527 :
528 : /** Return the associated memory resource.
529 :
530 : This function returns a smart pointer to the
531 : @ref boost::container::pmr::memory_resource used by the container.
532 :
533 : @par Complexity
534 : Constant.
535 :
536 : @par Exception Safety
537 : No-throw guarantee.
538 : */
539 : storage_ptr const&
540 116 : storage() const noexcept
541 : {
542 116 : return sp_;
543 : }
544 :
545 : /** Return the associated allocator.
546 :
547 : This function returns an instance of @ref allocator_type constructed
548 : from the associated @ref boost::container::pmr::memory_resource.
549 :
550 : @par Complexity
551 : Constant.
552 :
553 : @par Exception Safety
554 : No-throw guarantee.
555 : */
556 : allocator_type
557 1 : get_allocator() const noexcept
558 : {
559 1 : return sp_.get();
560 : }
561 :
562 : //------------------------------------------------------
563 : //
564 : // Element Access
565 : //
566 : //------------------------------------------------------
567 :
568 : /** Return a character with bounds checking.
569 :
570 : Returns @ref boost::system::result containing a reference to the
571 : character specified at location `pos`, if `pos` is within the range of
572 : the string. Otherwise the result contains an `error_code`.
573 :
574 : @par Exception Safety
575 : Strong guarantee.
576 :
577 : @param pos A zero-based index to access.
578 :
579 : @par Complexity
580 : Constant.
581 :
582 : @{
583 : */
584 : BOOST_JSON_DECL
585 : system::result<char&>
586 : try_at(std::size_t pos) noexcept;
587 :
588 : BOOST_JSON_DECL
589 : system::result<char const&>
590 : try_at(std::size_t pos) const noexcept;
591 : /// @}
592 :
593 : /** Return a character with bounds checking.
594 :
595 : Returns a reference to the character specified at location `pos`.
596 :
597 : @par Complexity
598 : Constant.
599 :
600 : @par Exception Safety
601 : Strong guarantee.
602 :
603 : @param pos A zero-based index to access.
604 : @param loc `source_location` to use in thrown exception; the source
605 : location of the call site by default.
606 :
607 : @throw boost::system::system_error `pos >=` @ref size().
608 :
609 : @{
610 : */
611 : inline
612 : char&
613 : at(
614 : std::size_t pos,
615 : source_location const& loc = BOOST_CURRENT_LOCATION);
616 :
617 : BOOST_JSON_DECL
618 : char const&
619 : at(
620 : std::size_t pos,
621 : source_location const& loc = BOOST_CURRENT_LOCATION) const;
622 : /// @}
623 :
624 : /** Return a character without bounds checking.
625 :
626 : Returns a reference to the character specified at location `pos`.
627 :
628 : @par Complexity
629 : Constant.
630 :
631 : @pre
632 : @code
633 : pos < size()
634 : @endcode
635 :
636 : @param pos A zero-based index to access.
637 :
638 : @{
639 : */
640 : char&
641 18 : operator[](std::size_t pos)
642 : {
643 18 : return impl_.data()[pos];
644 : }
645 :
646 : const char&
647 2 : operator[](std::size_t pos) const
648 : {
649 2 : return impl_.data()[pos];
650 : }
651 : /// @}
652 :
653 : /** Return the first character.
654 :
655 : Returns a reference to the first character.
656 :
657 : @pre
658 : @code
659 : ! empty()
660 : @endcode
661 :
662 : @par Complexity
663 : Constant.
664 :
665 : @par Exception Safety
666 : No-throw guarantee.
667 :
668 : @{
669 : */
670 : char&
671 10 : front()
672 : {
673 10 : return impl_.data()[0];
674 : }
675 :
676 : char const&
677 6 : front() const
678 : {
679 6 : return impl_.data()[0];
680 : }
681 : /// @}
682 :
683 : /** Return the last character.
684 :
685 : Returns a reference to the last character.
686 :
687 : @pre
688 : @code
689 : ! empty()
690 : @endcode
691 :
692 : @par Complexity
693 : Constant.
694 :
695 : @{
696 : */
697 : char&
698 39 : back()
699 : {
700 39 : return impl_.data()[impl_.size() - 1];
701 : }
702 :
703 : char const&
704 6 : back() const
705 : {
706 6 : return impl_.data()[impl_.size() - 1];
707 : }
708 : /// @}
709 :
710 : /** Return the underlying character array directly.
711 :
712 : Returns a pointer to the underlying array serving as storage. The value
713 : returned is such that the range `[data(), data() + size())` is always
714 : a valid range, even if the container is empty.
715 :
716 : @note The value returned from this function is never equal to
717 : `nullptr`.
718 :
719 : @par Complexity
720 : Constant.
721 :
722 : @par Exception Safety
723 : No-throw guarantee.
724 :
725 : @{
726 : */
727 : char*
728 24103 : data() noexcept
729 : {
730 24103 : return impl_.data();
731 : }
732 :
733 : char const*
734 43980 : data() const noexcept
735 : {
736 43980 : return impl_.data();
737 : }
738 : /// @@}
739 :
740 : /** Return the underlying character array directly.
741 :
742 : Returns a pointer to the underlying array serving as storage. The value
743 : returned is such that the range `[c_str(), c_str() + size())` is always
744 : a valid range, even if the container is empty.
745 :
746 : @note The value returned from this function is never equal to
747 : `nullptr`.
748 :
749 : @par Complexity
750 : Constant.
751 : */
752 : char const*
753 4 : c_str() const noexcept
754 : {
755 4 : return impl_.data();
756 : }
757 :
758 : /** Convert to a @ref string_view referring to the string.
759 :
760 : Returns a string view to the
761 : underlying character string. The size of the view
762 : does not include the null terminator.
763 :
764 : @par Complexity
765 :
766 : Constant.
767 : */
768 57 : operator string_view() const noexcept
769 : {
770 57 : return {data(), size()};
771 : }
772 :
773 : #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
774 : /** Convert to @ref std::string_view referring to the string.
775 :
776 : Returns a string view to the underlying character string. The size of
777 : the view does not include the null terminator.
778 :
779 : This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW` is
780 : defined.
781 :
782 : @par Complexity
783 :
784 : Constant.
785 : */
786 : operator std::string_view() const noexcept
787 : {
788 : return {data(), size()};
789 : }
790 : #endif
791 :
792 : //------------------------------------------------------
793 : //
794 : // Iterators
795 : //
796 : //------------------------------------------------------
797 :
798 : /** Return an iterator to the beginning.
799 :
800 : If the container is empty, @ref end() is returned.
801 :
802 : @par Complexity
803 : Constant.
804 :
805 : @par Exception Safety
806 : No-throw guarantee.
807 :
808 : @{
809 : */
810 : iterator
811 34 : begin() noexcept
812 : {
813 34 : return impl_.data();
814 : }
815 :
816 : const_iterator
817 8 : begin() const noexcept
818 : {
819 8 : return impl_.data();
820 : }
821 : /// @}
822 :
823 : /** Return a const iterator to the first element.
824 :
825 : If the container is empty, @ref cend() is returned.
826 :
827 : @par Complexity
828 : Constant.
829 :
830 : @par Exception Safety
831 : No-throw guarantee.
832 : */
833 : const_iterator
834 2 : cbegin() const noexcept
835 : {
836 2 : return impl_.data();
837 : }
838 :
839 : /** Return an iterator to the end.
840 :
841 : The returned iterator only acts as a sentinel. Dereferencing it results
842 : in undefined behavior.
843 :
844 : @par Complexity
845 : Constant.
846 :
847 : @par Exception Safety
848 : No-throw guarantee.
849 :
850 : @{
851 : */
852 : iterator
853 3 : end() noexcept
854 : {
855 3 : return impl_.end();
856 : }
857 :
858 : const_iterator
859 3 : end() const noexcept
860 : {
861 3 : return impl_.end();
862 : }
863 : /// @}
864 :
865 : /** Return a const iterator past the last element.
866 :
867 : The returned iterator only acts as a sentinel. Dereferencing it results
868 : in undefined behavior.
869 :
870 : @par Complexity
871 : Constant.
872 :
873 : @par Exception Safety
874 : No-throw guarantee.
875 : */
876 : const_iterator
877 2 : cend() const noexcept
878 : {
879 2 : return impl_.end();
880 : }
881 :
882 : /** Return a reverse iterator to the first character of the reversed container.
883 :
884 : Returns the pointed-to character that corresponds to the last character
885 : of the non-reversed container. If the container is empty, @ref rend()
886 : is returned.
887 :
888 : @par Complexity
889 : Constant.
890 :
891 : @{
892 : */
893 : reverse_iterator
894 3 : rbegin() noexcept
895 : {
896 3 : return reverse_iterator(impl_.end());
897 : }
898 :
899 : const_reverse_iterator
900 3 : rbegin() const noexcept
901 : {
902 3 : return const_reverse_iterator(impl_.end());
903 : }
904 : /// @}
905 :
906 : /** Return a const reverse iterator to the first element of the reversed container.
907 :
908 : Returns the pointed-to character that corresponds to the last character
909 : of the non-reversed container. If the container is empty, @ref crend()
910 : is returned.
911 :
912 : @par Complexity
913 : Constant.
914 :
915 : @par Exception Safety
916 : No-throw guarantee.
917 : */
918 : const_reverse_iterator
919 2 : crbegin() const noexcept
920 : {
921 2 : return const_reverse_iterator(impl_.end());
922 : }
923 :
924 : /** Return a reverse iterator to the character following the last character of the reversed container.
925 :
926 : The pointed-to element corresponds to the element preceding the first
927 : element of the non-reversed container. The returned iterator only acts
928 : as a sentinel. Dereferencing it results in undefined behavior.
929 :
930 : @par Complexity
931 : Constant.
932 :
933 : @par Exception Safety
934 : No-throw guarantee.
935 :
936 : @{
937 : */
938 : reverse_iterator
939 3 : rend() noexcept
940 : {
941 3 : return reverse_iterator(begin());
942 : }
943 :
944 : const_reverse_iterator
945 3 : rend() const noexcept
946 : {
947 3 : return const_reverse_iterator(begin());
948 : }
949 : /// @}
950 :
951 : /** Return a const reverse iterator to the character following the last character of the reversed container.
952 :
953 : The pointed-to character corresponds to the character preceding the
954 : first character of the non-reversed container. The returned iterator
955 : only acts as a sentinel. Dereferencing it results in undefined
956 : behavior.
957 :
958 : @par Complexity
959 : Constant.
960 :
961 : @par Exception Safety
962 : No-throw guarantee.
963 : */
964 : const_reverse_iterator
965 2 : crend() const noexcept
966 : {
967 2 : return const_reverse_iterator(begin());
968 : }
969 :
970 : //------------------------------------------------------
971 : //
972 : // Capacity
973 : //
974 : //------------------------------------------------------
975 :
976 : /** Check if the string has no characters.
977 :
978 : Returns `true` if there are no characters in the string, i.e. @ref
979 : size() returns 0.
980 :
981 : @par Complexity
982 : Constant.
983 :
984 : @par Exception Safety
985 : No-throw guarantee.
986 : */
987 : bool
988 69 : empty() const noexcept
989 : {
990 69 : return impl_.size() == 0;
991 : }
992 :
993 : /** Return the number of characters in the string.
994 :
995 : The value returned does not include the null terminator, which is
996 : always present.
997 :
998 : @par Complexity
999 : Constant.
1000 : */
1001 : std::size_t
1002 47864 : size() const noexcept
1003 : {
1004 47864 : return impl_.size();
1005 : }
1006 :
1007 : /** Return the maximum number of characters any string can hold.
1008 :
1009 : The maximum is an implementation-defined number. This value is
1010 : a theoretical limit; at runtime, the actual maximum size may be less
1011 : due to resource limits.
1012 :
1013 : @par Complexity
1014 : Constant.
1015 : */
1016 : static
1017 : constexpr
1018 : std::size_t
1019 7895 : max_size() noexcept
1020 : {
1021 7895 : return string_impl::max_size();
1022 : }
1023 :
1024 : /** Return the number of characters that can be held in currently allocated memory.
1025 :
1026 : Returns the number of characters that the container has currently
1027 : allocated space for. This number is never smaller than the value
1028 : returned by @ref size().
1029 :
1030 : @par Complexity
1031 : Constant.
1032 :
1033 : @par Exception Safety
1034 : No-throw guarantee.
1035 : */
1036 : std::size_t
1037 11691 : capacity() const noexcept
1038 : {
1039 11691 : return impl_.capacity();
1040 : }
1041 :
1042 : /** Increase the capacity to at least a certain amount.
1043 :
1044 : This increases the capacity of the array to a value that is greater
1045 : than or equal to `new_capacity`. If `new_capacity > `@ref capacity(),
1046 : new memory is allocated. Otherwise, the call has no effect. The number
1047 : of elements and therefore the @ref size() of the container is not
1048 : changed.
1049 :
1050 : If new memory is allocated, all iterators including any past-the-end
1051 : iterators, and all references to the elements are invalidated.
1052 : Otherwise, no iterators or references are invalidated.
1053 :
1054 : @par Complexity
1055 : At most, linear in @ref size().
1056 :
1057 : @par Exception Safety
1058 : Strong guarantee. Calls to `memory_resource::allocate` may throw.
1059 :
1060 : @param new_capacity The new capacity of the array.
1061 :
1062 : @throw boost::system::system_error `new_capacity > `@ref max_size().
1063 : */
1064 : void
1065 11381 : reserve(std::size_t new_capacity)
1066 : {
1067 11381 : if(new_capacity <= capacity())
1068 1695 : return;
1069 9686 : reserve_impl(new_capacity);
1070 : }
1071 :
1072 : /** Request the removal of unused capacity.
1073 :
1074 : This performs a non-binding request to reduce @ref capacity() to
1075 : @ref size(). The request may or may not be fulfilled.
1076 :
1077 : @note If reallocation occurs, all iterators including any past-the-end
1078 : iterators, and all references to characters are invalidated. Otherwise,
1079 : no iterators or references are invalidated.
1080 :
1081 : @par Complexity
1082 : At most, linear in @ref size().
1083 : */
1084 : BOOST_JSON_DECL
1085 : void
1086 : shrink_to_fit();
1087 :
1088 : //------------------------------------------------------
1089 : //
1090 : // Operations
1091 : //
1092 : //------------------------------------------------------
1093 :
1094 : /** Clear the contents.
1095 :
1096 : Erases all characters from the string. After this call, @ref size()
1097 : returns zero but @ref capacity() is unchanged. All references,
1098 : pointers, or iterators referring to contained elements are invalidated.
1099 : Any past-the-end iterators are also invalidated.
1100 :
1101 : @par Complexity
1102 : Linear in @ref size().
1103 :
1104 : @par Exception Safety
1105 : No-throw guarantee.
1106 : */
1107 : BOOST_JSON_DECL
1108 : void
1109 : clear() noexcept;
1110 :
1111 : /** Insert characters at the specified index.
1112 :
1113 : @li **(1)** inserts `sv`.
1114 : @li **(2)** inserts `count` copies of `ch`.
1115 : @li **(3)** inserts the character `ch`.
1116 : @li **(4)** inserts characters from the range `[first, last)`.
1117 :
1118 : The first character is inserted at the index `pos`. All references,
1119 : pointers, or iterators referring to contained elements are invalidated.
1120 : Any past-the-end iterators are also invalidated.
1121 :
1122 : @par Constraints
1123 : `InputIt` satisfies {req_InputIterator}.
1124 :
1125 : @pre
1126 : `[first, last)` is a valid range.
1127 :
1128 : @par Exception Safety
1129 : @li **(1)**--*(3)* strong guarantee.
1130 : @li **(4)** strong guarantee if `InputIt` satisfies
1131 : {req_ForwardIterator}, basic guarantee otherwise.
1132 :
1133 : @return `*this`
1134 :
1135 : @param pos The index to insert at.
1136 : @param sv The `string_view` to insert.
1137 :
1138 : @throw boost::system::system_error The size of the string would exceed
1139 : @ref max_size().
1140 :
1141 : @throw boost::system::system_error `pos > `@ref size().
1142 :
1143 : @{
1144 : */
1145 : BOOST_JSON_DECL
1146 : string&
1147 : insert(
1148 : std::size_t pos,
1149 : string_view sv);
1150 :
1151 : /** Overload
1152 : @param count The number of characters to insert.
1153 : @param ch The character to insert.
1154 : @param pos
1155 : */
1156 : BOOST_JSON_DECL
1157 : string&
1158 : insert(
1159 : std::size_t pos,
1160 : std::size_t count,
1161 : char ch);
1162 :
1163 : /** Overload
1164 : @param pos
1165 : @param ch
1166 : */
1167 : string&
1168 3 : insert(
1169 : size_type pos,
1170 : char ch)
1171 : {
1172 3 : return insert(pos, 1, ch);
1173 : }
1174 :
1175 : /** Overload
1176 :
1177 : @tparam InputIt The type of the iterators.
1178 :
1179 : @param first The beginning of the character range.
1180 : @param last The end of the character range.
1181 : @param pos
1182 : */
1183 : template<class InputIt
1184 : #ifndef BOOST_JSON_DOCS
1185 : ,class = is_inputit<InputIt>
1186 : #endif
1187 : >
1188 : string&
1189 : insert(
1190 : size_type pos,
1191 : InputIt first,
1192 : InputIt last);
1193 : /// @}
1194 :
1195 : /** Remove characters from the string.
1196 :
1197 : @li **(1)** removes at most `count` but not more than `size() - pos`
1198 : characters starting at `index`.
1199 : @li **(2)** removes the character at `pos`.
1200 : @li **(3)** removes characters in the range `[first, last)`.
1201 :
1202 : All references, pointers, or iterators referring to contained elements
1203 : are invalidated. Any past-the-end iterators are also invalidated.
1204 :
1205 : @pre
1206 : `pos`, `first`, and `last` are iterators into this string. `first` and
1207 : `last` form a valid range.
1208 :
1209 : @par Complexity
1210 : @li **(1)** linear in `count`.
1211 : @li **(2)** constant.
1212 : @li **(3)** linear in `std::distance(first, last)`.
1213 :
1214 : @par Exception Safety
1215 : Strong guarantee.
1216 :
1217 : @return
1218 : @li **(1)** `*this`.
1219 :
1220 : @li **(2)** An iterator referring to the character immediately
1221 : following the removed character, or @ref end() if one does not exist.
1222 :
1223 : @li **(3)** An iterator referring to the character `last` previously
1224 : referred to, or @ref end() if one does not exist.
1225 :
1226 : @param index The index of the first character to remove.
1227 :
1228 : @param count The number of characters to remove. By default remove
1229 : until the end of the string.
1230 :
1231 : @throw boost::system::system_error `pos >` @ref size().
1232 :
1233 : @{
1234 : */
1235 : BOOST_JSON_DECL
1236 : string&
1237 : erase(
1238 : std::size_t index = 0,
1239 : std::size_t count = npos);
1240 :
1241 : /** Overload
1242 : @param pos An iterator referring to the character to erase.
1243 : */
1244 : BOOST_JSON_DECL
1245 : iterator
1246 : erase(const_iterator pos);
1247 :
1248 : /** Overload
1249 : @param first An iterator representing the first character to erase.
1250 : @param last An iterator one past the last character to erase.
1251 : */
1252 : BOOST_JSON_DECL
1253 : iterator
1254 : erase(
1255 : const_iterator first,
1256 : const_iterator last);
1257 : /// @}
1258 :
1259 : //------------------------------------------------------
1260 :
1261 : /** Append a character.
1262 :
1263 : Appends a character to the end of the string.
1264 :
1265 : @par Exception Safety
1266 : Strong guarantee.
1267 :
1268 : @param ch The character to append.
1269 :
1270 : @throw boost::system::system_error @ref size() `+ 1 > `@ref max_size().
1271 : */
1272 : BOOST_JSON_DECL
1273 : void
1274 : push_back(char ch);
1275 :
1276 : /** Remove the last character.
1277 :
1278 : Removes a character from the end of the string.
1279 :
1280 : @pre
1281 : @code
1282 : ! empty()
1283 : @endcode
1284 : */
1285 : BOOST_JSON_DECL
1286 : void
1287 : pop_back();
1288 :
1289 : //------------------------------------------------------
1290 :
1291 : /** Append characters to the string.
1292 :
1293 : @li **(1)** appends `count` copies of `ch`.
1294 :
1295 : @li **(2)** appends copies of characters of `sv`, preserving order.
1296 :
1297 : @li **(3)** appends characters from the range `[first, last)`,
1298 : preserving order.
1299 :
1300 : @pre
1301 : `[first, last)` shall be a valid range.
1302 :
1303 : @par Constraints
1304 : `InputIt` satisfies {req_InputIterator}.
1305 :
1306 : @par Exception Safety
1307 : Strong guarantee.
1308 :
1309 : @return `*this`.
1310 :
1311 : @param count The number of characters to append.
1312 : @param ch The character to append.
1313 :
1314 : @throw boost::system::system_error The size of the string after the
1315 : operation would exceed @ref max_size().
1316 :
1317 : @{
1318 : */
1319 : BOOST_JSON_DECL
1320 : string&
1321 : append(
1322 : std::size_t count,
1323 : char ch);
1324 :
1325 : /** Overload
1326 : @param sv The `string_view` to append.
1327 : */
1328 : BOOST_JSON_DECL
1329 : string&
1330 : append(string_view sv);
1331 :
1332 : /** Overload
1333 :
1334 : @tparam InputIt The type of the iterators.
1335 :
1336 : @param first An iterator representing the first character to append.
1337 : @param last An iterator one past the last character to append.
1338 : */
1339 : template<class InputIt
1340 : #ifndef BOOST_JSON_DOCS
1341 : ,class = is_inputit<InputIt>
1342 : #endif
1343 : >
1344 : string&
1345 : append(InputIt first, InputIt last);
1346 : /// @}
1347 :
1348 : /** Append characters to the string.
1349 :
1350 : @li **(1)** appends `[sv.begin(), sv.end())`.
1351 : @li **(2)** appends `ch`.
1352 :
1353 : @par Exception Safety
1354 : Strong guarantee.
1355 :
1356 : @return `*this`
1357 :
1358 : @param sv The `string_view` to append.
1359 :
1360 : @throw boost::system::system_error The size of the string after the
1361 : operation would exceed @ref max_size().
1362 :
1363 : @{
1364 : */
1365 : string&
1366 11 : operator+=(string_view sv)
1367 : {
1368 11 : return append(sv);
1369 : }
1370 :
1371 : /** Overload
1372 : @param ch The character to append.
1373 : */
1374 : string&
1375 44 : operator+=(char ch)
1376 : {
1377 44 : push_back(ch);
1378 43 : return *this;
1379 : }
1380 : /// @}
1381 :
1382 : //------------------------------------------------------
1383 :
1384 : /** Compare a string with the string.
1385 :
1386 : Let `comp` be `std::char_traits<char>::compare(data(), sv.data(),
1387 : std::min(size(), sv.size())`. If `comp != 0`, then the result is
1388 : `comp`. Otherwise, the result is `0` if `size() == sv.size()`, `-1` if
1389 : `size() < sv.size()`, and `1` otherwise.
1390 :
1391 : @par Complexity
1392 : Linear.
1393 :
1394 : @return The result of lexicographically comparing the characters of
1395 : `sv` and the string.
1396 :
1397 : @param sv The `string_view` to compare.
1398 : */
1399 : int
1400 13 : compare(string_view sv) const noexcept
1401 : {
1402 13 : return subview().compare(sv);
1403 : }
1404 :
1405 : //------------------------------------------------------
1406 :
1407 : /** Return whether the string begins with another string.
1408 :
1409 : @li **(1)** checks if the string begins with `s`.
1410 : @li **(2)** checks if the string begins with `ch`.
1411 :
1412 : @par Complexity
1413 : @li **(1)** linear in `s.size()`.
1414 : @li **(2)** constant.
1415 :
1416 : @param s The string to check for.
1417 :
1418 : @{
1419 : */
1420 : bool
1421 8 : starts_with(string_view s) const noexcept
1422 : {
1423 8 : return subview(0, s.size()) == s;
1424 : }
1425 :
1426 : /** Overload
1427 :
1428 : @param ch The character to check for.
1429 : */
1430 : bool
1431 4 : starts_with(char ch) const noexcept
1432 : {
1433 4 : return ! empty() && front() == ch;
1434 : }
1435 : /// @}
1436 :
1437 : /** Check if the string ends with given suffix.
1438 :
1439 : @li **(1)** returns `true` if the string ends with `s`.
1440 : @li **(2)** returns `true` if the string ends with the character `ch`.
1441 :
1442 : @par Complexity
1443 : @li **(1)** linear in `s`.
1444 : @li **(2)** constant.
1445 :
1446 : @par Exception Safety
1447 : No-throw guarantee.
1448 :
1449 : @param s The string to check for.
1450 :
1451 : @{
1452 : */
1453 : bool
1454 8 : ends_with(string_view s) const noexcept
1455 : {
1456 16 : return size() >= s.size() &&
1457 16 : subview(size() - s.size()) == s;
1458 : }
1459 :
1460 : /** Overload
1461 : @param ch The character to check for.
1462 : */
1463 : bool
1464 4 : ends_with(char ch) const noexcept
1465 : {
1466 4 : return ! empty() && back() == ch;
1467 : }
1468 : /// @}
1469 :
1470 : /** Replace a substring with another string.
1471 :
1472 : @li **(1)** replaces `std::min(count, size() - pos)` characters
1473 : starting at index `pos` with those of `sv`.
1474 : @li **(2)** replaces the characters in the range `[first, last)` with
1475 : those of `sv`.
1476 : @li **(3)** replaces the characters in the range `[first, last)` with
1477 : those of `[first2, last2)`.
1478 : @li **(4)** replaces `std::min(count, size() - pos)` characters
1479 : starting at index `pos` with `count2` copies of `ch`.
1480 : @li **(5)** replaces the characters in the range `[first, last)` with
1481 : `count2` copies of `ch`.
1482 :
1483 : All references, pointers, or iterators referring to contained elements
1484 : are invalidated. Any past-the-end iterators are also invalidated.
1485 :
1486 : @pre
1487 : `[first, last)` is a valid range. `[first2, last2)` is a valid range.
1488 :
1489 : @par Constraints
1490 : `InputIt` satisfies {req_InputIterator}.
1491 :
1492 : @par Exception Safety
1493 : Strong guarantee.
1494 :
1495 : @return `*this`
1496 :
1497 : @param pos The index to replace at.
1498 :
1499 : @param count The number of characters to replace.
1500 :
1501 : @param sv The `string_view` to replace with.
1502 :
1503 : @throw boost::system::system_error The resulting string's size would
1504 : have exceeded @ref max_size().
1505 :
1506 : @{
1507 : */
1508 : BOOST_JSON_DECL
1509 : string&
1510 : replace(
1511 : std::size_t pos,
1512 : std::size_t count,
1513 : string_view sv);
1514 :
1515 : /** Overload
1516 :
1517 : @param first An iterator referring to the first character to replace.
1518 : @param last An iterator one past the end of the last character to
1519 : replace.
1520 : @param sv
1521 : */
1522 : string&
1523 6 : replace(
1524 : const_iterator first,
1525 : const_iterator last,
1526 : string_view sv)
1527 : {
1528 6 : return replace(first - begin(), last - first, sv);
1529 : }
1530 :
1531 : /** Overload
1532 :
1533 : @tparam InputIt The type of the iterators.
1534 :
1535 : @param first2 An iterator referring to the first character to replace
1536 : with.
1537 : @param last2 An iterator one past the end of the last character to
1538 : replace with.
1539 : @param first
1540 : @param last
1541 : */
1542 : template<class InputIt
1543 : #ifndef BOOST_JSON_DOCS
1544 : ,class = is_inputit<InputIt>
1545 : #endif
1546 : >
1547 : string&
1548 : replace(
1549 : const_iterator first,
1550 : const_iterator last,
1551 : InputIt first2,
1552 : InputIt last2);
1553 :
1554 : /** Overload
1555 :
1556 : @param count2 The number of characters to replace with.
1557 : @param ch The character to replace with.
1558 : @param pos
1559 : @param count
1560 : */
1561 : BOOST_JSON_DECL
1562 : string&
1563 : replace(
1564 : std::size_t pos,
1565 : std::size_t count,
1566 : std::size_t count2,
1567 : char ch);
1568 :
1569 : /** Overload
1570 :
1571 : @param first
1572 : @param last
1573 : @param count2
1574 : @param ch
1575 : */
1576 : string&
1577 1 : replace(
1578 : const_iterator first,
1579 : const_iterator last,
1580 : std::size_t count2,
1581 : char ch)
1582 : {
1583 1 : return replace(first - begin(), last - first, count2, ch);
1584 : }
1585 : /// @}
1586 :
1587 : //------------------------------------------------------
1588 :
1589 : /** Return a view.
1590 :
1591 : @li **(1)** equivalent to `subview().substr(pos, count)`.
1592 : @li **(2)** equivalent to `string_view(data(), size())`.
1593 :
1594 : @par Exception Safety
1595 : Strong guarantee.
1596 :
1597 : @param pos The index of the first character of the substring.
1598 : @param count The length of the substring.
1599 :
1600 : @throw boost::system::system_error `pos > ` @ref size().
1601 : */
1602 : string_view
1603 41 : subview(
1604 : std::size_t pos,
1605 : std::size_t count = npos) const
1606 : {
1607 41 : return subview().substr(pos, count);
1608 : }
1609 :
1610 : /// Overload
1611 : string_view
1612 28988 : subview() const noexcept
1613 : {
1614 28988 : return string_view( data(), size() );
1615 : }
1616 :
1617 : //------------------------------------------------------
1618 :
1619 : /** Copy a substring to another string.
1620 :
1621 : Copies `std::min(count, size() - pos)` characters starting at index
1622 : `pos` to the string pointed to by `dest`.
1623 :
1624 : @attention This function doesn't put the null terminator after the
1625 : copied characters.
1626 :
1627 : @return The number of characters copied.
1628 :
1629 : @param count The number of characters to copy.
1630 :
1631 : @param dest The string to copy to.
1632 :
1633 : @param pos The index to begin copying from.
1634 :
1635 : @throw boost::system::system_error `pos >` @ref max_size().
1636 : */
1637 : std::size_t
1638 2 : copy(
1639 : char* dest,
1640 : std::size_t count,
1641 : std::size_t pos = 0) const
1642 : {
1643 2 : return subview().copy(dest, count, pos);
1644 : }
1645 :
1646 : //------------------------------------------------------
1647 :
1648 : /** Change the size of the string.
1649 :
1650 : Resizes the string to contain `count` characters. If
1651 : `count > `@ref size(), **(2)** appends copies of `ch` and **(1)**
1652 : appends ``'\0'``. Otherwise, `size()` is reduced to `count`.
1653 :
1654 : @param count The size to resize the string to.
1655 :
1656 : @throw boost::system::system_error `count > `@ref max_size().
1657 :
1658 : @{
1659 : */
1660 : void
1661 57 : resize(std::size_t count)
1662 : {
1663 57 : resize(count, 0);
1664 54 : }
1665 :
1666 : /** Overload
1667 :
1668 : @param count
1669 : @param ch The characters to append if the size increases.
1670 : */
1671 : BOOST_JSON_DECL
1672 : void
1673 : resize(std::size_t count, char ch);
1674 : /// @}
1675 :
1676 : /** Increase size without changing capacity.
1677 :
1678 : This increases the size of the string by `n` characters, adjusting the
1679 : position of the terminating null character for the new size. The new
1680 : characters remain uninitialized. This function may be used to append
1681 : characters directly into the storage between @ref end() and @ref data()
1682 : ` + ` @ref capacity().
1683 :
1684 : @pre
1685 : @code
1686 : count <= capacity() - size()
1687 : @endcode
1688 :
1689 : @param n The amount to increase the size by.
1690 : */
1691 : void
1692 15153 : grow(std::size_t n) noexcept
1693 : {
1694 15153 : BOOST_ASSERT(
1695 : n <= impl_.capacity() - impl_.size());
1696 15153 : impl_.term(impl_.size() + n);
1697 15153 : }
1698 :
1699 : /** Swap the contents.
1700 :
1701 : Exchanges the contents of this string with another string. Ownership of
1702 : the respective @ref boost::container::pmr::memory_resource objects is
1703 : not transferred.
1704 :
1705 : @li If `&other == this`, do nothing. Otherwise,
1706 : @li if `*other.storage() == *this->storage()`, ownership of the
1707 : underlying memory is swapped in constant time, with no possibility
1708 : of exceptions. All iterators and references remain valid.
1709 : Otherwise,
1710 : @li the contents are logically swapped by making copies, which can
1711 : throw. In this case all iterators and references are invalidated.
1712 :
1713 : @par Complexity
1714 : Constant or linear in @ref size() `+ other.size()`.
1715 :
1716 : @par Exception Safety
1717 : Strong guarantee. Calls to `memory_resource::allocate` may throw.
1718 : */
1719 : BOOST_JSON_DECL
1720 : void
1721 : swap(string& other);
1722 :
1723 : /** Exchange the given values.
1724 :
1725 : Exchanges the contents of the string `lhs` with another string `rhs`.
1726 : Ownership of the respective @ref boost::container::pmr::memory_resource
1727 : objects is not transferred.
1728 :
1729 : @li If `&lhs == &rhs`, do nothing. Otherwise,
1730 : @li if `*lhs.storage() == *rhs.storage()`, ownership of the underlying
1731 : memory is swapped in constant time, with no possibility of
1732 : exceptions. All iterators and references remain valid. Otherwise,
1733 : @li the contents are logically swapped by making a copy, which can
1734 : throw. In this case all iterators and references are invalidated.
1735 :
1736 : @par Effects
1737 : @code
1738 : lhs.swap( rhs );
1739 : @endcode
1740 :
1741 : @par Complexity
1742 : Constant or linear in `lhs.size() + rhs.size()`.
1743 :
1744 : @par Exception Safety
1745 : Strong guarantee.
1746 : Calls to `memory_resource::allocate` may throw.
1747 :
1748 : @param lhs The string to exchange.
1749 : @param rhs The string to exchange.
1750 :
1751 : @see @ref string::swap
1752 : */
1753 : friend
1754 : void
1755 2 : swap(string& lhs, string& rhs)
1756 : {
1757 2 : lhs.swap(rhs);
1758 2 : }
1759 : //------------------------------------------------------
1760 : //
1761 : // Search
1762 : //
1763 : //------------------------------------------------------
1764 :
1765 : /** Find the first occurrence of characters within the string.
1766 :
1767 : Search from `pos` onward for the first substring that is equal to the
1768 : first argument.
1769 :
1770 : @li **(1)** searches for the presense of the substring equal to `sv`.
1771 : @li **(2)** searches for the presense of the substring consisting of
1772 : the character `ch`.
1773 :
1774 : @par Complexity
1775 : Linear in @ref size().
1776 :
1777 : @par Exception Safety
1778 : No-throw guarantee.
1779 :
1780 : @return The index of the first character of the found substring, or
1781 : @ref npos if none was found.
1782 :
1783 : @param sv The `string_view` to search for.
1784 : @param pos The index to start searching at.
1785 :
1786 : @{
1787 : */
1788 : std::size_t
1789 5 : find(
1790 : string_view sv,
1791 : std::size_t pos = 0) const noexcept
1792 : {
1793 5 : return subview().find(sv, pos);
1794 : }
1795 :
1796 : /** Overload
1797 :
1798 : @param ch The character to search for.
1799 : @param pos
1800 : */
1801 : std::size_t
1802 3 : find(
1803 : char ch,
1804 : std::size_t pos = 0) const noexcept
1805 : {
1806 3 : return subview().find(ch, pos);
1807 : }
1808 : /// @}
1809 :
1810 : /** Find the last occurrence of a string within the string.
1811 :
1812 : @li **(1)** searches for the last substring equal to `sv`.
1813 : @li **(2)** searches for the last occurrence of `ch`.
1814 :
1815 : Both functions search for substrings fully contained within `[begin(),
1816 : begin() + pos)`.
1817 :
1818 : @par Complexity
1819 : Linear.
1820 :
1821 : @return Index of the first character of the found substring or
1822 : @ref npos if none was found.
1823 :
1824 : @param sv The string to search for.
1825 : @param pos The index to start searching at. By default searches from
1826 : the end of the string.
1827 :
1828 : @{
1829 : */
1830 : std::size_t
1831 5 : rfind(
1832 : string_view sv,
1833 : std::size_t pos = npos) const noexcept
1834 : {
1835 5 : return subview().rfind(sv, pos);
1836 : }
1837 :
1838 : /** Overload
1839 :
1840 : @param ch The character to search for.
1841 : @param pos
1842 : */
1843 : std::size_t
1844 3 : rfind(
1845 : char ch,
1846 : std::size_t pos = npos) const noexcept
1847 : {
1848 3 : return subview().rfind(ch, pos);
1849 : }
1850 : /// @}
1851 :
1852 : //------------------------------------------------------
1853 :
1854 : /** Find the first character present in the specified string.
1855 :
1856 : Search from `pos` onward for the first character in this string that is
1857 : equal to any of the characters of `sv`.
1858 :
1859 : @par Complexity
1860 : Linear in @ref size() `+ sv.size()`.
1861 :
1862 : @par Exception Safety
1863 : No-throw guarantee.
1864 :
1865 : @return The index of the found character, or @ref npos if none exists.
1866 :
1867 : @param sv The characters to search for.
1868 : @param pos The index to start searching at.
1869 : */
1870 : std::size_t
1871 5 : find_first_of(
1872 : string_view sv,
1873 : std::size_t pos = 0) const noexcept
1874 : {
1875 5 : return subview().find_first_of(sv, pos);
1876 : }
1877 :
1878 : /** Find the first character missing from the specified string.
1879 :
1880 : Search from `pos` onward for the first character in this string that is
1881 : not equal to any of the characters in the string provided as the first
1882 : argument.
1883 :
1884 : @li **(1)** compares with the characters in `sv`.
1885 : @li **(2)** compares with the character `ch`.
1886 :
1887 : @par Complexity
1888 : @li **(1)** linear in @ref size() `+ sv.size()`.
1889 : @li **(2)** linear in @ref size().
1890 :
1891 : @par Exception Safety
1892 : No-throw guarantee.
1893 :
1894 : @return The index of the found character, or @ref npos if none exists.
1895 :
1896 : @param sv The characters to compare with.
1897 : @param pos The index to start searching at.
1898 :
1899 : @{
1900 : */
1901 : std::size_t
1902 4 : find_first_not_of(
1903 : string_view sv,
1904 : std::size_t pos = 0) const noexcept
1905 : {
1906 4 : return subview().find_first_not_of(sv, pos);
1907 : }
1908 :
1909 : /** Overload
1910 : @param ch The character to compare with.
1911 : @param pos
1912 : */
1913 : std::size_t
1914 3 : find_first_not_of(
1915 : char ch,
1916 : std::size_t pos = 0) const noexcept
1917 : {
1918 3 : return subview().find_first_not_of(ch, pos);
1919 : }
1920 : /// @}
1921 :
1922 : /** Find the last character present in the specified string.
1923 :
1924 : Search from `pos` backwards for the first character in this string that
1925 : is equal to any of the characters of `sv`. If `pos` is equal to @ref
1926 : npos (the default), search from the last character.
1927 :
1928 : @par Complexity
1929 : Linear in @ref size() `+ sv.size()`.
1930 :
1931 : @par Exception Safety
1932 : No-throw guarantee.
1933 :
1934 : @return The index of the found character, or @ref npos if none exists.
1935 :
1936 : @param sv The characters to search for.
1937 : @param pos The index to start searching at.
1938 : */
1939 : std::size_t
1940 5 : find_last_of(
1941 : string_view sv,
1942 : std::size_t pos = npos) const noexcept
1943 : {
1944 5 : return subview().find_last_of(sv, pos);
1945 : }
1946 :
1947 : /** Find the last character missing from the specified string.
1948 :
1949 :
1950 : Search from `pos` backwards for the first character in this string that
1951 : is not equal to any of the characters in the string provided as the
1952 : first argument. If `pos` is equal to @ref npos (the default), search
1953 : from the last character.
1954 :
1955 : @li **(1)** compares with the characters in `sv`.
1956 : @li **(2)** compares with the character `ch`.
1957 :
1958 : @par Complexity
1959 : @li **(1)** linear in @ref size() `+ sv.size()`.
1960 : @li **(2)** linear in @ref size().
1961 :
1962 : @par Exception Safety
1963 : No-throw guarantee.
1964 :
1965 : @return The index of the found character, or @ref npos if none exists.
1966 :
1967 : @param sv The characters to compare with.
1968 : @param pos The index to start searching at.
1969 :
1970 : @{
1971 : */
1972 : std::size_t
1973 4 : find_last_not_of(
1974 : string_view sv,
1975 : std::size_t pos = npos) const noexcept
1976 : {
1977 4 : return subview().find_last_not_of(sv, pos);
1978 : }
1979 :
1980 : /** Overload
1981 : @param ch The character to compare with.
1982 : @param pos
1983 : */
1984 : std::size_t
1985 3 : find_last_not_of(
1986 : char ch,
1987 : std::size_t pos = npos) const noexcept
1988 : {
1989 3 : return subview().find_last_not_of(ch, pos);
1990 : }
1991 : /// @}
1992 :
1993 : /** Serialize a @ref string to an output stream.
1994 :
1995 : This function serializes a `string` as JSON into the output stream.
1996 :
1997 : @return Reference to `os`.
1998 :
1999 : @par Complexity
2000 : Linear in the `str.size()`.
2001 :
2002 : @par Exception Safety
2003 : Strong guarantee. Calls to `memory_resource::allocate` may throw.
2004 :
2005 : @param os The output stream to serialize to.
2006 : @param str The value to serialize.
2007 : */
2008 : BOOST_JSON_DECL
2009 : friend
2010 : std::ostream&
2011 : operator<<(
2012 : std::ostream& os,
2013 : string const& str);
2014 :
2015 : private:
2016 : class undo;
2017 :
2018 : template<class It>
2019 : using iter_cat = typename
2020 : std::iterator_traits<It>::iterator_category;
2021 :
2022 : template<class InputIt>
2023 : void
2024 : assign(InputIt first, InputIt last,
2025 : std::random_access_iterator_tag);
2026 :
2027 : template<class InputIt>
2028 : void
2029 : assign(InputIt first, InputIt last,
2030 : std::input_iterator_tag);
2031 :
2032 : template<class InputIt>
2033 : void
2034 : append(InputIt first, InputIt last,
2035 : std::random_access_iterator_tag);
2036 :
2037 : template<class InputIt>
2038 : void
2039 : append(InputIt first, InputIt last,
2040 : std::input_iterator_tag);
2041 :
2042 : BOOST_JSON_DECL
2043 : void
2044 : reserve_impl(std::size_t new_capacity);
2045 : };
2046 :
2047 : //----------------------------------------------------------
2048 :
2049 : namespace detail
2050 : {
2051 :
2052 : template <>
2053 : inline
2054 : string_view
2055 28820 : to_string_view<string>(string const& s) noexcept
2056 : {
2057 28820 : return s.subview();
2058 : }
2059 :
2060 : } // namespace detail
2061 :
2062 :
2063 : /** Checks if lhs equals rhs.
2064 :
2065 : @li **(1)** A lexicographical comparison is used.
2066 : @li **(2)** equivalent to `lhs.get() == rhs.get()`.
2067 :
2068 : @par Complexity
2069 : @li **(1)** linear in `lhs.size() + rhs.size()`.
2070 : @li **(2)** constant.
2071 :
2072 : @par Exception Safety
2073 : No-throw guarantee.
2074 : */
2075 : #ifdef BOOST_JSON_DOCS
2076 : bool
2077 : operator==(string const& lhs, string const& rhs) noexcept
2078 : #else
2079 : template<class T, class U>
2080 : detail::string_comp_op_requirement<T, U>
2081 15595 : operator==(T const& lhs, U const& rhs) noexcept
2082 : #endif
2083 : {
2084 15595 : return detail::to_string_view(lhs) == detail::to_string_view(rhs);
2085 : }
2086 :
2087 : /** Checks if lhs does not equal rhs.
2088 :
2089 : @li **(1)** A lexicographical comparison is used.
2090 : @li **(2)** equivalent to `lhs.get() != rhs.get()`.
2091 :
2092 : @par Complexity
2093 : @li **(1)** linear in `lhs.size() + rhs.size()`.
2094 : @li **(2)** constant.
2095 :
2096 : @par Exception Safety
2097 : No-throw guarantee.
2098 : */
2099 : #ifdef BOOST_JSON_DOCS
2100 : bool
2101 : operator!=(string const& lhs, string const& rhs) noexcept
2102 : #else
2103 : template<class T, class U>
2104 : detail::string_comp_op_requirement<T, U>
2105 24 : operator!=(T const& lhs, U const& rhs) noexcept
2106 : #endif
2107 : {
2108 24 : return detail::to_string_view(lhs) != detail::to_string_view(rhs);
2109 : }
2110 :
2111 : /** Check if lhs is less than rhs.
2112 :
2113 : A lexicographical comparison is used.
2114 :
2115 : @par Complexity
2116 : Linear in `lhs.size() + rhs.size()`.
2117 :
2118 : @par Exception Safety
2119 : No-throw guarantee.
2120 : */
2121 : #ifdef BOOST_JSON_DOCS
2122 : bool
2123 : operator<(string const& lhs, string const& rhs) noexcept
2124 : #else
2125 : template<class T, class U>
2126 : detail::string_comp_op_requirement<T, U>
2127 12 : operator<(T const& lhs, U const& rhs) noexcept
2128 : #endif
2129 : {
2130 12 : return detail::to_string_view(lhs) < detail::to_string_view(rhs);
2131 : }
2132 :
2133 : /** Check if lhs is less than or equal to rhs.
2134 :
2135 : A lexicographical comparison is used.
2136 :
2137 : @par Complexity
2138 : Linear in `lhs.size() + rhs.size()`.
2139 :
2140 : @par Exception Safety
2141 : No-throw guarantee.
2142 : */
2143 : #ifdef BOOST_JSON_DOCS
2144 : bool
2145 : operator<=(string const& lhs, string const& rhs) noexcept
2146 : #else
2147 : template<class T, class U>
2148 : detail::string_comp_op_requirement<T, U>
2149 12 : operator<=(T const& lhs, U const& rhs) noexcept
2150 : #endif
2151 : {
2152 12 : return detail::to_string_view(lhs) <= detail::to_string_view(rhs);
2153 : }
2154 :
2155 : /** Check if lhs is more than or equal to rhs.
2156 :
2157 : A lexicographical comparison is used.
2158 :
2159 : @par Complexity
2160 : Linear in `lhs.size() + rhs.size()`.
2161 :
2162 : @par Exception Safety
2163 : No-throw guarantee.
2164 : */
2165 : #ifdef BOOST_JSON_DOCS
2166 : bool
2167 : operator>=(string const& lhs, string const& rhs) noexcept
2168 : #else
2169 : template<class T, class U>
2170 : detail::string_comp_op_requirement<T, U>
2171 12 : operator>=(T const& lhs, U const& rhs) noexcept
2172 : #endif
2173 : {
2174 12 : return detail::to_string_view(lhs) >= detail::to_string_view(rhs);
2175 : }
2176 :
2177 : /** Check if lhs is greater than rhs.
2178 :
2179 : A lexicographical comparison is used.
2180 :
2181 : @par Complexity
2182 : Linear in `lhs.size() + rhs.size()`.
2183 :
2184 : @par Exception Safety
2185 : No-throw guarantee.
2186 : */
2187 : #ifdef BOOST_JSON_DOCS
2188 : bool
2189 : operator>(string const& lhs, string const& rhs) noexcept
2190 : #else
2191 : template<class T, class U>
2192 : detail::string_comp_op_requirement<T, U>
2193 12 : operator>(T const& lhs, U const& rhs) noexcept
2194 : #endif
2195 : {
2196 12 : return detail::to_string_view(lhs) > detail::to_string_view(rhs);
2197 : }
2198 :
2199 : } // namespace json
2200 : } // namespace boost
2201 :
2202 : // std::hash specialization
2203 : #ifndef BOOST_JSON_DOCS
2204 : namespace std {
2205 : template<>
2206 : struct hash< ::boost::json::string >
2207 : {
2208 : BOOST_JSON_DECL
2209 : std::size_t
2210 : operator()( ::boost::json::string const& js ) const noexcept;
2211 : };
2212 : } // std
2213 : #endif
2214 :
2215 : #include <boost/json/impl/string.hpp>
2216 :
2217 : #endif
|