2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
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)
8 // Official repository: https://github.com/boostorg/json
11 #ifndef BOOST_JSON_STRING_HPP
12 #define BOOST_JSON_STRING_HPP
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>
24 #include <initializer_list>
29 #include <type_traits>
36 /** The native type of string values.
38 Instances of string store and manipulate sequences
39 of `char` using the UTF-8 encoding. The elements of
40 a string are stored contiguously. A pointer to any
41 character in a string may be passed to functions
42 that expect a pointer to the first element of a
43 null-terminated `char` array.
45 String iterators are regular `char` pointers.
47 @note `string` member functions do not validate
48 any UTF-8 byte sequences passed to them.
52 Non-const member functions may not be called
53 concurrently with any other member functions.
56 <a href="https://en.cppreference.com/w/cpp/named_req/ContiguousContainer"><em>ContiguousContainer</em></a>,
57 <a href="https://en.cppreference.com/w/cpp/named_req/ReversibleContainer"><em>ReversibleContainer</em></a>, and
58 <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>.
63 #ifndef BOOST_JSON_DOCS
64 // VFALCO doc toolchain shouldn't show this but does
65 friend struct detail::access;
68 using string_impl = detail::string_impl;
84 /** The type of _Allocator_ returned by @ref get_allocator
86 This type is a @ref polymorphic_allocator.
88 #ifdef BOOST_JSON_DOCS
89 // VFALCO doc toolchain renders this incorrectly
90 using allocator_type = __see_below__;
92 using allocator_type = polymorphic_allocator<value>;
95 /// The type of a character
96 using value_type = char;
98 /// The type used to represent unsigned integers
99 using size_type = std::size_t;
101 /// The type used to represent signed integers
102 using difference_type = std::ptrdiff_t;
104 /// A pointer to an element
105 using pointer = char*;
107 /// A const pointer to an element
108 using const_pointer = char const*;
110 /// A reference to an element
111 using reference = char&;
113 /// A const reference to an element
114 using const_reference = const char&;
116 /// A random access iterator to an element
117 using iterator = char*;
119 /// A random access const iterator to an element
120 using const_iterator = char const*;
122 /// A reverse random access iterator to an element
123 using reverse_iterator =
124 std::reverse_iterator<iterator>;
126 /// A reverse random access const iterator to an element
127 using const_reverse_iterator =
128 std::reverse_iterator<const_iterator>;
131 static constexpr std::size_t npos =
136 using is_inputit = typename std::enable_if<
137 std::is_convertible<typename
138 std::iterator_traits<T>::value_type,
141 storage_ptr sp_; // must come first
147 Any dynamically allocated internal storage
153 @par Exception Safety
161 //------------------------------------------------------
165 //------------------------------------------------------
167 /** Default constructor.
169 The string will have a zero size and a non-zero,
170 unspecified capacity, using the default memory resource.
178 /** Pilfer constructor.
180 The string is constructed by acquiring ownership
181 of the contents of `other` using pilfer semantics.
182 This is more efficient than move construction, when
183 it is known that the moved-from object will be
184 immediately destroyed afterwards.
189 @par Exception Safety
192 @param other The value to pilfer. After pilfer
193 construction, `other` is not in a usable state
194 and may only be destroyed.
197 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
198 Valueless Variants Considered Harmful</a>
200 string(pilfered<string> other) noexcept
201 : sp_(std::move(other.get().sp_))
202 , impl_(other.get().impl_)
204 ::new(&other.get().impl_) string_impl();
209 The string will have zero size and a non-zero,
210 unspecified capacity, obtained from the specified
217 @param sp A pointer to the @ref memory_resource
218 to use. The container will acquire shared
219 ownership of the memory resource.
222 string(storage_ptr sp)
229 Construct the contents with `count` copies of
236 @par Exception Safety
239 Calls to `memory_resource::allocate` may throw.
241 @param count The size of the resulting string.
243 @param ch The value to initialize characters
246 @param sp An optional pointer to the @ref memory_resource
247 to use. The container will acquire shared
248 ownership of the memory resource.
249 The default argument for this parameter is `{}`.
251 @throw std::length_error `count > max_size()`.
258 storage_ptr sp = {});
262 Construct the contents with those of the null
263 terminated string pointed to by `s`. The length
264 of the string is determined by the first null
269 Linear in `strlen(s)`.
271 @par Exception Safety
274 Calls to `memory_resource::allocate` may throw.
276 @param s A pointer to a character string used to
279 @param sp An optional pointer to the @ref memory_resource
280 to use. The container will acquire shared
281 ownership of the memory resource.
282 The default argument for this parameter is `{}`.
284 @throw std::length_error `strlen(s) > max_size()`.
289 storage_ptr sp = {});
293 Construct the contents with copies of the
294 characters in the range `{s, s+count)`.
295 This range can contain null characters.
301 @par Exception Safety
304 Calls to `memory_resource::allocate` may throw.
306 @param count The number of characters to copy.
308 @param s A pointer to a character string used to
311 @param sp An optional pointer to the @ref memory_resource
312 to use. The container will acquire shared
313 ownership of the memory resource.
314 The default argument for this parameter is `{}`.
316 @throw std::length_error `count > max_size()`.
323 storage_ptr sp = {});
327 Construct the contents with copies of characters
328 in the range `{first, last)`.
332 Linear in `std::distance(first, last)`.
334 @par Exception Safety
337 Calls to `memory_resource::allocate` may throw.
339 @tparam InputIt The type of the iterators.
343 `InputIt` satisfies __InputIterator__.
345 @param first An input iterator pointing to the
346 first character to insert, or pointing to the
349 @param last An input iterator pointing to the end
352 @param sp An optional pointer to the @ref memory_resource
353 to use. The container will acquire shared
354 ownership of the memory resource.
355 The default argument for this parameter is `{}`.
357 @throw std::length_error `std::distance(first, last) > max_size()`.
359 template<class InputIt
360 #ifndef BOOST_JSON_DOCS
361 ,class = is_inputit<InputIt>
368 storage_ptr sp = {});
370 /** Copy constructor.
372 Construct the contents with a copy of `other`.
376 Linear in `other.size()`.
378 @par Exception Safety
381 Calls to `memory_resource::allocate` may throw.
383 @param other The string to use as a source
387 string(string const& other);
391 Construct the contents with a copy of `other`.
395 Linear in `other.size()`.
397 @par Exception Safety
400 Calls to `memory_resource::allocate` may throw.
402 @param other The string to use as a source
405 @param sp An optional pointer to the @ref memory_resource
406 to use. The container will acquire shared
407 ownership of the memory resource.
408 The default argument for this parameter is `{}`.
416 /** Move constructor.
418 Constructs the string with the contents of `other`
419 using move semantics. Ownership of the underlying
420 memory is transferred.
421 The container acquires shared ownership of the
422 @ref memory_resource used by `other`. After construction,
423 the moved-from string behaves as if newly
424 constructed with its current memory resource.
430 @param other The string to move
432 string(string&& other) noexcept
436 ::new(&other.impl_) string_impl();
441 Construct the contents with those of `other`
442 using move semantics.
444 @li If `*other.storage() == *sp`,
445 ownership of the underlying memory is transferred
446 in constant time, with no possibility
447 of exceptions. After construction, the moved-from
448 string behaves as if newly constructed with
449 its current @ref memory_resource. Otherwise,
451 @li If `*other.storage() != *sp`,
452 a copy of the characters in `other` is made. In
453 this case, the moved-from string is not changed.
457 Constant or linear in `other.size()`.
459 @par Exception Safety
462 Calls to `memory_resource::allocate` may throw.
464 @param other The string to assign from.
466 @param sp An optional pointer to the @ref memory_resource
467 to use. The container will acquire shared
468 ownership of the memory resource.
469 The default argument for this parameter is `{}`.
479 Construct the contents with those of a
480 string view. This view can contain
485 Linear in `s.size()`.
487 @par Exception Safety
490 Calls to `memory_resource::allocate` may throw.
492 @param s The string view to copy from.
494 @param sp An optional pointer to the @ref memory_resource
495 to use. The container will acquire shared
496 ownership of the memory resource.
497 The default argument for this parameter is `{}`.
499 @throw std::length_error `s.size() > max_size()`.
504 storage_ptr sp = {});
506 //------------------------------------------------------
510 //------------------------------------------------------
514 Replace the contents with a copy of `other`.
518 Linear in `other.size()`.
520 @par Exception Safety
523 Calls to `memory_resource::allocate` may throw.
527 @param other The string to use as a source
532 operator=(string const& other);
536 Replace the contents with those of `other`
537 using move semantics.
539 @li If `*other.storage() == *this->storage()`,
540 ownership of the underlying memory is transferred
541 in constant time, with no possibility
542 of exceptions. After construction, the moved-from
543 string behaves as if newly constructed with its
544 current @ref memory_resource. Otherwise,
546 @li If `*other.storage() != *this->storage()`,
547 a copy of the characters in `other` is made. In
548 this case, the moved-from container is not changed.
552 Constant or linear in `other.size()`.
554 @par Exception Safety
557 Calls to `memory_resource::allocate` may throw.
561 @param other The string to use as a source
566 operator=(string&& other);
568 /** Assign a value to the string.
570 Replaces the contents with those of the null
571 terminated string pointed to by `s`. The length
572 of the string is determined by the first null
577 Linear in `std::strlen(s)`.
579 @par Exception Safety
582 Calls to `memory_resource::allocate` may throw.
586 @param s The null-terminated character string.
588 @throw std::length_error `std::strlen(s) > max_size()`.
592 operator=(char const* s);
594 /** Assign a value to the string.
596 Replaces the contents with those of a
597 string view. This view can contain
602 Linear in `s.size()`.
604 @par Exception Safety
607 Calls to `memory_resource::allocate` may throw.
611 @param s The string view to copy from.
613 @throw std::length_error `s.size() > max_size()`.
617 operator=(string_view s);
619 //------------------------------------------------------
621 /** Assign characters to a string.
623 Replace the contents with `count` copies of
630 @par Exception Safety
633 Calls to `memory_resource::allocate` may throw.
637 @param count The size of the resulting string.
639 @param ch The value to initialize characters
642 @throw std::length_error `count > max_size()`.
650 /** Assign characters to a string.
652 Replace the contents with a copy of `other`.
656 Linear in `other.size()`.
658 @par Exception Safety
661 Calls to `memory_resource::allocate` may throw.
665 @param other The string to use as a source
671 string const& other);
673 /** Assign characters to a string.
675 Replace the contents with those of `other`
676 using move semantics.
678 @li If `*other.storage() == *this->storage()`,
679 ownership of the underlying memory is transferred
680 in constant time, with no possibility of
681 exceptions. After construction, the moved-from
682 string behaves as if newly constructed with
683 its current @ref memory_resource, otherwise
685 @li If `*other.storage() != *this->storage()`,
686 a copy of the characters in `other` is made.
687 In this case, the moved-from container
692 Constant or linear in `other.size()`.
694 @par Exception Safety
697 Calls to `memory_resource::allocate` may throw.
701 @param other The string to assign from.
705 assign(string&& other);
707 /** Assign characters to a string.
709 Replaces the contents with copies of the
710 characters in the range `{s, s+count)`. This
711 range can contain null characters.
717 @par Exception Safety
720 Calls to `memory_resource::allocate` may throw.
724 @param count The number of characters to copy.
726 @param s A pointer to a character string used to
729 @throw std::length_error `count > max_size()`.
737 /** Assign characters to a string.
739 Replaces the contents with those of the null
740 terminated string pointed to by `s`. The length
741 of the string is determined by the first null
746 Linear in `strlen(s)`.
748 @par Exception Safety
754 Calls to `memory_resource::allocate` may throw.
758 @param s A pointer to a character string used to
761 @throw std::length_error `strlen(s) > max_size()`.
768 /** Assign characters to a string.
770 Replaces the contents with copies of characters
771 in the range `{first, last)`.
775 Linear in `std::distance(first, last)`.
777 @par Exception Safety
780 Calls to `memory_resource::allocate` may throw.
782 @tparam InputIt The type of the iterators.
786 `InputIt` satisfies __InputIterator__.
790 @param first An input iterator pointing to the
791 first character to insert, or pointing to the
794 @param last An input iterator pointing to the end
797 @throw std::length_error `std::distance(first, last) > max_size()`.
799 template<class InputIt
800 #ifndef BOOST_JSON_DOCS
801 ,class = is_inputit<InputIt>
809 /** Assign characters to a string.
811 Replaces the contents with those of a
812 string view. This view can contain
817 Linear in `s.size()`.
819 @par Exception Safety
822 Calls to `memory_resource::allocate` may throw.
826 @param s The string view to copy from.
828 @throw std::length_error `s.size() > max_size()`.
831 assign(string_view s)
833 return assign(s.data(), s.size());
836 //------------------------------------------------------
838 /** Return the associated @ref memory_resource
840 This returns the @ref memory_resource used by
847 @par Exception Safety
852 storage() const noexcept
857 /** Return the associated @ref memory_resource
859 This function returns an instance of
860 @ref polymorphic_allocator constructed from the
861 associated @ref memory_resource.
867 @par Exception Safety
872 get_allocator() const noexcept
877 //------------------------------------------------------
881 //------------------------------------------------------
883 /** Return a character with bounds checking.
885 Returns a reference to the character specified at
892 @par Exception Safety
896 @param pos A zero-based index to access.
898 @throw std::out_of_range `pos >= size()`
904 detail::throw_out_of_range(
905 BOOST_JSON_SOURCE_POS);
906 return impl_.data()[pos];
909 /** Return a character with bounds checking.
911 Returns a reference to the character specified at
918 @par Exception Safety
922 @param pos A zero-based index to access.
924 @throw std::out_of_range `pos >= size()`
927 at(std::size_t pos) const
930 detail::throw_out_of_range(
931 BOOST_JSON_SOURCE_POS);
932 return impl_.data()[pos];
935 /** Return a character without bounds checking.
937 Returns a reference to the character specified at
950 @param pos A zero-based index to access.
953 operator[](std::size_t pos)
955 return impl_.data()[pos];
958 /** Return a character without bounds checking.
960 Returns a reference to the character specified at
973 @param pos A zero-based index to access.
976 operator[](std::size_t pos) const
978 return impl_.data()[pos];
981 /** Return the first character.
983 Returns a reference to the first character.
998 return impl_.data()[0];
1001 /** Return the first character.
1003 Returns a reference to the first character.
1018 return impl_.data()[0];
1021 /** Return the last character.
1023 Returns a reference to the last character.
1038 return impl_.data()[impl_.size() - 1];
1041 /** Return the last character.
1043 Returns a reference to the last character.
1058 return impl_.data()[impl_.size() - 1];
1061 /** Return the underlying character array directly.
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.
1072 @note The value returned from
1073 this function is never equal to `nullptr`.
1078 return impl_.data();
1081 /** Return the underlying character array directly.
1083 Returns a pointer to the underlying array
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`.
1097 data() const noexcept
1099 return impl_.data();
1102 /** Return the underlying character array directly.
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.
1113 @note The value returned from
1114 this function is never equal to `nullptr`.
1117 c_str() const noexcept
1119 return impl_.data();
1122 /** Convert to a `string_view` referring to the string.
1124 Returns a string view to the
1125 underlying character string. The size of the view
1126 does not include the null terminator.
1132 operator string_view() const noexcept
1134 return {data(), size()};
1137 #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
1138 /** Convert to a `std::string_view` referring to the string.
1140 Returns a string view to the underlying character string. The size of
1141 the view does not include the null terminator.
1143 This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW`
1150 operator std::string_view() const noexcept
1152 return {data(), size()};
1156 //------------------------------------------------------
1160 //------------------------------------------------------
1162 /** Return an iterator to the beginning.
1164 If the container is empty, @ref end() is returned.
1169 @par Exception Safety
1175 return impl_.data();
1178 /** Return an iterator to the beginning.
1180 If the container is empty, @ref end() is returned.
1185 @par Exception Safety
1189 begin() const noexcept
1191 return impl_.data();
1194 /** Return an iterator to the beginning.
1196 If the container is empty, @ref cend() is returned.
1201 @par Exception Safety
1205 cbegin() const noexcept
1207 return impl_.data();
1210 /** Return an iterator to the end.
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.
1220 @par Exception Safety
1229 /** Return an iterator to the end.
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.
1239 @par Exception Safety
1243 end() const noexcept
1248 /** Return an iterator to the end.
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.
1258 @par Exception Safety
1262 cend() const noexcept
1267 /** Return a reverse iterator to the first character of the reversed container.
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.
1277 @par Exception Safety
1283 return reverse_iterator(impl_.end());
1286 /** Return a reverse iterator to the first character of the reversed container.
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.
1296 @par Exception Safety
1299 const_reverse_iterator
1300 rbegin() const noexcept
1302 return const_reverse_iterator(impl_.end());
1305 /** Return a reverse iterator to the first character of the reversed container.
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.
1315 @par Exception Safety
1318 const_reverse_iterator
1319 crbegin() const noexcept
1321 return const_reverse_iterator(impl_.end());
1324 /** Return a reverse iterator to the character following the last character of the reversed container.
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.
1335 @par Exception Safety
1341 return reverse_iterator(begin());
1344 /** Return a reverse iterator to the character following the last character of the reversed container.
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.
1355 @par Exception Safety
1358 const_reverse_iterator
1359 rend() const noexcept
1361 return const_reverse_iterator(begin());
1364 /** Return a reverse iterator to the character following the last character of the reversed container.
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.
1375 @par Exception Safety
1378 const_reverse_iterator
1379 crend() const noexcept
1381 return const_reverse_iterator(begin());
1384 //------------------------------------------------------
1388 //------------------------------------------------------
1390 /** Check if the string has no characters.
1392 Returns `true` if there are no characters in
1393 the string, i.e. @ref size() returns 0.
1400 empty() const noexcept
1402 return impl_.size() == 0;
1405 /** Return the number of characters in the string.
1407 The value returned does not include the
1408 null terminator, which is always present.
1415 size() const noexcept
1417 return impl_.size();
1420 /** Return the maximum number of characters any string can hold.
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
1436 return string_impl::max_size();
1439 /** Return the number of characters that can be held without a reallocation.
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
1451 capacity() const noexcept
1453 return impl_.capacity();
1456 /** Increase the capacity to at least a certain amount.
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.
1467 At most, linear in @ref size().
1469 @par Exception Safety
1472 Calls to `memory_resource::allocate` may throw.
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.
1481 @param new_capacity The new capacity of the array.
1483 @throw std::length_error `new_capacity > max_size()`
1486 reserve(std::size_t new_capacity)
1488 if(new_capacity <= capacity())
1490 reserve_impl(new_capacity);
1493 /** Request the removal of unused capacity.
1495 This performs a non-binding request to reduce
1496 @ref capacity() to @ref size(). The request may
1497 or may not be fulfilled.
1501 At most, linear in @ref size().
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
1513 //------------------------------------------------------
1517 //------------------------------------------------------
1519 /** Clear the contents.
1521 Erases all characters from the string. After this
1522 call, @ref size() returns zero but @ref capacity()
1527 Linear in @ref size().
1529 @note All references, pointers, or iterators
1530 referring to contained elements are invalidated.
1531 Any past-the-end iterators are also invalidated.
1537 //------------------------------------------------------
1539 /** Insert a string.
1541 Inserts the `string_view` `sv` at the position `pos`.
1543 @par Exception Safety
1547 @note All references, pointers, or iterators
1548 referring to contained elements are invalidated.
1549 Any past-the-end iterators are also invalidated.
1553 @param pos The index to insert at.
1555 @param sv The `string_view` to insert.
1557 @throw std::length_error `size() + s.size() > max_size()`
1559 @throw std::out_of_range `pos > size()`
1567 /** Insert a character.
1569 Inserts `count` copies of `ch` at the position `pos`.
1571 @par Exception Safety
1575 @note All references, pointers, or iterators
1576 referring to contained elements are invalidated.
1577 Any past-the-end iterators are also invalidated.
1581 @param pos The index to insert at.
1583 @param count The number of characters to insert.
1585 @param ch The character to insert.
1587 @throw std::length_error `size() + count > max_size()`
1589 @throw std::out_of_range `pos > size()`
1598 /** Insert a character.
1600 Inserts the character `ch` before the character
1603 @par Exception Safety
1607 @note All references, pointers, or iterators
1608 referring to contained elements are invalidated.
1609 Any past-the-end iterators are also invalidated.
1613 @param pos The index to insert at.
1615 @param ch The character to insert.
1617 @throw std::length_error `size() + 1 > max_size()`
1619 @throw std::out_of_range `pos > size()`
1626 return insert(pos, 1, ch);
1629 /** Insert a range of characters.
1631 Inserts characters from the range `{first, last)`
1632 before the character at index `pos`.
1636 `{first, last)` is a valid range.
1638 @par Exception Safety
1642 @note All references, pointers, or iterators
1643 referring to contained elements are invalidated.
1644 Any past-the-end iterators are also invalidated.
1646 @tparam InputIt The type of the iterators.
1650 `InputIt` satisfies __InputIterator__.
1654 @param pos The index to insert at.
1656 @param first The beginning of the character range.
1658 @param last The end of the character range.
1660 @throw std::length_error `size() + insert_count > max_size()`
1662 @throw std::out_of_range `pos > size()`
1664 template<class InputIt
1665 #ifndef BOOST_JSON_DOCS
1666 ,class = is_inputit<InputIt>
1675 //------------------------------------------------------
1677 /** Erase characters from the string.
1679 Erases `num` characters from the string, starting
1680 at `pos`. `num` is determined as the smaller of
1681 `count` and `size() - pos`.
1683 @par Exception Safety
1687 @note All references, pointers, or iterators
1688 referring to contained elements are invalidated.
1689 Any past-the-end iterators are also invalidated.
1693 @param pos The index to erase at.
1694 The default argument for this parameter is `0`.
1696 @param count The number of characters to erase.
1697 The default argument for this parameter
1700 @throw std::out_of_range `pos > size()`
1705 std::size_t pos = 0,
1706 std::size_t count = npos);
1708 /** Erase a character from the string.
1710 Erases the character at `pos`.
1715 pos >= data() && pos <= data() + size()
1718 @par Exception Safety
1722 @note All references, pointers, or iterators
1723 referring to contained elements are invalidated.
1724 Any past-the-end iterators are also invalidated.
1726 @return An iterator referring to character
1727 immediately following the erased character, or
1728 @ref end() if one does not exist.
1730 @param pos An iterator referring to the
1735 erase(const_iterator pos);
1737 /** Erase a range from the string.
1739 Erases the characters in the range `{first, last)`.
1743 `{first, last}` shall be valid within
1745 {data(), data() + size()}
1748 @par Exception Safety
1752 @note All references, pointers, or iterators
1753 referring to contained elements are invalidated.
1754 Any past-the-end iterators are also invalidated.
1756 @return An iterator referring to the character
1757 `last` previously referred to, or @ref end()
1758 if one does not exist.
1760 @param first An iterator representing the first
1763 @param last An iterator one past the last
1769 const_iterator first,
1770 const_iterator last);
1772 //------------------------------------------------------
1774 /** Append a character.
1776 Appends a character to the end of the string.
1778 @par Exception Safety
1782 @param ch The character to append.
1784 @throw std::length_error `size() + 1 > max_size()`
1790 /** Remove the last character.
1792 Removes a character from the end of the string.
1804 //------------------------------------------------------
1806 /** Append characters to the string.
1808 Appends `count` copies of `ch` to the end of
1811 @par Exception Safety
1817 @param count The number of characters to append.
1819 @param ch The character to append.
1821 @throw std::length_error `size() + count > max_size()`
1829 /** Append a string to the string.
1831 Appends `sv` the end of the string.
1833 @par Exception Safety
1839 @param sv The `string_view` to append.
1841 @throw std::length_error `size() + s.size() > max_size()`
1845 append(string_view sv);
1847 /** Append a range of characters.
1849 Appends characters from the range `{first, last)`
1850 to the end of the string.
1854 `{first, last)` shall be a valid range
1856 @par Exception Safety
1860 @tparam InputIt The type of the iterators.
1864 `InputIt` satisfies __InputIterator__.
1868 @param first An iterator representing the
1869 first character to append.
1871 @param last An iterator one past the
1872 last character to append.
1874 @throw std::length_error `size() + insert_count > max_size()`
1876 template<class InputIt
1877 #ifndef BOOST_JSON_DOCS
1878 ,class = is_inputit<InputIt>
1882 append(InputIt first, InputIt last);
1884 //------------------------------------------------------
1886 /** Append characters from a string.
1888 Appends `{sv.begin(), sv.end())` to the end of
1891 @par Exception Safety
1897 @param sv The `string_view` to append.
1899 @throw std::length_error `size() + sv.size() > max_size()`
1902 operator+=(string_view sv)
1907 /** Append a character.
1909 Appends a character to the end of the string.
1911 @par Exception Safety
1915 @param ch The character to append.
1917 @throw std::length_error `size() + 1 > max_size()`
1926 //------------------------------------------------------
1928 /** Compare a string with the string.
1931 `std::char_traits<char>::compare(data(), sv.data(), std::min(size(), sv.size())`.
1932 If `comp != 0`, then the result is `comp`. Otherwise,
1933 the result is `0` if `size() == sv.size()`,
1934 `-1` if `size() < sv.size()`, and `1` otherwise.
1940 @return The result of lexicographically comparing
1941 the characters of `sv` and the string.
1943 @param sv The `string_view` to compare.
1946 compare(string_view sv) const noexcept
1948 return string_view(*this).compare(sv);
1951 //------------------------------------------------------
1953 /** Return whether the string begins with a string.
1955 Returns `true` if the string begins with `s`,
1956 and `false` otherwise.
1962 @param s The `string_view` to check for.
1965 starts_with(string_view s) const noexcept
1967 return subview(0, s.size()) == s;
1970 /** Return whether the string begins with a character.
1972 Returns `true` if the string begins with `ch`,
1973 and `false` otherwise.
1979 @param ch The character to check for.
1982 starts_with(char ch) const noexcept
1984 return ! empty() && front() == ch;
1987 /** Return whether the string end with a string.
1989 Returns `true` if the string end with `s`,
1990 and `false` otherwise.
1996 @param s The string to check for.
1999 ends_with(string_view s) const noexcept
2001 return size() >= s.size() &&
2002 subview(size() - s.size()) == s;
2005 /** Return whether the string ends with a character.
2007 Returns `true` if the string ends with `ch`,
2008 and `false` otherwise.
2014 @param ch The character to check for.
2017 ends_with(char ch) const noexcept
2019 return ! empty() && back() == ch;
2022 //------------------------------------------------------
2024 /** Replace a substring with a string.
2026 Replaces `rcount` characters starting at index
2027 `pos` with those of `sv`, where `rcount` is
2028 `std::min(count, size() - pos)`.
2030 @par Exception Safety
2034 @note All references, pointers, or iterators
2035 referring to contained elements are invalidated.
2036 Any past-the-end iterators are also invalidated.
2040 @param pos The index to replace at.
2042 @param count The number of characters to replace.
2044 @param sv The `string_view` to replace with.
2046 @throw std::length_error `size() + (sv.size() - rcount) > max_size()`
2048 @throw std::out_of_range `pos > size()`
2057 /** Replace a range with a string.
2059 Replaces the characters in the range
2060 `{first, last)` with those of `sv`.
2064 `{first, last)` is a valid range.
2066 @par Exception Safety
2070 @note All references, pointers, or iterators
2071 referring to contained elements are invalidated.
2072 Any past-the-end iterators are also invalidated.
2076 @param first An iterator referring to the first
2077 character to replace.
2079 @param last An iterator one past the end of
2080 the last character to replace.
2082 @param sv The `string_view` to replace with.
2084 @throw std::length_error `size() + (sv.size() - std::distance(first, last)) > max_size()`
2088 const_iterator first,
2089 const_iterator last,
2092 return replace(first - begin(), last - first, sv);
2095 /** Replace a range with a range.
2097 Replaces the characters in the range
2098 `{first, last)` with those of `{first2, last2)`.
2102 `{first, last)` is a valid range.
2104 `{first2, last2)` is a valid range.
2106 @par Exception Safety
2110 @note All references, pointers, or iterators
2111 referring to contained elements are invalidated.
2112 Any past-the-end iterators are also invalidated.
2114 @tparam InputIt The type of the iterators.
2118 `InputIt` satisfies __InputIterator__.
2122 @param first An iterator referring to the first
2123 character to replace.
2125 @param last An iterator one past the end of
2126 the last character to replace.
2128 @param first2 An iterator referring to the first
2129 character to replace with.
2131 @param last2 An iterator one past the end of
2132 the last character to replace with.
2134 @throw std::length_error `size() + (inserted - std::distance(first, last)) > max_size()`
2136 template<class InputIt
2137 #ifndef BOOST_JSON_DOCS
2138 ,class = is_inputit<InputIt>
2143 const_iterator first,
2144 const_iterator last,
2148 /** Replace a substring with copies of a character.
2150 Replaces `rcount` characters starting at index
2151 `pos`with `count2` copies of `ch`, where
2152 `rcount` is `std::min(count, size() - pos)`.
2154 @par Exception Safety
2158 @note All references, pointers, or iterators
2159 referring to contained elements are invalidated.
2160 Any past-the-end iterators are also invalidated.
2164 @param pos The index to replace at.
2166 @param count The number of characters to replace.
2168 @param count2 The number of characters to
2171 @param ch The character to replace with.
2173 @throw std::length_error `size() + (count2 - rcount) > max_size()`
2175 @throw std::out_of_range `pos > size()`
2185 /** Replace a range with copies of a character.
2187 Replaces the characters in the range
2188 `{first, last)` with `count` copies of `ch`.
2192 `{first, last)` is a valid range.
2194 @par Exception Safety
2198 @note All references, pointers, or iterators
2199 referring to contained elements are invalidated.
2200 Any past-the-end iterators are also invalidated.
2204 @param first An iterator referring to the first
2205 character to replace.
2207 @param last An iterator one past the end of
2208 the last character to replace.
2210 @param count The number of characters to
2213 @param ch The character to replace with.
2215 @throw std::length_error `size() + (count - std::distance(first, last)) > max_size()`
2219 const_iterator first,
2220 const_iterator last,
2224 return replace(first - begin(), last - first, count, ch);
2227 //------------------------------------------------------
2229 /** Return a substring.
2231 Returns a view of a substring.
2233 @par Exception Safety
2237 @return A `string_view` object referring
2238 to `{data() + pos, std::min(count, size() - pos))`.
2240 @param pos The index to being the substring at.
2241 The default argument for this parameter is `0`.
2243 @param count The length of the substring.
2244 The default argument for this parameter
2247 @throw std::out_of_range `pos > size()`
2251 std::size_t pos = 0,
2252 std::size_t count = npos) const
2254 return string_view(*this).substr(pos, count);
2257 //------------------------------------------------------
2259 /** Copy a substring to another string.
2261 Copies `std::min(count, size() - pos)` characters
2262 starting at index `pos` to the string pointed
2265 @note The resulting string is not null terminated.
2267 @return The number of characters copied.
2269 @param count The number of characters to copy.
2271 @param dest The string to copy to.
2273 @param pos The index to begin copying from. The
2274 default argument for this parameter is `0`.
2276 @throw std::out_of_range `pos > max_size()`
2282 std::size_t pos = 0) const
2284 return string_view(*this).copy(dest, count, pos);
2287 //------------------------------------------------------
2289 /** Change the size of the string.
2291 Resizes the string to contain `count` characters.
2292 If `count > size()`, characters with the value `0`
2293 are appended. Otherwise, `size()` is reduced
2296 @param count The size to resize the string to.
2298 @throw std::out_of_range `count > max_size()`
2301 resize(std::size_t count)
2306 /** Change the size of the string.
2308 Resizes the string to contain `count` characters.
2309 If `count > size()`, copies of `ch` are
2310 appended. Otherwise, `size()` is reduced
2313 @param count The size to resize the string to.
2315 @param ch The characters to append if the size
2318 @throw std::out_of_range `count > max_size()`
2322 resize(std::size_t count, char ch);
2324 /** Increase size without changing capacity.
2326 This increases the size of the string by `n`
2327 characters, adjusting the position of the
2328 terminating null for the new size. The new
2329 characters remain uninitialized. This function
2330 may be used to append characters directly into
2331 the storage between `end()` and
2332 `data() + capacity()`.
2337 count <= capacity() - size()
2340 @param n The amount to increase the size by.
2343 grow(std::size_t n) noexcept
2346 n <= impl_.capacity() - impl_.size());
2347 impl_.term(impl_.size() + n);
2350 //------------------------------------------------------
2352 /** Swap the contents.
2354 Exchanges the contents of this string with another
2355 string. Ownership of the respective @ref memory_resource
2356 objects is not transferred.
2358 @li If `*other.storage() == *this->storage()`,
2359 ownership of the underlying memory is swapped in
2360 constant time, with no possibility of exceptions.
2361 All iterators and references remain valid.
2363 @li If `*other.storage() != *this->storage()`,
2364 the contents are logically swapped by making copies,
2365 which can throw. In this case all iterators and
2366 references are invalidated.
2370 Constant or linear in @ref size() plus
2379 @par Exception Safety
2382 Calls to `memory_resource::allocate` may throw.
2384 @param other The string to swap with
2385 If `this == &other`, this function call has no effect.
2389 swap(string& other);
2391 /** Exchange the given values.
2393 Exchanges the contents of the string `lhs` with
2394 another string `rhs`. Ownership of the respective
2395 @ref memory_resource objects is not transferred.
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.
2402 @li If `*lhs.storage() != *rhs.storage()`,
2403 the contents are logically swapped by making a copy,
2404 which can throw. In this case all iterators and
2405 references are invalidated.
2413 Constant or linear in `lhs.size() + rhs.size()`.
2415 @par Exception Safety
2417 Calls to `memory_resource::allocate` may throw.
2419 @param lhs The string to exchange.
2421 @param rhs The string to exchange.
2422 If `&lhs == &rhs`, this function call has no effect.
2424 @see @ref string::swap
2428 swap(string& lhs, string& rhs)
2432 //------------------------------------------------------
2436 //------------------------------------------------------
2438 /** Find the first occurrence of a string within the string.
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.
2449 @return The first occurrence of `sv` within the
2450 string starting at the index `pos`, or @ref npos
2453 @param sv The `string_view` to search for.
2455 @param pos The index to start searching at.
2456 The default argument for this parameter is `0`.
2461 std::size_t pos = 0) const noexcept
2463 return string_view(*this).find(sv, pos);
2466 /** Find the first occurrence of a character within the string.
2468 Returns the index corrosponding to the first
2469 occurrence of `ch` within `{begin() + pos, end())`
2470 if it exists, and @ref npos otherwise.
2476 @return The first occurrence of `ch` within the
2477 string starting at the index `pos`, or @ref npos
2480 @param ch The character to search for.
2482 @param pos The index to start searching at.
2483 The default argument for this parameter is `0`.
2488 std::size_t pos = 0) const noexcept
2490 return string_view(*this).find(ch, pos);
2493 //------------------------------------------------------
2495 /** Find the last occurrence of a string within the string.
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.
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.
2510 @param sv The `string_view` to search for.
2512 @param pos The index to start searching at.
2513 The default argument for this parameter
2519 std::size_t pos = npos) const noexcept
2521 return string_view(*this).rfind(sv, pos);
2524 /** Find the last occurrence of a character within the string.
2526 Returns index corrosponding to the last occurrence
2527 of `ch` within `{begin(), begin() + pos}` if it
2528 exists, and @ref npos otherwise.
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.
2538 @param ch The character to search for.
2540 @param pos The index to stop searching at.
2541 The default argument for this parameter
2547 std::size_t pos = npos) const noexcept
2549 return string_view(*this).rfind(ch, pos);
2552 //------------------------------------------------------
2554 /** Find the first occurrence of any of the characters within the string.
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.
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
2570 @param sv The characters to search for.
2572 @param pos The index to start searching at.
2573 The default argument for this parameter is `0`.
2578 std::size_t pos = 0) const noexcept
2580 return string_view(*this).find_first_of(sv, pos);
2583 //------------------------------------------------------
2585 /** Find the first occurrence of any of the characters not within the string.
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
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.
2600 @param sv The characters to ignore.
2602 @param pos The index to start searching at.
2603 The default argument for this parameter is `0`.
2608 std::size_t pos = 0) const noexcept
2610 return string_view(*this).find_first_not_of(sv, pos);
2613 /** Find the first occurrence of a character not equal to `ch`.
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.
2624 @return The first occurrence of a character that
2625 is not equal to `ch`, or @ref npos if none exists.
2627 @param ch The character to ignore.
2629 @param pos The index to start searching at.
2630 The default argument for this parameter is `0`.
2635 std::size_t pos = 0) const noexcept
2637 return string_view(*this).find_first_not_of(ch, pos);
2640 //------------------------------------------------------
2642 /** Find the last occurrence of any of the characters within the string.
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.
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
2658 @param sv The characters to search for.
2660 @param pos The index to stop searching at.
2661 The default argument for this parameter
2667 std::size_t pos = npos) const noexcept
2669 return string_view(*this).find_last_of(sv, pos);
2672 //------------------------------------------------------
2674 /** Find the last occurrence of a character not within the string.
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.
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.
2688 @param sv The characters to ignore.
2690 @param pos The index to stop searching at.
2691 The default argument for this parameter
2697 std::size_t pos = npos) const noexcept
2699 return string_view(*this).find_last_not_of(sv, pos);
2702 /** Find the last occurrence of a character not equal to `ch`.
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
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.
2717 @param ch The character to ignore.
2719 @param pos The index to start searching at.
2720 The default argument for this parameter
2726 std::size_t pos = npos) const noexcept
2728 return string_view(*this).find_last_not_of(ch, pos);
2735 using iter_cat = typename
2736 std::iterator_traits<It>::iterator_category;
2738 template<class InputIt>
2740 assign(InputIt first, InputIt last,
2741 std::random_access_iterator_tag);
2743 template<class InputIt>
2745 assign(InputIt first, InputIt last,
2746 std::input_iterator_tag);
2748 template<class InputIt>
2750 append(InputIt first, InputIt last,
2751 std::random_access_iterator_tag);
2753 template<class InputIt>
2755 append(InputIt first, InputIt last,
2756 std::input_iterator_tag);
2760 reserve_impl(std::size_t new_capacity);
2763 //----------------------------------------------------------
2765 /** Return true if lhs equals rhs.
2767 A lexicographical comparison is used.
2769 #ifdef BOOST_JSON_DOCS
2771 operator==(string const& lhs, string const& rhs) noexcept
2773 template<class T, class U>
2774 typename std::enable_if<
2775 (std::is_same<T, string>::value &&
2776 std::is_convertible<
2777 U const&, string_view>::value) ||
2778 (std::is_same<U, string>::value &&
2779 std::is_convertible<
2780 T const&, string_view>::value),
2782 operator==(T const& lhs, U const& rhs) noexcept
2785 return string_view(lhs) == string_view(rhs);
2788 /** Return true if lhs does not equal rhs.
2790 A lexicographical comparison is used.
2792 #ifdef BOOST_JSON_DOCS
2794 operator!=(string const& lhs, string const& rhs) noexcept
2796 template<class T, class U>
2797 typename std::enable_if<
2798 (std::is_same<T, string>::value &&
2799 std::is_convertible<
2800 U const&, string_view>::value) ||
2801 (std::is_same<U, string>::value &&
2802 std::is_convertible<
2803 T const&, string_view>::value),
2805 operator!=(T const& lhs, U const& rhs) noexcept
2808 return string_view(lhs) != string_view(rhs);
2811 /** Return true if lhs is less than rhs.
2813 A lexicographical comparison is used.
2815 #ifdef BOOST_JSON_DOCS
2817 operator<(string const& lhs, string const& rhs) noexcept
2819 template<class T, class U>
2820 typename std::enable_if<
2821 (std::is_same<T, string>::value &&
2822 std::is_convertible<
2823 U const&, string_view>::value) ||
2824 (std::is_same<U, string>::value &&
2825 std::is_convertible<
2826 T const&, string_view>::value),
2828 operator<(T const& lhs, U const& rhs) noexcept
2831 return string_view(lhs) < string_view(rhs);
2834 /** Return true if lhs is less than or equal to rhs.
2836 A lexicographical comparison is used.
2838 #ifdef BOOST_JSON_DOCS
2840 operator<=(string const& lhs, string const& rhs) noexcept
2842 template<class T, class U>
2843 typename std::enable_if<
2844 (std::is_same<T, string>::value &&
2845 std::is_convertible<
2846 U const&, string_view>::value) ||
2847 (std::is_same<U, string>::value &&
2848 std::is_convertible<
2849 T const&, string_view>::value),
2851 operator<=(T const& lhs, U const& rhs) noexcept
2854 return string_view(lhs) <= string_view(rhs);
2857 #ifdef BOOST_JSON_DOCS
2859 operator>=(string const& lhs, string const& rhs) noexcept
2861 template<class T, class U>
2862 typename std::enable_if<
2863 (std::is_same<T, string>::value &&
2864 std::is_convertible<
2865 U const&, string_view>::value) ||
2866 (std::is_same<U, string>::value &&
2867 std::is_convertible<
2868 T const&, string_view>::value),
2870 operator>=(T const& lhs, U const& rhs) noexcept
2873 return string_view(lhs) >= string_view(rhs);
2876 /** Return true if lhs is greater than rhs.
2878 A lexicographical comparison is used.
2880 #ifdef BOOST_JSON_DOCS
2882 operator>(string const& lhs, string const& rhs) noexcept
2884 template<class T, class U>
2885 typename std::enable_if<
2886 (std::is_same<T, string>::value &&
2887 std::is_convertible<
2888 U const&, string_view>::value) ||
2889 (std::is_same<U, string>::value &&
2890 std::is_convertible<
2891 T const&, string_view>::value),
2893 operator>(T const& lhs, U const& rhs) noexcept
2896 return string_view(lhs) > string_view(rhs);
2901 // std::hash specialization
2902 #ifndef BOOST_JSON_DOCS
2905 struct hash< ::boost::json::string >
2908 hash(hash const&) = default;
2909 hash& operator=(hash const&) = default;
2912 hash(std::size_t salt) noexcept
2918 operator()(::boost::json::string const& js) const noexcept
2920 return ::boost::json::detail::digest(
2921 js.begin(), js.end(), salt_);
2925 std::size_t salt_ = 0;
2930 #include <boost/json/impl/string.hpp>