GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: string.hpp
Date: 2025-12-23 17:38:58
Exec Total Coverage
Lines: 151 151 100.0%
Functions: 93 93 100.0%
Branches: 14 18 77.8%

Line Branch Exec Source
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 30626 ~string() noexcept
148 {
149 30626 impl_.destroy(sp_);
150 30626 }
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 2423 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 24004 data() noexcept
729 {
730 24004 return impl_.data();
731 }
732
733 char const*
734 43947 data() const noexcept
735 {
736 43947 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 47754 size() const noexcept
1003 {
1004 47754 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 7779 max_size() noexcept
1020 {
1021 7779 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 11658 capacity() const noexcept
1038 {
1039 11658 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 11348 reserve(std::size_t new_capacity)
1066 {
1067
2/2
✓ Branch 1 taken 1662 times.
✓ Branch 2 taken 9686 times.
11348 if(new_capacity <= capacity())
1068 1662 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
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
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
3/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
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
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
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
1/1
✓ Branch 2 taken 41 times.
41 return subview().substr(pos, count);
1608 }
1609
1610 /// Overload
1611 string_view
1612 28955 subview() const noexcept
1613 {
1614 28955 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
1/1
✓ Branch 2 taken 2 times.
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 15054 grow(std::size_t n) noexcept
1693 {
1694
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 15054 times.
15054 BOOST_ASSERT(
1695 n <= impl_.capacity() - impl_.size());
1696 15054 impl_.term(impl_.size() + n);
1697 15054 }
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 28787 to_string_view<string>(string const& s) noexcept
2056 {
2057 28787 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 15772 operator==(T const& lhs, U const& rhs) noexcept
2082 #endif
2083 {
2084 15772 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 36 operator!=(T const& lhs, U const& rhs) noexcept
2106 #endif
2107 {
2108 36 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 24 operator<(T const& lhs, U const& rhs) noexcept
2128 #endif
2129 {
2130 24 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 24 operator<=(T const& lhs, U const& rhs) noexcept
2150 #endif
2151 {
2152 24 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 24 operator>=(T const& lhs, U const& rhs) noexcept
2172 #endif
2173 {
2174 24 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
2218