100.00% Lines (151/151) 100.00% Functions (68/68)
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   30633 ~string() noexcept 147   30633 ~string() noexcept
148   { 148   {
HITCBC 149   30633 impl_.destroy(sp_); 149   30633 impl_.destroy(sp_);
HITCBC 150   30633 } 150   30633 }
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   2423 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   9103 string(storage_ptr sp) 242   9103 string(storage_ptr sp)
HITCBC 243   9103 : sp_(std::move(sp)) 243   9103 : sp_(std::move(sp))
244   { 244   {
HITCBC 245   9103 } 245   9103 }
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   417 string(string&& other) noexcept 318   417 string(string&& other) noexcept
HITCBC 319   417 : sp_(other.sp_) 319   417 : sp_(other.sp_)
HITCBC 320   417 , impl_(other.impl_) 320   417 , impl_(other.impl_)
321   { 321   {
HITCBC 322   417 ::new(&other.impl_) string_impl(); 322   417 ::new(&other.impl_) string_impl();
HITCBC 323   417 } 323   417 }
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   17972 assign(string_view s) 507   17972 assign(string_view s)
508   { 508   {
HITCBC 509   17972 return assign(s.data(), s.size()); 509   17972 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   116 storage() const noexcept 540   116 storage() const noexcept
541   { 541   {
HITCBC 542   116 return sp_; 542   116 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   //------------------------------------------------------ 562   //------------------------------------------------------
563   // 563   //
564   // Element Access 564   // Element Access
565   // 565   //
566   //------------------------------------------------------ 566   //------------------------------------------------------
567   567  
568   /** Return a character with bounds checking. 568   /** Return a character with bounds checking.
569   569  
570   Returns @ref boost::system::result containing a reference to the 570   Returns @ref boost::system::result containing a reference to the
571   character specified at location `pos`, if `pos` is within the range of 571   character specified at location `pos`, if `pos` is within the range of
572   the string. Otherwise the result contains an `error_code`. 572   the string. Otherwise the result contains an `error_code`.
573   573  
574   @par Exception Safety 574   @par Exception Safety
575   Strong guarantee. 575   Strong guarantee.
576   576  
577   @param pos A zero-based index to access. 577   @param pos A zero-based index to access.
578   578  
579   @par Complexity 579   @par Complexity
580   Constant. 580   Constant.
581   581  
582   @{ 582   @{
583   */ 583   */
584   BOOST_JSON_DECL 584   BOOST_JSON_DECL
585   system::result<char&> 585   system::result<char&>
586   try_at(std::size_t pos) noexcept; 586   try_at(std::size_t pos) noexcept;
587   587  
588   BOOST_JSON_DECL 588   BOOST_JSON_DECL
589   system::result<char const&> 589   system::result<char const&>
590   try_at(std::size_t pos) const noexcept; 590   try_at(std::size_t pos) const noexcept;
591   /// @} 591   /// @}
592   592  
593   /** Return a character with bounds checking. 593   /** Return a character with bounds checking.
594   594  
595   Returns a reference to the character specified at location `pos`. 595   Returns a reference to the character specified at location `pos`.
596   596  
597   @par Complexity 597   @par Complexity
598   Constant. 598   Constant.
599   599  
600   @par Exception Safety 600   @par Exception Safety
601   Strong guarantee. 601   Strong guarantee.
602   602  
603   @param pos A zero-based index to access. 603   @param pos A zero-based index to access.
604   @param loc `source_location` to use in thrown exception; the source 604   @param loc `source_location` to use in thrown exception; the source
605   location of the call site by default. 605   location of the call site by default.
606   606  
607   @throw boost::system::system_error `pos >=` @ref size(). 607   @throw boost::system::system_error `pos >=` @ref size().
608   608  
609   @{ 609   @{
610   */ 610   */
611   inline 611   inline
612   char& 612   char&
613   at( 613   at(
614   std::size_t pos, 614   std::size_t pos,
615   source_location const& loc = BOOST_CURRENT_LOCATION); 615   source_location const& loc = BOOST_CURRENT_LOCATION);
616   616  
617   BOOST_JSON_DECL 617   BOOST_JSON_DECL
618   char const& 618   char const&
619   at( 619   at(
620   std::size_t pos, 620   std::size_t pos,
621   source_location const& loc = BOOST_CURRENT_LOCATION) const; 621   source_location const& loc = BOOST_CURRENT_LOCATION) const;
622   /// @} 622   /// @}
623   623  
624   /** Return a character without bounds checking. 624   /** Return a character without bounds checking.
625   625  
626   Returns a reference to the character specified at location `pos`. 626   Returns a reference to the character specified at location `pos`.
627   627  
628   @par Complexity 628   @par Complexity
629   Constant. 629   Constant.
630   630  
631   @pre 631   @pre
632   @code 632   @code
633   pos < size() 633   pos < size()
634   @endcode 634   @endcode
635   635  
636   @param pos A zero-based index to access. 636   @param pos A zero-based index to access.
637   637  
638   @{ 638   @{
639   */ 639   */
640   char& 640   char&
HITCBC 641   18 operator[](std::size_t pos) 641   18 operator[](std::size_t pos)
642   { 642   {
HITCBC 643   18 return impl_.data()[pos]; 643   18 return impl_.data()[pos];
644   } 644   }
645   645  
646   const char& 646   const char&
HITCBC 647   2 operator[](std::size_t pos) const 647   2 operator[](std::size_t pos) const
648   { 648   {
HITCBC 649   2 return impl_.data()[pos]; 649   2 return impl_.data()[pos];
650   } 650   }
651   /// @} 651   /// @}
652   652  
653   /** Return the first character. 653   /** Return the first character.
654   654  
655   Returns a reference to the first character. 655   Returns a reference to the first character.
656   656  
657   @pre 657   @pre
658   @code 658   @code
659   ! empty() 659   ! empty()
660   @endcode 660   @endcode
661   661  
662   @par Complexity 662   @par Complexity
663   Constant. 663   Constant.
664   664  
665   @par Exception Safety 665   @par Exception Safety
666   No-throw guarantee. 666   No-throw guarantee.
667   667  
668   @{ 668   @{
669   */ 669   */
670   char& 670   char&
HITCBC 671   10 front() 671   10 front()
672   { 672   {
HITCBC 673   10 return impl_.data()[0]; 673   10 return impl_.data()[0];
674   } 674   }
675   675  
676   char const& 676   char const&
HITCBC 677   6 front() const 677   6 front() const
678   { 678   {
HITCBC 679   6 return impl_.data()[0]; 679   6 return impl_.data()[0];
680   } 680   }
681   /// @} 681   /// @}
682   682  
683   /** Return the last character. 683   /** Return the last character.
684   684  
685   Returns a reference to the last character. 685   Returns a reference to the last character.
686   686  
687   @pre 687   @pre
688   @code 688   @code
689   ! empty() 689   ! empty()
690   @endcode 690   @endcode
691   691  
692   @par Complexity 692   @par Complexity
693   Constant. 693   Constant.
694   694  
695   @{ 695   @{
696   */ 696   */
697   char& 697   char&
HITCBC 698   39 back() 698   39 back()
699   { 699   {
HITCBC 700   39 return impl_.data()[impl_.size() - 1]; 700   39 return impl_.data()[impl_.size() - 1];
701   } 701   }
702   702  
703   char const& 703   char const&
HITCBC 704   6 back() const 704   6 back() const
705   { 705   {
HITCBC 706   6 return impl_.data()[impl_.size() - 1]; 706   6 return impl_.data()[impl_.size() - 1];
707   } 707   }
708   /// @} 708   /// @}
709   709  
710   /** Return the underlying character array directly. 710   /** Return the underlying character array directly.
711   711  
712   Returns a pointer to the underlying array serving as storage. The value 712   Returns a pointer to the underlying array serving as storage. The value
713   returned is such that the range `[data(), data() + size())` is always 713   returned is such that the range `[data(), data() + size())` is always
714   a valid range, even if the container is empty. 714   a valid range, even if the container is empty.
715   715  
716   @note The value returned from this function is never equal to 716   @note The value returned from this function is never equal to
717   `nullptr`. 717   `nullptr`.
718   718  
719   @par Complexity 719   @par Complexity
720   Constant. 720   Constant.
721   721  
722   @par Exception Safety 722   @par Exception Safety
723   No-throw guarantee. 723   No-throw guarantee.
724   724  
725   @{ 725   @{
726   */ 726   */
727   char* 727   char*
HITCBC 728   24004 data() noexcept 728   24004 data() noexcept
729   { 729   {
HITCBC 730   24004 return impl_.data(); 730   24004 return impl_.data();
731   } 731   }
732   732  
733   char const* 733   char const*
HITCBC 734   43951 data() const noexcept 734   43951 data() const noexcept
735   { 735   {
HITCBC 736   43951 return impl_.data(); 736   43951 return impl_.data();
737   } 737   }
738   /// @@} 738   /// @@}
739   739  
740   /** Return the underlying character array directly. 740   /** Return the underlying character array directly.
741   741  
742   Returns a pointer to the underlying array serving as storage. The value 742   Returns a pointer to the underlying array serving as storage. The value
743   returned is such that the range `[c_str(), c_str() + size())` is always 743   returned is such that the range `[c_str(), c_str() + size())` is always
744   a valid range, even if the container is empty. 744   a valid range, even if the container is empty.
745   745  
746   @note The value returned from this function is never equal to 746   @note The value returned from this function is never equal to
747   `nullptr`. 747   `nullptr`.
748   748  
749   @par Complexity 749   @par Complexity
750   Constant. 750   Constant.
751   */ 751   */
752   char const* 752   char const*
HITCBC 753   4 c_str() const noexcept 753   4 c_str() const noexcept
754   { 754   {
HITCBC 755   4 return impl_.data(); 755   4 return impl_.data();
756   } 756   }
757   757  
758   /** Convert to a @ref string_view referring to the string. 758   /** Convert to a @ref string_view referring to the string.
759   759  
760   Returns a string view to the 760   Returns a string view to the
761   underlying character string. The size of the view 761   underlying character string. The size of the view
762   does not include the null terminator. 762   does not include the null terminator.
763   763  
764   @par Complexity 764   @par Complexity
765   765  
766   Constant. 766   Constant.
767   */ 767   */
HITCBC 768   57 operator string_view() const noexcept 768   57 operator string_view() const noexcept
769   { 769   {
HITCBC 770   57 return {data(), size()}; 770   57 return {data(), size()};
771   } 771   }
772   772  
773   #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW) 773   #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
774   /** Convert to @ref std::string_view referring to the string. 774   /** Convert to @ref std::string_view referring to the string.
775   775  
776   Returns a string view to the underlying character string. The size of 776   Returns a string view to the underlying character string. The size of
777   the view does not include the null terminator. 777   the view does not include the null terminator.
778   778  
779   This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW` is 779   This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW` is
780   defined. 780   defined.
781   781  
782   @par Complexity 782   @par Complexity
783   783  
784   Constant. 784   Constant.
785   */ 785   */
786   operator std::string_view() const noexcept 786   operator std::string_view() const noexcept
787   { 787   {
788   return {data(), size()}; 788   return {data(), size()};
789   } 789   }
790   #endif 790   #endif
791   791  
792   //------------------------------------------------------ 792   //------------------------------------------------------
793   // 793   //
794   // Iterators 794   // Iterators
795   // 795   //
796   //------------------------------------------------------ 796   //------------------------------------------------------
797   797  
798   /** Return an iterator to the beginning. 798   /** Return an iterator to the beginning.
799   799  
800   If the container is empty, @ref end() is returned. 800   If the container is empty, @ref end() is returned.
801   801  
802   @par Complexity 802   @par Complexity
803   Constant. 803   Constant.
804   804  
805   @par Exception Safety 805   @par Exception Safety
806   No-throw guarantee. 806   No-throw guarantee.
807   807  
808   @{ 808   @{
809   */ 809   */
810   iterator 810   iterator
HITCBC 811   34 begin() noexcept 811   34 begin() noexcept
812   { 812   {
HITCBC 813   34 return impl_.data(); 813   34 return impl_.data();
814   } 814   }
815   815  
816   const_iterator 816   const_iterator
HITCBC 817   8 begin() const noexcept 817   8 begin() const noexcept
818   { 818   {
HITCBC 819   8 return impl_.data(); 819   8 return impl_.data();
820   } 820   }
821   /// @} 821   /// @}
822   822  
823   /** Return a const iterator to the first element. 823   /** Return a const iterator to the first element.
824   824  
825   If the container is empty, @ref cend() is returned. 825   If the container is empty, @ref cend() is returned.
826   826  
827   @par Complexity 827   @par Complexity
828   Constant. 828   Constant.
829   829  
830   @par Exception Safety 830   @par Exception Safety
831   No-throw guarantee. 831   No-throw guarantee.
832   */ 832   */
833   const_iterator 833   const_iterator
HITCBC 834   2 cbegin() const noexcept 834   2 cbegin() const noexcept
835   { 835   {
HITCBC 836   2 return impl_.data(); 836   2 return impl_.data();
837   } 837   }
838   838  
839   /** Return an iterator to the end. 839   /** Return an iterator to the end.
840   840  
841   The returned iterator only acts as a sentinel. Dereferencing it results 841   The returned iterator only acts as a sentinel. Dereferencing it results
842   in undefined behavior. 842   in undefined behavior.
843   843  
844   @par Complexity 844   @par Complexity
845   Constant. 845   Constant.
846   846  
847   @par Exception Safety 847   @par Exception Safety
848   No-throw guarantee. 848   No-throw guarantee.
849   849  
850   @{ 850   @{
851   */ 851   */
852   iterator 852   iterator
HITCBC 853   3 end() noexcept 853   3 end() noexcept
854   { 854   {
HITCBC 855   3 return impl_.end(); 855   3 return impl_.end();
856   } 856   }
857   857  
858   const_iterator 858   const_iterator
HITCBC 859   3 end() const noexcept 859   3 end() const noexcept
860   { 860   {
HITCBC 861   3 return impl_.end(); 861   3 return impl_.end();
862   } 862   }
863   /// @} 863   /// @}
864   864  
865   /** Return a const iterator past the last element. 865   /** Return a const iterator past the last element.
866   866  
867   The returned iterator only acts as a sentinel. Dereferencing it results 867   The returned iterator only acts as a sentinel. Dereferencing it results
868   in undefined behavior. 868   in undefined behavior.
869   869  
870   @par Complexity 870   @par Complexity
871   Constant. 871   Constant.
872   872  
873   @par Exception Safety 873   @par Exception Safety
874   No-throw guarantee. 874   No-throw guarantee.
875   */ 875   */
876   const_iterator 876   const_iterator
HITCBC 877   2 cend() const noexcept 877   2 cend() const noexcept
878   { 878   {
HITCBC 879   2 return impl_.end(); 879   2 return impl_.end();
880   } 880   }
881   881  
882   /** Return a reverse iterator to the first character of the reversed container. 882   /** Return a reverse iterator to the first character of the reversed container.
883   883  
884   Returns the pointed-to character that corresponds to the last character 884   Returns the pointed-to character that corresponds to the last character
885   of the non-reversed container. If the container is empty, @ref rend() 885   of the non-reversed container. If the container is empty, @ref rend()
886   is returned. 886   is returned.
887   887  
888   @par Complexity 888   @par Complexity
889   Constant. 889   Constant.
890   890  
891   @{ 891   @{
892   */ 892   */
893   reverse_iterator 893   reverse_iterator
HITCBC 894   3 rbegin() noexcept 894   3 rbegin() noexcept
895   { 895   {
HITCBC 896   3 return reverse_iterator(impl_.end()); 896   3 return reverse_iterator(impl_.end());
897   } 897   }
898   898  
899   const_reverse_iterator 899   const_reverse_iterator
HITCBC 900   3 rbegin() const noexcept 900   3 rbegin() const noexcept
901   { 901   {
HITCBC 902   3 return const_reverse_iterator(impl_.end()); 902   3 return const_reverse_iterator(impl_.end());
903   } 903   }
904   /// @} 904   /// @}
905   905  
906   /** Return a const reverse iterator to the first element of the reversed container. 906   /** Return a const reverse iterator to the first element of the reversed container.
907   907  
908   Returns the pointed-to character that corresponds to the last character 908   Returns the pointed-to character that corresponds to the last character
909   of the non-reversed container. If the container is empty, @ref crend() 909   of the non-reversed container. If the container is empty, @ref crend()
910   is returned. 910   is returned.
911   911  
912   @par Complexity 912   @par Complexity
913   Constant. 913   Constant.
914   914  
915   @par Exception Safety 915   @par Exception Safety
916   No-throw guarantee. 916   No-throw guarantee.
917   */ 917   */
918   const_reverse_iterator 918   const_reverse_iterator
HITCBC 919   2 crbegin() const noexcept 919   2 crbegin() const noexcept
920   { 920   {
HITCBC 921   2 return const_reverse_iterator(impl_.end()); 921   2 return const_reverse_iterator(impl_.end());
922   } 922   }
923   923  
924   /** Return a reverse iterator to the character following the last character of the reversed container. 924   /** Return a reverse iterator to the character following the last character of the reversed container.
925   925  
926   The pointed-to element corresponds to the element preceding the first 926   The pointed-to element corresponds to the element preceding the first
927   element of the non-reversed container. The returned iterator only acts 927   element of the non-reversed container. The returned iterator only acts
928   as a sentinel. Dereferencing it results in undefined behavior. 928   as a sentinel. Dereferencing it results in undefined behavior.
929   929  
930   @par Complexity 930   @par Complexity
931   Constant. 931   Constant.
932   932  
933   @par Exception Safety 933   @par Exception Safety
934   No-throw guarantee. 934   No-throw guarantee.
935   935  
936   @{ 936   @{
937   */ 937   */
938   reverse_iterator 938   reverse_iterator
HITCBC 939   3 rend() noexcept 939   3 rend() noexcept
940   { 940   {
HITCBC 941   3 return reverse_iterator(begin()); 941   3 return reverse_iterator(begin());
942   } 942   }
943   943  
944   const_reverse_iterator 944   const_reverse_iterator
HITCBC 945   3 rend() const noexcept 945   3 rend() const noexcept
946   { 946   {
HITCBC 947   3 return const_reverse_iterator(begin()); 947   3 return const_reverse_iterator(begin());
948   } 948   }
949   /// @} 949   /// @}
950   950  
951   /** Return a const reverse iterator to the character following the last character of the reversed container. 951   /** Return a const reverse iterator to the character following the last character of the reversed container.
952   952  
953   The pointed-to character corresponds to the character preceding the 953   The pointed-to character corresponds to the character preceding the
954   first character of the non-reversed container. The returned iterator 954   first character of the non-reversed container. The returned iterator
955   only acts as a sentinel. Dereferencing it results in undefined 955   only acts as a sentinel. Dereferencing it results in undefined
956   behavior. 956   behavior.
957   957  
958   @par Complexity 958   @par Complexity
959   Constant. 959   Constant.
960   960  
961   @par Exception Safety 961   @par Exception Safety
962   No-throw guarantee. 962   No-throw guarantee.
963   */ 963   */
964   const_reverse_iterator 964   const_reverse_iterator
HITCBC 965   2 crend() const noexcept 965   2 crend() const noexcept
966   { 966   {
HITCBC 967   2 return const_reverse_iterator(begin()); 967   2 return const_reverse_iterator(begin());
968   } 968   }
969   969  
970   //------------------------------------------------------ 970   //------------------------------------------------------
971   // 971   //
972   // Capacity 972   // Capacity
973   // 973   //
974   //------------------------------------------------------ 974   //------------------------------------------------------
975   975  
976   /** Check if the string has no characters. 976   /** Check if the string has no characters.
977   977  
978   Returns `true` if there are no characters in the string, i.e. @ref 978   Returns `true` if there are no characters in the string, i.e. @ref
979   size() returns 0. 979   size() returns 0.
980   980  
981   @par Complexity 981   @par Complexity
982   Constant. 982   Constant.
983   983  
984   @par Exception Safety 984   @par Exception Safety
985   No-throw guarantee. 985   No-throw guarantee.
986   */ 986   */
987   bool 987   bool
HITCBC 988   69 empty() const noexcept 988   69 empty() const noexcept
989   { 989   {
HITCBC 990   69 return impl_.size() == 0; 990   69 return impl_.size() == 0;
991   } 991   }
992   992  
993   /** Return the number of characters in the string. 993   /** Return the number of characters in the string.
994   994  
995   The value returned does not include the null terminator, which is 995   The value returned does not include the null terminator, which is
996   always present. 996   always present.
997   997  
998   @par Complexity 998   @par Complexity
999   Constant. 999   Constant.
1000   */ 1000   */
1001   std::size_t 1001   std::size_t
HITCBC 1002   47769 size() const noexcept 1002   47769 size() const noexcept
1003   { 1003   {
HITCBC 1004   47769 return impl_.size(); 1004   47769 return impl_.size();
1005   } 1005   }
1006   1006  
1007   /** Return the maximum number of characters any string can hold. 1007   /** Return the maximum number of characters any string can hold.
1008   1008  
1009   The maximum is an implementation-defined number. This value is 1009   The maximum is an implementation-defined number. This value is
1010   a theoretical limit; at runtime, the actual maximum size may be less 1010   a theoretical limit; at runtime, the actual maximum size may be less
1011   due to resource limits. 1011   due to resource limits.
1012   1012  
1013   @par Complexity 1013   @par Complexity
1014   Constant. 1014   Constant.
1015   */ 1015   */
1016   static 1016   static
1017   constexpr 1017   constexpr
1018   std::size_t 1018   std::size_t
HITCBC 1019   7898 max_size() noexcept 1019   7898 max_size() noexcept
1020   { 1020   {
HITCBC 1021   7898 return string_impl::max_size(); 1021   7898 return string_impl::max_size();
1022   } 1022   }
1023   1023  
1024   /** Return the number of characters that can be held in currently allocated memory. 1024   /** Return the number of characters that can be held in currently allocated memory.
1025   1025  
1026   Returns the number of characters that the container has currently 1026   Returns the number of characters that the container has currently
1027   allocated space for. This number is never smaller than the value 1027   allocated space for. This number is never smaller than the value
1028   returned by @ref size(). 1028   returned by @ref size().
1029   1029  
1030   @par Complexity 1030   @par Complexity
1031   Constant. 1031   Constant.
1032   1032  
1033   @par Exception Safety 1033   @par Exception Safety
1034   No-throw guarantee. 1034   No-throw guarantee.
1035   */ 1035   */
1036   std::size_t 1036   std::size_t
HITCBC 1037   11658 capacity() const noexcept 1037   11658 capacity() const noexcept
1038   { 1038   {
HITCBC 1039   11658 return impl_.capacity(); 1039   11658 return impl_.capacity();
1040   } 1040   }
1041   1041  
1042   /** Increase the capacity to at least a certain amount. 1042   /** Increase the capacity to at least a certain amount.
1043   1043  
1044   This increases the capacity of the array to a value that is greater 1044   This increases the capacity of the array to a value that is greater
1045   than or equal to `new_capacity`. If `new_capacity > `@ref capacity(), 1045   than or equal to `new_capacity`. If `new_capacity > `@ref capacity(),
1046   new memory is allocated. Otherwise, the call has no effect. The number 1046   new memory is allocated. Otherwise, the call has no effect. The number
1047   of elements and therefore the @ref size() of the container is not 1047   of elements and therefore the @ref size() of the container is not
1048   changed. 1048   changed.
1049   1049  
1050   If new memory is allocated, all iterators including any past-the-end 1050   If new memory is allocated, all iterators including any past-the-end
1051   iterators, and all references to the elements are invalidated. 1051   iterators, and all references to the elements are invalidated.
1052   Otherwise, no iterators or references are invalidated. 1052   Otherwise, no iterators or references are invalidated.
1053   1053  
1054   @par Complexity 1054   @par Complexity
1055   At most, linear in @ref size(). 1055   At most, linear in @ref size().
1056   1056  
1057   @par Exception Safety 1057   @par Exception Safety
1058   Strong guarantee. Calls to `memory_resource::allocate` may throw. 1058   Strong guarantee. Calls to `memory_resource::allocate` may throw.
1059   1059  
1060   @param new_capacity The new capacity of the array. 1060   @param new_capacity The new capacity of the array.
1061   1061  
1062   @throw boost::system::system_error `new_capacity > `@ref max_size(). 1062   @throw boost::system::system_error `new_capacity > `@ref max_size().
1063   */ 1063   */
1064   void 1064   void
HITCBC 1065   11348 reserve(std::size_t new_capacity) 1065   11348 reserve(std::size_t new_capacity)
1066   { 1066   {
HITCBC 1067   11348 if(new_capacity <= capacity()) 1067   11348 if(new_capacity <= capacity())
HITCBC 1068   1662 return; 1068   1662 return;
HITCBC 1069   9686 reserve_impl(new_capacity); 1069   9686 reserve_impl(new_capacity);
1070   } 1070   }
1071   1071  
1072   /** Request the removal of unused capacity. 1072   /** Request the removal of unused capacity.
1073   1073  
1074   This performs a non-binding request to reduce @ref capacity() to 1074   This performs a non-binding request to reduce @ref capacity() to
1075   @ref size(). The request may or may not be fulfilled. 1075   @ref size(). The request may or may not be fulfilled.
1076   1076  
1077   @note If reallocation occurs, all iterators including any past-the-end 1077   @note If reallocation occurs, all iterators including any past-the-end
1078   iterators, and all references to characters are invalidated. Otherwise, 1078   iterators, and all references to characters are invalidated. Otherwise,
1079   no iterators or references are invalidated. 1079   no iterators or references are invalidated.
1080   1080  
1081   @par Complexity 1081   @par Complexity
1082   At most, linear in @ref size(). 1082   At most, linear in @ref size().
1083   */ 1083   */
1084   BOOST_JSON_DECL 1084   BOOST_JSON_DECL
1085   void 1085   void
1086   shrink_to_fit(); 1086   shrink_to_fit();
1087   1087  
1088   //------------------------------------------------------ 1088   //------------------------------------------------------
1089   // 1089   //
1090   // Operations 1090   // Operations
1091   // 1091   //
1092   //------------------------------------------------------ 1092   //------------------------------------------------------
1093   1093  
1094   /** Clear the contents. 1094   /** Clear the contents.
1095   1095  
1096   Erases all characters from the string. After this call, @ref size() 1096   Erases all characters from the string. After this call, @ref size()
1097   returns zero but @ref capacity() is unchanged. All references, 1097   returns zero but @ref capacity() is unchanged. All references,
1098   pointers, or iterators referring to contained elements are invalidated. 1098   pointers, or iterators referring to contained elements are invalidated.
1099   Any past-the-end iterators are also invalidated. 1099   Any past-the-end iterators are also invalidated.
1100   1100  
1101   @par Complexity 1101   @par Complexity
1102   Linear in @ref size(). 1102   Linear in @ref size().
1103   1103  
1104   @par Exception Safety 1104   @par Exception Safety
1105   No-throw guarantee. 1105   No-throw guarantee.
1106   */ 1106   */
1107   BOOST_JSON_DECL 1107   BOOST_JSON_DECL
1108   void 1108   void
1109   clear() noexcept; 1109   clear() noexcept;
1110   1110  
1111   /** Insert characters at the specified index. 1111   /** Insert characters at the specified index.
1112   1112  
1113   @li **(1)** inserts `sv`. 1113   @li **(1)** inserts `sv`.
1114   @li **(2)** inserts `count` copies of `ch`. 1114   @li **(2)** inserts `count` copies of `ch`.
1115   @li **(3)** inserts the character `ch`. 1115   @li **(3)** inserts the character `ch`.
1116   @li **(4)** inserts characters from the range `[first, last)`. 1116   @li **(4)** inserts characters from the range `[first, last)`.
1117   1117  
1118   The first character is inserted at the index `pos`. All references, 1118   The first character is inserted at the index `pos`. All references,
1119   pointers, or iterators referring to contained elements are invalidated. 1119   pointers, or iterators referring to contained elements are invalidated.
1120   Any past-the-end iterators are also invalidated. 1120   Any past-the-end iterators are also invalidated.
1121   1121  
1122   @par Constraints 1122   @par Constraints
1123   `InputIt` satisfies {req_InputIterator}. 1123   `InputIt` satisfies {req_InputIterator}.
1124   1124  
1125   @pre 1125   @pre
1126   `[first, last)` is a valid range. 1126   `[first, last)` is a valid range.
1127   1127  
1128   @par Exception Safety 1128   @par Exception Safety
1129   @li **(1)**--*(3)* strong guarantee. 1129   @li **(1)**--*(3)* strong guarantee.
1130   @li **(4)** strong guarantee if `InputIt` satisfies 1130   @li **(4)** strong guarantee if `InputIt` satisfies
1131   {req_ForwardIterator}, basic guarantee otherwise. 1131   {req_ForwardIterator}, basic guarantee otherwise.
1132   1132  
1133   @return `*this` 1133   @return `*this`
1134   1134  
1135   @param pos The index to insert at. 1135   @param pos The index to insert at.
1136   @param sv The `string_view` to insert. 1136   @param sv The `string_view` to insert.
1137   1137  
1138   @throw boost::system::system_error The size of the string would exceed 1138   @throw boost::system::system_error The size of the string would exceed
1139   @ref max_size(). 1139   @ref max_size().
1140   1140  
1141   @throw boost::system::system_error `pos > `@ref size(). 1141   @throw boost::system::system_error `pos > `@ref size().
1142   1142  
1143   @{ 1143   @{
1144   */ 1144   */
1145   BOOST_JSON_DECL 1145   BOOST_JSON_DECL
1146   string& 1146   string&
1147   insert( 1147   insert(
1148   std::size_t pos, 1148   std::size_t pos,
1149   string_view sv); 1149   string_view sv);
1150   1150  
1151   /** Overload 1151   /** Overload
1152   @param count The number of characters to insert. 1152   @param count The number of characters to insert.
1153   @param ch The character to insert. 1153   @param ch The character to insert.
1154   @param pos 1154   @param pos
1155   */ 1155   */
1156   BOOST_JSON_DECL 1156   BOOST_JSON_DECL
1157   string& 1157   string&
1158   insert( 1158   insert(
1159   std::size_t pos, 1159   std::size_t pos,
1160   std::size_t count, 1160   std::size_t count,
1161   char ch); 1161   char ch);
1162   1162  
1163   /** Overload 1163   /** Overload
1164   @param pos 1164   @param pos
1165   @param ch 1165   @param ch
1166   */ 1166   */
1167   string& 1167   string&
HITCBC 1168   3 insert( 1168   3 insert(
1169   size_type pos, 1169   size_type pos,
1170   char ch) 1170   char ch)
1171   { 1171   {
HITCBC 1172   3 return insert(pos, 1, ch); 1172   3 return insert(pos, 1, ch);
1173   } 1173   }
1174   1174  
1175   /** Overload 1175   /** Overload
1176   1176  
1177   @tparam InputIt The type of the iterators. 1177   @tparam InputIt The type of the iterators.
1178   1178  
1179   @param first The beginning of the character range. 1179   @param first The beginning of the character range.
1180   @param last The end of the character range. 1180   @param last The end of the character range.
1181   @param pos 1181   @param pos
1182   */ 1182   */
1183   template<class InputIt 1183   template<class InputIt
1184   #ifndef BOOST_JSON_DOCS 1184   #ifndef BOOST_JSON_DOCS
1185   ,class = is_inputit<InputIt> 1185   ,class = is_inputit<InputIt>
1186   #endif 1186   #endif
1187   > 1187   >
1188   string& 1188   string&
1189   insert( 1189   insert(
1190   size_type pos, 1190   size_type pos,
1191   InputIt first, 1191   InputIt first,
1192   InputIt last); 1192   InputIt last);
1193   /// @} 1193   /// @}
1194   1194  
1195   /** Remove characters from the string. 1195   /** Remove characters from the string.
1196   1196  
1197   @li **(1)** removes at most `count` but not more than `size() - pos` 1197   @li **(1)** removes at most `count` but not more than `size() - pos`
1198   characters starting at `index`. 1198   characters starting at `index`.
1199   @li **(2)** removes the character at `pos`. 1199   @li **(2)** removes the character at `pos`.
1200   @li **(3)** removes characters in the range `[first, last)`. 1200   @li **(3)** removes characters in the range `[first, last)`.
1201   1201  
1202   All references, pointers, or iterators referring to contained elements 1202   All references, pointers, or iterators referring to contained elements
1203   are invalidated. Any past-the-end iterators are also invalidated. 1203   are invalidated. Any past-the-end iterators are also invalidated.
1204   1204  
1205   @pre 1205   @pre
1206   `pos`, `first`, and `last` are iterators into this string. `first` and 1206   `pos`, `first`, and `last` are iterators into this string. `first` and
1207   `last` form a valid range. 1207   `last` form a valid range.
1208   1208  
1209   @par Complexity 1209   @par Complexity
1210   @li **(1)** linear in `count`. 1210   @li **(1)** linear in `count`.
1211   @li **(2)** constant. 1211   @li **(2)** constant.
1212   @li **(3)** linear in `std::distance(first, last)`. 1212   @li **(3)** linear in `std::distance(first, last)`.
1213   1213  
1214   @par Exception Safety 1214   @par Exception Safety
1215   Strong guarantee. 1215   Strong guarantee.
1216   1216  
1217   @return 1217   @return
1218   @li **(1)** `*this`. 1218   @li **(1)** `*this`.
1219   1219  
1220   @li **(2)** An iterator referring to the character immediately 1220   @li **(2)** An iterator referring to the character immediately
1221   following the removed character, or @ref end() if one does not exist. 1221   following the removed character, or @ref end() if one does not exist.
1222   1222  
1223   @li **(3)** An iterator referring to the character `last` previously 1223   @li **(3)** An iterator referring to the character `last` previously
1224   referred to, or @ref end() if one does not exist. 1224   referred to, or @ref end() if one does not exist.
1225   1225  
1226   @param index The index of the first character to remove. 1226   @param index The index of the first character to remove.
1227   1227  
1228   @param count The number of characters to remove. By default remove 1228   @param count The number of characters to remove. By default remove
1229   until the end of the string. 1229   until the end of the string.
1230   1230  
1231   @throw boost::system::system_error `pos >` @ref size(). 1231   @throw boost::system::system_error `pos >` @ref size().
1232   1232  
1233   @{ 1233   @{
1234   */ 1234   */
1235   BOOST_JSON_DECL 1235   BOOST_JSON_DECL
1236   string& 1236   string&
1237   erase( 1237   erase(
1238   std::size_t index = 0, 1238   std::size_t index = 0,
1239   std::size_t count = npos); 1239   std::size_t count = npos);
1240   1240  
1241   /** Overload 1241   /** Overload
1242   @param pos An iterator referring to the character to erase. 1242   @param pos An iterator referring to the character to erase.
1243   */ 1243   */
1244   BOOST_JSON_DECL 1244   BOOST_JSON_DECL
1245   iterator 1245   iterator
1246   erase(const_iterator pos); 1246   erase(const_iterator pos);
1247   1247  
1248   /** Overload 1248   /** Overload
1249   @param first An iterator representing the first character to erase. 1249   @param first An iterator representing the first character to erase.
1250   @param last An iterator one past the last character to erase. 1250   @param last An iterator one past the last character to erase.
1251   */ 1251   */
1252   BOOST_JSON_DECL 1252   BOOST_JSON_DECL
1253   iterator 1253   iterator
1254   erase( 1254   erase(
1255   const_iterator first, 1255   const_iterator first,
1256   const_iterator last); 1256   const_iterator last);
1257   /// @} 1257   /// @}
1258   1258  
1259   //------------------------------------------------------ 1259   //------------------------------------------------------
1260   1260  
1261   /** Append a character. 1261   /** Append a character.
1262   1262  
1263   Appends a character to the end of the string. 1263   Appends a character to the end of the string.
1264   1264  
1265   @par Exception Safety 1265   @par Exception Safety
1266   Strong guarantee. 1266   Strong guarantee.
1267   1267  
1268   @param ch The character to append. 1268   @param ch The character to append.
1269   1269  
1270   @throw boost::system::system_error @ref size() `+ 1 > `@ref max_size(). 1270   @throw boost::system::system_error @ref size() `+ 1 > `@ref max_size().
1271   */ 1271   */
1272   BOOST_JSON_DECL 1272   BOOST_JSON_DECL
1273   void 1273   void
1274   push_back(char ch); 1274   push_back(char ch);
1275   1275  
1276   /** Remove the last character. 1276   /** Remove the last character.
1277   1277  
1278   Removes a character from the end of the string. 1278   Removes a character from the end of the string.
1279   1279  
1280   @pre 1280   @pre
1281   @code 1281   @code
1282   ! empty() 1282   ! empty()
1283   @endcode 1283   @endcode
1284   */ 1284   */
1285   BOOST_JSON_DECL 1285   BOOST_JSON_DECL
1286   void 1286   void
1287   pop_back(); 1287   pop_back();
1288   1288  
1289   //------------------------------------------------------ 1289   //------------------------------------------------------
1290   1290  
1291   /** Append characters to the string. 1291   /** Append characters to the string.
1292   1292  
1293   @li **(1)** appends `count` copies of `ch`. 1293   @li **(1)** appends `count` copies of `ch`.
1294   1294  
1295   @li **(2)** appends copies of characters of `sv`, preserving order. 1295   @li **(2)** appends copies of characters of `sv`, preserving order.
1296   1296  
1297   @li **(3)** appends characters from the range `[first, last)`, 1297   @li **(3)** appends characters from the range `[first, last)`,
1298   preserving order. 1298   preserving order.
1299   1299  
1300   @pre 1300   @pre
1301   `[first, last)` shall be a valid range. 1301   `[first, last)` shall be a valid range.
1302   1302  
1303   @par Constraints 1303   @par Constraints
1304   `InputIt` satisfies {req_InputIterator}. 1304   `InputIt` satisfies {req_InputIterator}.
1305   1305  
1306   @par Exception Safety 1306   @par Exception Safety
1307   Strong guarantee. 1307   Strong guarantee.
1308   1308  
1309   @return `*this`. 1309   @return `*this`.
1310   1310  
1311   @param count The number of characters to append. 1311   @param count The number of characters to append.
1312   @param ch The character to append. 1312   @param ch The character to append.
1313   1313  
1314   @throw boost::system::system_error The size of the string after the 1314   @throw boost::system::system_error The size of the string after the
1315   operation would exceed @ref max_size(). 1315   operation would exceed @ref max_size().
1316   1316  
1317   @{ 1317   @{
1318   */ 1318   */
1319   BOOST_JSON_DECL 1319   BOOST_JSON_DECL
1320   string& 1320   string&
1321   append( 1321   append(
1322   std::size_t count, 1322   std::size_t count,
1323   char ch); 1323   char ch);
1324   1324  
1325   /** Overload 1325   /** Overload
1326   @param sv The `string_view` to append. 1326   @param sv The `string_view` to append.
1327   */ 1327   */
1328   BOOST_JSON_DECL 1328   BOOST_JSON_DECL
1329   string& 1329   string&
1330   append(string_view sv); 1330   append(string_view sv);
1331   1331  
1332   /** Overload 1332   /** Overload
1333   1333  
1334   @tparam InputIt The type of the iterators. 1334   @tparam InputIt The type of the iterators.
1335   1335  
1336   @param first An iterator representing the first character to append. 1336   @param first An iterator representing the first character to append.
1337   @param last An iterator one past the last character to append. 1337   @param last An iterator one past the last character to append.
1338   */ 1338   */
1339   template<class InputIt 1339   template<class InputIt
1340   #ifndef BOOST_JSON_DOCS 1340   #ifndef BOOST_JSON_DOCS
1341   ,class = is_inputit<InputIt> 1341   ,class = is_inputit<InputIt>
1342   #endif 1342   #endif
1343   > 1343   >
1344   string& 1344   string&
1345   append(InputIt first, InputIt last); 1345   append(InputIt first, InputIt last);
1346   /// @} 1346   /// @}
1347   1347  
1348   /** Append characters to the string. 1348   /** Append characters to the string.
1349   1349  
1350   @li **(1)** appends `[sv.begin(), sv.end())`. 1350   @li **(1)** appends `[sv.begin(), sv.end())`.
1351   @li **(2)** appends `ch`. 1351   @li **(2)** appends `ch`.
1352   1352  
1353   @par Exception Safety 1353   @par Exception Safety
1354   Strong guarantee. 1354   Strong guarantee.
1355   1355  
1356   @return `*this` 1356   @return `*this`
1357   1357  
1358   @param sv The `string_view` to append. 1358   @param sv The `string_view` to append.
1359   1359  
1360   @throw boost::system::system_error The size of the string after the 1360   @throw boost::system::system_error The size of the string after the
1361   operation would exceed @ref max_size(). 1361   operation would exceed @ref max_size().
1362   1362  
1363   @{ 1363   @{
1364   */ 1364   */
1365   string& 1365   string&
HITCBC 1366   11 operator+=(string_view sv) 1366   11 operator+=(string_view sv)
1367   { 1367   {
HITCBC 1368   11 return append(sv); 1368   11 return append(sv);
1369   } 1369   }
1370   1370  
1371   /** Overload 1371   /** Overload
1372   @param ch The character to append. 1372   @param ch The character to append.
1373   */ 1373   */
1374   string& 1374   string&
HITCBC 1375   44 operator+=(char ch) 1375   44 operator+=(char ch)
1376   { 1376   {
HITCBC 1377   44 push_back(ch); 1377   44 push_back(ch);
HITCBC 1378   43 return *this; 1378   43 return *this;
1379   } 1379   }
1380   /// @} 1380   /// @}
1381   1381  
1382   //------------------------------------------------------ 1382   //------------------------------------------------------
1383   1383  
1384   /** Compare a string with the string. 1384   /** Compare a string with the string.
1385   1385  
1386   Let `comp` be `std::char_traits<char>::compare(data(), sv.data(), 1386   Let `comp` be `std::char_traits<char>::compare(data(), sv.data(),
1387   std::min(size(), sv.size())`. If `comp != 0`, then the result is 1387   std::min(size(), sv.size())`. If `comp != 0`, then the result is
1388   `comp`. Otherwise, the result is `0` if `size() == sv.size()`, `-1` if 1388   `comp`. Otherwise, the result is `0` if `size() == sv.size()`, `-1` if
1389   `size() < sv.size()`, and `1` otherwise. 1389   `size() < sv.size()`, and `1` otherwise.
1390   1390  
1391   @par Complexity 1391   @par Complexity
1392   Linear. 1392   Linear.
1393   1393  
1394   @return The result of lexicographically comparing the characters of 1394   @return The result of lexicographically comparing the characters of
1395   `sv` and the string. 1395   `sv` and the string.
1396   1396  
1397   @param sv The `string_view` to compare. 1397   @param sv The `string_view` to compare.
1398   */ 1398   */
1399   int 1399   int
HITCBC 1400   13 compare(string_view sv) const noexcept 1400   13 compare(string_view sv) const noexcept
1401   { 1401   {
HITCBC 1402   13 return subview().compare(sv); 1402   13 return subview().compare(sv);
1403   } 1403   }
1404   1404  
1405   //------------------------------------------------------ 1405   //------------------------------------------------------
1406   1406  
1407   /** Return whether the string begins with another string. 1407   /** Return whether the string begins with another string.
1408   1408  
1409   @li **(1)** checks if the string begins with `s`. 1409   @li **(1)** checks if the string begins with `s`.
1410   @li **(2)** checks if the string begins with `ch`. 1410   @li **(2)** checks if the string begins with `ch`.
1411   1411  
1412   @par Complexity 1412   @par Complexity
1413   @li **(1)** linear in `s.size()`. 1413   @li **(1)** linear in `s.size()`.
1414   @li **(2)** constant. 1414   @li **(2)** constant.
1415   1415  
1416   @param s The string to check for. 1416   @param s The string to check for.
1417   1417  
1418   @{ 1418   @{
1419   */ 1419   */
1420   bool 1420   bool
HITCBC 1421   8 starts_with(string_view s) const noexcept 1421   8 starts_with(string_view s) const noexcept
1422   { 1422   {
HITCBC 1423   8 return subview(0, s.size()) == s; 1423   8 return subview(0, s.size()) == s;
1424   } 1424   }
1425   1425  
1426   /** Overload 1426   /** Overload
1427   1427  
1428   @param ch The character to check for. 1428   @param ch The character to check for.
1429   */ 1429   */
1430   bool 1430   bool
HITCBC 1431   4 starts_with(char ch) const noexcept 1431   4 starts_with(char ch) const noexcept
1432   { 1432   {
HITCBC 1433   4 return ! empty() && front() == ch; 1433   4 return ! empty() && front() == ch;
1434   } 1434   }
1435   /// @} 1435   /// @}
1436   1436  
1437   /** Check if the string ends with given suffix. 1437   /** Check if the string ends with given suffix.
1438   1438  
1439   @li **(1)** returns `true` if the string ends with `s`. 1439   @li **(1)** returns `true` if the string ends with `s`.
1440   @li **(2)** returns `true` if the string ends with the character `ch`. 1440   @li **(2)** returns `true` if the string ends with the character `ch`.
1441   1441  
1442   @par Complexity 1442   @par Complexity
1443   @li **(1)** linear in `s`. 1443   @li **(1)** linear in `s`.
1444   @li **(2)** constant. 1444   @li **(2)** constant.
1445   1445  
1446   @par Exception Safety 1446   @par Exception Safety
1447   No-throw guarantee. 1447   No-throw guarantee.
1448   1448  
1449   @param s The string to check for. 1449   @param s The string to check for.
1450   1450  
1451   @{ 1451   @{
1452   */ 1452   */
1453   bool 1453   bool
HITCBC 1454   8 ends_with(string_view s) const noexcept 1454   8 ends_with(string_view s) const noexcept
1455   { 1455   {
HITCBC 1456   16 return size() >= s.size() && 1456   16 return size() >= s.size() &&
HITCBC 1457   16 subview(size() - s.size()) == s; 1457   16 subview(size() - s.size()) == s;
1458   } 1458   }
1459   1459  
1460   /** Overload 1460   /** Overload
1461   @param ch The character to check for. 1461   @param ch The character to check for.
1462   */ 1462   */
1463   bool 1463   bool
HITCBC 1464   4 ends_with(char ch) const noexcept 1464   4 ends_with(char ch) const noexcept
1465   { 1465   {
HITCBC 1466   4 return ! empty() && back() == ch; 1466   4 return ! empty() && back() == ch;
1467   } 1467   }
1468   /// @} 1468   /// @}
1469   1469  
1470   /** Replace a substring with another string. 1470   /** Replace a substring with another string.
1471   1471  
1472   @li **(1)** replaces `std::min(count, size() - pos)` characters 1472   @li **(1)** replaces `std::min(count, size() - pos)` characters
1473   starting at index `pos` with those of `sv`. 1473   starting at index `pos` with those of `sv`.
1474   @li **(2)** replaces the characters in the range `[first, last)` with 1474   @li **(2)** replaces the characters in the range `[first, last)` with
1475   those of `sv`. 1475   those of `sv`.
1476   @li **(3)** replaces the characters in the range `[first, last)` with 1476   @li **(3)** replaces the characters in the range `[first, last)` with
1477   those of `[first2, last2)`. 1477   those of `[first2, last2)`.
1478   @li **(4)** replaces `std::min(count, size() - pos)` characters 1478   @li **(4)** replaces `std::min(count, size() - pos)` characters
1479   starting at index `pos` with `count2` copies of `ch`. 1479   starting at index `pos` with `count2` copies of `ch`.
1480   @li **(5)** replaces the characters in the range `[first, last)` with 1480   @li **(5)** replaces the characters in the range `[first, last)` with
1481   `count2` copies of `ch`. 1481   `count2` copies of `ch`.
1482   1482  
1483   All references, pointers, or iterators referring to contained elements 1483   All references, pointers, or iterators referring to contained elements
1484   are invalidated. Any past-the-end iterators are also invalidated. 1484   are invalidated. Any past-the-end iterators are also invalidated.
1485   1485  
1486   @pre 1486   @pre
1487   `[first, last)` is a valid range. `[first2, last2)` is a valid range. 1487   `[first, last)` is a valid range. `[first2, last2)` is a valid range.
1488   1488  
1489   @par Constraints 1489   @par Constraints
1490   `InputIt` satisfies {req_InputIterator}. 1490   `InputIt` satisfies {req_InputIterator}.
1491   1491  
1492   @par Exception Safety 1492   @par Exception Safety
1493   Strong guarantee. 1493   Strong guarantee.
1494   1494  
1495   @return `*this` 1495   @return `*this`
1496   1496  
1497   @param pos The index to replace at. 1497   @param pos The index to replace at.
1498   1498  
1499   @param count The number of characters to replace. 1499   @param count The number of characters to replace.
1500   1500  
1501   @param sv The `string_view` to replace with. 1501   @param sv The `string_view` to replace with.
1502   1502  
1503   @throw boost::system::system_error The resulting string's size would 1503   @throw boost::system::system_error The resulting string's size would
1504   have exceeded @ref max_size(). 1504   have exceeded @ref max_size().
1505   1505  
1506   @{ 1506   @{
1507   */ 1507   */
1508   BOOST_JSON_DECL 1508   BOOST_JSON_DECL
1509   string& 1509   string&
1510   replace( 1510   replace(
1511   std::size_t pos, 1511   std::size_t pos,
1512   std::size_t count, 1512   std::size_t count,
1513   string_view sv); 1513   string_view sv);
1514   1514  
1515   /** Overload 1515   /** Overload
1516   1516  
1517   @param first An iterator referring to the first character to replace. 1517   @param first An iterator referring to the first character to replace.
1518   @param last An iterator one past the end of the last character to 1518   @param last An iterator one past the end of the last character to
1519   replace. 1519   replace.
1520   @param sv 1520   @param sv
1521   */ 1521   */
1522   string& 1522   string&
HITCBC 1523   6 replace( 1523   6 replace(
1524   const_iterator first, 1524   const_iterator first,
1525   const_iterator last, 1525   const_iterator last,
1526   string_view sv) 1526   string_view sv)
1527   { 1527   {
HITCBC 1528   6 return replace(first - begin(), last - first, sv); 1528   6 return replace(first - begin(), last - first, sv);
1529   } 1529   }
1530   1530  
1531   /** Overload 1531   /** Overload
1532   1532  
1533   @tparam InputIt The type of the iterators. 1533   @tparam InputIt The type of the iterators.
1534   1534  
1535   @param first2 An iterator referring to the first character to replace 1535   @param first2 An iterator referring to the first character to replace
1536   with. 1536   with.
1537   @param last2 An iterator one past the end of the last character to 1537   @param last2 An iterator one past the end of the last character to
1538   replace with. 1538   replace with.
1539   @param first 1539   @param first
1540   @param last 1540   @param last
1541   */ 1541   */
1542   template<class InputIt 1542   template<class InputIt
1543   #ifndef BOOST_JSON_DOCS 1543   #ifndef BOOST_JSON_DOCS
1544   ,class = is_inputit<InputIt> 1544   ,class = is_inputit<InputIt>
1545   #endif 1545   #endif
1546   > 1546   >
1547   string& 1547   string&
1548   replace( 1548   replace(
1549   const_iterator first, 1549   const_iterator first,
1550   const_iterator last, 1550   const_iterator last,
1551   InputIt first2, 1551   InputIt first2,
1552   InputIt last2); 1552   InputIt last2);
1553   1553  
1554   /** Overload 1554   /** Overload
1555   1555  
1556   @param count2 The number of characters to replace with. 1556   @param count2 The number of characters to replace with.
1557   @param ch The character to replace with. 1557   @param ch The character to replace with.
1558   @param pos 1558   @param pos
1559   @param count 1559   @param count
1560   */ 1560   */
1561   BOOST_JSON_DECL 1561   BOOST_JSON_DECL
1562   string& 1562   string&
1563   replace( 1563   replace(
1564   std::size_t pos, 1564   std::size_t pos,
1565   std::size_t count, 1565   std::size_t count,
1566   std::size_t count2, 1566   std::size_t count2,
1567   char ch); 1567   char ch);
1568   1568  
1569   /** Overload 1569   /** Overload
1570   1570  
1571   @param first 1571   @param first
1572   @param last 1572   @param last
1573   @param count2 1573   @param count2
1574   @param ch 1574   @param ch
1575   */ 1575   */
1576   string& 1576   string&
HITCBC 1577   1 replace( 1577   1 replace(
1578   const_iterator first, 1578   const_iterator first,
1579   const_iterator last, 1579   const_iterator last,
1580   std::size_t count2, 1580   std::size_t count2,
1581   char ch) 1581   char ch)
1582   { 1582   {
HITCBC 1583   1 return replace(first - begin(), last - first, count2, ch); 1583   1 return replace(first - begin(), last - first, count2, ch);
1584   } 1584   }
1585   /// @} 1585   /// @}
1586   1586  
1587   //------------------------------------------------------ 1587   //------------------------------------------------------
1588   1588  
1589   /** Return a view. 1589   /** Return a view.
1590   1590  
1591   @li **(1)** equivalent to `subview().substr(pos, count)`. 1591   @li **(1)** equivalent to `subview().substr(pos, count)`.
1592   @li **(2)** equivalent to `string_view(data(), size())`. 1592   @li **(2)** equivalent to `string_view(data(), size())`.
1593   1593  
1594   @par Exception Safety 1594   @par Exception Safety
1595   Strong guarantee. 1595   Strong guarantee.
1596   1596  
1597   @param pos The index of the first character of the substring. 1597   @param pos The index of the first character of the substring.
1598   @param count The length of the substring. 1598   @param count The length of the substring.
1599   1599  
1600   @throw boost::system::system_error `pos > ` @ref size(). 1600   @throw boost::system::system_error `pos > ` @ref size().
1601   */ 1601   */
1602   string_view 1602   string_view
HITCBC 1603   41 subview( 1603   41 subview(
1604   std::size_t pos, 1604   std::size_t pos,
1605   std::size_t count = npos) const 1605   std::size_t count = npos) const
1606   { 1606   {
HITCBC 1607   41 return subview().substr(pos, count); 1607   41 return subview().substr(pos, count);
1608   } 1608   }
1609   1609  
1610   /// Overload 1610   /// Overload
1611   string_view 1611   string_view
HITCBC 1612   28959 subview() const noexcept 1612   28959 subview() const noexcept
1613   { 1613   {
HITCBC 1614   28959 return string_view( data(), size() ); 1614   28959 return string_view( data(), size() );
1615   } 1615   }
1616   1616  
1617   //------------------------------------------------------ 1617   //------------------------------------------------------
1618   1618  
1619   /** Copy a substring to another string. 1619   /** Copy a substring to another string.
1620   1620  
1621   Copies `std::min(count, size() - pos)` characters starting at index 1621   Copies `std::min(count, size() - pos)` characters starting at index
1622   `pos` to the string pointed to by `dest`. 1622   `pos` to the string pointed to by `dest`.
1623   1623  
1624   @attention This function doesn't put the null terminator after the 1624   @attention This function doesn't put the null terminator after the
1625   copied characters. 1625   copied characters.
1626   1626  
1627   @return The number of characters copied. 1627   @return The number of characters copied.
1628   1628  
1629   @param count The number of characters to copy. 1629   @param count The number of characters to copy.
1630   1630  
1631   @param dest The string to copy to. 1631   @param dest The string to copy to.
1632   1632  
1633   @param pos The index to begin copying from. 1633   @param pos The index to begin copying from.
1634   1634  
1635   @throw boost::system::system_error `pos >` @ref max_size(). 1635   @throw boost::system::system_error `pos >` @ref max_size().
1636   */ 1636   */
1637   std::size_t 1637   std::size_t
HITCBC 1638   2 copy( 1638   2 copy(
1639   char* dest, 1639   char* dest,
1640   std::size_t count, 1640   std::size_t count,
1641   std::size_t pos = 0) const 1641   std::size_t pos = 0) const
1642   { 1642   {
HITCBC 1643   2 return subview().copy(dest, count, pos); 1643   2 return subview().copy(dest, count, pos);
1644   } 1644   }
1645   1645  
1646   //------------------------------------------------------ 1646   //------------------------------------------------------
1647   1647  
1648   /** Change the size of the string. 1648   /** Change the size of the string.
1649   1649  
1650   Resizes the string to contain `count` characters. If 1650   Resizes the string to contain `count` characters. If
1651   `count > `@ref size(), **(2)** appends copies of `ch` and **(1)** 1651   `count > `@ref size(), **(2)** appends copies of `ch` and **(1)**
1652   appends ``'\0'``. Otherwise, `size()` is reduced to `count`. 1652   appends ``'\0'``. Otherwise, `size()` is reduced to `count`.
1653   1653  
1654   @param count The size to resize the string to. 1654   @param count The size to resize the string to.
1655   1655  
1656   @throw boost::system::system_error `count > `@ref max_size(). 1656   @throw boost::system::system_error `count > `@ref max_size().
1657   1657  
1658   @{ 1658   @{
1659   */ 1659   */
1660   void 1660   void
HITCBC 1661   57 resize(std::size_t count) 1661   57 resize(std::size_t count)
1662   { 1662   {
HITCBC 1663   57 resize(count, 0); 1663   57 resize(count, 0);
HITCBC 1664   54 } 1664   54 }
1665   1665  
1666   /** Overload 1666   /** Overload
1667   1667  
1668   @param count 1668   @param count
1669   @param ch The characters to append if the size increases. 1669   @param ch The characters to append if the size increases.
1670   */ 1670   */
1671   BOOST_JSON_DECL 1671   BOOST_JSON_DECL
1672   void 1672   void
1673   resize(std::size_t count, char ch); 1673   resize(std::size_t count, char ch);
1674   /// @} 1674   /// @}
1675   1675  
1676   /** Increase size without changing capacity. 1676   /** Increase size without changing capacity.
1677   1677  
1678   This increases the size of the string by `n` characters, adjusting the 1678   This increases the size of the string by `n` characters, adjusting the
1679   position of the terminating null character for the new size. The new 1679   position of the terminating null character for the new size. The new
1680   characters remain uninitialized. This function may be used to append 1680   characters remain uninitialized. This function may be used to append
1681   characters directly into the storage between @ref end() and @ref data() 1681   characters directly into the storage between @ref end() and @ref data()
1682   ` + ` @ref capacity(). 1682   ` + ` @ref capacity().
1683   1683  
1684   @pre 1684   @pre
1685   @code 1685   @code
1686   count <= capacity() - size() 1686   count <= capacity() - size()
1687   @endcode 1687   @endcode
1688   1688  
1689   @param n The amount to increase the size by. 1689   @param n The amount to increase the size by.
1690   */ 1690   */
1691   void 1691   void
HITCBC 1692   15054 grow(std::size_t n) noexcept 1692   15054 grow(std::size_t n) noexcept
1693   { 1693   {
HITCBC 1694   15054 BOOST_ASSERT( 1694   15054 BOOST_ASSERT(
1695   n <= impl_.capacity() - impl_.size()); 1695   n <= impl_.capacity() - impl_.size());
HITCBC 1696   15054 impl_.term(impl_.size() + n); 1696   15054 impl_.term(impl_.size() + n);
HITCBC 1697   15054 } 1697   15054 }
1698   1698  
1699   /** Swap the contents. 1699   /** Swap the contents.
1700   1700  
1701   Exchanges the contents of this string with another string. Ownership of 1701   Exchanges the contents of this string with another string. Ownership of
1702   the respective @ref boost::container::pmr::memory_resource objects is 1702   the respective @ref boost::container::pmr::memory_resource objects is
1703   not transferred. 1703   not transferred.
1704   1704  
1705   @li If `&other == this`, do nothing. Otherwise, 1705   @li If `&other == this`, do nothing. Otherwise,
1706   @li if `*other.storage() == *this->storage()`, ownership of the 1706   @li if `*other.storage() == *this->storage()`, ownership of the
1707   underlying memory is swapped in constant time, with no possibility 1707   underlying memory is swapped in constant time, with no possibility
1708   of exceptions. All iterators and references remain valid. 1708   of exceptions. All iterators and references remain valid.
1709   Otherwise, 1709   Otherwise,
1710   @li the contents are logically swapped by making copies, which can 1710   @li the contents are logically swapped by making copies, which can
1711   throw. In this case all iterators and references are invalidated. 1711   throw. In this case all iterators and references are invalidated.
1712   1712  
1713   @par Complexity 1713   @par Complexity
1714   Constant or linear in @ref size() `+ other.size()`. 1714   Constant or linear in @ref size() `+ other.size()`.
1715   1715  
1716   @par Exception Safety 1716   @par Exception Safety
1717   Strong guarantee. Calls to `memory_resource::allocate` may throw. 1717   Strong guarantee. Calls to `memory_resource::allocate` may throw.
1718   */ 1718   */
1719   BOOST_JSON_DECL 1719   BOOST_JSON_DECL
1720   void 1720   void
1721   swap(string& other); 1721   swap(string& other);
1722   1722  
1723   /** Exchange the given values. 1723   /** Exchange the given values.
1724   1724  
1725   Exchanges the contents of the string `lhs` with another string `rhs`. 1725   Exchanges the contents of the string `lhs` with another string `rhs`.
1726   Ownership of the respective @ref boost::container::pmr::memory_resource 1726   Ownership of the respective @ref boost::container::pmr::memory_resource
1727   objects is not transferred. 1727   objects is not transferred.
1728   1728  
1729   @li If `&lhs == &rhs`, do nothing. Otherwise, 1729   @li If `&lhs == &rhs`, do nothing. Otherwise,
1730   @li if `*lhs.storage() == *rhs.storage()`, ownership of the underlying 1730   @li if `*lhs.storage() == *rhs.storage()`, ownership of the underlying
1731   memory is swapped in constant time, with no possibility of 1731   memory is swapped in constant time, with no possibility of
1732   exceptions. All iterators and references remain valid. Otherwise, 1732   exceptions. All iterators and references remain valid. Otherwise,
1733   @li the contents are logically swapped by making a copy, which can 1733   @li the contents are logically swapped by making a copy, which can
1734   throw. In this case all iterators and references are invalidated. 1734   throw. In this case all iterators and references are invalidated.
1735   1735  
1736   @par Effects 1736   @par Effects
1737   @code 1737   @code
1738   lhs.swap( rhs ); 1738   lhs.swap( rhs );
1739   @endcode 1739   @endcode
1740   1740  
1741   @par Complexity 1741   @par Complexity
1742   Constant or linear in `lhs.size() + rhs.size()`. 1742   Constant or linear in `lhs.size() + rhs.size()`.
1743   1743  
1744   @par Exception Safety 1744   @par Exception Safety
1745   Strong guarantee. 1745   Strong guarantee.
1746   Calls to `memory_resource::allocate` may throw. 1746   Calls to `memory_resource::allocate` may throw.
1747   1747  
1748   @param lhs The string to exchange. 1748   @param lhs The string to exchange.
1749   @param rhs The string to exchange. 1749   @param rhs The string to exchange.
1750   1750  
1751   @see @ref string::swap 1751   @see @ref string::swap
1752   */ 1752   */
1753   friend 1753   friend
1754   void 1754   void
HITCBC 1755   2 swap(string& lhs, string& rhs) 1755   2 swap(string& lhs, string& rhs)
1756   { 1756   {
HITCBC 1757   2 lhs.swap(rhs); 1757   2 lhs.swap(rhs);
HITCBC 1758   2 } 1758   2 }
1759   //------------------------------------------------------ 1759   //------------------------------------------------------
1760   // 1760   //
1761   // Search 1761   // Search
1762   // 1762   //
1763   //------------------------------------------------------ 1763   //------------------------------------------------------
1764   1764  
1765   /** Find the first occurrence of characters within the string. 1765   /** Find the first occurrence of characters within the string.
1766   1766  
1767   Search from `pos` onward for the first substring that is equal to the 1767   Search from `pos` onward for the first substring that is equal to the
1768   first argument. 1768   first argument.
1769   1769  
1770   @li **(1)** searches for the presense of the substring equal to `sv`. 1770   @li **(1)** searches for the presense of the substring equal to `sv`.
1771   @li **(2)** searches for the presense of the substring consisting of 1771   @li **(2)** searches for the presense of the substring consisting of
1772   the character `ch`. 1772   the character `ch`.
1773   1773  
1774   @par Complexity 1774   @par Complexity
1775   Linear in @ref size(). 1775   Linear in @ref size().
1776   1776  
1777   @par Exception Safety 1777   @par Exception Safety
1778   No-throw guarantee. 1778   No-throw guarantee.
1779   1779  
1780   @return The index of the first character of the found substring, or 1780   @return The index of the first character of the found substring, or
1781   @ref npos if none was found. 1781   @ref npos if none was found.
1782   1782  
1783   @param sv The `string_view` to search for. 1783   @param sv The `string_view` to search for.
1784   @param pos The index to start searching at. 1784   @param pos The index to start searching at.
1785   1785  
1786   @{ 1786   @{
1787   */ 1787   */
1788   std::size_t 1788   std::size_t
HITCBC 1789   5 find( 1789   5 find(
1790   string_view sv, 1790   string_view sv,
1791   std::size_t pos = 0) const noexcept 1791   std::size_t pos = 0) const noexcept
1792   { 1792   {
HITCBC 1793   5 return subview().find(sv, pos); 1793   5 return subview().find(sv, pos);
1794   } 1794   }
1795   1795  
1796   /** Overload 1796   /** Overload
1797   1797  
1798   @param ch The character to search for. 1798   @param ch The character to search for.
1799   @param pos 1799   @param pos
1800   */ 1800   */
1801   std::size_t 1801   std::size_t
HITCBC 1802   3 find( 1802   3 find(
1803   char ch, 1803   char ch,
1804   std::size_t pos = 0) const noexcept 1804   std::size_t pos = 0) const noexcept
1805   { 1805   {
HITCBC 1806   3 return subview().find(ch, pos); 1806   3 return subview().find(ch, pos);
1807   } 1807   }
1808   /// @} 1808   /// @}
1809   1809  
1810   /** Find the last occurrence of a string within the string. 1810   /** Find the last occurrence of a string within the string.
1811   1811  
1812   @li **(1)** searches for the last substring equal to `sv`. 1812   @li **(1)** searches for the last substring equal to `sv`.
1813   @li **(2)** searches for the last occurrence of `ch`. 1813   @li **(2)** searches for the last occurrence of `ch`.
1814   1814  
1815   Both functions search for substrings fully contained within `[begin(), 1815   Both functions search for substrings fully contained within `[begin(),
1816   begin() + pos)`. 1816   begin() + pos)`.
1817   1817  
1818   @par Complexity 1818   @par Complexity
1819   Linear. 1819   Linear.
1820   1820  
1821   @return Index of the first character of the found substring or 1821   @return Index of the first character of the found substring or
1822   @ref npos if none was found. 1822   @ref npos if none was found.
1823   1823  
1824   @param sv The string to search for. 1824   @param sv The string to search for.
1825   @param pos The index to start searching at. By default searches from 1825   @param pos The index to start searching at. By default searches from
1826   the end of the string. 1826   the end of the string.
1827   1827  
1828   @{ 1828   @{
1829   */ 1829   */
1830   std::size_t 1830   std::size_t
HITCBC 1831   5 rfind( 1831   5 rfind(
1832   string_view sv, 1832   string_view sv,
1833   std::size_t pos = npos) const noexcept 1833   std::size_t pos = npos) const noexcept
1834   { 1834   {
HITCBC 1835   5 return subview().rfind(sv, pos); 1835   5 return subview().rfind(sv, pos);
1836   } 1836   }
1837   1837  
1838   /** Overload 1838   /** Overload
1839   1839  
1840   @param ch The character to search for. 1840   @param ch The character to search for.
1841   @param pos 1841   @param pos
1842   */ 1842   */
1843   std::size_t 1843   std::size_t
HITCBC 1844   3 rfind( 1844   3 rfind(
1845   char ch, 1845   char ch,
1846   std::size_t pos = npos) const noexcept 1846   std::size_t pos = npos) const noexcept
1847   { 1847   {
HITCBC 1848   3 return subview().rfind(ch, pos); 1848   3 return subview().rfind(ch, pos);
1849   } 1849   }
1850   /// @} 1850   /// @}
1851   1851  
1852   //------------------------------------------------------ 1852   //------------------------------------------------------
1853   1853  
1854   /** Find the first character present in the specified string. 1854   /** Find the first character present in the specified string.
1855   1855  
1856   Search from `pos` onward for the first character in this string that is 1856   Search from `pos` onward for the first character in this string that is
1857   equal to any of the characters of `sv`. 1857   equal to any of the characters of `sv`.
1858   1858  
1859   @par Complexity 1859   @par Complexity
1860   Linear in @ref size() `+ sv.size()`. 1860   Linear in @ref size() `+ sv.size()`.
1861   1861  
1862   @par Exception Safety 1862   @par Exception Safety
1863   No-throw guarantee. 1863   No-throw guarantee.
1864   1864  
1865   @return The index of the found character, or @ref npos if none exists. 1865   @return The index of the found character, or @ref npos if none exists.
1866   1866  
1867   @param sv The characters to search for. 1867   @param sv The characters to search for.
1868   @param pos The index to start searching at. 1868   @param pos The index to start searching at.
1869   */ 1869   */
1870   std::size_t 1870   std::size_t
HITCBC 1871   5 find_first_of( 1871   5 find_first_of(
1872   string_view sv, 1872   string_view sv,
1873   std::size_t pos = 0) const noexcept 1873   std::size_t pos = 0) const noexcept
1874   { 1874   {
HITCBC 1875   5 return subview().find_first_of(sv, pos); 1875   5 return subview().find_first_of(sv, pos);
1876   } 1876   }
1877   1877  
1878   /** Find the first character missing from the specified string. 1878   /** Find the first character missing from the specified string.
1879   1879  
1880   Search from `pos` onward for the first character in this string that is 1880   Search from `pos` onward for the first character in this string that is
1881   not equal to any of the characters in the string provided as the first 1881   not equal to any of the characters in the string provided as the first
1882   argument. 1882   argument.
1883   1883  
1884   @li **(1)** compares with the characters in `sv`. 1884   @li **(1)** compares with the characters in `sv`.
1885   @li **(2)** compares with the character `ch`. 1885   @li **(2)** compares with the character `ch`.
1886   1886  
1887   @par Complexity 1887   @par Complexity
1888   @li **(1)** linear in @ref size() `+ sv.size()`. 1888   @li **(1)** linear in @ref size() `+ sv.size()`.
1889   @li **(2)** linear in @ref size(). 1889   @li **(2)** linear in @ref size().
1890   1890  
1891   @par Exception Safety 1891   @par Exception Safety
1892   No-throw guarantee. 1892   No-throw guarantee.
1893   1893  
1894   @return The index of the found character, or @ref npos if none exists. 1894   @return The index of the found character, or @ref npos if none exists.
1895   1895  
1896   @param sv The characters to compare with. 1896   @param sv The characters to compare with.
1897   @param pos The index to start searching at. 1897   @param pos The index to start searching at.
1898   1898  
1899   @{ 1899   @{
1900   */ 1900   */
1901   std::size_t 1901   std::size_t
HITCBC 1902   4 find_first_not_of( 1902   4 find_first_not_of(
1903   string_view sv, 1903   string_view sv,
1904   std::size_t pos = 0) const noexcept 1904   std::size_t pos = 0) const noexcept
1905   { 1905   {
HITCBC 1906   4 return subview().find_first_not_of(sv, pos); 1906   4 return subview().find_first_not_of(sv, pos);
1907   } 1907   }
1908   1908  
1909   /** Overload 1909   /** Overload
1910   @param ch The character to compare with. 1910   @param ch The character to compare with.
1911   @param pos 1911   @param pos
1912   */ 1912   */
1913   std::size_t 1913   std::size_t
HITCBC 1914   3 find_first_not_of( 1914   3 find_first_not_of(
1915   char ch, 1915   char ch,
1916   std::size_t pos = 0) const noexcept 1916   std::size_t pos = 0) const noexcept
1917   { 1917   {
HITCBC 1918   3 return subview().find_first_not_of(ch, pos); 1918   3 return subview().find_first_not_of(ch, pos);
1919   } 1919   }
1920   /// @} 1920   /// @}
1921   1921  
1922   /** Find the last character present in the specified string. 1922   /** Find the last character present in the specified string.
1923   1923  
1924   Search from `pos` backwards for the first character in this string that 1924   Search from `pos` backwards for the first character in this string that
1925   is equal to any of the characters of `sv`. If `pos` is equal to @ref 1925   is equal to any of the characters of `sv`. If `pos` is equal to @ref
1926   npos (the default), search from the last character. 1926   npos (the default), search from the last character.
1927   1927  
1928   @par Complexity 1928   @par Complexity
1929   Linear in @ref size() `+ sv.size()`. 1929   Linear in @ref size() `+ sv.size()`.
1930   1930  
1931   @par Exception Safety 1931   @par Exception Safety
1932   No-throw guarantee. 1932   No-throw guarantee.
1933   1933  
1934   @return The index of the found character, or @ref npos if none exists. 1934   @return The index of the found character, or @ref npos if none exists.
1935   1935  
1936   @param sv The characters to search for. 1936   @param sv The characters to search for.
1937   @param pos The index to start searching at. 1937   @param pos The index to start searching at.
1938   */ 1938   */
1939   std::size_t 1939   std::size_t
HITCBC 1940   5 find_last_of( 1940   5 find_last_of(
1941   string_view sv, 1941   string_view sv,
1942   std::size_t pos = npos) const noexcept 1942   std::size_t pos = npos) const noexcept
1943   { 1943   {
HITCBC 1944   5 return subview().find_last_of(sv, pos); 1944   5 return subview().find_last_of(sv, pos);
1945   } 1945   }
1946   1946  
1947   /** Find the last character missing from the specified string. 1947   /** Find the last character missing from the specified string.
1948   1948  
1949   1949  
1950   Search from `pos` backwards for the first character in this string that 1950   Search from `pos` backwards for the first character in this string that
1951   is not equal to any of the characters in the string provided as the 1951   is not equal to any of the characters in the string provided as the
1952   first argument. If `pos` is equal to @ref npos (the default), search 1952   first argument. If `pos` is equal to @ref npos (the default), search
1953   from the last character. 1953   from the last character.
1954   1954  
1955   @li **(1)** compares with the characters in `sv`. 1955   @li **(1)** compares with the characters in `sv`.
1956   @li **(2)** compares with the character `ch`. 1956   @li **(2)** compares with the character `ch`.
1957   1957  
1958   @par Complexity 1958   @par Complexity
1959   @li **(1)** linear in @ref size() `+ sv.size()`. 1959   @li **(1)** linear in @ref size() `+ sv.size()`.
1960   @li **(2)** linear in @ref size(). 1960   @li **(2)** linear in @ref size().
1961   1961  
1962   @par Exception Safety 1962   @par Exception Safety
1963   No-throw guarantee. 1963   No-throw guarantee.
1964   1964  
1965   @return The index of the found character, or @ref npos if none exists. 1965   @return The index of the found character, or @ref npos if none exists.
1966   1966  
1967   @param sv The characters to compare with. 1967   @param sv The characters to compare with.
1968   @param pos The index to start searching at. 1968   @param pos The index to start searching at.
1969   1969  
1970   @{ 1970   @{
1971   */ 1971   */
1972   std::size_t 1972   std::size_t
HITCBC 1973   4 find_last_not_of( 1973   4 find_last_not_of(
1974   string_view sv, 1974   string_view sv,
1975   std::size_t pos = npos) const noexcept 1975   std::size_t pos = npos) const noexcept
1976   { 1976   {
HITCBC 1977   4 return subview().find_last_not_of(sv, pos); 1977   4 return subview().find_last_not_of(sv, pos);
1978   } 1978   }
1979   1979  
1980   /** Overload 1980   /** Overload
1981   @param ch The character to compare with. 1981   @param ch The character to compare with.
1982   @param pos 1982   @param pos
1983   */ 1983   */
1984   std::size_t 1984   std::size_t
HITCBC 1985   3 find_last_not_of( 1985   3 find_last_not_of(
1986   char ch, 1986   char ch,
1987   std::size_t pos = npos) const noexcept 1987   std::size_t pos = npos) const noexcept
1988   { 1988   {
HITCBC 1989   3 return subview().find_last_not_of(ch, pos); 1989   3 return subview().find_last_not_of(ch, pos);
1990   } 1990   }
1991   /// @} 1991   /// @}
1992   1992  
1993   /** Serialize a @ref string to an output stream. 1993   /** Serialize a @ref string to an output stream.
1994   1994  
1995   This function serializes a `string` as JSON into the output stream. 1995   This function serializes a `string` as JSON into the output stream.
1996   1996  
1997   @return Reference to `os`. 1997   @return Reference to `os`.
1998   1998  
1999   @par Complexity 1999   @par Complexity
2000   Linear in the `str.size()`. 2000   Linear in the `str.size()`.
2001   2001  
2002   @par Exception Safety 2002   @par Exception Safety
2003   Strong guarantee. Calls to `memory_resource::allocate` may throw. 2003   Strong guarantee. Calls to `memory_resource::allocate` may throw.
2004   2004  
2005   @param os The output stream to serialize to. 2005   @param os The output stream to serialize to.
2006   @param str The value to serialize. 2006   @param str The value to serialize.
2007   */ 2007   */
2008   BOOST_JSON_DECL 2008   BOOST_JSON_DECL
2009   friend 2009   friend
2010   std::ostream& 2010   std::ostream&
2011   operator<<( 2011   operator<<(
2012   std::ostream& os, 2012   std::ostream& os,
2013   string const& str); 2013   string const& str);
2014   2014  
2015   private: 2015   private:
2016   class undo; 2016   class undo;
2017   2017  
2018   template<class It> 2018   template<class It>
2019   using iter_cat = typename 2019   using iter_cat = typename
2020   std::iterator_traits<It>::iterator_category; 2020   std::iterator_traits<It>::iterator_category;
2021   2021  
2022   template<class InputIt> 2022   template<class InputIt>
2023   void 2023   void
2024   assign(InputIt first, InputIt last, 2024   assign(InputIt first, InputIt last,
2025   std::random_access_iterator_tag); 2025   std::random_access_iterator_tag);
2026   2026  
2027   template<class InputIt> 2027   template<class InputIt>
2028   void 2028   void
2029   assign(InputIt first, InputIt last, 2029   assign(InputIt first, InputIt last,
2030   std::input_iterator_tag); 2030   std::input_iterator_tag);
2031   2031  
2032   template<class InputIt> 2032   template<class InputIt>
2033   void 2033   void
2034   append(InputIt first, InputIt last, 2034   append(InputIt first, InputIt last,
2035   std::random_access_iterator_tag); 2035   std::random_access_iterator_tag);
2036   2036  
2037   template<class InputIt> 2037   template<class InputIt>
2038   void 2038   void
2039   append(InputIt first, InputIt last, 2039   append(InputIt first, InputIt last,
2040   std::input_iterator_tag); 2040   std::input_iterator_tag);
2041   2041  
2042   BOOST_JSON_DECL 2042   BOOST_JSON_DECL
2043   void 2043   void
2044   reserve_impl(std::size_t new_capacity); 2044   reserve_impl(std::size_t new_capacity);
2045   }; 2045   };
2046   2046  
2047   //---------------------------------------------------------- 2047   //----------------------------------------------------------
2048   2048  
2049   namespace detail 2049   namespace detail
2050   { 2050   {
2051   2051  
2052   template <> 2052   template <>
2053   inline 2053   inline
2054   string_view 2054   string_view
HITCBC 2055   28791 to_string_view<string>(string const& s) noexcept 2055   28791 to_string_view<string>(string const& s) noexcept
2056   { 2056   {
HITCBC 2057   28791 return s.subview(); 2057   28791 return s.subview();
2058   } 2058   }
2059   2059  
2060   } // namespace detail 2060   } // namespace detail
2061   2061  
2062   2062  
2063   /** Checks if lhs equals rhs. 2063   /** Checks if lhs equals rhs.
2064   2064  
2065   @li **(1)** A lexicographical comparison is used. 2065   @li **(1)** A lexicographical comparison is used.
2066   @li **(2)** equivalent to `lhs.get() == rhs.get()`. 2066   @li **(2)** equivalent to `lhs.get() == rhs.get()`.
2067   2067  
2068   @par Complexity 2068   @par Complexity
2069   @li **(1)** linear in `lhs.size() + rhs.size()`. 2069   @li **(1)** linear in `lhs.size() + rhs.size()`.
2070   @li **(2)** constant. 2070   @li **(2)** constant.
2071   2071  
2072   @par Exception Safety 2072   @par Exception Safety
2073   No-throw guarantee. 2073   No-throw guarantee.
2074   */ 2074   */
2075   #ifdef BOOST_JSON_DOCS 2075   #ifdef BOOST_JSON_DOCS
2076   bool 2076   bool
2077   operator==(string const& lhs, string const& rhs) noexcept 2077   operator==(string const& lhs, string const& rhs) noexcept
2078   #else 2078   #else
2079   template<class T, class U> 2079   template<class T, class U>
2080   detail::string_comp_op_requirement<T, U> 2080   detail::string_comp_op_requirement<T, U>
HITCBC 2081   15564 operator==(T const& lhs, U const& rhs) noexcept 2081   15564 operator==(T const& lhs, U const& rhs) noexcept
2082   #endif 2082   #endif
2083   { 2083   {
HITCBC 2084   15564 return detail::to_string_view(lhs) == detail::to_string_view(rhs); 2084   15564 return detail::to_string_view(lhs) == detail::to_string_view(rhs);
2085   } 2085   }
2086   2086  
2087   /** Checks if lhs does not equal rhs. 2087   /** Checks if lhs does not equal rhs.
2088   2088  
2089   @li **(1)** A lexicographical comparison is used. 2089   @li **(1)** A lexicographical comparison is used.
2090   @li **(2)** equivalent to `lhs.get() != rhs.get()`. 2090   @li **(2)** equivalent to `lhs.get() != rhs.get()`.
2091   2091  
2092   @par Complexity 2092   @par Complexity
2093   @li **(1)** linear in `lhs.size() + rhs.size()`. 2093   @li **(1)** linear in `lhs.size() + rhs.size()`.
2094   @li **(2)** constant. 2094   @li **(2)** constant.
2095   2095  
2096   @par Exception Safety 2096   @par Exception Safety
2097   No-throw guarantee. 2097   No-throw guarantee.
2098   */ 2098   */
2099   #ifdef BOOST_JSON_DOCS 2099   #ifdef BOOST_JSON_DOCS
2100   bool 2100   bool
2101   operator!=(string const& lhs, string const& rhs) noexcept 2101   operator!=(string const& lhs, string const& rhs) noexcept
2102   #else 2102   #else
2103   template<class T, class U> 2103   template<class T, class U>
2104   detail::string_comp_op_requirement<T, U> 2104   detail::string_comp_op_requirement<T, U>
HITCBC 2105   24 operator!=(T const& lhs, U const& rhs) noexcept 2105   24 operator!=(T const& lhs, U const& rhs) noexcept
2106   #endif 2106   #endif
2107   { 2107   {
HITCBC 2108   24 return detail::to_string_view(lhs) != detail::to_string_view(rhs); 2108   24 return detail::to_string_view(lhs) != detail::to_string_view(rhs);
2109   } 2109   }
2110   2110  
2111   /** Check if lhs is less than rhs. 2111   /** Check if lhs is less than rhs.
2112   2112  
2113   A lexicographical comparison is used. 2113   A lexicographical comparison is used.
2114   2114  
2115   @par Complexity 2115   @par Complexity
2116   Linear in `lhs.size() + rhs.size()`. 2116   Linear in `lhs.size() + rhs.size()`.
2117   2117  
2118   @par Exception Safety 2118   @par Exception Safety
2119   No-throw guarantee. 2119   No-throw guarantee.
2120   */ 2120   */
2121   #ifdef BOOST_JSON_DOCS 2121   #ifdef BOOST_JSON_DOCS
2122   bool 2122   bool
2123   operator<(string const& lhs, string const& rhs) noexcept 2123   operator<(string const& lhs, string const& rhs) noexcept
2124   #else 2124   #else
2125   template<class T, class U> 2125   template<class T, class U>
2126   detail::string_comp_op_requirement<T, U> 2126   detail::string_comp_op_requirement<T, U>
HITCBC 2127   12 operator<(T const& lhs, U const& rhs) noexcept 2127   12 operator<(T const& lhs, U const& rhs) noexcept
2128   #endif 2128   #endif
2129   { 2129   {
HITCBC 2130   12 return detail::to_string_view(lhs) < detail::to_string_view(rhs); 2130   12 return detail::to_string_view(lhs) < detail::to_string_view(rhs);
2131   } 2131   }
2132   2132  
2133   /** Check if lhs is less than or equal to rhs. 2133   /** Check if lhs is less than or equal to rhs.
2134   2134  
2135   A lexicographical comparison is used. 2135   A lexicographical comparison is used.
2136   2136  
2137   @par Complexity 2137   @par Complexity
2138   Linear in `lhs.size() + rhs.size()`. 2138   Linear in `lhs.size() + rhs.size()`.
2139   2139  
2140   @par Exception Safety 2140   @par Exception Safety
2141   No-throw guarantee. 2141   No-throw guarantee.
2142   */ 2142   */
2143   #ifdef BOOST_JSON_DOCS 2143   #ifdef BOOST_JSON_DOCS
2144   bool 2144   bool
2145   operator<=(string const& lhs, string const& rhs) noexcept 2145   operator<=(string const& lhs, string const& rhs) noexcept
2146   #else 2146   #else
2147   template<class T, class U> 2147   template<class T, class U>
2148   detail::string_comp_op_requirement<T, U> 2148   detail::string_comp_op_requirement<T, U>
HITCBC 2149   12 operator<=(T const& lhs, U const& rhs) noexcept 2149   12 operator<=(T const& lhs, U const& rhs) noexcept
2150   #endif 2150   #endif
2151   { 2151   {
HITCBC 2152   12 return detail::to_string_view(lhs) <= detail::to_string_view(rhs); 2152   12 return detail::to_string_view(lhs) <= detail::to_string_view(rhs);
2153   } 2153   }
2154   2154  
2155   /** Check if lhs is more than or equal to rhs. 2155   /** Check if lhs is more than or equal to rhs.
2156   2156  
2157   A lexicographical comparison is used. 2157   A lexicographical comparison is used.
2158   2158  
2159   @par Complexity 2159   @par Complexity
2160   Linear in `lhs.size() + rhs.size()`. 2160   Linear in `lhs.size() + rhs.size()`.
2161   2161  
2162   @par Exception Safety 2162   @par Exception Safety
2163   No-throw guarantee. 2163   No-throw guarantee.
2164   */ 2164   */
2165   #ifdef BOOST_JSON_DOCS 2165   #ifdef BOOST_JSON_DOCS
2166   bool 2166   bool
2167   operator>=(string const& lhs, string const& rhs) noexcept 2167   operator>=(string const& lhs, string const& rhs) noexcept
2168   #else 2168   #else
2169   template<class T, class U> 2169   template<class T, class U>
2170   detail::string_comp_op_requirement<T, U> 2170   detail::string_comp_op_requirement<T, U>
HITCBC 2171   12 operator>=(T const& lhs, U const& rhs) noexcept 2171   12 operator>=(T const& lhs, U const& rhs) noexcept
2172   #endif 2172   #endif
2173   { 2173   {
HITCBC 2174   12 return detail::to_string_view(lhs) >= detail::to_string_view(rhs); 2174   12 return detail::to_string_view(lhs) >= detail::to_string_view(rhs);
2175   } 2175   }
2176   2176  
2177   /** Check if lhs is greater than rhs. 2177   /** Check if lhs is greater than rhs.
2178   2178  
2179   A lexicographical comparison is used. 2179   A lexicographical comparison is used.
2180   2180  
2181   @par Complexity 2181   @par Complexity
2182   Linear in `lhs.size() + rhs.size()`. 2182   Linear in `lhs.size() + rhs.size()`.
2183   2183  
2184   @par Exception Safety 2184   @par Exception Safety
2185   No-throw guarantee. 2185   No-throw guarantee.
2186   */ 2186   */
2187   #ifdef BOOST_JSON_DOCS 2187   #ifdef BOOST_JSON_DOCS
2188   bool 2188   bool
2189   operator>(string const& lhs, string const& rhs) noexcept 2189   operator>(string const& lhs, string const& rhs) noexcept
2190   #else 2190   #else
2191   template<class T, class U> 2191   template<class T, class U>
2192   detail::string_comp_op_requirement<T, U> 2192   detail::string_comp_op_requirement<T, U>
HITCBC 2193   12 operator>(T const& lhs, U const& rhs) noexcept 2193   12 operator>(T const& lhs, U const& rhs) noexcept
2194   #endif 2194   #endif
2195   { 2195   {
HITCBC 2196   12 return detail::to_string_view(lhs) > detail::to_string_view(rhs); 2196   12 return detail::to_string_view(lhs) > detail::to_string_view(rhs);
2197   } 2197   }
2198   2198  
2199   } // namespace json 2199   } // namespace json
2200   } // namespace boost 2200   } // namespace boost
2201   2201  
2202   // std::hash specialization 2202   // std::hash specialization
2203   #ifndef BOOST_JSON_DOCS 2203   #ifndef BOOST_JSON_DOCS
2204   namespace std { 2204   namespace std {
2205   template<> 2205   template<>
2206   struct hash< ::boost::json::string > 2206   struct hash< ::boost::json::string >
2207   { 2207   {
2208   BOOST_JSON_DECL 2208   BOOST_JSON_DECL
2209   std::size_t 2209   std::size_t
2210   operator()( ::boost::json::string const& js ) const noexcept; 2210   operator()( ::boost::json::string const& js ) const noexcept;
2211   }; 2211   };
2212   } // std 2212   } // std
2213   #endif 2213   #endif
2214   2214  
2215   #include <boost/json/impl/string.hpp> 2215   #include <boost/json/impl/string.hpp>
2216   2216  
2217   #endif 2217   #endif