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  
    */
147  
    ~string() noexcept
147  
    ~string() noexcept
148  
    {
148  
    {
149  
        impl_.destroy(sp_);
149  
        impl_.destroy(sp_);
150  
    }
150  
    }
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  
    */
233  
    string() = default;
233  
    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
242  
    string(storage_ptr sp)
242  
    string(storage_ptr sp)
243  
        : sp_(std::move(sp))
243  
        : sp_(std::move(sp))
244  
    {
244  
    {
245  
    }
245  
    }
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
318  
    string(string&& other) noexcept
318  
    string(string&& other) noexcept
319  
        : sp_(other.sp_)
319  
        : sp_(other.sp_)
320  
        , impl_(other.impl_)
320  
        , impl_(other.impl_)
321  
    {
321  
    {
322  
        ::new(&other.impl_) string_impl();
322  
        ::new(&other.impl_) string_impl();
323  
    }
323  
    }
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
333  
    string(pilfered<string> other) noexcept
333  
    string(pilfered<string> other) noexcept
334  
        : sp_(std::move(other.get().sp_))
334  
        : sp_(std::move(other.get().sp_))
335  
        , impl_(other.get().impl_)
335  
        , impl_(other.get().impl_)
336  
    {
336  
    {
337  
        ::new(&other.get().impl_) string_impl();
337  
        ::new(&other.get().impl_) string_impl();
338  
    }
338  
    }
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&
507  
    assign(string_view s)
507  
    assign(string_view s)
