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