GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: string.hpp
Date: 2025-12-23 17:20:53
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
38 of `char` using the UTF-8 encoding. The elements of
39 a string are stored contiguously. A pointer to any
40 character in a string may be passed to functions
41 that expect a pointer to the first element of a
42 null-terminated `char` array. The type uses small
43 buffer optimisation to avoid allocations for small
44 strings.
45
46 String iterators are regular `char` pointers.
47
48 @note `string` member functions do not validate
49 any UTF-8 byte sequences passed to them.
50
51 @par Thread Safety
52
53 Non-const member functions may not be called
54 concurrently with any other member functions.
55
56 @par Satisfies
57 <a href="https://en.cppreference.com/w/cpp/named_req/ContiguousContainer"><em>ContiguousContainer</em></a>,
58 <a href="https://en.cppreference.com/w/cpp/named_req/ReversibleContainer"><em>ReversibleContainer</em></a>, and
59 <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>.
60 */
61 class string
62 {
63 friend class value;
64 #ifndef BOOST_JSON_DOCS
65 // VFALCO doc toolchain shouldn't show this but does
66 friend struct detail::access;
67 #endif
68
69 using string_impl = detail::string_impl;
70
71 inline
72 string(
73 detail::key_t const&,
74 string_view s,
75 storage_ptr sp);
76
77 inline
78 string(
79 detail::key_t const&,
80 string_view s1,
81 string_view s2,
82 storage_ptr sp);
83
84 public:
85 /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
86 using allocator_type = container::pmr::polymorphic_allocator<value>;
87
88 /// The type of a character
89 using value_type = char;
90
91 /// The type used to represent unsigned integers
92 using size_type = std::size_t;
93
94 /// The type used to represent signed integers
95 using difference_type = std::ptrdiff_t;
96
97 /// A pointer to an element
98 using pointer = char*;
99
100 /// A const pointer to an element
101 using const_pointer = char const*;
102
103 /// A reference to an element
104 using reference = char&;
105
106 /// A const reference to an element
107 using const_reference = const char&;
108
109 /// A random access iterator to an element
110 using iterator = char*;
111
112 /// A random access const iterator to an element
113 using const_iterator = char const*;
114
115 /// A reverse random access iterator to an element
116 using reverse_iterator =
117 std::reverse_iterator<iterator>;
118
119 /// A reverse random access const iterator to an element
120 using const_reverse_iterator =
121 std::reverse_iterator<const_iterator>;
122
123 /// A special index
124 static constexpr std::size_t npos =
125 string_view::npos;
126
127 private:
128 template<class T>
129 using is_inputit = typename std::enable_if<
130 std::is_convertible<typename
131 std::iterator_traits<T>::reference,
132 char>::value>::type;
133
134 storage_ptr sp_; // must come first
135 string_impl impl_;
136
137 public:
138 /** Destructor.
139
140 Any dynamically allocated internal storage
141 is freed.
142
143 @par Complexity
144 Constant.
145
146 @par Exception Safety
147 No-throw guarantee.
148 */
149 30985 ~string() noexcept
150 {
151 30985 impl_.destroy(sp_);
152 30985 }
153
154 //------------------------------------------------------
155 //
156 // Construction
157 //
158 //------------------------------------------------------
159
160 /** Default constructor.
161
162 The string will have a zero size and a non-zero,
163 unspecified capacity, using the [default memory resource].
164
165 @par Complexity
166
167 Constant.
168
169 [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
170 */
171 2423 string() = default;
172
173 /** Pilfer constructor.
174
175 The string is constructed by acquiring ownership
176 of the contents of `other` using pilfer semantics.
177 This is more efficient than move construction, when
178 it is known that the moved-from object will be
179 immediately destroyed afterwards.
180
181 @par Complexity
182 Constant.
183
184 @par Exception Safety
185 No-throw guarantee.
186
187 @param other The value to pilfer. After pilfer
188 construction, `other` is not in a usable state
189 and may only be destroyed.
190
191 @see @ref pilfer,
192 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
193 Valueless Variants Considered Harmful</a>
194 */
195 5 string(pilfered<string> other) noexcept
196 5 : sp_(std::move(other.get().sp_))
197 5 , impl_(other.get().impl_)
198 {
199 5 ::new(&other.get().impl_) string_impl();
200 5 }
201
202 /** Constructor.
203
204 The string will have zero size and a non-zero,
205 unspecified capacity, obtained from the specified
206 memory resource.
207
208 @par Complexity
209
210 Constant.
211
212 @param sp A pointer to the `boost::container::pmr::memory_resource` to
213 use. The container will acquire shared ownership of the memory
214 resource.
215 */
216 explicit
217 9163 string(storage_ptr sp)
218 9163 : sp_(std::move(sp))
219 {
220 9163 }
221
222 /** Constructor.
223
224 Construct the contents with `count` copies of
225 character `ch`.
226
227 @par Complexity
228
229 Linear in `count`.
230
231 @par Exception Safety
232
233 Strong guarantee.
234 Calls to `memory_resource::allocate` may throw.
235
236 @param count The size of the resulting string.
237
238 @param ch The value to initialize characters
239 of the string with.
240
241 @param sp An optional pointer to the
242 `boost::container::pmr::memory_resource` to use. The container will
243 acquire shared ownership of the memory resource. The default argument
244 for this parameter is `{}`.
245
246 @throw `boost::system::system_error` `count > max_size()`.
247 */
248 BOOST_JSON_DECL
249 explicit
250 string(
251 std::size_t count,
252 char ch,
253 storage_ptr sp = {});
254
255 /** Constructor.
256
257 Construct the contents with those of the null
258 terminated string pointed to by `s`. The length
259 of the string is determined by the first null
260 character.
261
262 @par Complexity
263
264 Linear in `strlen(s)`.
265
266 @par Exception Safety
267
268 Strong guarantee.
269 Calls to `memory_resource::allocate` may throw.
270
271 @param s A pointer to a character string used to
272 copy from.
273
274 @param sp An optional pointer to the
275 `boost::container::pmr::memory_resource` to use. The container will
276 acquire shared ownership of the memory resource. The default argument
277 for this parameter is `{}`.
278
279 @throw `boost::system::system_error` `strlen(s) > max_size()`.
280 */
281 BOOST_JSON_DECL
282 string(
283 char const* s,
284 storage_ptr sp = {});
285
286 /** Constructor.
287
288 Construct the contents with copies of the
289 characters in the range `{s, s+count)`.
290 This range can contain null characters.
291
292 @par Complexity
293
294 Linear in `count`.
295
296 @par Exception Safety
297
298 Strong guarantee.
299 Calls to `memory_resource::allocate` may throw.
300
301 @param count The number of characters to copy.
302
303 @param s A pointer to a character string used to
304 copy from.
305
306 @param sp An optional pointer to the
307 `boost::container::pmr::memory_resource` to use. The container will
308 acquire shared ownership of the memory resource. The default argument
309 for this parameter is `{}`.
310
311 @throw `boost::system::system_error` `count > max_size()`.
312 */
313 BOOST_JSON_DECL
314 explicit
315 string(
316 char const* s,
317 std::size_t count,
318 storage_ptr sp = {});
319
320 /** Constructor.
321
322 Construct the contents with copies of characters
323 in the range `{first, last)`.
324
325 @par Complexity
326
327 Linear in `std::distance(first, last)`.
328
329 @par Exception Safety
330
331 Strong guarantee.
332 Calls to `memory_resource::allocate` may throw.
333
334 @tparam InputIt The type of the iterators.
335
336 @par Constraints
337
338 `InputIt` satisfies __InputIterator__.
339
340 @param first An input iterator pointing to the
341 first character to insert, or pointing to the
342 end of the range.
343
344 @param last An input iterator pointing to the end
345 of the range.
346
347 @param sp An optional pointer to the
348 `boost::container::pmr::memory_resource` to use. The container will
349 acquire shared ownership of the memory resource. The default argument
350 for this parameter is `{}`.
351
352 @throw `boost::system::system_error` `std::distance(first, last) > max_size()`.
353 */
354 template<class InputIt
355 #ifndef BOOST_JSON_DOCS
356 ,class = is_inputit<InputIt>
357 #endif
358 >
359 explicit
360 string(
361 InputIt first,
362 InputIt last,
363 storage_ptr sp = {});
364
365 /** Copy constructor.
366
367 Construct the contents with a copy of `other`.
368
369 @par Complexity
370
371 Linear in `other.size()`.
372
373 @par Exception Safety
374
375 Strong guarantee.
376 Calls to `memory_resource::allocate` may throw.
377
378 @param other The string to use as a source
379 to copy from.
380 */
381 BOOST_JSON_DECL
382 string(string const& other);
383
384 /** Constructor.
385
386 Construct the contents with a copy of `other`.
387
388 @par Complexity
389
390 Linear in `other.size()`.
391
392 @par Exception Safety
393
394 Strong guarantee.
395 Calls to `memory_resource::allocate` may throw.
396
397 @param other The string to use as a source
398 to copy from.
399
400 @param sp An optional pointer to the
401 `boost::container::pmr::memory_resource` to use. The container will
402 acquire shared ownership of the memory resource. The default argument
403 for this parameter is `{}`.
404 */
405 BOOST_JSON_DECL
406 explicit
407 string(
408 string const& other,
409 storage_ptr sp);
410
411 /** Move constructor.
412
413 Constructs the string with the contents of `other` using move
414 semantics. Ownership of the underlying memory is transferred. The
415 container acquires shared ownership of the
416 `boost::container::pmr::memory_resource` used by `other`. After
417 construction, the moved-from string behaves as if newly constructed
418 with its current memory resource.
419
420 @par Complexity
421
422 Constant.
423
424 @param other The string to move
425 */
426 487 string(string&& other) noexcept
427 487 : sp_(other.sp_)
428 487 , impl_(other.impl_)
429 {
430 487 ::new(&other.impl_) string_impl();
431 487 }
432
433 /** Constructor.
434
435 Construct the contents with those of `other`
436 using move semantics.
437
438 @li If `*other.storage() == *sp`, ownership of the underlying memory is
439 transferred in constant time, with no possibility of exceptions. After
440 construction, the moved-from string behaves as if newly constructed
441 with its current `boost::container::pmr::memory_resource`. Otherwise,
442
443 @li If `*other.storage() != *sp`,
444 a copy of the characters in `other` is made. In
445 this case, the moved-from string is not changed.
446
447 @par Complexity
448
449 Constant or linear in `other.size()`.
450
451 @par Exception Safety
452
453 Strong guarantee.
454 Calls to `memory_resource::allocate` may throw.
455
456 @param other The string to assign from.
457
458 @param sp An optional pointer to the
459 `boost::container::pmr::memory_resource` to use. The container will
460 acquire shared ownership of the memory resource. The default argument
461 for this parameter is `{}`.
462 */
463 BOOST_JSON_DECL
464 explicit
465 string(
466 string&& other,
467 storage_ptr sp);
468
469 /** Constructor.
470
471 Construct the contents with those of a
472 string view. This view can contain
473 null characters.
474
475 @par Complexity
476
477 Linear in `s.size()`.
478
479 @par Exception Safety
480
481 Strong guarantee.
482 Calls to `memory_resource::allocate` may throw.
483
484 @param s The string view to copy from.
485
486 @param sp An optional pointer to the
487 `boost::container::pmr::memory_resource` to use. The container will
488 acquire shared ownership of the memory resource. The default argument
489 for this parameter is `{}`.
490
491 @throw `boost::system::system_error` `std::distance(first, last) > max_size()`.
492 */
493 BOOST_JSON_DECL
494 string(
495 string_view s,
496 storage_ptr sp = {});
497
498 //------------------------------------------------------
499 //
500 // Assignment
501 //
502 //------------------------------------------------------
503
504 /** Copy assignment.
505
506 Replace the contents with a copy of `other`.
507
508 @par Complexity
509
510 Linear in `other.size()`.
511
512 @par Exception Safety
513
514 Strong guarantee.
515 Calls to `memory_resource::allocate` may throw.
516
517 @return `*this`
518
519 @param other The string to use as a source
520 to copy from.
521 */
522 BOOST_JSON_DECL
523 string&
524 operator=(string const& other);
525
526 /** Move assignment.
527
528 Replace the contents with those of `other`
529 using move semantics.
530
531 @li If `&other == this`, do nothing. Otherwise,
532
533 @li If `*other.storage() == *this->storage()`, ownership of the
534 underlying memory is transferred in constant time, with no possibility
535 of exceptions. After construction, the moved-from string behaves as if
536 newly constructed with its current
537 `boost::container::pmr::memory_resource`. Otherwise,
538
539 @li a copy of the characters in `other` is made. In
540 this case, the moved-from container is not changed.
541
542 @par Complexity
543
544 Constant or linear in `other.size()`.
545
546 @par Exception Safety
547
548 Strong guarantee.
549 Calls to `memory_resource::allocate` may throw.
550
551 @return `*this`
552
553 @param other The string to use as a source
554 to move from.
555 */
556 BOOST_JSON_DECL
557 string&
558 operator=(string&& other);
559
560 /** Assign a value to the string.
561
562 Replaces the contents with those of the null
563 terminated string pointed to by `s`. The length
564 of the string is determined by the first null
565 character.
566
567 @par Complexity
568
569 Linear in `std::strlen(s)`.
570
571 @par Exception Safety
572
573 Strong guarantee.
574 Calls to `memory_resource::allocate` may throw.
575
576 @return `*this`
577
578 @param s The null-terminated character string.
579
580 @throw `boost::system::system_error` `std::strlen(s) > max_size()`.
581 */
582 BOOST_JSON_DECL
583 string&
584 operator=(char const* s);
585
586 /** Assign a value to the string.
587
588 Replaces the contents with those of a
589 string view. This view can contain
590 null characters.
591
592 @par Complexity
593
594 Linear in `s.size()`.
595
596 @par Exception Safety
597
598 Strong guarantee.
599 Calls to `memory_resource::allocate` may throw.
600
601 @return `*this`
602
603 @param s The string view to copy from.
604
605 @throw `boost::system::system_error` `s.size() > max_size()`.
606 */
607 BOOST_JSON_DECL
608 string&
609 operator=(string_view s);
610
611 //------------------------------------------------------
612
613 /** Assign characters to a string.
614
615 Replace the contents with `count` copies of
616 character `ch`.
617
618 @par Complexity
619
620 Linear in `count`.
621
622 @par Exception Safety
623
624 Strong guarantee.
625 Calls to `memory_resource::allocate` may throw.
626
627 @return `*this`
628
629 @param count The size of the resulting string.
630
631 @param ch The value to initialize characters
632 of the string with.
633
634 @throw `boost::system::system_error` `count > max_size()`.
635 */
636 BOOST_JSON_DECL
637 string&
638 assign(
639 std::size_t count,
640 char ch);
641
642 /** Assign characters to a string.
643
644 Replace the contents with a copy of `other`.
645
646 @par Complexity
647
648 Linear in `other.size()`.
649
650 @par Exception Safety
651
652 Strong guarantee.
653 Calls to `memory_resource::allocate` may throw.
654
655 @return `*this`
656
657 @param other The string to use as a source
658 to copy from.
659 */
660 BOOST_JSON_DECL
661 string&
662 assign(
663 string const& other);
664
665 /** Assign characters to a string.
666
667 Replace the contents with those of `other`
668 using move semantics.
669
670 @li If `&other == this`, do nothing. Otherwise,
671
672 @li If `*other.storage() == *this->storage()`, ownership of the
673 underlying memory is transferred in constant time, with no possibility
674 of exceptions. After construction, the moved-from string behaves as if
675 newly constructed with its current
676 `boost::container::pmr::memory_resource`, otherwise
677
678 @li If `*other.storage() != *this->storage()`,
679 a copy of the characters in `other` is made.
680 In this case, the moved-from container
681 is not changed.
682
683 @par Complexity
684
685 Constant or linear in `other.size()`.
686
687 @par Exception Safety
688
689 Strong guarantee.
690 Calls to `memory_resource::allocate` may throw.
691
692 @return `*this`
693
694 @param other The string to assign from.
695 */
696 BOOST_JSON_DECL
697 string&
698 assign(string&& other);
699
700 /** Assign characters to a string.
701
702 Replaces the contents with copies of the
703 characters in the range `{s, s+count)`. This
704 range can contain null characters.
705
706 @par Complexity
707
708 Linear in `count`.
709
710 @par Exception Safety
711
712 Strong guarantee.
713 Calls to `memory_resource::allocate` may throw.
714
715 @return `*this`
716
717 @param count The number of characters to copy.
718
719 @param s A pointer to a character string used to
720 copy from.
721
722 @throw `boost::system::system_error` `count > max_size()`.
723 */
724 BOOST_JSON_DECL
725 string&
726 assign(
727 char const* s,
728 std::size_t count);
729
730 /** Assign characters to a string.
731
732 Replaces the contents with those of the null
733 terminated string pointed to by `s`. The length
734 of the string is determined by the first null
735 character.
736
737 @par Complexity
738
739 Linear in `strlen(s)`.
740
741 @par Exception Safety
742
743 Strong guarantee.
744
745 @note
746
747 Calls to `memory_resource::allocate` may throw.
748
749 @return `*this`
750
751 @param s A pointer to a character string used to
752 copy from.
753
754 @throw `boost::system::system_error` `strlen(s) > max_size()`.
755 */
756 BOOST_JSON_DECL
757 string&
758 assign(
759 char const* s);
760
761 /** Assign characters to a string.
762
763 Replaces the contents with copies of characters
764 in the range `{first, last)`.
765
766 @par Complexity
767
768 Linear in `std::distance(first, last)`.
769
770 @par Exception Safety
771
772 Strong guarantee.
773 Calls to `memory_resource::allocate` may throw.
774
775 @tparam InputIt The type of the iterators.
776
777 @par Constraints
778
779 `InputIt` satisfies __InputIterator__.
780
781 @return `*this`
782
783 @param first An input iterator pointing to the
784 first character to insert, or pointing to the
785 end of the range.
786
787 @param last An input iterator pointing to the end
788 of the range.
789
790 @throw `boost::system::system_error` `std::distance(first, last) > max_size()`.
791 */
792 template<class InputIt
793 #ifndef BOOST_JSON_DOCS
794 ,class = is_inputit<InputIt>
795 #endif
796 >
797 string&
798 assign(
799 InputIt first,
800 InputIt last);
801
802 /** Assign characters to a string.
803
804 Replaces the contents with those of a
805 string view. This view can contain
806 null characters.
807
808 @par Complexity
809
810 Linear in `s.size()`.
811
812 @par Exception Safety
813
814 Strong guarantee.
815 Calls to `memory_resource::allocate` may throw.
816
817 @return `*this`
818
819 @param s The string view to copy from.
820
821 @throw `boost::system::system_error` `s.size() > max_size()`.
822 */
823 string&
824 18102 assign(string_view s)
825 {
826 18102 return assign(s.data(), s.size());
827 }
828
829 //------------------------------------------------------
830
831 /** Return the associated memory resource.
832
833 This returns the `boost::container::pmr::memory_resource` used by
834 the container.
835
836 @par Complexity
837
838 Constant.
839
840 @par Exception Safety
841
842 No-throw guarantee.
843 */
844 storage_ptr const&
845 116 storage() const noexcept
846 {
847 116 return sp_;
848 }
849
850 /** Return the associated allocator.
851
852 This function returns an instance of @ref allocator_type constructed
853 from the associated `boost::container::pmr::memory_resource`.
854
855 @par Complexity
856
857 Constant.
858
859 @par Exception Safety
860
861 No-throw guarantee.
862 */
863 allocator_type
864 1 get_allocator() const noexcept
865 {
866 1 return sp_.get();
867 }
868
869 //------------------------------------------------------
870 //
871 // Element Access
872 //
873 //------------------------------------------------------
874
875 /** Return a character with bounds checking.
876
877 Returns `boost::system::result` containing a reference to the character
878 specified at location `pos`, if `pos` is within the range of the
879 string. Otherwise the result contains an `error_code`.
880
881 @par Exception Safety
882 Strong guarantee.
883
884 @param pos A zero-based index to access.
885
886 @par Complexity
887 Constant.
888 */
889 /** @{ */
890 BOOST_JSON_DECL
891 system::result<char&>
892 try_at(std::size_t pos) noexcept;
893
894 BOOST_JSON_DECL
895 system::result<char const&>
896 try_at(std::size_t pos) const noexcept;
897 /** @} */
898
899 /** Return a character with bounds checking.
900
901 Returns a reference to the character specified at
902 location `pos`.
903
904 @par Complexity
905
906 Constant.
907
908 @par Exception Safety
909
910 Strong guarantee.
911
912 @param pos A zero-based index to access.
913
914 @param loc `source_location` to use in thrown exception; the source
915 location of the call site by default.
916
917 @throw `boost::system::system_error` `pos >= size()`.
918 */
919 /** @{ */
920 inline
921 char&
922 at(
923 std::size_t pos,
924 source_location const& loc = BOOST_CURRENT_LOCATION);
925
926 BOOST_JSON_DECL
927 char const&
928 at(
929 std::size_t pos,
930 source_location const& loc = BOOST_CURRENT_LOCATION) const;
931 /** @} */
932
933 /** Return a character without bounds checking.
934
935 Returns a reference to the character specified at
936 location `pos`.
937
938 @par Complexity
939
940 Constant.
941
942 @par Precondition
943
944 @code
945 pos >= size
946 @endcode
947
948 @param pos A zero-based index to access.
949 */
950 char&
951 18 operator[](std::size_t pos)
952 {
953 18 return impl_.data()[pos];
954 }
955
956 /** Return a character without bounds checking.
957
958 Returns a reference to the character specified at
959 location `pos`.
960
961 @par Complexity
962
963 Constant.
964
965 @par Precondition
966
967 @code
968 pos >= size
969 @endcode
970
971 @param pos A zero-based index to access.
972 */
973 const char&
974 2 operator[](std::size_t pos) const
975 {
976 2 return impl_.data()[pos];
977 }
978
979 /** Return the first character.
980
981 Returns a reference to the first character.
982
983 @par Complexity
984
985 Constant.
986
987 @par Precondition
988
989 @code
990 not empty()
991 @endcode
992 */
993 char&
994 10 front()
995 {
996 10 return impl_.data()[0];
997 }
998
999 /** Return the first character.
1000
1001 Returns a reference to the first character.
1002
1003 @par Complexity
1004
1005 Constant.
1006
1007 @par Precondition
1008
1009 @code
1010 not empty()
1011 @endcode
1012 */
1013 char const&
1014 6 front() const
1015 {
1016 6 return impl_.data()[0];
1017 }
1018
1019 /** Return the last character.
1020
1021 Returns a reference to the last character.
1022
1023 @par Complexity
1024
1025 Constant.
1026
1027 @par Precondition
1028
1029 @code
1030 not empty()
1031 @endcode
1032 */
1033 char&
1034 39 back()
1035 {
1036 39 return impl_.data()[impl_.size() - 1];
1037 }
1038
1039 /** Return the last character.
1040
1041 Returns a reference to the last character.
1042
1043 @par Complexity
1044
1045 Constant.
1046
1047 @par Precondition
1048
1049 @code
1050 not empty()
1051 @endcode
1052 */
1053 char const&
1054 6 back() const
1055 {
1056 6 return impl_.data()[impl_.size() - 1];
1057 }
1058
1059 /** Return the underlying character array directly.
1060
1061 Returns a pointer to the underlying array
1062 serving as storage. The value returned is such that
1063 the range `{data(), data()+size())` is always a
1064 valid range, even if the container is empty.
1065
1066 @par Complexity
1067
1068 Constant.
1069
1070 @note The value returned from
1071 this function is never equal to `nullptr`.
1072 */
1073 char*
1074 24004 data() noexcept
1075 {
1076 24004 return impl_.data();
1077 }
1078
1079 /** Return the underlying character array directly.
1080
1081 Returns a pointer to the underlying array
1082 serving as storage.
1083
1084 @note The value returned is such that
1085 the range `{data(), data() + size())` is always a
1086 valid range, even if the container is empty.
1087 The value returned from
1088 this function is never equal to `nullptr`.
1089
1090 @par Complexity
1091
1092 Constant.
1093 */
1094 char const*
1095 44127 data() const noexcept
1096 {
1097 44127 return impl_.data();
1098 }
1099
1100 /** Return the underlying character array directly.
1101
1102 Returns a pointer to the underlying array
1103 serving as storage. The value returned is such that
1104 the range `{c_str(), c_str() + size()}` is always a
1105 valid range, even if the container is empty.
1106
1107 @par Complexity
1108
1109 Constant.
1110
1111 @note The value returned from
1112 this function is never equal to `nullptr`.
1113 */
1114 char const*
1115 4 c_str() const noexcept
1116 {
1117 4 return impl_.data();
1118 }
1119
1120 /** Convert to a @ref string_view referring to the string.
1121
1122 Returns a string view to the
1123 underlying character string. The size of the view
1124 does not include the null terminator.
1125
1126 @par Complexity
1127
1128 Constant.
1129 */
1130 57 operator string_view() const noexcept
1131 {
1132 57 return {data(), size()};
1133 }
1134
1135 #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
1136 /** Convert to a `std::string_view` referring to the string.
1137
1138 Returns a string view to the underlying character string. The size of
1139 the view does not include the null terminator.
1140
1141 This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW`
1142 is defined.
1143
1144 @par Complexity
1145
1146 Constant.
1147 */
1148 operator std::string_view() const noexcept
1149 {
1150 return {data(), size()};
1151 }
1152 #endif
1153
1154 //------------------------------------------------------
1155 //
1156 // Iterators
1157 //
1158 //------------------------------------------------------
1159
1160 /** Return an iterator to the beginning.
1161
1162 If the container is empty, @ref end() is returned.
1163
1164 @par Complexity
1165 Constant.
1166
1167 @par Exception Safety
1168 No-throw guarantee.
1169 */
1170 iterator
1171 34 begin() noexcept
1172 {
1173 34 return impl_.data();
1174 }
1175
1176 /** Return an iterator to the beginning.
1177
1178 If the container is empty, @ref end() is returned.
1179
1180 @par Complexity
1181 Constant.
1182
1183 @par Exception Safety
1184 No-throw guarantee.
1185 */
1186 const_iterator
1187 8 begin() const noexcept
1188 {
1189 8 return impl_.data();
1190 }
1191
1192 /** Return an iterator to the beginning.
1193
1194 If the container is empty, @ref cend() is returned.
1195
1196 @par Complexity
1197 Constant.
1198
1199 @par Exception Safety
1200 No-throw guarantee.
1201 */
1202 const_iterator
1203 2 cbegin() const noexcept
1204 {
1205 2 return impl_.data();
1206 }
1207
1208 /** Return an iterator to the end.
1209
1210 Returns an iterator to the character
1211 following the last character of the string.
1212 This character acts as a placeholder, attempting
1213 to access it results in undefined behavior.
1214
1215 @par Complexity
1216 Constant.
1217
1218 @par Exception Safety
1219 No-throw guarantee.
1220 */
1221 iterator
1222 3 end() noexcept
1223 {
1224 3 return impl_.end();
1225 }
1226
1227 /** Return an iterator to the end.
1228
1229 Returns an iterator to the character following
1230 the last character of the string.
1231 This character acts as a placeholder, attempting
1232 to access it results in undefined behavior.
1233
1234 @par Complexity
1235 Constant.
1236
1237 @par Exception Safety
1238 No-throw guarantee.
1239 */
1240 const_iterator
1241 3 end() const noexcept
1242 {
1243 3 return impl_.end();
1244 }
1245
1246 /** Return an iterator to the end.
1247
1248 Returns an iterator to the character following
1249 the last character of the string.
1250 This character acts as a placeholder, attempting
1251 to access it results in undefined behavior.
1252
1253 @par Complexity
1254 Constant.
1255
1256 @par Exception Safety
1257 No-throw guarantee.
1258 */
1259 const_iterator
1260 2 cend() const noexcept
1261 {
1262 2 return impl_.end();
1263 }
1264
1265 /** Return a reverse iterator to the first character of the reversed container.
1266
1267 Returns the pointed-to character that
1268 corresponds to the last character of the
1269 non-reversed container.
1270 If the container is empty, @ref rend() is returned.
1271
1272 @par Complexity
1273 Constant.
1274
1275 @par Exception Safety
1276 No-throw guarantee.
1277 */
1278 reverse_iterator
1279 3 rbegin() noexcept
1280 {
1281 3 return reverse_iterator(impl_.end());
1282 }
1283
1284 /** Return a reverse iterator to the first character of the reversed container.
1285
1286 Returns the pointed-to character that
1287 corresponds to the last character of the
1288 non-reversed container.
1289 If the container is empty, @ref rend() is returned.
1290
1291 @par Complexity
1292 Constant.
1293
1294 @par Exception Safety
1295 No-throw guarantee.
1296 */
1297 const_reverse_iterator
1298 3 rbegin() const noexcept
1299 {
1300 3 return const_reverse_iterator(impl_.end());
1301 }
1302
1303 /** Return a reverse iterator to the first character of the reversed container.
1304
1305 Returns the pointed-to character that
1306 corresponds to the last character of the
1307 non-reversed container.
1308 If the container is empty, @ref crend() is returned.
1309
1310 @par Complexity
1311 Constant.
1312
1313 @par Exception Safety
1314 No-throw guarantee.
1315 */
1316 const_reverse_iterator
1317 2 crbegin() const noexcept
1318 {
1319 2 return const_reverse_iterator(impl_.end());
1320 }
1321
1322 /** Return a reverse iterator to the character following the last character of the reversed container.
1323
1324 Returns the pointed-to character that corresponds
1325 to the character preceding the first character of
1326 the non-reversed container.
1327 This character acts as a placeholder, attempting
1328 to access it results in undefined behavior.
1329
1330 @par Complexity
1331 Constant.
1332
1333 @par Exception Safety
1334 No-throw guarantee.
1335 */
1336 reverse_iterator
1337 3 rend() noexcept
1338 {
1339 3 return reverse_iterator(begin());
1340 }
1341
1342 /** Return a reverse iterator to the character following the last character of the reversed container.
1343
1344 Returns the pointed-to character that corresponds
1345 to the character preceding the first character of
1346 the non-reversed container.
1347 This character acts as a placeholder, attempting
1348 to access it results in undefined behavior.
1349
1350 @par Complexity
1351 Constant.
1352
1353 @par Exception Safety
1354 No-throw guarantee.
1355 */
1356 const_reverse_iterator
1357 3 rend() const noexcept
1358 {
1359 3 return const_reverse_iterator(begin());
1360 }
1361
1362 /** Return a reverse iterator to the character following the last character of the reversed container.
1363
1364 Returns the pointed-to character that corresponds
1365 to the character preceding the first character of
1366 the non-reversed container.
1367 This character acts as a placeholder, attempting
1368 to access it results in undefined behavior.
1369
1370 @par Complexity
1371 Constant.
1372
1373 @par Exception Safety
1374 No-throw guarantee.
1375 */
1376 const_reverse_iterator
1377 2 crend() const noexcept
1378 {
1379 2 return const_reverse_iterator(begin());
1380 }
1381
1382 //------------------------------------------------------
1383 //
1384 // Capacity
1385 //
1386 //------------------------------------------------------
1387
1388 /** Check if the string has no characters.
1389
1390 Returns `true` if there are no characters in
1391 the string, i.e. @ref size() returns 0.
1392
1393 @par Complexity
1394
1395 Constant.
1396 */
1397 bool
1398 69 empty() const noexcept
1399 {
1400 69 return impl_.size() == 0;
1401 }
1402
1403 /** Return the number of characters in the string.
1404
1405 The value returned does not include the
1406 null terminator, which is always present.
1407
1408 @par Complexity
1409
1410 Constant.
1411 */
1412 std::size_t
1413 47934 size() const noexcept
1414 {
1415 47934 return impl_.size();
1416 }
1417
1418 /** Return the maximum number of characters any string can hold.
1419
1420 The maximum is an implementation-defined number.
1421 This value is a theoretical limit; at runtime,
1422 the actual maximum size may be less due to
1423 resource limits.
1424
1425 @par Complexity
1426
1427 Constant.
1428 */
1429 static
1430 constexpr
1431 std::size_t
1432 7839 max_size() noexcept
1433 {
1434 7839 return string_impl::max_size();
1435 }
1436
1437 /** Return the number of characters that can be held without a reallocation.
1438
1439 This number represents the largest number of
1440 characters the currently allocated storage can contain.
1441 This number may be larger than the value returned
1442 by @ref size().
1443
1444 @par Complexity
1445
1446 Constant.
1447 */
1448 std::size_t
1449 11658 capacity() const noexcept
1450 {
1451 11658 return impl_.capacity();
1452 }
1453
1454 /** Increase the capacity to at least a certain amount.
1455
1456 This increases the capacity of the array to a value
1457 that is greater than or equal to `new_capacity`. If
1458 `new_capacity > capacity()`, new memory is
1459 allocated. Otherwise, the call has no effect.
1460 The number of elements and therefore the
1461 @ref size() of the container is not changed.
1462
1463 @par Complexity
1464
1465 At most, linear in @ref size().
1466
1467 @par Exception Safety
1468
1469 Strong guarantee.
1470 Calls to `memory_resource::allocate` may throw.
1471
1472 @note
1473
1474 If new memory is allocated, all iterators including
1475 any past-the-end iterators, and all references to
1476 the elements are invalidated. Otherwise, no
1477 iterators or references are invalidated.
1478
1479 @param new_capacity The new capacity of the array.
1480
1481 @throw `boost::system::system_error` `new_capacity > max_size()`.
1482 */
1483 void
1484 11348 reserve(std::size_t new_capacity)
1485 {
1486
2/2
✓ Branch 1 taken 1662 times.
✓ Branch 2 taken 9686 times.
11348 if(new_capacity <= capacity())
1487 1662 return;
1488 9686 reserve_impl(new_capacity);
1489 }
1490
1491 /** Request the removal of unused capacity.
1492
1493 This performs a non-binding request to reduce
1494 @ref capacity() to @ref size(). The request may
1495 or may not be fulfilled.
1496
1497 @par Complexity
1498
1499 At most, linear in @ref size().
1500
1501 @note If reallocation occurs, all iterators
1502 including any past-the-end iterators, and all
1503 references to characters are invalidated.
1504 Otherwise, no iterators or references are
1505 invalidated.
1506 */
1507 BOOST_JSON_DECL
1508 void
1509 shrink_to_fit();
1510
1511 //------------------------------------------------------
1512 //
1513 // Operations
1514 //
1515 //------------------------------------------------------
1516
1517 /** Clear the contents.
1518
1519 Erases all characters from the string. After this
1520 call, @ref size() returns zero but @ref capacity()
1521 is unchanged.
1522
1523 @par Complexity
1524
1525 Linear in @ref size().
1526
1527 @note All references, pointers, or iterators
1528 referring to contained elements are invalidated.
1529 Any past-the-end iterators are also invalidated.
1530 */
1531 BOOST_JSON_DECL
1532 void
1533 clear() noexcept;
1534
1535 //------------------------------------------------------
1536
1537 /** Insert a string.
1538
1539 Inserts the `string_view` `sv` at the position `pos`.
1540
1541 @par Exception Safety
1542
1543 Strong guarantee.
1544
1545 @note All references, pointers, or iterators
1546 referring to contained elements are invalidated.
1547 Any past-the-end iterators are also invalidated.
1548
1549 @return `*this`
1550
1551 @param pos The index to insert at.
1552
1553 @param sv The `string_view` to insert.
1554
1555 @throw `boost::system::system_error` `size() + s.size() > max_size()`.
1556 @throw `boost::system::system_error` `pos > size()`.
1557 */
1558 BOOST_JSON_DECL
1559 string&
1560 insert(
1561 std::size_t pos,
1562 string_view sv);
1563
1564 /** Insert a character.
1565
1566 Inserts `count` copies of `ch` at the position `pos`.
1567
1568 @par Exception Safety
1569
1570 Strong guarantee.
1571
1572 @note All references, pointers, or iterators
1573 referring to contained elements are invalidated.
1574 Any past-the-end iterators are also invalidated.
1575
1576 @return `*this`
1577
1578 @param pos The index to insert at.
1579
1580 @param count The number of characters to insert.
1581
1582 @param ch The character to insert.
1583
1584 @throw `boost::system::system_error` `size() + count > max_size()`.
1585 @throw `boost::system::system_error` `pos > size()`.
1586 */
1587 BOOST_JSON_DECL
1588 string&
1589 insert(
1590 std::size_t pos,
1591 std::size_t count,
1592 char ch);
1593
1594 /** Insert a character.
1595
1596 Inserts the character `ch` before the character
1597 at index `pos`.
1598
1599 @par Exception Safety
1600
1601 Strong guarantee.
1602
1603 @note All references, pointers, or iterators
1604 referring to contained elements are invalidated.
1605 Any past-the-end iterators are also invalidated.
1606
1607 @return `*this`
1608
1609 @param pos The index to insert at.
1610
1611 @param ch The character to insert.
1612
1613 @throw `boost::system::system_error` `size() + 1 > max_size()`.
1614 @throw `boost::system::system_error` `pos > size()`.
1615 */
1616 string&
1617 3 insert(
1618 size_type pos,
1619 char ch)
1620 {
1621 3 return insert(pos, 1, ch);
1622 }
1623
1624 /** Insert a range of characters.
1625
1626 Inserts characters from the range `{first, last)`
1627 before the character at index `pos`.
1628
1629 @par Precondition
1630
1631 `{first, last)` is a valid range.
1632
1633 @par Exception Safety
1634
1635 Strong guarantee.
1636
1637 @note All references, pointers, or iterators
1638 referring to contained elements are invalidated.
1639 Any past-the-end iterators are also invalidated.
1640
1641 @tparam InputIt The type of the iterators.
1642
1643 @par Constraints
1644
1645 `InputIt` satisfies __InputIterator__.
1646
1647 @return `*this`
1648
1649 @param pos The index to insert at.
1650
1651 @param first The beginning of the character range.
1652
1653 @param last The end of the character range.
1654
1655 @throw `boost::system::system_error` `size() + insert_count > max_size()`.
1656 @throw `boost::system::system_error` `pos > size()`.
1657 */
1658 template<class InputIt
1659 #ifndef BOOST_JSON_DOCS
1660 ,class = is_inputit<InputIt>
1661 #endif
1662 >
1663 string&
1664 insert(
1665 size_type pos,
1666 InputIt first,
1667 InputIt last);
1668
1669 //------------------------------------------------------
1670
1671 /** Erase characters from the string.
1672
1673 Erases `num` characters from the string, starting
1674 at `pos`. `num` is determined as the smaller of
1675 `count` and `size() - pos`.
1676
1677 @par Exception Safety
1678
1679 Strong guarantee.
1680
1681 @note All references, pointers, or iterators
1682 referring to contained elements are invalidated.
1683 Any past-the-end iterators are also invalidated.
1684
1685 @return `*this`
1686
1687 @param pos The index to erase at.
1688 The default argument for this parameter is `0`.
1689
1690 @param count The number of characters to erase.
1691 The default argument for this parameter
1692 is @ref npos.
1693
1694 @throw `boost::system::system_error` `pos > size()`.
1695 */
1696 BOOST_JSON_DECL
1697 string&
1698 erase(
1699 std::size_t pos = 0,
1700 std::size_t count = npos);
1701
1702 /** Erase a character from the string.
1703
1704 Erases the character at `pos`.
1705
1706 @par Precondition
1707
1708 @code
1709 pos >= data() && pos <= data() + size()
1710 @endcode
1711
1712 @par Exception Safety
1713
1714 Strong guarantee.
1715
1716 @note All references, pointers, or iterators
1717 referring to contained elements are invalidated.
1718 Any past-the-end iterators are also invalidated.
1719
1720 @return An iterator referring to character
1721 immediately following the erased character, or
1722 @ref end() if one does not exist.
1723
1724 @param pos An iterator referring to the
1725 character to erase.
1726 */
1727 BOOST_JSON_DECL
1728 iterator
1729 erase(const_iterator pos);
1730
1731 /** Erase a range from the string.
1732
1733 Erases the characters in the range `{first, last)`.
1734
1735 @par Precondition
1736
1737 `{first, last}` shall be valid within
1738 @code
1739 {data(), data() + size()}
1740 @endcode
1741
1742 @par Exception Safety
1743
1744 Strong guarantee.
1745
1746 @note All references, pointers, or iterators
1747 referring to contained elements are invalidated.
1748 Any past-the-end iterators are also invalidated.
1749
1750 @return An iterator referring to the character
1751 `last` previously referred to, or @ref end()
1752 if one does not exist.
1753
1754 @param first An iterator representing the first
1755 character to erase.
1756
1757 @param last An iterator one past the last
1758 character to erase.
1759 */
1760 BOOST_JSON_DECL
1761 iterator
1762 erase(
1763 const_iterator first,
1764 const_iterator last);
1765
1766 //------------------------------------------------------
1767
1768 /** Append a character.
1769
1770 Appends a character to the end of the string.
1771
1772 @par Exception Safety
1773
1774 Strong guarantee.
1775
1776 @param ch The character to append.
1777
1778 @throw `boost::system::system_error` `size() + 1 > max_size()`.
1779 */
1780 BOOST_JSON_DECL
1781 void
1782 push_back(char ch);
1783
1784 /** Remove the last character.
1785
1786 Removes a character from the end of the string.
1787
1788 @par Precondition
1789
1790 @code
1791 not empty()
1792 @endcode
1793 */
1794 BOOST_JSON_DECL
1795 void
1796 pop_back();
1797
1798 //------------------------------------------------------
1799
1800 /** Append characters to the string.
1801
1802 Appends `count` copies of `ch` to the end of
1803 the string.
1804
1805 @par Exception Safety
1806
1807 Strong guarantee.
1808
1809 @return `*this`
1810
1811 @param count The number of characters to append.
1812
1813 @param ch The character to append.
1814
1815 @throw `boost::system::system_error` `size() + count > max_size()`.
1816 */
1817 BOOST_JSON_DECL
1818 string&
1819 append(
1820 std::size_t count,
1821 char ch);
1822
1823 /** Append a string to the string.
1824
1825 Appends `sv` the end of the string.
1826
1827 @par Exception Safety
1828
1829 Strong guarantee.
1830
1831 @return `*this`
1832
1833 @param sv The `string_view` to append.
1834
1835 @throw `boost::system::system_error` `size() + s.size() > max_size()`.
1836 */
1837 BOOST_JSON_DECL
1838 string&
1839 append(string_view sv);
1840
1841 /** Append a range of characters.
1842
1843 Appends characters from the range `{first, last)`
1844 to the end of the string.
1845
1846 @par Precondition
1847
1848 `{first, last)` shall be a valid range
1849
1850 @par Exception Safety
1851
1852 Strong guarantee.
1853
1854 @tparam InputIt The type of the iterators.
1855
1856 @par Constraints
1857
1858 `InputIt` satisfies __InputIterator__.
1859
1860 @return `*this`
1861
1862 @param first An iterator representing the
1863 first character to append.
1864
1865 @param last An iterator one past the
1866 last character to append.
1867
1868 @throw `boost::system::system_error` `size() + insert_count > max_size()`.
1869 */
1870 template<class InputIt
1871 #ifndef BOOST_JSON_DOCS
1872 ,class = is_inputit<InputIt>
1873 #endif
1874 >
1875 string&
1876 append(InputIt first, InputIt last);
1877
1878 //------------------------------------------------------
1879
1880 /** Append characters from a string.
1881
1882 Appends `{sv.begin(), sv.end())` to the end of
1883 the string.
1884
1885 @par Exception Safety
1886
1887 Strong guarantee.
1888
1889 @return `*this`
1890
1891 @param sv The `string_view` to append.
1892
1893 @throw `boost::system::system_error` `size() + sv.size() > max_size()`.
1894 */
1895 string&
1896 11 operator+=(string_view sv)
1897 {
1898 11 return append(sv);
1899 }
1900
1901 /** Append a character.
1902
1903 Appends a character to the end of the string.
1904
1905 @par Exception Safety
1906
1907 Strong guarantee.
1908
1909 @param ch The character to append.
1910
1911 @throw `boost::system::system_error` `size() + 1 > max_size()`.
1912 */
1913 string&
1914 44 operator+=(char ch)
1915 {
1916 44 push_back(ch);
1917 43 return *this;
1918 }
1919
1920 //------------------------------------------------------
1921
1922 /** Compare a string with the string.
1923
1924 Let `comp` be
1925 `std::char_traits<char>::compare(data(), sv.data(), std::min(size(), sv.size())`.
1926 If `comp != 0`, then the result is `comp`. Otherwise,
1927 the result is `0` if `size() == sv.size()`,
1928 `-1` if `size() < sv.size()`, and `1` otherwise.
1929
1930 @par Complexity
1931
1932 Linear.
1933
1934 @return The result of lexicographically comparing
1935 the characters of `sv` and the string.
1936
1937 @param sv The `string_view` to compare.
1938 */
1939 int
1940 13 compare(string_view sv) const noexcept
1941 {
1942 13 return subview().compare(sv);
1943 }
1944
1945 //------------------------------------------------------
1946
1947 /** Return whether the string begins with a string.
1948
1949 Returns `true` if the string begins with `s`,
1950 and `false` otherwise.
1951
1952 @par Complexity
1953
1954 Linear.
1955
1956 @param s The `string_view` to check for.
1957 */
1958 bool
1959 8 starts_with(string_view s) const noexcept
1960 {
1961 8 return subview(0, s.size()) == s;
1962 }
1963
1964 /** Return whether the string begins with a character.
1965
1966 Returns `true` if the string begins with `ch`,
1967 and `false` otherwise.
1968
1969 @par Complexity
1970
1971 Constant.
1972
1973 @param ch The character to check for.
1974 */
1975 bool
1976 4 starts_with(char ch) const noexcept
1977 {
1978
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;
1979 }
1980
1981 /** Return whether the string end with a string.
1982
1983 Returns `true` if the string end with `s`,
1984 and `false` otherwise.
1985
1986 @par Complexity
1987
1988 Linear.
1989
1990 @param s The string to check for.
1991 */
1992 bool
1993 8 ends_with(string_view s) const noexcept
1994 {
1995
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() &&
1996 16 subview(size() - s.size()) == s;
1997 }
1998
1999 /** Return whether the string ends with a character.
2000
2001 Returns `true` if the string ends with `ch`,
2002 and `false` otherwise.
2003
2004 @par Complexity
2005
2006 Constant.
2007
2008 @param ch The character to check for.
2009 */
2010 bool
2011 4 ends_with(char ch) const noexcept
2012 {
2013
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;
2014 }
2015
2016 //------------------------------------------------------
2017
2018 /** Replace a substring with a string.
2019
2020 Replaces `rcount` characters starting at index
2021 `pos` with those of `sv`, where `rcount` is
2022 `std::min(count, size() - pos)`.
2023
2024 @par Exception Safety
2025
2026 Strong guarantee.
2027
2028 @note All references, pointers, or iterators
2029 referring to contained elements are invalidated.
2030 Any past-the-end iterators are also invalidated.
2031
2032 @return `*this`
2033
2034 @param pos The index to replace at.
2035
2036 @param count The number of characters to replace.
2037
2038 @param sv The `string_view` to replace with.
2039
2040 @throw `boost::system::system_error` `size() + (sv.size() - rcount) > max_size()`.
2041 @throw `boost::system::system_error` `pos > size()`.
2042 */
2043 BOOST_JSON_DECL
2044 string&
2045 replace(
2046 std::size_t pos,
2047 std::size_t count,
2048 string_view sv);
2049
2050 /** Replace a range with a string.
2051
2052 Replaces the characters in the range
2053 `{first, last)` with those of `sv`.
2054
2055 @par Precondition
2056
2057 `{first, last)` is a valid range.
2058
2059 @par Exception Safety
2060
2061 Strong guarantee.
2062
2063 @note All references, pointers, or iterators
2064 referring to contained elements are invalidated.
2065 Any past-the-end iterators are also invalidated.
2066
2067 @return `*this`
2068
2069 @param first An iterator referring to the first
2070 character to replace.
2071
2072 @param last An iterator one past the end of
2073 the last character to replace.
2074
2075 @param sv The `string_view` to replace with.
2076
2077 @throw `boost::system::system_error` `size() + (sv.size() - std::distance(first, last)) > max_size()`.
2078 */
2079 string&
2080 6 replace(
2081 const_iterator first,
2082 const_iterator last,
2083 string_view sv)
2084 {
2085 6 return replace(first - begin(), last - first, sv);
2086 }
2087
2088 /** Replace a range with a range.
2089
2090 Replaces the characters in the range
2091 `{first, last)` with those of `{first2, last2)`.
2092
2093 @par Precondition
2094
2095 `{first, last)` is a valid range.
2096
2097 `{first2, last2)` is a valid range.
2098
2099 @par Exception Safety
2100
2101 Strong guarantee.
2102
2103 @note All references, pointers, or iterators
2104 referring to contained elements are invalidated.
2105 Any past-the-end iterators are also invalidated.
2106
2107 @tparam InputIt The type of the iterators.
2108
2109 @par Constraints
2110
2111 `InputIt` satisfies __InputIterator__.
2112
2113 @return `*this`
2114
2115 @param first An iterator referring to the first
2116 character to replace.
2117
2118 @param last An iterator one past the end of
2119 the last character to replace.
2120
2121 @param first2 An iterator referring to the first
2122 character to replace with.
2123
2124 @param last2 An iterator one past the end of
2125 the last character to replace with.
2126
2127 @throw `boost::system::system_error` `size() + (inserted - std::distance(first, last)) > max_size()`.
2128 */
2129 template<class InputIt
2130 #ifndef BOOST_JSON_DOCS
2131 ,class = is_inputit<InputIt>
2132 #endif
2133 >
2134 string&
2135 replace(
2136 const_iterator first,
2137 const_iterator last,
2138 InputIt first2,
2139 InputIt last2);
2140
2141 /** Replace a substring with copies of a character.
2142
2143 Replaces `rcount` characters starting at index
2144 `pos`with `count2` copies of `ch`, where
2145 `rcount` is `std::min(count, size() - pos)`.
2146
2147 @par Exception Safety
2148
2149 Strong guarantee.
2150
2151 @note All references, pointers, or iterators
2152 referring to contained elements are invalidated.
2153 Any past-the-end iterators are also invalidated.
2154
2155 @return `*this`
2156
2157 @param pos The index to replace at.
2158
2159 @param count The number of characters to replace.
2160
2161 @param count2 The number of characters to
2162 replace with.
2163
2164 @param ch The character to replace with.
2165
2166 @throw `boost::system::system_error` `size() + (count2 - rcount) > max_size()`.
2167 @throw `boost::system::system_error` `pos > size()`.
2168 */
2169 BOOST_JSON_DECL
2170 string&
2171 replace(
2172 std::size_t pos,
2173 std::size_t count,
2174 std::size_t count2,
2175 char ch);
2176
2177 /** Replace a range with copies of a character.
2178
2179 Replaces the characters in the range
2180 `{first, last)` with `count` copies of `ch`.
2181
2182 @par Precondition
2183
2184 `{first, last)` is a valid range.
2185
2186 @par Exception Safety
2187
2188 Strong guarantee.
2189
2190 @note All references, pointers, or iterators
2191 referring to contained elements are invalidated.
2192 Any past-the-end iterators are also invalidated.
2193
2194 @return `*this`
2195
2196 @param first An iterator referring to the first
2197 character to replace.
2198
2199 @param last An iterator one past the end of
2200 the last character to replace.
2201
2202 @param count The number of characters to
2203 replace with.
2204
2205 @param ch The character to replace with.
2206
2207 @throw `boost::system::system_error` `size() + (count - std::distance(first, last)) > max_size()`.
2208 */
2209 string&
2210 1 replace(
2211 const_iterator first,
2212 const_iterator last,
2213 std::size_t count,
2214 char ch)
2215 {
2216 1 return replace(first - begin(), last - first, count, ch);
2217 }
2218
2219 //------------------------------------------------------
2220
2221 /** Return a view.
2222
2223 Returns a view of a substring.
2224
2225 @par Exception Safety
2226
2227 Strong guarantee.
2228
2229 @return `this->subview().substr(pos, count)`
2230
2231 @param pos The index to being the substring at.
2232 The default argument for this parameter is `0`.
2233
2234 @param count The length of the substring.
2235 The default argument for this parameter
2236 is @ref npos.
2237
2238 @throw `boost::system::system_error` `pos > size()`.
2239 */
2240 string_view
2241 41 subview(
2242 std::size_t pos
2243 ,std::size_t count = npos) const
2244 {
2245
1/1
✓ Branch 2 taken 41 times.
41 return subview().substr(pos, count);
2246 }
2247
2248 /** Return a view.
2249
2250 Returns a view of the whole string.
2251
2252 @par Exception Safety
2253 No-throw guarantee.
2254
2255 @return `string_view(this->data(), this->size())`.
2256 */
2257 string_view
2258 29117 subview() const noexcept
2259 {
2260 29117 return string_view( data(), size() );
2261 }
2262
2263 //------------------------------------------------------
2264
2265 /** Copy a substring to another string.
2266
2267 Copies `std::min(count, size() - pos)` characters
2268 starting at index `pos` to the string pointed
2269 to by `dest`.
2270
2271 @note The resulting string is not null terminated.
2272
2273 @return The number of characters copied.
2274
2275 @param count The number of characters to copy.
2276
2277 @param dest The string to copy to.
2278
2279 @param pos The index to begin copying from. The
2280 default argument for this parameter is `0`.
2281
2282 @throw `boost::system::system_error` `pos > max_size()`.
2283 */
2284 std::size_t
2285 2 copy(
2286 char* dest,
2287 std::size_t count,
2288 std::size_t pos = 0) const
2289 {
2290
1/1
✓ Branch 2 taken 2 times.
2 return subview().copy(dest, count, pos);
2291 }
2292
2293 //------------------------------------------------------
2294
2295 /** Change the size of the string.
2296
2297 Resizes the string to contain `count` characters.
2298 If `count > size()`, characters with the value `0`
2299 are appended. Otherwise, `size()` is reduced
2300 to `count`.
2301
2302 @param count The size to resize the string to.
2303
2304 @throw `boost::system::system_error` `count > max_size()`.
2305 */
2306 void
2307 57 resize(std::size_t count)
2308 {
2309 57 resize(count, 0);
2310 54 }
2311
2312 /** Change the size of the string.
2313
2314 Resizes the string to contain `count` characters.
2315 If `count > size()`, copies of `ch` are
2316 appended. Otherwise, `size()` is reduced
2317 to `count`.
2318
2319 @param count The size to resize the string to.
2320
2321 @param ch The characters to append if the size
2322 increases.
2323
2324 @throw `boost::system::system_error` `count > max_size()`.
2325 */
2326 BOOST_JSON_DECL
2327 void
2328 resize(std::size_t count, char ch);
2329
2330 /** Increase size without changing capacity.
2331
2332 This increases the size of the string by `n`
2333 characters, adjusting the position of the
2334 terminating null for the new size. The new
2335 characters remain uninitialized. This function
2336 may be used to append characters directly into
2337 the storage between `end()` and
2338 `data() + capacity()`.
2339
2340 @par Precondition
2341
2342 @code
2343 count <= capacity() - size()
2344 @endcode
2345
2346 @param n The amount to increase the size by.
2347 */
2348 void
2349 15054 grow(std::size_t n) noexcept
2350 {
2351
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 15054 times.
15054 BOOST_ASSERT(
2352 n <= impl_.capacity() - impl_.size());
2353 15054 impl_.term(impl_.size() + n);
2354 15054 }
2355
2356 //------------------------------------------------------
2357
2358 /** Swap the contents.
2359
2360 Exchanges the contents of this string with another string. Ownership of
2361 the respective `boost::container::pmr::memory_resource` objects is not
2362 transferred.
2363
2364 @li If `&other == this`, do nothing. Otherwise,
2365
2366 @li if `*other.storage() == *this->storage()`,
2367 ownership of the underlying memory is swapped in
2368 constant time, with no possibility of exceptions.
2369 All iterators and references remain valid. Otherwise,
2370
2371 @li the contents are logically swapped by making copies,
2372 which can throw. In this case all iterators and
2373 references are invalidated.
2374
2375 @par Complexity
2376
2377 Constant or linear in @ref size() plus
2378 `other.size()`.
2379
2380 @par Exception Safety
2381
2382 Strong guarantee.
2383 Calls to `memory_resource::allocate` may throw.
2384 */
2385 BOOST_JSON_DECL
2386 void
2387 swap(string& other);
2388
2389 /** Exchange the given values.
2390
2391 Exchanges the contents of the string `lhs` with another string `rhs`.
2392 Ownership of the respective `boost::container::pmr::memory_resource`
2393 objects is not transferred.
2394
2395 @li If `&lhs == &rhs`, do nothing. Otherwise,
2396
2397 @li if `*lhs.storage() == *rhs.storage()`,
2398 ownership of the underlying memory is swapped in
2399 constant time, with no possibility of exceptions.
2400 All iterators and references remain valid. Otherwise,
2401
2402 @li the contents are logically swapped by making a copy,
2403 which can throw. In this case all iterators and
2404 references are invalidated.
2405
2406 @par Effects
2407 @code
2408 lhs.swap( rhs );
2409 @endcode
2410
2411 @par Complexity
2412 Constant or linear in `lhs.size() + rhs.size()`.
2413
2414 @par Exception Safety
2415 Strong guarantee.
2416 Calls to `memory_resource::allocate` may throw.
2417
2418 @param lhs The string to exchange.
2419
2420 @param rhs The string to exchange.
2421
2422 @see @ref string::swap
2423 */
2424 friend
2425 void
2426 2 swap(string& lhs, string& rhs)
2427 {
2428 2 lhs.swap(rhs);
2429 2 }
2430 //------------------------------------------------------
2431 //
2432 // Search
2433 //
2434 //------------------------------------------------------
2435
2436 /** Find the first occurrence of a string within the string.
2437
2438 Returns the lowest index `idx` greater than or equal
2439 to `pos` where each element of `sv` is equal to
2440 that of `{begin() + idx, begin() + idx + sv.size())`
2441 if one exists, and @ref npos otherwise.
2442
2443 @par Complexity
2444
2445 Linear.
2446
2447 @return The first occurrence of `sv` within the
2448 string starting at the index `pos`, or @ref npos
2449 if none exists.
2450
2451 @param sv The `string_view` to search for.
2452
2453 @param pos The index to start searching at.
2454 The default argument for this parameter is `0`.
2455 */
2456 std::size_t
2457 5 find(
2458 string_view sv,
2459 std::size_t pos = 0) const noexcept
2460 {
2461 5 return subview().find(sv, pos);
2462 }
2463
2464 /** Find the first occurrence of a character within the string.
2465
2466 Returns the index corrosponding to the first
2467 occurrence of `ch` within `{begin() + pos, end())`
2468 if it exists, and @ref npos otherwise.
2469
2470 @par Complexity
2471
2472 Linear.
2473
2474 @return The first occurrence of `ch` within the
2475 string starting at the index `pos`, or @ref npos
2476 if none exists.
2477
2478 @param ch The character to search for.
2479
2480 @param pos The index to start searching at.
2481 The default argument for this parameter is `0`.
2482 */
2483 std::size_t
2484 3 find(
2485 char ch,
2486 std::size_t pos = 0) const noexcept
2487 {
2488 3 return subview().find(ch, pos);
2489 }
2490
2491 //------------------------------------------------------
2492
2493 /** Find the last occurrence of a string within the string.
2494
2495 Returns the highest index `idx` less than or equal
2496 to `pos` where each element of `sv` is equal to that
2497 of `{begin() + idx, begin() + idx + sv.size())`
2498 if one exists, and @ref npos otherwise.
2499
2500 @par Complexity
2501
2502 Linear.
2503
2504 @return The last occurrence of `sv` within the
2505 string starting before or at the index `pos`,
2506 or @ref npos if none exists.
2507
2508 @param sv The `string_view` to search for.
2509
2510 @param pos The index to start searching at.
2511 The default argument for this parameter
2512 is @ref npos.
2513 */
2514 std::size_t
2515 5 rfind(
2516 string_view sv,
2517 std::size_t pos = npos) const noexcept
2518 {
2519 5 return subview().rfind(sv, pos);
2520 }
2521
2522 /** Find the last occurrence of a character within the string.
2523
2524 Returns index corrosponding to the last occurrence
2525 of `ch` within `{begin(), begin() + pos}` if it
2526 exists, and @ref npos otherwise.
2527
2528 @par Complexity
2529
2530 Linear.
2531
2532 @return The last occurrence of `ch` within the
2533 string starting before or at the index `pos`,
2534 or @ref npos if none exists.
2535
2536 @param ch The character to search for.
2537
2538 @param pos The index to stop searching at.
2539 The default argument for this parameter
2540 is @ref npos.
2541 */
2542 std::size_t
2543 3 rfind(
2544 char ch,
2545 std::size_t pos = npos) const noexcept
2546 {
2547 3 return subview().rfind(ch, pos);
2548 }
2549
2550 //------------------------------------------------------
2551
2552 /** Find the first occurrence of any of the characters within the string.
2553
2554 Returns the index corrosponding to the first
2555 occurrence of any of the characters of `sv`
2556 within `{begin() + pos, end())` if it exists,
2557 and @ref npos otherwise.
2558
2559 @par Complexity
2560
2561 Linear.
2562
2563 @return The first occurrence of any of the
2564 characters within `sv` within the string
2565 starting at the index `pos`, or @ref npos
2566 if none exists.
2567
2568 @param sv The characters to search for.
2569
2570 @param pos The index to start searching at.
2571 The default argument for this parameter is `0`.
2572 */
2573 std::size_t
2574 5 find_first_of(
2575 string_view sv,
2576 std::size_t pos = 0) const noexcept
2577 {
2578 5 return subview().find_first_of(sv, pos);
2579 }
2580
2581 //------------------------------------------------------
2582
2583 /** Find the first occurrence of any of the characters not within the string.
2584
2585 Returns the index corrosponding to the first
2586 character of `{begin() + pos, end())` that is
2587 not within `sv` if it exists, and @ref npos
2588 otherwise.
2589
2590 @par Complexity
2591
2592 Linear.
2593
2594 @return The first occurrence of a character that
2595 is not within `sv` within the string starting at
2596 the index `pos`, or @ref npos if none exists.
2597
2598 @param sv The characters to ignore.
2599
2600 @param pos The index to start searching at.
2601 The default argument for this parameter is `0`.
2602 */
2603 std::size_t
2604 4 find_first_not_of(
2605 string_view sv,
2606 std::size_t pos = 0) const noexcept
2607 {
2608 4 return subview().find_first_not_of(sv, pos);
2609 }
2610
2611 /** Find the first occurrence of a character not equal to `ch`.
2612
2613 Returns the index corrosponding to the first
2614 character of `{begin() + pos, end())` that is
2615 not equal to `ch` if it exists, and
2616 @ref npos otherwise.
2617
2618 @par Complexity
2619
2620 Linear.
2621
2622 @return The first occurrence of a character that
2623 is not equal to `ch`, or @ref npos if none exists.
2624
2625 @param ch The character to ignore.
2626
2627 @param pos The index to start searching at.
2628 The default argument for this parameter is `0`.
2629 */
2630 std::size_t
2631 3 find_first_not_of(
2632 char ch,
2633 std::size_t pos = 0) const noexcept
2634 {
2635 3 return subview().find_first_not_of(ch, pos);
2636 }
2637
2638 //------------------------------------------------------
2639
2640 /** Find the last occurrence of any of the characters within the string.
2641
2642 Returns the index corrosponding to the last
2643 occurrence of any of the characters of `sv` within
2644 `{begin(), begin() + pos}` if it exists,
2645 and @ref npos otherwise.
2646
2647 @par Complexity
2648
2649 Linear.
2650
2651 @return The last occurrence of any of the
2652 characters within `sv` within the string starting
2653 before or at the index `pos`, or @ref npos if
2654 none exists.
2655
2656 @param sv The characters to search for.
2657
2658 @param pos The index to stop searching at.
2659 The default argument for this parameter
2660 is @ref npos.
2661 */
2662 std::size_t
2663 5 find_last_of(
2664 string_view sv,
2665 std::size_t pos = npos) const noexcept
2666 {
2667 5 return subview().find_last_of(sv, pos);
2668 }
2669
2670 //------------------------------------------------------
2671
2672 /** Find the last occurrence of a character not within the string.
2673
2674 Returns the index corrosponding to the last
2675 character of `{begin(), begin() + pos}` that is not
2676 within `sv` if it exists, and @ref npos otherwise.
2677
2678 @par Complexity
2679
2680 Linear.
2681
2682 @return The last occurrence of a character that is
2683 not within `sv` within the string before or at the
2684 index `pos`, or @ref npos if none exists.
2685
2686 @param sv The characters to ignore.
2687
2688 @param pos The index to stop searching at.
2689 The default argument for this parameter
2690 is @ref npos.
2691 */
2692 std::size_t
2693 4 find_last_not_of(
2694 string_view sv,
2695 std::size_t pos = npos) const noexcept
2696 {
2697 4 return subview().find_last_not_of(sv, pos);
2698 }
2699
2700 /** Find the last occurrence of a character not equal to `ch`.
2701
2702 Returns the index corrosponding to the last
2703 character of `{begin(), begin() + pos}` that is
2704 not equal to `ch` if it exists, and @ref npos
2705 otherwise.
2706
2707 @par Complexity
2708
2709 Linear.
2710
2711 @return The last occurrence of a character that
2712 is not equal to `ch` before or at the index `pos`,
2713 or @ref npos if none exists.
2714
2715 @param ch The character to ignore.
2716
2717 @param pos The index to start searching at.
2718 The default argument for this parameter
2719 is @ref npos.
2720 */
2721 std::size_t
2722 3 find_last_not_of(
2723 char ch,
2724 std::size_t pos = npos) const noexcept
2725 {
2726 3 return subview().find_last_not_of(ch, pos);
2727 }
2728
2729 /** Serialize @ref string to an output stream.
2730
2731 This function serializes a `string` as JSON into the output stream.
2732
2733 @return Reference to `os`.
2734
2735 @par Complexity
2736 Constant or linear in the size of `str`.
2737
2738 @par Exception Safety
2739 Strong guarantee.
2740 Calls to `memory_resource::allocate` may throw.
2741
2742 @param os The output stream to serialize to.
2743
2744 @param str The value to serialize.
2745 */
2746 BOOST_JSON_DECL
2747 friend
2748 std::ostream&
2749 operator<<(
2750 std::ostream& os,
2751 string const& str);
2752
2753 private:
2754 class undo;
2755
2756 template<class It>
2757 using iter_cat = typename
2758 std::iterator_traits<It>::iterator_category;
2759
2760 template<class InputIt>
2761 void
2762 assign(InputIt first, InputIt last,
2763 std::random_access_iterator_tag);
2764
2765 template<class InputIt>
2766 void
2767 assign(InputIt first, InputIt last,
2768 std::input_iterator_tag);
2769
2770 template<class InputIt>
2771 void
2772 append(InputIt first, InputIt last,
2773 std::random_access_iterator_tag);
2774
2775 template<class InputIt>
2776 void
2777 append(InputIt first, InputIt last,
2778 std::input_iterator_tag);
2779
2780 BOOST_JSON_DECL
2781 void
2782 reserve_impl(std::size_t new_capacity);
2783 };
2784
2785 //----------------------------------------------------------
2786
2787 namespace detail
2788 {
2789
2790 template <>
2791 inline
2792 string_view
2793 28883 to_string_view<string>(string const& s) noexcept
2794 {
2795 28883 return s.subview();
2796 }
2797
2798 } // namespace detail
2799
2800
2801 /** Return true if lhs equals rhs.
2802
2803 A lexicographical comparison is used.
2804 */
2805 #ifdef BOOST_JSON_DOCS
2806 bool
2807 operator==(string const& lhs, string const& rhs) noexcept
2808 #else
2809 template<class T, class U>
2810 detail::string_comp_op_requirement<T, U>
2811 15820 operator==(T const& lhs, U const& rhs) noexcept
2812 #endif
2813 {
2814 15820 return detail::to_string_view(lhs) == detail::to_string_view(rhs);
2815 }
2816
2817 /** Return true if lhs does not equal rhs.
2818
2819 A lexicographical comparison is used.
2820 */
2821 #ifdef BOOST_JSON_DOCS
2822 bool
2823 operator!=(string const& lhs, string const& rhs) noexcept
2824 #else
2825 template<class T, class U>
2826 detail::string_comp_op_requirement<T, U>
2827 36 operator!=(T const& lhs, U const& rhs) noexcept
2828 #endif
2829 {
2830 36 return detail::to_string_view(lhs) != detail::to_string_view(rhs);
2831 }
2832
2833 /** Return true if lhs is less than rhs.
2834
2835 A lexicographical comparison is used.
2836 */
2837 #ifdef BOOST_JSON_DOCS
2838 bool
2839 operator<(string const& lhs, string const& rhs) noexcept
2840 #else
2841 template<class T, class U>
2842 detail::string_comp_op_requirement<T, U>
2843 24 operator<(T const& lhs, U const& rhs) noexcept
2844 #endif
2845 {
2846 24 return detail::to_string_view(lhs) < detail::to_string_view(rhs);
2847 }
2848
2849 /** Return true if lhs is less than or equal to rhs.
2850
2851 A lexicographical comparison is used.
2852 */
2853 #ifdef BOOST_JSON_DOCS
2854 bool
2855 operator<=(string const& lhs, string const& rhs) noexcept
2856 #else
2857 template<class T, class U>
2858 detail::string_comp_op_requirement<T, U>
2859 24 operator<=(T const& lhs, U const& rhs) noexcept
2860 #endif
2861 {
2862 24 return detail::to_string_view(lhs) <= detail::to_string_view(rhs);
2863 }
2864
2865 #ifdef BOOST_JSON_DOCS
2866 bool
2867 operator>=(string const& lhs, string const& rhs) noexcept
2868 #else
2869 template<class T, class U>
2870 detail::string_comp_op_requirement<T, U>
2871 24 operator>=(T const& lhs, U const& rhs) noexcept
2872 #endif
2873 {
2874 24 return detail::to_string_view(lhs) >= detail::to_string_view(rhs);
2875 }
2876
2877 /** Return true if lhs is greater than rhs.
2878
2879 A lexicographical comparison is used.
2880 */
2881 #ifdef BOOST_JSON_DOCS
2882 bool
2883 operator>(string const& lhs, string const& rhs) noexcept
2884 #else
2885 template<class T, class U>
2886 detail::string_comp_op_requirement<T, U>
2887 12 operator>(T const& lhs, U const& rhs) noexcept
2888 #endif
2889 {
2890 12 return detail::to_string_view(lhs) > detail::to_string_view(rhs);
2891 }
2892
2893 } // namespace json
2894 } // namespace boost
2895
2896 // std::hash specialization
2897 #ifndef BOOST_JSON_DOCS
2898 namespace std {
2899 template<>
2900 struct hash< ::boost::json::string >
2901 {
2902 BOOST_JSON_DECL
2903 std::size_t
2904 operator()( ::boost::json::string const& js ) const noexcept;
2905 };
2906 } // std
2907 #endif
2908
2909 #include <boost/json/impl/string.hpp>
2910
2911 #endif
2912