508  
    {
508  
    {
509  
        return assign(s.data(), s.size());
509  
        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&
540  
    storage() const noexcept
540  
    storage() const noexcept
541  
    {
541  
    {
542  
        return sp_;
542  
        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
557  
    get_allocator() const noexcept
557  
    get_allocator() const noexcept
558  
    {
558  
    {
559  
        return sp_.get();
559  
        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&
641  
    operator[](std::size_t pos)
641  
    operator[](std::size_t pos)
642  
    {
642  
    {
643  
        return impl_.data()[pos];
643  
        return impl_.data()[pos];
644  
    }
644  
    }
645  

645  

646  
    const char&
646  
    const char&
647  
    operator[](std::size_t pos) const
647  
    operator[](std::size_t pos) const
648  
    {
648  
    {
649  
        return impl_.data()[pos];
649  
        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&
671  
    front()
671  
    front()
672  
    {
672  
    {
673  
        return impl_.data()[0];
673  
        return impl_.data()[0];
674  
    }
674  
    }
675  

675  

676  
    char const&
676  
    char const&
677  
    front() const
677  
    front() const
678  
    {
678  
    {
679  
        return impl_.data()[0];
679  
        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&
698  
    back()
698  
    back()
699  
    {
699  
    {
700  
        return impl_.data()[impl_.size() - 1];
700  
        return impl_.data()[impl_.size() - 1];
701  
    }
701  
    }
702  

702  

703  
    char const&
703  
    char const&
704  
    back() const
704  
    back() const
705  
    {
705  
    {
706  
        return impl_.data()[impl_.size() - 1];
706  
        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*
728  
    data() noexcept
728  
    data() noexcept
729  
    {
729  
    {
730  
        return impl_.data();
730  
        return impl_.data();
731  
    }
731  
    }
732  

732  

733  
    char const*
733  
    char const*
734  
    data() const noexcept
734  
    data() const noexcept
735  
    {
735  
    {
736  
        return impl_.data();
736  
        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*
753  
    c_str() const noexcept
753  
    c_str() const noexcept
754  
    {
754  
    {
755  
        return impl_.data();
755  
        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  
    */
768  
    operator string_view() const noexcept
768  
    operator string_view() const noexcept
769  
    {
769  
    {
770  
        return {data(), size()};
770  
        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
811  
    begin() noexcept
811  
    begin() noexcept
812  
    {
812  
    {
813  
        return impl_.data();
813  
        return impl_.data();
814  
    }
814  
    }
815  

815  

816  
    const_iterator
816  
    const_iterator
817  
    begin() const noexcept
817  
    begin() const noexcept
818  
    {
818  
    {
819  
        return impl_.data();
819  
        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
834  
    cbegin() const noexcept
834  
    cbegin() const noexcept
835  
    {
835  
    {
836  
        return impl_.data();
836  
        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
853  
    end() noexcept
853  
    end() noexcept
854  
    {
854  
    {
855  
        return impl_.end();
855  
        return impl_.end();
856  
    }
856  
    }
857  

857  

858  
    const_iterator
858  
    const_iterator
859  
    end() const noexcept
859  
    end() const noexcept
860  
    {
860  
    {
861  
        return impl_.end();
861  
        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
877  
    cend() const noexcept
877  
    cend() const noexcept
878  
    {
878  
    {
879  
        return impl_.end();
879  
        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
894  
    rbegin() noexcept
894  
    rbegin() noexcept
895  
    {
895  
    {
896  
        return reverse_iterator(impl_.end());
896  
        return reverse_iterator(impl_.end());
897  
    }
897  
    }
898  

898  

899  
    const_reverse_iterator
899  
    const_reverse_iterator
900  
    rbegin() const noexcept
900  
    rbegin() const noexcept
901  
    {
901  
    {
902  
        return const_reverse_iterator(impl_.end());
902  
        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
919  
    crbegin() const noexcept
919  
    crbegin() const noexcept
920  
    {
920  
    {
921  
        return const_reverse_iterator(impl_.end());
921  
        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
939  
    rend() noexcept
939  
    rend() noexcept
940  
    {
940  
    {
941  
        return reverse_iterator(begin());
941  
        return reverse_iterator(begin());
942  
    }
942  
    }
943  

943  

944  
    const_reverse_iterator
944  
    const_reverse_iterator
945  
    rend() const noexcept
945  
    rend() const noexcept
946  
    {
946  
    {
947  
        return const_reverse_iterator(begin());
947  
        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
965  
    crend() const noexcept
965  
    crend() const noexcept
966  
    {
966  
    {
967  
        return const_reverse_iterator(begin());
967  
        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
988  
    empty() const noexcept
988  
    empty() const noexcept
989  
    {
989  
    {
990  
        return impl_.size() == 0;
990  
        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
1002  
    size() const noexcept
1002  
    size() const noexcept
1003  
    {
1003  
    {
1004  
        return impl_.size();
1004  
        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
1019  
    max_size() noexcept
1019  
    max_size() noexcept
1020  
    {
1020  
    {
1021  
        return string_impl::max_size();
1021  
        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
1037  
    capacity() const noexcept
1037  
    capacity() const noexcept
1038  
    {
1038  
    {
1039  
        return impl_.capacity();
1039  
        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
1065  
    reserve(std::size_t new_capacity)
1065  
    reserve(std::size_t new_capacity)
1066  
    {
1066  
    {
1067  
        if(new_capacity <= capacity())
1067  
        if(new_capacity <= capacity())
1068  
            return;
1068  
            return;
1069  
        reserve_impl(new_capacity);
1069  
        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&
1168  
    insert(
1168  
    insert(
1169  
        size_type pos,
1169  
        size_type pos,
1170  
        char ch)
1170  
        char ch)
1171  
    {
1171  
    {
1172  
        return insert(pos, 1, ch);
1172  
        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&
1366  
    operator+=(string_view sv)
1366  
    operator+=(string_view sv)
1367  
    {
1367  
    {
1368  
        return append(sv);
1368  
        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&
1375  
    operator+=(char ch)
1375  
    operator+=(char ch)
1376  
    {
1376  
    {
1377  
        push_back(ch);
1377  
        push_back(ch);
1378  
        return *this;
1378  
        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
1400  
    compare(string_view sv) const noexcept
1400  
    compare(string_view sv) const noexcept
1401  
    {
1401  
    {
1402  
        return subview().compare(sv);
1402  
        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
1421  
    starts_with(string_view s) const noexcept
1421  
    starts_with(string_view s) const noexcept
1422  
    {
1422  
    {
1423  
        return subview(0, s.size()) == s;
1423  
        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
1431  
    starts_with(char ch) const noexcept
1431  
    starts_with(char ch) const noexcept
1432  
    {
1432  
    {
1433  
        return ! empty() && front() == ch;
1433  
        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
1454  
    ends_with(string_view s) const noexcept
1454  
    ends_with(string_view s) const noexcept
1455  
    {
1455  
    {
1456  
        return size() >= s.size() &&
1456  
        return size() >= s.size() &&
1457  
            subview(size() - s.size()) == s;
1457  
            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
1464  
    ends_with(char ch) const noexcept
1464  
    ends_with(char ch) const noexcept
1465  
    {
1465  
    {
1466  
        return ! empty() && back() == ch;
1466  
        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&
1523  
    replace(
1523  
    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  
    {
1528  
        return replace(first - begin(), last - first, sv);
1528  
        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&
1577  
    replace(
1577  
    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  
    {
1583  
        return replace(first - begin(), last - first, count2, ch);
1583  
        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
1603  
    subview(
1603  
    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  
    {
1607  
        return subview().substr(pos, count);
1607  
        return subview().substr(pos, count);
1608  
    }
1608  
    }
1609  

1609  

1610  
    /// Overload
1610  
    /// Overload
1611  
    string_view
1611  
    string_view
1612  
    subview() const noexcept
1612  
    subview() const noexcept
1613  
    {
1613  
    {
1614  
        return string_view( data(), size() );
1614  
        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
1638  
    copy(
1638  
    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  
    {
1643  
        return subview().copy(dest, count, pos);
1643  
        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
1661  
    resize(std::size_t count)
1661  
    resize(std::size_t count)
1662  
    {
1662  
    {
1663  
        resize(count, 0);
1663  
        resize(count, 0);
1664  
    }
1664  
    }
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
1692  
    grow(std::size_t n) noexcept
1692  
    grow(std::size_t n) noexcept
1693  
    {
1693  
    {
1694  
        BOOST_ASSERT(
1694  
        BOOST_ASSERT(
1695  
            n <= impl_.capacity() - impl_.size());
1695  
            n <= impl_.capacity() - impl_.size());
1696  
        impl_.term(impl_.size() + n);
1696  
        impl_.term(impl_.size() + n);
1697  
    }
1697  
    }
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
1755  
    swap(string& lhs, string& rhs)
1755  
    swap(string& lhs, string& rhs)
1756  
    {
1756  
    {
1757  
        lhs.swap(rhs);
1757  
        lhs.swap(rhs);
1758  
    }
1758  
    }
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
1789  
    find(
1789  
    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  
    {
1793  
        return subview().find(sv, pos);
1793  
        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
1802  
    find(
1802  
    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  
    {
1806  
        return subview().find(ch, pos);
1806  
        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
1831  
    rfind(
1831  
    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  
    {
1835  
        return subview().rfind(sv, pos);
1835  
        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
1844  
    rfind(
1844  
    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  
    {
1848  
        return subview().rfind(ch, pos);
1848  
        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
1871  
    find_first_of(
1871  
    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  
    {
1875  
        return subview().find_first_of(sv, pos);
1875  
        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
1902  
    find_first_not_of(
1902  
    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  
    {
1906  
        return subview().find_first_not_of(sv, pos);
1906  
        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
1914  
    find_first_not_of(
1914  
    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  
    {
1918  
        return subview().find_first_not_of(ch, pos);
1918  
        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
1940  
    find_last_of(
1940  
    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  
    {
1944  
        return subview().find_last_of(sv, pos);
1944  
        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
1973  
    find_last_not_of(
1973  
    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  
    {
1977  
        return subview().find_last_not_of(sv, pos);
1977  
        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
1985  
    find_last_not_of(
1985  
    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  
    {
1989  
        return subview().find_last_not_of(ch, pos);
1989  
        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
2055  
to_string_view<string>(string const& s) noexcept
2055  
to_string_view<string>(string const& s) noexcept
2056  
{
2056  
{
2057  
    return s.subview();
2057  
    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>
2081  
operator==(T const& lhs, U const& rhs) noexcept
2081  
operator==(T const& lhs, U const& rhs) noexcept
2082  
#endif
2082  
#endif
2083  
{
2083  
{
2084  
    return detail::to_string_view(lhs) == detail::to_string_view(rhs);
2084  
    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>
2105  
operator!=(T const& lhs, U const& rhs) noexcept
2105  
operator!=(T const& lhs, U const& rhs) noexcept
2106  
#endif
2106  
#endif
2107  
{
2107  
{
2108  
    return detail::to_string_view(lhs) != detail::to_string_view(rhs);
2108  
    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>
2127  
operator<(T const& lhs, U const& rhs) noexcept
2127  
operator<(T const& lhs, U const& rhs) noexcept
2128  
#endif
2128  
#endif
2129  
{
2129  
{
2130  
    return detail::to_string_view(lhs) < detail::to_string_view(rhs);
2130  
    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>
2149  
operator<=(T const& lhs, U const& rhs) noexcept
2149  
operator<=(T const& lhs, U const& rhs) noexcept
2150  
#endif
2150  
#endif
2151  
{
2151  
{
2152  
    return detail::to_string_view(lhs) <= detail::to_string_view(rhs);
2152  
    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>
2171  
operator>=(T const& lhs, U const& rhs) noexcept
2171  
operator>=(T const& lhs, U const& rhs) noexcept
2172  
#endif
2172  
#endif
2173  
{
2173  
{
2174  
    return detail::to_string_view(lhs) >= detail::to_string_view(rhs);
2174  
    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>
2193  
operator>(T const& lhs, U const& rhs) noexcept
2193  
operator>(T const& lhs, U const& rhs) noexcept
2194  
#endif
2194  
#endif
2195  
{
2195  
{
2196  
    return detail::to_string_view(lhs) > detail::to_string_view(rhs);
2196  
    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