GCC Code Coverage Report


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