1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/json
7  
// Official repository: https://github.com/boostorg/json
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_JSON_ARRAY_HPP
10  
#ifndef BOOST_JSON_ARRAY_HPP
11  
#define BOOST_JSON_ARRAY_HPP
11  
#define BOOST_JSON_ARRAY_HPP
12  

12  

13  
#include <boost/json/detail/config.hpp>
13  
#include <boost/json/detail/config.hpp>
14  
#include <boost/json/detail/array.hpp>
14  
#include <boost/json/detail/array.hpp>
15  
#include <boost/json/kind.hpp>
15  
#include <boost/json/kind.hpp>
16  
#include <boost/json/pilfer.hpp>
16  
#include <boost/json/pilfer.hpp>
17  
#include <boost/json/storage_ptr.hpp>
17  
#include <boost/json/storage_ptr.hpp>
18  
#include <boost/system/result.hpp>
18  
#include <boost/system/result.hpp>
19  
#include <cstdlib>
19  
#include <cstdlib>
20  
#include <initializer_list>
20  
#include <initializer_list>
21  
#include <iterator>
21  
#include <iterator>
22  

22  

23  
namespace boost {
23  
namespace boost {
24  
namespace json {
24  
namespace json {
25  

25  

26  
#ifndef BOOST_JSON_DOCS
26  
#ifndef BOOST_JSON_DOCS
27  
class value;
27  
class value;
28  
class value_ref;
28  
class value_ref;
29  
#endif
29  
#endif
30  

30  

31  
/** A dynamically sized array of JSON values
31  
/** A dynamically sized array of JSON values
32  

32  

33  
    This is the type used to represent a JSON array as a modifiable container.
33  
    This is the type used to represent a JSON array as a modifiable container.
34  
    The interface and performance characteristics are modeled after
34  
    The interface and performance characteristics are modeled after
35  
    `std::vector<value>`.
35  
    `std::vector<value>`.
36  

36  

37  
    Elements are stored contiguously, which means that they can be accessed not
37  
    Elements are stored contiguously, which means that they can be accessed not
38  
    only through iterators, but also using offsets to regular pointers to
38  
    only through iterators, but also using offsets to regular pointers to
39  
    elements. A pointer to an element of an `array` may be passed to any
39  
    elements. A pointer to an element of an `array` may be passed to any
40  
    function that expects a pointer to @ref value.
40  
    function that expects a pointer to @ref value.
41  

41  

42  
    The storage of the array is handled automatically, being expanded and
42  
    The storage of the array is handled automatically, being expanded and
43  
    contracted as needed. Arrays usually occupy more space than array language
43  
    contracted as needed. Arrays usually occupy more space than array language
44  
    constructs, because more memory is allocated to handle future growth. This
44  
    constructs, because more memory is allocated to handle future growth. This
45  
    way an array does not need to reallocate each time an element is inserted,
45  
    way an array does not need to reallocate each time an element is inserted,
46  
    but only when the additional memory is used up. The total amount of
46  
    but only when the additional memory is used up. The total amount of
47  
    allocated memory can be queried using the @ref capacity function. Extra
47  
    allocated memory can be queried using the @ref capacity function. Extra
48  
    memory can be relinquished by calling @ref shrink_to_fit.
48  
    memory can be relinquished by calling @ref shrink_to_fit.
49  

49  

50  

50  

51  
    Reallocations are usually costly operations in terms of performance. The
51  
    Reallocations are usually costly operations in terms of performance. The
52  
    @ref reserve function can be used to eliminate reallocations if the number
52  
    @ref reserve function can be used to eliminate reallocations if the number
53  
    of elements is known beforehand.
53  
    of elements is known beforehand.
54  

54  

55  
    The complexity (efficiency) of common operations on arrays is as follows:
55  
    The complexity (efficiency) of common operations on arrays is as follows:
56  

56  

57  
    @li Random access---constant *O(1)*.
57  
    @li Random access---constant *O(1)*.
58  
    @li Insertion or removal of elements at the end - amortized
58  
    @li Insertion or removal of elements at the end - amortized
59  
        constant *O(1)*.
59  
        constant *O(1)*.
60  
    @li Insertion or removal of elements---linear in the distance to the end of
60  
    @li Insertion or removal of elements---linear in the distance to the end of
61  
        the array *O(n)*.
61  
        the array *O(n)*.
62  

62  

63  
    @par Allocators
63  
    @par Allocators
64  

64  

65  
    All elements stored in the container, and their children if any, will use
65  
    All elements stored in the container, and their children if any, will use
66  
    the same memory resource that was used to construct the container.
66  
    the same memory resource that was used to construct the container.
67  

67  

68  
    @par Thread Safety
68  
    @par Thread Safety
69  

69  

70  
    Non-const member functions may not be called concurrently with any other
70  
    Non-const member functions may not be called concurrently with any other
71  
    member functions.
71  
    member functions.
72  

72  

73  
    @par Satisfies
73  
    @par Satisfies
74  
        [*ContiguousContainer*](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
74  
        [*ContiguousContainer*](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
75  
        [*ReversibleContainer*](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and
75  
        [*ReversibleContainer*](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and
76  
        {req_SequenceContainer}.
76  
        {req_SequenceContainer}.
77  
*/
77  
*/
78  
class array
78  
class array
79  
{
79  
{
80  
    struct table;
80  
    struct table;
81  
    class revert_construct;
81  
    class revert_construct;
82  
    class revert_insert;
82  
    class revert_insert;
83  
    friend class value;
83  
    friend class value;
84  

84  

85  
    storage_ptr sp_;        // must come first
85  
    storage_ptr sp_;        // must come first
86  
    kind k_ = kind::array;  // must come second
86  
    kind k_ = kind::array;  // must come second
87  
    table* t_;
87  
    table* t_;
88  

88  

89  
    BOOST_JSON_DECL
89  
    BOOST_JSON_DECL
90  
    static table empty_;
90  
    static table empty_;
91  

91  

92  
    inline
92  
    inline
93  
    static
93  
    static
94  
    void
94  
    void
95  
    relocate(
95  
    relocate(
96  
        value* dest,
96  
        value* dest,
97  
        value* src,
97  
        value* src,
98  
        std::size_t n) noexcept;
98  
        std::size_t n) noexcept;
99  

99  

100  
    inline
100  
    inline
101  
    void
101  
    void
102  
    destroy(
102  
    destroy(
103  
        value* first,
103  
        value* first,
104  
        value* last) noexcept;
104  
        value* last) noexcept;
105  

105  

106  
    BOOST_JSON_DECL
106  
    BOOST_JSON_DECL
107  
    void
107  
    void
108  
    destroy() noexcept;
108  
    destroy() noexcept;
109  

109  

110  
    BOOST_JSON_DECL
110  
    BOOST_JSON_DECL
111  
    explicit
111  
    explicit
112  
    array(detail::unchecked_array&& ua);
112  
    array(detail::unchecked_array&& ua);
113  

113  

114  
public:
114  
public:
115  
    /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
115  
    /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
116  
    using allocator_type = container::pmr::polymorphic_allocator<value>;
116  
    using allocator_type = container::pmr::polymorphic_allocator<value>;
117  

117  

118  
    /// The type used to represent unsigned integers
118  
    /// The type used to represent unsigned integers
119  
    using size_type = std::size_t;
119  
    using size_type = std::size_t;
120  

120  

121  
    /// The type of each element
121  
    /// The type of each element
122  
    using value_type = value;
122  
    using value_type = value;
123  

123  

124  
    /// The type used to represent signed integers
124  
    /// The type used to represent signed integers
125  
    using difference_type = std::ptrdiff_t;
125  
    using difference_type = std::ptrdiff_t;
126  

126  

127  
    /// A reference to an element
127  
    /// A reference to an element
128  
    using reference = value&;
128  
    using reference = value&;
129  

129  

130  
    /// A const reference to an element
130  
    /// A const reference to an element
131  
    using const_reference = value const&;
131  
    using const_reference = value const&;
132  

132  

133  
    /// A pointer to an element
133  
    /// A pointer to an element
134  
    using pointer = value*;
134  
    using pointer = value*;
135  

135  

136  
    /// A const pointer to an element
136  
    /// A const pointer to an element
137  
    using const_pointer = value const*;
137  
    using const_pointer = value const*;
138  

138  

139  
    /// A random access iterator to an element
139  
    /// A random access iterator to an element
140  
    using iterator = value*;
140  
    using iterator = value*;
141  

141  

142  
    /// A random access const iterator to an element
142  
    /// A random access const iterator to an element
143  
    using const_iterator = value const*;
143  
    using const_iterator = value const*;
144  

144  

145  
    /// A reverse random access iterator to an element
145  
    /// A reverse random access iterator to an element
146  
    using reverse_iterator =
146  
    using reverse_iterator =
147  
        std::reverse_iterator<iterator>;
147  
        std::reverse_iterator<iterator>;
148  

148  

149  
    /// A reverse random access const iterator to an element
149  
    /// A reverse random access const iterator to an element
150  
    using const_reverse_iterator =
150  
    using const_reverse_iterator =
151  
        std::reverse_iterator<const_iterator>;
151  
        std::reverse_iterator<const_iterator>;
152  

152  

153  
    //------------------------------------------------------
153  
    //------------------------------------------------------
154  

154  

155  
    /** Destructor.
155  
    /** Destructor.
156  

156  

157  
        The destructor for each element is called if needed, any used memory is
157  
        The destructor for each element is called if needed, any used memory is
158  
        deallocated, and shared ownership of the
158  
        deallocated, and shared ownership of the
159  
        @ref boost::container::pmr::memory_resource is released.
159  
        @ref boost::container::pmr::memory_resource is released.
160  

160  

161  
        @par Complexity
161  
        @par Complexity
162  
        Linear in @ref size().
162  
        Linear in @ref size().
163  

163  

164  
        @par Exception Safety
164  
        @par Exception Safety
165  
        No-throw guarantee.
165  
        No-throw guarantee.
166  
    */
166  
    */
167  
    BOOST_JSON_DECL
167  
    BOOST_JSON_DECL
168  
    ~array() noexcept;
168  
    ~array() noexcept;
169  

169  

170  
    //------------------------------------------------------
170  
    //------------------------------------------------------
171  

171  

172  
    /** Constructors.
172  
    /** Constructors.
173  

173  

174  
        Constructs an array.
174  
        Constructs an array.
175  

175  

176  
        @li **(1)**, **(2)**  the array is empty and has zero capacity.
176  
        @li **(1)**, **(2)**  the array is empty and has zero capacity.
177  

177  

178  
        @li **(3)** the array is filled with `count` copies of `jv`.
178  
        @li **(3)** the array is filled with `count` copies of `jv`.
179  

179  

180  
        @li **(4)** the array is filled with `count` null values.
180  
        @li **(4)** the array is filled with `count` null values.
181  

181  

182  
        @li **(5)** the array is filled with values in the range
182  
        @li **(5)** the array is filled with values in the range
183  
            `[first, last)`, preserving order.
183  
            `[first, last)`, preserving order.
184  

184  

185  
        @li **(6)** the array is filled with copies of the values in `init`,
185  
        @li **(6)** the array is filled with copies of the values in `init`,
186  
            preserving order.
186  
            preserving order.
187  

187  

188  
        @li **(7)**, **(8)** the array is filled with copies of the elements of
188  
        @li **(7)**, **(8)** the array is filled with copies of the elements of
189  
            `other`, preserving order.
189  
            `other`, preserving order.
190  

190  

191  
        @li **(9)** the array acquires ownership of the contents of `other`.
191  
        @li **(9)** the array acquires ownership of the contents of `other`.
192  

192  

193  
        @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`;
193  
        @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`;
194  
            otherwise equivalent to **(8)**.
194  
            otherwise equivalent to **(8)**.
195  

195  

196  
        @li **(11)** the array acquires ownership of the contents of `other`
196  
        @li **(11)** the array acquires ownership of the contents of `other`
197  
            using pilfer semantics. This is more efficient than move
197  
            using pilfer semantics. This is more efficient than move
198  
            construction, when it is known that the moved-from object will be
198  
            construction, when it is known that the moved-from object will be
199  
            immediately destroyed afterwards.
199  
            immediately destroyed afterwards.
200  

200  

201  
        With **(2)**, **(4)**, **(5)**, **(6)**, **(8)**, **(10)** the
201  
        With **(2)**, **(4)**, **(5)**, **(6)**, **(8)**, **(10)** the
202  
        constructed array uses memory resource of `sp`. With **(7)**, **(9)**,
202  
        constructed array uses memory resource of `sp`. With **(7)**, **(9)**,
203  
        and **(11)** it uses `other`'s memory resource. In either case the
203  
        and **(11)** it uses `other`'s memory resource. In either case the
204  
        array will share the ownership of the memory resource. With **(1)**
204  
        array will share the ownership of the memory resource. With **(1)**
205  
        and **(3)** it uses the
205  
        and **(3)** it uses the
206  
        \<\<default_memory_resource, default memory resource\>\>.
206  
        \<\<default_memory_resource, default memory resource\>\>.
207  

207  

208  
        After **(9)** `other` behaves as if newly constructed with its
208  
        After **(9)** `other` behaves as if newly constructed with its
209  
        current storage pointer.
209  
        current storage pointer.
210  

210  

211  
        After **(11)** `other` is not in a usable state and may only be
211  
        After **(11)** `other` is not in a usable state and may only be
212  
        destroyed.
212  
        destroyed.
213  

213  

214  
        @par Constraints
214  
        @par Constraints
215  

215  

216  
        @code
216  
        @code
217  
        std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
217  
        std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
218  
        @endcode
218  
        @endcode
219  

219  

220  
        @par Complexity
220  
        @par Complexity
221  
        @li **(1)**, **(2)**, **(9)**, **(11)** constant.
221  
        @li **(1)**, **(2)**, **(9)**, **(11)** constant.
222  
        @li **(3)**, **(4)** linear in `count`.
222  
        @li **(3)**, **(4)** linear in `count`.
223  
        @li **(5)** linear in `std::distance(first, last)`
223  
        @li **(5)** linear in `std::distance(first, last)`
224  
        @li **(6)** linear in `init.size()`.
224  
        @li **(6)** linear in `init.size()`.
225  
        @li **(7)**, **(8)** linear in `other.size()`.
225  
        @li **(7)**, **(8)** linear in `other.size()`.
226  
        @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in
226  
        @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in
227  
            `other.size()`.
227  
            `other.size()`.
228  

228  

229  
        @par Exception Safety
229  
        @par Exception Safety
230  
        @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee.
230  
        @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee.
231  
        @li **(3)**, **(4)**, **(6)**--**(8)**, **(10)** strong
231  
        @li **(3)**, **(4)**, **(6)**--**(8)**, **(10)** strong
232  
            guarantee.
232  
            guarantee.
233  
        @li **(5)** strong guarantee if `InputIt` satisfies
233  
        @li **(5)** strong guarantee if `InputIt` satisfies
234  
        {req_ForwardIterator}, basic guarantee otherwise.
234  
        {req_ForwardIterator}, basic guarantee otherwise.
235  

235  

236  
        Calls to `memory_resource::allocate` may throw.
236  
        Calls to `memory_resource::allocate` may throw.
237  

237  

238  
        @see @ref pilfer,
238  
        @see @ref pilfer,
239  
            [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
239  
            [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
240  
        @{
240  
        @{
241  
    */
241  
    */
242  
    array() noexcept
242  
    array() noexcept
243  
        : t_(&empty_)
243  
        : t_(&empty_)
244  
    {
244  
    {
245  
    }
245  
    }
246  

246  

247  
    /** Overload
247  
    /** Overload
248  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
248  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
249  
        to use. The container will acquire shared ownership of the memory
249  
        to use. The container will acquire shared ownership of the memory
250  
        resource.
250  
        resource.
251  
    */
251  
    */
252  
    explicit
252  
    explicit
253  
    array(storage_ptr sp) noexcept
253  
    array(storage_ptr sp) noexcept
254  
        : sp_(std::move(sp))
254  
        : sp_(std::move(sp))
255  
        , k_(kind::array)
255  
        , k_(kind::array)
256  
        , t_(&empty_)
256  
        , t_(&empty_)
257  
    {
257  
    {
258  
    }
258  
    }
259  

259  

260  
    /** Overload
260  
    /** Overload
261  
        @param count The number of copies to insert.
261  
        @param count The number of copies to insert.
262  
        @param jv The value to be inserted.
262  
        @param jv The value to be inserted.
263  
        @param sp
263  
        @param sp
264  
    */
264  
    */
265  
    BOOST_JSON_DECL
265  
    BOOST_JSON_DECL
266  
    array(
266  
    array(
267  
        std::size_t count,
267  
        std::size_t count,
268  
        value const& jv,
268  
        value const& jv,
269  
        storage_ptr sp = {});
269  
        storage_ptr sp = {});
270  

270  

271  
    /// Overload
271  
    /// Overload
272  
    BOOST_JSON_DECL
272  
    BOOST_JSON_DECL
273  
    array(
273  
    array(
274  
        std::size_t count,
274  
        std::size_t count,
275  
        storage_ptr sp = {});
275  
        storage_ptr sp = {});
276  

276  

277  
    /** Overload
277  
    /** Overload
278  

278  

279  
        @param first An input iterator pointing to the first element to insert,
279  
        @param first An input iterator pointing to the first element to insert,
280  
               or pointing to the end of the range.
280  
               or pointing to the end of the range.
281  
        @param last An input iterator pointing to the end of the range.
281  
        @param last An input iterator pointing to the end of the range.
282  
        @param sp
282  
        @param sp
283  

283  

284  
        @tparam InputIt a type satisfying the {req_InputIterator} requirement.
284  
        @tparam InputIt a type satisfying the {req_InputIterator} requirement.
285  
    */
285  
    */
286  
    template<
286  
    template<
287  
        class InputIt
287  
        class InputIt
288  
    #ifndef BOOST_JSON_DOCS
288  
    #ifndef BOOST_JSON_DOCS
289  
        ,class = typename std::enable_if<
289  
        ,class = typename std::enable_if<
290  
            std::is_constructible<value,
290  
            std::is_constructible<value,
291  
                typename std::iterator_traits<
291  
                typename std::iterator_traits<
292  
                    InputIt>::reference>::value>::type
292  
                    InputIt>::reference>::value>::type
293  
    #endif
293  
    #endif
294  
    >
294  
    >
295  
    array(
295  
    array(
296  
        InputIt first, InputIt last,
296  
        InputIt first, InputIt last,
297  
        storage_ptr sp = {});
297  
        storage_ptr sp = {});
298  

298  

299  
    /** Overload
299  
    /** Overload
300  
        @param init The initializer list with elements to insert.
300  
        @param init The initializer list with elements to insert.
301  
        @param sp
301  
        @param sp
302  
    */
302  
    */
303  
    BOOST_JSON_DECL
303  
    BOOST_JSON_DECL
304  
    array(
304  
    array(
305  
        std::initializer_list<value_ref> init,
305  
        std::initializer_list<value_ref> init,
306  
        storage_ptr sp = {});
306  
        storage_ptr sp = {});
307  

307  

308  
    /** Overload
308  
    /** Overload
309  
        @param other Another array.
309  
        @param other Another array.
310  
    */
310  
    */
311  
    BOOST_JSON_DECL
311  
    BOOST_JSON_DECL
312  
    array(array const& other);
312  
    array(array const& other);
313  

313  

314  
    /// Overload
314  
    /// Overload
315  
    BOOST_JSON_DECL
315  
    BOOST_JSON_DECL
316  
    array(
316  
    array(
317  
        array const& other,
317  
        array const& other,
318  
        storage_ptr sp);
318  
        storage_ptr sp);
319  

319  

320  
    /// Overload
320  
    /// Overload
321  
    array(array&& other) noexcept
321  
    array(array&& other) noexcept
322  
        : sp_(other.sp_)
322  
        : sp_(other.sp_)
323  
        , t_(detail::exchange(
323  
        , t_(detail::exchange(
324  
            other.t_, &empty_))
324  
            other.t_, &empty_))
325  
    {
325  
    {
326  
    }
326  
    }
327  

327  

328  
    /// Overload
328  
    /// Overload
329  
    BOOST_JSON_DECL
329  
    BOOST_JSON_DECL
330  
    array(
330  
    array(
331  
        array&& other,
331  
        array&& other,
332  
        storage_ptr sp);
332  
        storage_ptr sp);
333  

333  

334  
    /// Overload
334  
    /// Overload
335  
    array(pilfered<array> other) noexcept
335  
    array(pilfered<array> other) noexcept
336  
        : sp_(std::move(other.get().sp_))
336  
        : sp_(std::move(other.get().sp_))
337  
        , t_(detail::exchange(
337  
        , t_(detail::exchange(
338  
            other.get().t_, &empty_))
338  
            other.get().t_, &empty_))
339  
    {
339  
    {
340  
    }
340  
    }
341  
    /// @}
341  
    /// @}
342  

342  

343  
    /** Assignment operators.
343  
    /** Assignment operators.
344  

344  

345  
        Replaces the contents of the array.
345  
        Replaces the contents of the array.
346  
        @li **(1)** the contents are replaced with an element-wise copy of
346  
        @li **(1)** the contents are replaced with an element-wise copy of
347  
            `other`.
347  
            `other`.
348  
        @li **(2)** takes ownership of `other`'s element storage if
348  
        @li **(2)** takes ownership of `other`'s element storage if
349  
            `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
349  
            `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
350  
        @li **(3)** the contents are replaced with a copy of the values in
350  
        @li **(3)** the contents are replaced with a copy of the values in
351  
            `init`.
351  
            `init`.
352  

352  

353  
        After **(2)**, the moved-from array behaves as if newly constructed
353  
        After **(2)**, the moved-from array behaves as if newly constructed
354  
        with its current storage pointer.
354  
        with its current storage pointer.
355  

355  

356  
        @par Complexity
356  
        @par Complexity
357  
        @li **(1)** linear in `size() + other.size()`.
357  
        @li **(1)** linear in `size() + other.size()`.
358  
        @li **(2)** constant if `*storage() == *other.storage()`; otherwise
358  
        @li **(2)** constant if `*storage() == *other.storage()`; otherwise
359  
            linear in `size() + other.size()`.
359  
            linear in `size() + other.size()`.
360  
        @li **(1)** linear in `size() + init.size()`.
360  
        @li **(1)** linear in `size() + init.size()`.
361  

361  

362  
        @par Exception Safety
362  
        @par Exception Safety
363  
        {sp} **(2)** provides strong guarantee if
363  
        {sp} **(2)** provides strong guarantee if
364  
        `*storage() != *other.storage()` and no-throw guarantee otherwise.
364  
        `*storage() != *other.storage()` and no-throw guarantee otherwise.
365  
        Other overloads provide strong guarantee.
365  
        Other overloads provide strong guarantee.
366  
        Calls to `memory_resource::allocate` may throw.
366  
        Calls to `memory_resource::allocate` may throw.
367  

367  

368  
        @param other The array to copy.
368  
        @param other The array to copy.
369  

369  

370  
        @return `*this`
370  
        @return `*this`
371  

371  

372  
        @{
372  
        @{
373  
    */
373  
    */
374  
    BOOST_JSON_DECL
374  
    BOOST_JSON_DECL
375  
    array&
375  
    array&
376  
    operator=(array const& other);
376  
    operator=(array const& other);
377  

377  

378  
    /** Overload
378  
    /** Overload
379  
        @param other The array to move.
379  
        @param other The array to move.
380  
    */
380  
    */
381  
    BOOST_JSON_DECL
381  
    BOOST_JSON_DECL
382  
    array&
382  
    array&
383  
    operator=(array&& other);
383  
    operator=(array&& other);
384  

384  

385  
    /** Overload
385  
    /** Overload
386  
        @param init The initializer list to copy.
386  
        @param init The initializer list to copy.
387  
    */
387  
    */
388  
    BOOST_JSON_DECL
388  
    BOOST_JSON_DECL
389  
    array&
389  
    array&
390  
    operator=(
390  
    operator=(
391  
        std::initializer_list<value_ref> init);
391  
        std::initializer_list<value_ref> init);
392  
    /// @}
392  
    /// @}
393  

393  

394  
    /** Return the associated memory resource.
394  
    /** Return the associated memory resource.
395  

395  

396  
        This function returns a smart pointer to the
396  
        This function returns a smart pointer to the
397  
        @ref boost::container::pmr::memory_resource used by the container.
397  
        @ref boost::container::pmr::memory_resource used by the container.
398  

398  

399  
        @par Complexity
399  
        @par Complexity
400  
        Constant.
400  
        Constant.
401  

401  

402  
        @par Exception Safety
402  
        @par Exception Safety
403  
        No-throw guarantee.
403  
        No-throw guarantee.
404  
    */
404  
    */
405  
    storage_ptr const&
405  
    storage_ptr const&
406  
    storage() const noexcept
406  
    storage() const noexcept
407  
    {
407  
    {
408  
        return sp_;
408  
        return sp_;
409  
    }
409  
    }
410  

410  

411  
    /** Return the associated allocator.
411  
    /** Return the associated allocator.
412  

412  

413  
        This function returns an instance of @ref allocator_type constructed
413  
        This function returns an instance of @ref allocator_type constructed
414  
        from the associated @ref boost::container::pmr::memory_resource.
414  
        from the associated @ref boost::container::pmr::memory_resource.
415  

415  

416  
        @par Complexity
416  
        @par Complexity
417  
        Constant.
417  
        Constant.
418  

418  

419  
        @par Exception Safety
419  
        @par Exception Safety
420  
        No-throw guarantee.
420  
        No-throw guarantee.
421  
    */
421  
    */
422  
    allocator_type
422  
    allocator_type
423  
    get_allocator() const noexcept
423  
    get_allocator() const noexcept
424  
    {
424  
    {
425  
        return sp_.get();
425  
        return sp_.get();
426  
    }
426  
    }
427  

427  

428  
    //------------------------------------------------------
428  
    //------------------------------------------------------
429  
    //
429  
    //
430  
    // Element access
430  
    // Element access
431  
    //
431  
    //
432  
    //------------------------------------------------------
432  
    //------------------------------------------------------
433  

433  

434  
    /** Access an element, with bounds checking.
434  
    /** Access an element, with bounds checking.
435  

435  

436  
        Returns @ref boost::system::result containing a reference to the
436  
        Returns @ref boost::system::result containing a reference to the
437  
        element specified at location `pos`, if `pos` is within the range of
437  
        element specified at location `pos`, if `pos` is within the range of
438  
        the container. Otherwise the result contains an `error_code`.
438  
        the container. Otherwise the result contains an `error_code`.
439  

439  

440  
        @par Exception Safety
440  
        @par Exception Safety
441  
        No-throw guarantee.
441  
        No-throw guarantee.
442  

442  

443  
        @param pos A zero-based index.
443  
        @param pos A zero-based index.
444  

444  

445  
        @par Complexity
445  
        @par Complexity
446  
        Constant.
446  
        Constant.
447  

447  

448  
        @{
448  
        @{
449  
    */
449  
    */
450  
    BOOST_JSON_DECL
450  
    BOOST_JSON_DECL
451  
    system::result<value&>
451  
    system::result<value&>
452  
    try_at(std::size_t pos) noexcept;
452  
    try_at(std::size_t pos) noexcept;
453  

453  

454  
    BOOST_JSON_DECL
454  
    BOOST_JSON_DECL
455  
    system::result<value const&>
455  
    system::result<value const&>
456  
    try_at(std::size_t pos) const noexcept;
456  
    try_at(std::size_t pos) const noexcept;
457  
    /// @}
457  
    /// @}
458  

458  

459  
    /** Access an element, with bounds checking.
459  
    /** Access an element, with bounds checking.
460  

460  

461  
        Returns a reference to the element specified at location `pos`, with
461  
        Returns a reference to the element specified at location `pos`, with
462  
        bounds checking. If `pos` is not within the range of the container, an
462  
        bounds checking. If `pos` is not within the range of the container, an
463  
        exception of type @ref boost::system::system_error is thrown.
463  
        exception of type @ref boost::system::system_error is thrown.
464  

464  

465  
        @par Complexity
465  
        @par Complexity
466  
        Constant.
466  
        Constant.
467  

467  

468  
        @param pos A zero-based index.
468  
        @param pos A zero-based index.
469  

469  

470  
        @param loc `source_location` to use in thrown exception; the source
470  
        @param loc `source_location` to use in thrown exception; the source
471  
            location of the call site by default.
471  
            location of the call site by default.
472  

472  

473  
        @throw `boost::system::system_error` `pos >= size()`.
473  
        @throw `boost::system::system_error` `pos >= size()`.
474  

474  

475  
        @{
475  
        @{
476  
    */
476  
    */
477  
    inline
477  
    inline
478  
    value&
478  
    value&
479  
    at(
479  
    at(
480  
        std::size_t pos,
480  
        std::size_t pos,
481  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
481  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
482  

482  

483  
    inline
483  
    inline
484  
    value&&
484  
    value&&
485  
    at(
485  
    at(
486  
        std::size_t pos,
486  
        std::size_t pos,
487  
        source_location const& loc = BOOST_CURRENT_LOCATION) &&;
487  
        source_location const& loc = BOOST_CURRENT_LOCATION) &&;
488  

488  

489  
    BOOST_JSON_DECL
489  
    BOOST_JSON_DECL
490  
    value const&
490  
    value const&
491  
    at(
491  
    at(
492  
        std::size_t pos,
492  
        std::size_t pos,
493  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
493  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
494  
    /// @}
494  
    /// @}
495  

495  

496  
    /** Access an element.
496  
    /** Access an element.
497  

497  

498  
        Returns a reference to the element specified at
498  
        Returns a reference to the element specified at
499  
        location `pos`. No bounds checking is performed.
499  
        location `pos`. No bounds checking is performed.
500  

500  

501  
        @pre `pos < size()`
501  
        @pre `pos < size()`
502  

502  

503  
        @par Complexity
503  
        @par Complexity
504  
        Constant.
504  
        Constant.
505  

505  

506  
        @param pos A zero-based index
506  
        @param pos A zero-based index
507  

507  

508  
        @{
508  
        @{
509  
    */
509  
    */
510  
    inline
510  
    inline
511  
    value&
511  
    value&
512  
    operator[](std::size_t pos) & noexcept;
512  
    operator[](std::size_t pos) & noexcept;
513  

513  

514  
    inline
514  
    inline
515  
    value&&
515  
    value&&
516  
    operator[](std::size_t pos) && noexcept;
516  
    operator[](std::size_t pos) && noexcept;
517  

517  

518  
    inline
518  
    inline
519  
    value const&
519  
    value const&
520  
    operator[](std::size_t pos) const& noexcept;
520  
    operator[](std::size_t pos) const& noexcept;
521  
    /// @}
521  
    /// @}
522  

522  

523  
    /** Access the first element.
523  
    /** Access the first element.
524  

524  

525  
        Returns a reference to the first element.
525  
        Returns a reference to the first element.
526  

526  

527  
        @pre `! empty()`
527  
        @pre `! empty()`
528  

528  

529  
        @par Complexity
529  
        @par Complexity
530  
        Constant.
530  
        Constant.
531  

531  

532  
        @{
532  
        @{
533  
    */
533  
    */
534  
    inline
534  
    inline
535  
    value&
535  
    value&
536  
    front() & noexcept;
536  
    front() & noexcept;
537  

537  

538  
    inline
538  
    inline
539  
    value&&
539  
    value&&
540  
    front() && noexcept;
540  
    front() && noexcept;
541  

541  

542  
    inline
542  
    inline
543  
    value const&
543  
    value const&
544  
    front() const& noexcept;
544  
    front() const& noexcept;
545  
    /// @}
545  
    /// @}
546  

546  

547  
    /** Access the last element.
547  
    /** Access the last element.
548  

548  

549  
        Returns a reference to the last element.
549  
        Returns a reference to the last element.
550  

550  

551  
        @pre `!empty()`
551  
        @pre `!empty()`
552  

552  

553  
        @par Complexity
553  
        @par Complexity
554  
        Constant.
554  
        Constant.
555  

555  

556  
        @{
556  
        @{
557  
    */
557  
    */
558  
    inline
558  
    inline
559  
    value&
559  
    value&
560  
    back() & noexcept;
560  
    back() & noexcept;
561  

561  

562  
    inline
562  
    inline
563  
    value&&
563  
    value&&
564  
    back() && noexcept;
564  
    back() && noexcept;
565  

565  

566  
    inline
566  
    inline
567  
    value const&
567  
    value const&
568  
    back() const& noexcept;
568  
    back() const& noexcept;
569  
    /// @}
569  
    /// @}
570  

570  

571  
    /** Access the underlying array directly.
571  
    /** Access the underlying array directly.
572  

572  

573  
        Returns a pointer to the underlying array serving as element storage.
573  
        Returns a pointer to the underlying array serving as element storage.
574  
        The value returned is such that the range `[data(), data() + size())`
574  
        The value returned is such that the range `[data(), data() + size())`
575  
        is always a valid range, even if the container is empty.
575  
        is always a valid range, even if the container is empty.
576  

576  

577  
        @note
577  
        @note
578  
        If `size() == 0`, the function may or may not return
578  
        If `size() == 0`, the function may or may not return
579  
        a null pointer.
579  
        a null pointer.
580  

580  

581  
        @par Complexity
581  
        @par Complexity
582  
        Constant.
582  
        Constant.
583  

583  

584  
        @par Exception Safety
584  
        @par Exception Safety
585  
        No-throw guarantee.
585  
        No-throw guarantee.
586  

586  

587  
        @{
587  
        @{
588  
    */
588  
    */
589  
    inline
589  
    inline
590  
    value*
590  
    value*
591  
    data() noexcept;
591  
    data() noexcept;
592  

592  

593  
    inline
593  
    inline
594  
    value const*
594  
    value const*
595  
    data() const noexcept;
595  
    data() const noexcept;
596  
    /// @}
596  
    /// @}
597  

597  

598  
    /** Return a pointer to an element if it exists.
598  
    /** Return a pointer to an element if it exists.
599  

599  

600  
        This function returns a pointer to the element at index `pos` when the
600  
        This function returns a pointer to the element at index `pos` when the
601  
        index is less then the size of the container. Otherwise it returns
601  
        index is less then the size of the container. Otherwise it returns
602  
        null.
602  
        null.
603  

603  

604  
        @par Example
604  
        @par Example
605  
        @code
605  
        @code
606  
        if( auto p = arr.if_contains( 1 ) )
606  
        if( auto p = arr.if_contains( 1 ) )
607  
            std::cout << *p;
607  
            std::cout << *p;
608  
        @endcode
608  
        @endcode
609  

609  

610  
        @par Complexity
610  
        @par Complexity
611  
        Constant.
611  
        Constant.
612  

612  

613  
        @par Exception Safety
613  
        @par Exception Safety
614  
        No-throw guarantee.
614  
        No-throw guarantee.
615  

615  

616  
        @param pos The index of the element to return.
616  
        @param pos The index of the element to return.
617  

617  

618  
        @{
618  
        @{
619  
    */
619  
    */
620  
    inline
620  
    inline
621  
    value const*
621  
    value const*
622  
    if_contains(std::size_t pos) const noexcept;
622  
    if_contains(std::size_t pos) const noexcept;
623  

623  

624  
    inline
624  
    inline
625  
    value*
625  
    value*
626  
    if_contains(std::size_t pos) noexcept;
626  
    if_contains(std::size_t pos) noexcept;
627  
    /// @}
627  
    /// @}
628  

628  

629  
    //------------------------------------------------------
629  
    //------------------------------------------------------
630  
    //
630  
    //
631  
    // Iterators
631  
    // Iterators
632  
    //
632  
    //
633  
    //------------------------------------------------------
633  
    //------------------------------------------------------
634  

634  

635  
    /** Return an iterator to the first element.
635  
    /** Return an iterator to the first element.
636  

636  

637  
        If the container is empty, @ref end() is returned.
637  
        If the container is empty, @ref end() is returned.
638  

638  

639  
        @par Complexity
639  
        @par Complexity
640  
        Constant.
640  
        Constant.
641  

641  

642  
        @par Exception Safety
642  
        @par Exception Safety
643  
        No-throw guarantee.
643  
        No-throw guarantee.
644  

644  

645  
        @{
645  
        @{
646  
    */
646  
    */
647  
    inline
647  
    inline
648  
    iterator
648  
    iterator
649  
    begin() noexcept;
649  
    begin() noexcept;
650  

650  

651  
    inline
651  
    inline
652  
    const_iterator
652  
    const_iterator
653  
    begin() const noexcept;
653  
    begin() const noexcept;
654  
    /// @}
654  
    /// @}
655  

655  

656  
    /** Return a const iterator to the first element.
656  
    /** Return a const iterator to the first element.
657  

657  

658  
        If the container is empty, @ref cend() is returned.
658  
        If the container is empty, @ref cend() is returned.
659  

659  

660  
        @par Complexity
660  
        @par Complexity
661  
        Constant.
661  
        Constant.
662  

662  

663  
        @par Exception Safety
663  
        @par Exception Safety
664  
        No-throw guarantee.
664  
        No-throw guarantee.
665  
    */
665  
    */
666  
    inline
666  
    inline
667  
    const_iterator
667  
    const_iterator
668  
    cbegin() const noexcept;
668  
    cbegin() const noexcept;
669  

669  

670  
    /** Return a const iterator past the last element.
670  
    /** Return a const iterator past the last element.
671  

671  

672  
        The returned iterator only acts as a sentinel. Dereferencing it results
672  
        The returned iterator only acts as a sentinel. Dereferencing it results
673  
        in undefined behavior.
673  
        in undefined behavior.
674  

674  

675  
        @par Complexity
675  
        @par Complexity
676  
        Constant.
676  
        Constant.
677  

677  

678  
        @par Exception Safety
678  
        @par Exception Safety
679  
        No-throw guarantee.
679  
        No-throw guarantee.
680  

680  

681  
        @{
681  
        @{
682  
    */
682  
    */
683  
    inline
683  
    inline
684  
    iterator
684  
    iterator
685  
    end() noexcept;
685  
    end() noexcept;
686  

686  

687  
    inline
687  
    inline
688  
    const_iterator
688  
    const_iterator
689  
    end() const noexcept;
689  
    end() const noexcept;
690  
    /// @}
690  
    /// @}
691  

691  

692  
    /** Return a const iterator past the last element.
692  
    /** Return a const iterator past the last element.
693  

693  

694  
        The returned iterator only acts as a sentinel. Dereferencing it results
694  
        The returned iterator only acts as a sentinel. Dereferencing it results
695  
        in undefined behavior.
695  
        in undefined behavior.
696  

696  

697  
        @par Complexity
697  
        @par Complexity
698  
        Constant.
698  
        Constant.
699  

699  

700  
        @par Exception Safety
700  
        @par Exception Safety
701  
        No-throw guarantee.
701  
        No-throw guarantee.
702  
    */
702  
    */
703  
    inline
703  
    inline
704  
    const_iterator
704  
    const_iterator
705  
    cend() const noexcept;
705  
    cend() const noexcept;
706  

706  

707  
    /** Return a reverse iterator to the first element of the reversed container.
707  
    /** Return a reverse iterator to the first element of the reversed container.
708  

708  

709  
        The pointed-to element corresponds to the
709  
        The pointed-to element corresponds to the
710  
        last element of the non-reversed container.
710  
        last element of the non-reversed container.
711  
        If the container is empty, @ref rend() is returned.
711  
        If the container is empty, @ref rend() is returned.
712  

712  

713  
        @par Complexity
713  
        @par Complexity
714  
        Constant.
714  
        Constant.
715  

715  

716  
        @par Exception Safety
716  
        @par Exception Safety
717  
        No-throw guarantee.
717  
        No-throw guarantee.
718  

718  

719  
        @{
719  
        @{
720  
    */
720  
    */
721  
    inline
721  
    inline
722  
    reverse_iterator
722  
    reverse_iterator
723  
    rbegin() noexcept;
723  
    rbegin() noexcept;
724  

724  

725  
    inline
725  
    inline
726  
    const_reverse_iterator
726  
    const_reverse_iterator
727  
    rbegin() const noexcept;
727  
    rbegin() const noexcept;
728  
    /// @}
728  
    /// @}
729  

729  

730  
    /** Return a const reverse iterator to the first element of the reversed container.
730  
    /** Return a const reverse iterator to the first element of the reversed container.
731  

731  

732  
        The pointed-to element corresponds to the
732  
        The pointed-to element corresponds to the
733  
        last element of the non-reversed container.
733  
        last element of the non-reversed container.
734  
        If the container is empty, @ref crend() is returned.
734  
        If the container is empty, @ref crend() is returned.
735  

735  

736  
        @par Complexity
736  
        @par Complexity
737  
        Constant.
737  
        Constant.
738  

738  

739  
        @par Exception Safety
739  
        @par Exception Safety
740  
        No-throw guarantee.
740  
        No-throw guarantee.
741  
    */
741  
    */
742  
    inline
742  
    inline
743  
    const_reverse_iterator
743  
    const_reverse_iterator
744  
    crbegin() const noexcept;
744  
    crbegin() const noexcept;
745  

745  

746  
    /** Return a reverse iterator to the element following the last element of the reversed container.
746  
    /** Return a reverse iterator to the element following the last element of the reversed container.
747  

747  

748  
        The pointed-to element corresponds to the element
748  
        The pointed-to element corresponds to the element
749  
        preceding the first element of the non-reversed container.
749  
        preceding the first element of the non-reversed container.
750  
        The returned iterator only acts as a sentinel. Dereferencing it results
750  
        The returned iterator only acts as a sentinel. Dereferencing it results
751  
        in undefined behavior.
751  
        in undefined behavior.
752  

752  

753  
        @par Complexity
753  
        @par Complexity
754  
        Constant.
754  
        Constant.
755  

755  

756  
        @par Exception Safety
756  
        @par Exception Safety
757  
        No-throw guarantee.
757  
        No-throw guarantee.
758  

758  

759  
        @{
759  
        @{
760  
    */
760  
    */
761  
    inline
761  
    inline
762  
    reverse_iterator
762  
    reverse_iterator
763  
    rend() noexcept;
763  
    rend() noexcept;
764  

764  

765  
    inline
765  
    inline
766  
    const_reverse_iterator
766  
    const_reverse_iterator
767  
    rend() const noexcept;
767  
    rend() const noexcept;
768  
    /// @}
768  
    /// @}
769  

769  

770  
    /** Return a const reverse iterator to the element following the last element of the reversed container.
770  
    /** Return a const reverse iterator to the element following the last element of the reversed container.
771  

771  

772  
        The pointed-to element corresponds to the element preceding the first
772  
        The pointed-to element corresponds to the element preceding the first
773  
        element of the non-reversed container. The returned iterator only acts
773  
        element of the non-reversed container. The returned iterator only acts
774  
        as a sentinel. Dereferencing it results in undefined behavior.
774  
        as a sentinel. Dereferencing it results in undefined behavior.
775  

775  

776  
        @par Complexity
776  
        @par Complexity
777  
        Constant.
777  
        Constant.
778  

778  

779  
        @par Exception Safety
779  
        @par Exception Safety
780  
        No-throw guarantee.
780  
        No-throw guarantee.
781  
    */
781  
    */
782  
    inline
782  
    inline
783  
    const_reverse_iterator
783  
    const_reverse_iterator
784  
    crend() const noexcept;
784  
    crend() const noexcept;
785  

785  

786  
    //------------------------------------------------------
786  
    //------------------------------------------------------
787  
    //
787  
    //
788  
    // Capacity
788  
    // Capacity
789  
    //
789  
    //
790  
    //------------------------------------------------------
790  
    //------------------------------------------------------
791  

791  

792  
    /** Return the number of elements in the array.
792  
    /** Return the number of elements in the array.
793  

793  

794  
        This returns the number of elements in the array.
794  
        This returns the number of elements in the array.
795  
        The value returned may be different from the number
795  
        The value returned may be different from the number
796  
        returned from @ref capacity.
796  
        returned from @ref capacity.
797  

797  

798  
        @par Complexity
798  
        @par Complexity
799  
        Constant.
799  
        Constant.
800  

800  

801  
        @par Exception Safety
801  
        @par Exception Safety
802  
        No-throw guarantee.
802  
        No-throw guarantee.
803  
    */
803  
    */
804  
    inline
804  
    inline
805  
    std::size_t
805  
    std::size_t
806  
    size() const noexcept;
806  
    size() const noexcept;
807  

807  

808  
    /** The maximum number of elements an array can hold.
808  
    /** The maximum number of elements an array can hold.
809  

809  

810  
        The maximum is an implementation-defined number. This value is
810  
        The maximum is an implementation-defined number. This value is
811  
        a theoretical limit; at runtime, the actual maximum size may be less
811  
        a theoretical limit; at runtime, the actual maximum size may be less
812  
        due to resource limits.
812  
        due to resource limits.
813  

813  

814  
        @par Complexity
814  
        @par Complexity
815  
        Constant.
815  
        Constant.
816  

816  

817  
        @par Exception Safety
817  
        @par Exception Safety
818  
        No-throw guarantee.
818  
        No-throw guarantee.
819  
    */
819  
    */
820  
    static
820  
    static
821  
    inline
821  
    inline
822  
    constexpr
822  
    constexpr
823  
    std::size_t
823  
    std::size_t
824  
    max_size() noexcept;
824  
    max_size() noexcept;
825  

825  

826  
    /** Return the number of elements that can be held in currently allocated memory.
826  
    /** Return the number of elements that can be held in currently allocated memory.
827  

827  

828  
        Returns the number of elements that the container has currently
828  
        Returns the number of elements that the container has currently
829  
        allocated space for. This number is never smaller than the value
829  
        allocated space for. This number is never smaller than the value
830  
        returned by @ref size().
830  
        returned by @ref size().
831  

831  

832  
        @par Complexity
832  
        @par Complexity
833  
        Constant.
833  
        Constant.
834  

834  

835  
        @par Exception Safety
835  
        @par Exception Safety
836  
        No-throw guarantee.
836  
        No-throw guarantee.
837  
    */
837  
    */
838  
    inline
838  
    inline
839  
    std::size_t
839  
    std::size_t
840  
    capacity() const noexcept;
840  
    capacity() const noexcept;
841  

841  

842  
    /** Check if the array has no elements.
842  
    /** Check if the array has no elements.
843  

843  

844  
        Returns `true` if there are no elements in the
844  
        Returns `true` if there are no elements in the
845  
        array, i.e. @ref size() returns 0.
845  
        array, i.e. @ref size() returns 0.
846  

846  

847  
        @par Complexity
847  
        @par Complexity
848  
        Constant.
848  
        Constant.
849  

849  

850  
        @par Exception Safety
850  
        @par Exception Safety
851  
        No-throw guarantee.
851  
        No-throw guarantee.
852  
    */
852  
    */
853  
    inline
853  
    inline
854  
    bool
854  
    bool
855  
    empty() const noexcept;
855  
    empty() const noexcept;
856  

856  

857  
    /** Increase the capacity to at least a certain amount.
857  
    /** Increase the capacity to at least a certain amount.
858  

858  

859  
        This increases the @ref capacity() to a value that is greater than or
859  
        This increases the @ref capacity() to a value that is greater than or
860  
        equal to `new_capacity`. If `new_capacity > capacity()`, new memory is
860  
        equal to `new_capacity`. If `new_capacity > capacity()`, new memory is
861  
        allocated. Otherwise, the call has no effect. The number of elements
861  
        allocated. Otherwise, the call has no effect. The number of elements
862  
        and therefore the @ref size() of the container is not changed.
862  
        and therefore the @ref size() of the container is not changed.
863  

863  

864  
        If new memory is allocated, all iterators including any past-the-end
864  
        If new memory is allocated, all iterators including any past-the-end
865  
        iterators, and all references to the elements are invalidated.
865  
        iterators, and all references to the elements are invalidated.
866  
        Otherwise, no iterators or references are invalidated.
866  
        Otherwise, no iterators or references are invalidated.
867  

867  

868  
        @par Complexity
868  
        @par Complexity
869  
        At most, linear in @ref size().
869  
        At most, linear in @ref size().
870  

870  

871  
        @par Exception Safety
871  
        @par Exception Safety
872  
        Strong guarantee.
872  
        Strong guarantee.
873  
        Calls to `memory_resource::allocate` may throw.
873  
        Calls to `memory_resource::allocate` may throw.
874  

874  

875  
        @param new_capacity The new capacity of the array.
875  
        @param new_capacity The new capacity of the array.
876  

876  

877  
        @throw boost::system::system_error `new_capacity >` @ref max_size().
877  
        @throw boost::system::system_error `new_capacity >` @ref max_size().
878  
    */
878  
    */
879  
    inline
879  
    inline
880  
    void
880  
    void
881  
    reserve(std::size_t new_capacity);
881  
    reserve(std::size_t new_capacity);
882  

882  

883  
    /** Request the removal of unused capacity.
883  
    /** Request the removal of unused capacity.
884  

884  

885  
        This performs a non-binding request to reduce the
885  
        This performs a non-binding request to reduce the
886  
        capacity to the current size. The request may or
886  
        capacity to the current size. The request may or
887  
        may not be fulfilled. If reallocation occurs, all
887  
        may not be fulfilled. If reallocation occurs, all
888  
        iterators including any past-the-end iterators,
888  
        iterators including any past-the-end iterators,
889  
        and all references to the elements are invalidated.
889  
        and all references to the elements are invalidated.
890  
        Otherwise, no iterators or references are
890  
        Otherwise, no iterators or references are
891  
        invalidated.
891  
        invalidated.
892  

892  

893  
        @par Complexity
893  
        @par Complexity
894  
        At most, linear in @ref size().
894  
        At most, linear in @ref size().
895  

895  

896  
        @par Exception Safety
896  
        @par Exception Safety
897  
        No-throw guarantee.
897  
        No-throw guarantee.
898  
    */
898  
    */
899  
    BOOST_JSON_DECL
899  
    BOOST_JSON_DECL
900  
    void
900  
    void
901  
    shrink_to_fit() noexcept;
901  
    shrink_to_fit() noexcept;
902  

902  

903  
    //------------------------------------------------------
903  
    //------------------------------------------------------
904  
    //
904  
    //
905  
    // Modifiers
905  
    // Modifiers
906  
    //
906  
    //
907  
    //------------------------------------------------------
907  
    //------------------------------------------------------
908  

908  

909  
    /** Clear the contents.
909  
    /** Clear the contents.
910  

910  

911  
        Erases all elements from the container. After this call, @ref size()
911  
        Erases all elements from the container. After this call, @ref size()
912  
        returns zero but @ref capacity() is unchanged. All references,
912  
        returns zero but @ref capacity() is unchanged. All references,
913  
        pointers, and iterators are invalidated
913  
        pointers, and iterators are invalidated
914  

914  

915  
        @par Complexity
915  
        @par Complexity
916  
        Linear in @ref size().
916  
        Linear in @ref size().
917  

917  

918  
        @par Exception Safety
918  
        @par Exception Safety
919  
        No-throw guarantee.
919  
        No-throw guarantee.
920  
    */
920  
    */
921  
    BOOST_JSON_DECL
921  
    BOOST_JSON_DECL
922  
    void
922  
    void
923  
    clear() noexcept;
923  
    clear() noexcept;
924  

924  

925  
    /** Insert elements before the specified location.
925  
    /** Insert elements before the specified location.
926  

926  

927  
        @li **(1)** and **(2)** insert a single new element before
927  
        @li **(1)** and **(2)** insert a single new element before
928  
            `pos`. **(1)** copy-constructs and **(2)** move-constructs the new
928  
            `pos`. **(1)** copy-constructs and **(2)** move-constructs the new
929  
            element from `jv`.
929  
            element from `jv`.
930  
        @li **(3)** inserts `count` copies of `jv` before `pos`.
930  
        @li **(3)** inserts `count` copies of `jv` before `pos`.
931  
        @li **(4)** the elements in the range `[first, last)` are inserted in
931  
        @li **(4)** the elements in the range `[first, last)` are inserted in
932  
            order.
932  
            order.
933  
        @li **(5)** the elements of the initializer list `init` are inserted in
933  
        @li **(5)** the elements of the initializer list `init` are inserted in
934  
            order.
934  
            order.
935  

935  

936  
        Inserted values will be constructed using the container's
936  
        Inserted values will be constructed using the container's
937  
        associated @ref boost::container::pmr::memory_resource.
937  
        associated @ref boost::container::pmr::memory_resource.
938  

938  

939  
        @note Overload **(2)** is equivalent to **(1)** if
939  
        @note Overload **(2)** is equivalent to **(1)** if
940  
        `*jv.storage() != *this->storage()`.
940  
        `*jv.storage() != *this->storage()`.
941  

941  

942  
        If the size of the array after insertion would have exceeded
942  
        If the size of the array after insertion would have exceeded
943  
        @ref capacity(), a reallocation occurs first, and all iterators and
943  
        @ref capacity(), a reallocation occurs first, and all iterators and
944  
        references are invalidated. Otherwise, only the iterators and
944  
        references are invalidated. Otherwise, only the iterators and
945  
        references from the insertion point forward are invalidated. All
945  
        references from the insertion point forward are invalidated. All
946  
        past-the-end iterators are also invalidated.
946  
        past-the-end iterators are also invalidated.
947  

947  

948  
        @pre
948  
        @pre
949  
        `first` and `last` are not iterators into `*this`.
949  
        `first` and `last` are not iterators into `*this`.
950  

950  

951  
        @par Constraints
951  
        @par Constraints
952  
        @code
952  
        @code
953  
        ! std::is_convertible_v<InputIt, value>
953  
        ! std::is_convertible_v<InputIt, value>
954  
        std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
954  
        std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
955  
        @endcode
955  
        @endcode
956  

956  

957  
        @par Complexity
957  
        @par Complexity
958  
        @li **(1)**, **(2)** linear in `std::distance(pos, end())`.
958  
        @li **(1)**, **(2)** linear in `std::distance(pos, end())`.
959  
        @li **(3)** linear in `count + std::distance(pos, end())`.
959  
        @li **(3)** linear in `count + std::distance(pos, end())`.
960  
        @li **(4)** linear in `std::distance(first, last) +
960  
        @li **(4)** linear in `std::distance(first, last) +
961  
            std::distance(pos, end())`.
961  
            std::distance(pos, end())`.
962  
        @li **(5)** linear in `init.size() + std::distance(pos, end())`.
962  
        @li **(5)** linear in `init.size() + std::distance(pos, end())`.
963  

963  

964  
        @par Exception Safety
964  
        @par Exception Safety
965  
        {sp}**(4)** provides strong guarantee if `InputIt` satisfies
965  
        {sp}**(4)** provides strong guarantee if `InputIt` satisfies
966  
        {req_ForwardIterator}, and basic guarantee otherwise. Other overloads
966  
        {req_ForwardIterator}, and basic guarantee otherwise. Other overloads
967  
        provide strong guarantee.
967  
        provide strong guarantee.
968  
        Calls to `memory_resource::allocate` may throw.
968  
        Calls to `memory_resource::allocate` may throw.
969  

969  

970  
        @param pos Iterator before which the new elements will
970  
        @param pos Iterator before which the new elements will
971  
        be inserted. This may be the @ref end() iterator.
971  
        be inserted. This may be the @ref end() iterator.
972  

972  

973  
        @param jv The value to insert. A copy will be made
973  
        @param jv The value to insert. A copy will be made
974  
        using container's associated
974  
        using container's associated
975  
        @ref boost::container::pmr::memory_resource.
975  
        @ref boost::container::pmr::memory_resource.
976  

976  

977  
        @return An iterator to the first inserted value, or `pos` if no values
977  
        @return An iterator to the first inserted value, or `pos` if no values
978  
                were inserted.
978  
                were inserted.
979  

979  

980  
        @{
980  
        @{
981  
    */
981  
    */
982  
    BOOST_JSON_DECL
982  
    BOOST_JSON_DECL
983  
    iterator
983  
    iterator
984  
    insert(
984  
    insert(
985  
        const_iterator pos,
985  
        const_iterator pos,
986  
        value const& jv);
986  
        value const& jv);
987  

987  

988  
    // Overload
988  
    // Overload
989  
    BOOST_JSON_DECL
989  
    BOOST_JSON_DECL
990  
    iterator
990  
    iterator
991  
    insert(
991  
    insert(
992  
        const_iterator pos,
992  
        const_iterator pos,
993  
        value&& jv);
993  
        value&& jv);
994  

994  

995  

995  

996  
    /** Overload
996  
    /** Overload
997  
        @param count The number of copies to insert.
997  
        @param count The number of copies to insert.
998  
        @param pos
998  
        @param pos
999  
        @param jv
999  
        @param jv
1000  
    */
1000  
    */
1001  
    BOOST_JSON_DECL
1001  
    BOOST_JSON_DECL
1002  
    iterator
1002  
    iterator
1003  
    insert(
1003  
    insert(
1004  
        const_iterator pos,
1004  
        const_iterator pos,
1005  
        std::size_t count,
1005  
        std::size_t count,
1006  
        value const& jv);
1006  
        value const& jv);
1007  

1007  

1008  
    /** Overload
1008  
    /** Overload
1009  

1009  

1010  
        @param first An input iterator pointing to the first element to insert,
1010  
        @param first An input iterator pointing to the first element to insert,
1011  
               or pointing to the end of the range.
1011  
               or pointing to the end of the range.
1012  
        @param last An input iterator pointing to the end of the range.
1012  
        @param last An input iterator pointing to the end of the range.
1013  
        @param pos
1013  
        @param pos
1014  

1014  

1015  
        @tparam InputIt a type satisfying the requirements
1015  
        @tparam InputIt a type satisfying the requirements
1016  
        of {req_InputIterator}.
1016  
        of {req_InputIterator}.
1017  
    */
1017  
    */
1018  
    template<
1018  
    template<
1019  
        class InputIt
1019  
        class InputIt
1020  
    #ifndef BOOST_JSON_DOCS
1020  
    #ifndef BOOST_JSON_DOCS
1021  
        ,class = typename std::enable_if<
1021  
        ,class = typename std::enable_if<
1022  
            std::is_constructible<value,
1022  
            std::is_constructible<value,
1023  
                typename std::iterator_traits<
1023  
                typename std::iterator_traits<
1024  
                    InputIt>::reference>::value>::type
1024  
                    InputIt>::reference>::value>::type
1025  
    #endif
1025  
    #endif
1026  
    >
1026  
    >
1027  
    iterator
1027  
    iterator
1028  
    insert(
1028  
    insert(
1029  
        const_iterator pos,
1029  
        const_iterator pos,
1030  
        InputIt first, InputIt last);
1030  
        InputIt first, InputIt last);
1031  

1031  

1032  
    /** Overload
1032  
    /** Overload
1033  
        @param init The initializer list to insert
1033  
        @param init The initializer list to insert
1034  
        @param pos
1034  
        @param pos
1035  
    */
1035  
    */
1036  
    BOOST_JSON_DECL
1036  
    BOOST_JSON_DECL
1037  
    iterator
1037  
    iterator
1038  
    insert(
1038  
    insert(
1039  
        const_iterator pos,
1039  
        const_iterator pos,
1040  
        std::initializer_list<value_ref> init);
1040  
        std::initializer_list<value_ref> init);
1041  
    /// @}
1041  
    /// @}
1042  

1042  

1043  
    /** Insert a constructed element in-place.
1043  
    /** Insert a constructed element in-place.
1044  

1044  

1045  
        Inserts a new element into the container directly before
1045  
        Inserts a new element into the container directly before
1046  
        `pos`. The element is constructed using placement-new
1046  
        `pos`. The element is constructed using placement-new
1047  
        with the parameter `std::forward<Arg>(arg)`.
1047  
        with the parameter `std::forward<Arg>(arg)`.
1048  
        If `capacity() < size() + 1`,
1048  
        If `capacity() < size() + 1`,
1049  
        a reallocation occurs first, and all iterators and
1049  
        a reallocation occurs first, and all iterators and
1050  
        references are invalidated.
1050  
        references are invalidated.
1051  
        Otherwise, only the iterators and references from
1051  
        Otherwise, only the iterators and references from
1052  
        the insertion point forward are invalidated. All
1052  
        the insertion point forward are invalidated. All
1053  
        past-the-end iterators are also invalidated.
1053  
        past-the-end iterators are also invalidated.
1054  

1054  

1055  
        @par Complexity
1055  
        @par Complexity
1056  
        Linear in `std::distance(pos, end())`.
1056  
        Linear in `std::distance(pos, end())`.
1057  

1057  

1058  
        @par Exception Safety
1058  
        @par Exception Safety
1059  
        Strong guarantee.
1059  
        Strong guarantee.
1060  
        Calls to `memory_resource::allocate` may throw.
1060  
        Calls to `memory_resource::allocate` may throw.
1061  

1061  

1062  
        @param pos Iterator before which the element will
1062  
        @param pos Iterator before which the element will
1063  
        be inserted. This may be the @ref end() iterator.
1063  
        be inserted. This may be the @ref end() iterator.
1064  

1064  

1065  
        @param arg The argument to forward to the @ref value
1065  
        @param arg The argument to forward to the @ref value
1066  
        constructor.
1066  
        constructor.
1067  

1067  

1068  
        @return An iterator to the inserted element
1068  
        @return An iterator to the inserted element
1069  
    */
1069  
    */
1070  
    template<class Arg>
1070  
    template<class Arg>
1071  
    iterator
1071  
    iterator
1072  
    emplace(
1072  
    emplace(
1073  
        const_iterator pos,
1073  
        const_iterator pos,
1074  
        Arg&& arg);
1074  
        Arg&& arg);
1075  

1075  

1076  
    /** Remove elements from the array.
1076  
    /** Remove elements from the array.
1077  

1077  

1078  
        @li **(1)** the element at `pos` is removed.
1078  
        @li **(1)** the element at `pos` is removed.
1079  
        @li **(2)** the elements in the range `[first, last)` are removed.
1079  
        @li **(2)** the elements in the range `[first, last)` are removed.
1080  

1080  

1081  
        @par Complexity
1081  
        @par Complexity
1082  
        @li **(1)** linear in `std::distance(pos, end())`.
1082  
        @li **(1)** linear in `std::distance(pos, end())`.
1083  
        @li **(2)** linear in `std::distance(first, end())`.
1083  
        @li **(2)** linear in `std::distance(first, end())`.
1084  

1084  

1085  
        @par Exception Safety
1085  
        @par Exception Safety
1086  
        No-throw guarantee.
1086  
        No-throw guarantee.
1087  

1087  

1088  
        @param pos Iterator to the element to remove
1088  
        @param pos Iterator to the element to remove
1089  

1089  

1090  
        @return Iterator following the last removed element. If that was the
1090  
        @return Iterator following the last removed element. If that was the
1091  
                last element of the array, the @ref end() iterator is returned.
1091  
                last element of the array, the @ref end() iterator is returned.
1092  

1092  

1093  
        @{
1093  
        @{
1094  
    */
1094  
    */
1095  
    BOOST_JSON_DECL
1095  
    BOOST_JSON_DECL
1096  
    iterator
1096  
    iterator
1097  
    erase(const_iterator pos) noexcept;
1097  
    erase(const_iterator pos) noexcept;
1098  

1098  

1099  
    /** Overload
1099  
    /** Overload
1100  
        @param first An iterator pointing to the first element to erase, or
1100  
        @param first An iterator pointing to the first element to erase, or
1101  
               pointing to the end of the range.
1101  
               pointing to the end of the range.
1102  
        @param last An iterator pointing to one past the last element to erase,
1102  
        @param last An iterator pointing to one past the last element to erase,
1103  
                    or pointing to the end of the range.
1103  
                    or pointing to the end of the range.
1104  
    */
1104  
    */
1105  
    BOOST_JSON_DECL
1105  
    BOOST_JSON_DECL
1106  
    iterator
1106  
    iterator
1107  
    erase(
1107  
    erase(
1108  
        const_iterator first,
1108  
        const_iterator first,
1109  
        const_iterator last) noexcept;
1109  
        const_iterator last) noexcept;
1110  
    /// @}
1110  
    /// @}
1111  

1111  

1112  
    /** Add an element to the end.
1112  
    /** Add an element to the end.
1113  

1113  

1114  
        Insert a new element at the end of the container. **(1)**
1114  
        Insert a new element at the end of the container. **(1)**
1115  
        copy-constructs the new element from `jv`, **(2)** move-constructs from
1115  
        copy-constructs the new element from `jv`, **(2)** move-constructs from
1116  
        `jv`.
1116  
        `jv`.
1117  

1117  

1118  
        If `capacity() < size() + 1`, a reallocation occurs first, and all
1118  
        If `capacity() < size() + 1`, a reallocation occurs first, and all
1119  
        iterators and references are invalidated. Any past-the-end iterators
1119  
        iterators and references are invalidated. Any past-the-end iterators
1120  
        are always invalidated.
1120  
        are always invalidated.
1121  

1121  

1122  
        The new element will be constructed using the container's associated
1122  
        The new element will be constructed using the container's associated
1123  
        @ref boost::container::pmr::memory_resource.
1123  
        @ref boost::container::pmr::memory_resource.
1124  

1124  

1125  
        @par Complexity
1125  
        @par Complexity
1126  
        Amortized constant.
1126  
        Amortized constant.
1127  

1127  

1128  
        @par Exception Safety
1128  
        @par Exception Safety
1129  
        Strong guarantee.
1129  
        Strong guarantee.
1130  
        Calls to `memory_resource::allocate` may throw.
1130  
        Calls to `memory_resource::allocate` may throw.
1131  

1131  

1132  
        @param jv The value to insert.
1132  
        @param jv The value to insert.
1133  

1133  

1134  
        @{
1134  
        @{
1135  
    */
1135  
    */
1136  
    BOOST_JSON_DECL
1136  
    BOOST_JSON_DECL
1137  
    void
1137  
    void
1138  
    push_back(value const& jv);
1138  
    push_back(value const& jv);
1139  

1139  

1140  
    BOOST_JSON_DECL
1140  
    BOOST_JSON_DECL
1141  
    void
1141  
    void
1142  
    push_back(value&& jv);
1142  
    push_back(value&& jv);
1143  
    /// @}
1143  
    /// @}
1144  

1144  

1145  
    /** Append a constructed element in-place.
1145  
    /** Append a constructed element in-place.
1146  

1146  

1147  
        Appends a new element to the end of the container's
1147  
        Appends a new element to the end of the container's
1148  
        list of elements.
1148  
        list of elements.
1149  
        The element is constructed using placement-new
1149  
        The element is constructed using placement-new
1150  
        with the parameter `std::forward<Arg>(arg)`.
1150  
        with the parameter `std::forward<Arg>(arg)`.
1151  
        If `capacity() < size() + 1`,
1151  
        If `capacity() < size() + 1`,
1152  
        a reallocation occurs first, and all iterators and
1152  
        a reallocation occurs first, and all iterators and
1153  
        references are invalidated.
1153  
        references are invalidated.
1154  
        Otherwise, only the iterators and references from
1154  
        Otherwise, only the iterators and references from
1155  
        the insertion point forward are invalidated. All
1155  
        the insertion point forward are invalidated. All
1156  
        past-the-end iterators are also invalidated.
1156  
        past-the-end iterators are also invalidated.
1157  

1157  

1158  
        @par Complexity
1158  
        @par Complexity
1159  
        Amortized constant.
1159  
        Amortized constant.
1160  

1160  

1161  
        @par Exception Safety
1161  
        @par Exception Safety
1162  
        Strong guarantee.
1162  
        Strong guarantee.
1163  
        Calls to `memory_resource::allocate` may throw.
1163  
        Calls to `memory_resource::allocate` may throw.
1164  

1164  

1165  
        @param arg The argument to forward to the @ref value
1165  
        @param arg The argument to forward to the @ref value
1166  
        constructor.
1166  
        constructor.
1167  

1167  

1168  
        @return A reference to the inserted element
1168  
        @return A reference to the inserted element
1169  
    */
1169  
    */
1170  
    template<class Arg>
1170  
    template<class Arg>
1171  
    value&
1171  
    value&
1172  
    emplace_back(Arg&& arg);
1172  
    emplace_back(Arg&& arg);
1173  

1173  

1174  
    /** Remove the last element
1174  
    /** Remove the last element
1175  

1175  

1176  
        The last element of the container is erased.
1176  
        The last element of the container is erased.
1177  

1177  

1178  
        @pre
1178  
        @pre
1179  
        `! empty()`
1179  
        `! empty()`
1180  

1180  

1181  
        @par Exception Safety
1181  
        @par Exception Safety
1182  
        No-throw guarantee.
1182  
        No-throw guarantee.
1183  
    */
1183  
    */
1184  
    BOOST_JSON_DECL
1184  
    BOOST_JSON_DECL
1185  
    void
1185  
    void
1186  
    pop_back() noexcept;
1186  
    pop_back() noexcept;
1187  

1187  

1188  
    /** Change the number of elements stored.
1188  
    /** Change the number of elements stored.
1189  

1189  

1190  
        Resizes the container to contain `count` elements.
1190  
        Resizes the container to contain `count` elements.
1191  

1191  

1192  
        @li If `size() > count`, the container is reduced to its first `count`
1192  
        @li If `size() > count`, the container is reduced to its first `count`
1193  
            elements.
1193  
            elements.
1194  
        @li If `size() < count`, additional null values (**(1)**) or copies
1194  
        @li If `size() < count`, additional null values (**(1)**) or copies
1195  
            of `jv` (**(2)**) are appended.
1195  
            of `jv` (**(2)**) are appended.
1196  

1196  

1197  
        If `capacity() < count`, a reallocation occurs first, and all iterators
1197  
        If `capacity() < count`, a reallocation occurs first, and all iterators
1198  
        and references are invalidated. Any past-the-end iterators are always
1198  
        and references are invalidated. Any past-the-end iterators are always
1199  
        invalidated.
1199  
        invalidated.
1200  

1200  

1201  
        @par Complexity
1201  
        @par Complexity
1202  
        Linear in `size() + count`.
1202  
        Linear in `size() + count`.
1203  

1203  

1204  
        @par Exception Safety
1204  
        @par Exception Safety
1205  
        Strong guarantee.
1205  
        Strong guarantee.
1206  
        Calls to `memory_resource::allocate` may throw.
1206  
        Calls to `memory_resource::allocate` may throw.
1207  

1207  

1208  
        @param count The new size of the container.
1208  
        @param count The new size of the container.
1209  

1209  

1210  
        @{
1210  
        @{
1211  
    */
1211  
    */
1212  
    BOOST_JSON_DECL
1212  
    BOOST_JSON_DECL
1213  
    void
1213  
    void
1214  
    resize(std::size_t count);
1214  
    resize(std::size_t count);
1215  

1215  

1216  
    /** Overload
1216  
    /** Overload
1217  
        @param jv The @ref value to copy into the new elements.
1217  
        @param jv The @ref value to copy into the new elements.
1218  
        @param count
1218  
        @param count
1219  
    */
1219  
    */
1220  
    BOOST_JSON_DECL
1220  
    BOOST_JSON_DECL
1221  
    void
1221  
    void
1222  
    resize(
1222  
    resize(
1223  
        std::size_t count,
1223  
        std::size_t count,
1224  
        value const& jv);
1224  
        value const& jv);
1225  
    /// @}
1225  
    /// @}
1226  

1226  

1227  
    /** Swap two arrays.
1227  
    /** Swap two arrays.
1228  

1228  

1229  
        Exchanges the contents of this array with another array. Ownership of
1229  
        Exchanges the contents of this array with another array. Ownership of
1230  
        the respective @ref boost::container::pmr::memory_resource objects is
1230  
        the respective @ref boost::container::pmr::memory_resource objects is
1231  
        not transferred. If `this == &other`, this function call has no effect.
1231  
        not transferred. If `this == &other`, this function call has no effect.
1232  

1232  

1233  
        @li If `*storage() == *other.storage()` all iterators and references
1233  
        @li If `*storage() == *other.storage()` all iterators and references
1234  
        remain valid.
1234  
        remain valid.
1235  

1235  

1236  
        @li Otherwise, the contents are logically swapped by making copies,
1236  
        @li Otherwise, the contents are logically swapped by making copies,
1237  
        which can throw. In this case all iterators and references are
1237  
        which can throw. In this case all iterators and references are
1238  
        invalidated.
1238  
        invalidated.
1239  

1239  

1240  
        @par Complexity
1240  
        @par Complexity
1241  
        If `*storage() == *other.storage()`, then constant; otherwise linear in
1241  
        If `*storage() == *other.storage()`, then constant; otherwise linear in
1242  
        `size() + other.size()`.
1242  
        `size() + other.size()`.
1243  

1243  

1244  
        @par Exception Safety
1244  
        @par Exception Safety
1245  
        No-throw guarantee if `*storage() == *other.storage()`. Otherwise
1245  
        No-throw guarantee if `*storage() == *other.storage()`. Otherwise
1246  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
1246  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
1247  

1247  

1248  
        @param other The value to swap with.
1248  
        @param other The value to swap with.
1249  
    */
1249  
    */
1250  
    BOOST_JSON_DECL
1250  
    BOOST_JSON_DECL
1251  
    void
1251  
    void
1252  
    swap(array& other);
1252  
    swap(array& other);
1253  

1253  

1254  
    /** Swap two arrays.
1254  
    /** Swap two arrays.
1255  

1255  

1256  
        Exchanges the contents of the array `lhs` with another array `rhs`.
1256  
        Exchanges the contents of the array `lhs` with another array `rhs`.
1257  
        Ownership of the respective @ref boost::container::pmr::memory_resource
1257  
        Ownership of the respective @ref boost::container::pmr::memory_resource
1258  
        objects is not transferred. If `&lhs == &rhs`, this function call has
1258  
        objects is not transferred. If `&lhs == &rhs`, this function call has
1259  
        no effect.
1259  
        no effect.
1260  

1260  

1261  
        @li If `*lhs.storage() == *rhs.storage()` all iterators and references
1261  
        @li If `*lhs.storage() == *rhs.storage()` all iterators and references
1262  
        remain valid.
1262  
        remain valid.
1263  

1263  

1264  
        @li Otherwise, the contents are logically swapped by making copies,
1264  
        @li Otherwise, the contents are logically swapped by making copies,
1265  
        which can throw. In this case all iterators and references are
1265  
        which can throw. In this case all iterators and references are
1266  
        invalidated.
1266  
        invalidated.
1267  

1267  

1268  
        @par Complexity
1268  
        @par Complexity
1269  
        If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear
1269  
        If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear
1270  
        in `lhs.size() + rhs.size()`.
1270  
        in `lhs.size() + rhs.size()`.
1271  

1271  

1272  
        @par Exception Safety
1272  
        @par Exception Safety
1273  
        No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise
1273  
        No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise
1274  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
1274  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
1275  

1275  

1276  
        @param lhs The array to exchange.
1276  
        @param lhs The array to exchange.
1277  

1277  

1278  
        @param rhs The array to exchange.
1278  
        @param rhs The array to exchange.
1279  
        If `&lhs == &rhs`, this function call has no effect.
1279  
        If `&lhs == &rhs`, this function call has no effect.
1280  

1280  

1281  
        @see @ref array::swap
1281  
        @see @ref array::swap
1282  
    */
1282  
    */
1283  
    friend
1283  
    friend
1284  
    void
1284  
    void
1285  
    swap(array& lhs, array& rhs)
1285  
    swap(array& lhs, array& rhs)
1286  
    {
1286  
    {
1287  
        lhs.swap(rhs);
1287  
        lhs.swap(rhs);
1288  
    }
1288  
    }
1289  

1289  

1290  
    /** Compare two arrays for equality.
1290  
    /** Compare two arrays for equality.
1291  

1291  

1292  
        Arrays are equal when their sizes are the same, and they are
1292  
        Arrays are equal when their sizes are the same, and they are
1293  
        element-for-element equal in order.
1293  
        element-for-element equal in order.
1294  

1294  

1295  
        @par Complexity
1295  
        @par Complexity
1296  
        Linear in `lhs.size()`.
1296  
        Linear in `lhs.size()`.
1297  

1297  

1298  
        @par Exception Safety
1298  
        @par Exception Safety
1299  
        No-throw guarantee.
1299  
        No-throw guarantee.
1300  
    */
1300  
    */
1301  
    // inline friend speeds up overload resolution
1301  
    // inline friend speeds up overload resolution
1302  
    friend
1302  
    friend
1303  
    bool
1303  
    bool
1304  
    operator==(
1304  
    operator==(
1305  
        array const& lhs,
1305  
        array const& lhs,
1306  
        array const& rhs) noexcept
1306  
        array const& rhs) noexcept
1307  
    {
1307  
    {
1308  
        return lhs.equal(rhs);
1308  
        return lhs.equal(rhs);
1309  
    }
1309  
    }
1310  

1310  

1311  
    /** Compare two arrays for inequality.
1311  
    /** Compare two arrays for inequality.
1312  

1312  

1313  
        Arrays are equal when their sizes are the same, and they are
1313  
        Arrays are equal when their sizes are the same, and they are
1314  
        element-for-element equal in order.
1314  
        element-for-element equal in order.
1315  

1315  

1316  
        @par Complexity
1316  
        @par Complexity
1317  
        Linear in `lhs.size()`.
1317  
        Linear in `lhs.size()`.
1318  

1318  

1319  
        @par Exception Safety
1319  
        @par Exception Safety
1320  
        No-throw guarantee.
1320  
        No-throw guarantee.
1321  
    */
1321  
    */
1322  
    // inline friend speeds up overload resolution
1322  
    // inline friend speeds up overload resolution
1323  
    friend
1323  
    friend
1324  
    bool
1324  
    bool
1325  
    operator!=(
1325  
    operator!=(
1326  
        array const& lhs,
1326  
        array const& lhs,
1327  
        array const& rhs) noexcept
1327  
        array const& rhs) noexcept
1328  
    {
1328  
    {
1329  
        return ! (lhs == rhs);
1329  
        return ! (lhs == rhs);
1330  
    }
1330  
    }
1331  

1331  

1332  
    /** Serialize to an output stream.
1332  
    /** Serialize to an output stream.
1333  

1333  

1334  
        This function serializes an `array` as JSON into the output stream.
1334  
        This function serializes an `array` as JSON into the output stream.
1335  

1335  

1336  
        @return Reference to `os`.
1336  
        @return Reference to `os`.
1337  

1337  

1338  
        @par Complexity
1338  
        @par Complexity
1339  
        Constant or linear in the size of `arr`.
1339  
        Constant or linear in the size of `arr`.
1340  

1340  

1341  
        @par Exception Safety
1341  
        @par Exception Safety
1342  
        Strong guarantee.
1342  
        Strong guarantee.
1343  
        Calls to `memory_resource::allocate` may throw.
1343  
        Calls to `memory_resource::allocate` may throw.
1344  

1344  

1345  
        @param os The output stream to serialize to.
1345  
        @param os The output stream to serialize to.
1346  

1346  

1347  
        @param arr The value to serialize.
1347  
        @param arr The value to serialize.
1348  
    */
1348  
    */
1349  
    BOOST_JSON_DECL
1349  
    BOOST_JSON_DECL
1350  
    friend
1350  
    friend
1351  
    std::ostream&
1351  
    std::ostream&
1352  
    operator<<(
1352  
    operator<<(
1353  
        std::ostream& os,
1353  
        std::ostream& os,
1354  
        array const& arr);
1354  
        array const& arr);
1355  

1355  

1356  
private:
1356  
private:
1357  
    template<class It>
1357  
    template<class It>
1358  
    using iter_cat = typename
1358  
    using iter_cat = typename
1359  
        std::iterator_traits<It>::iterator_category;
1359  
        std::iterator_traits<It>::iterator_category;
1360  

1360  

1361  
    template<class InputIt>
1361  
    template<class InputIt>
1362  
    array(
1362  
    array(
1363  
        InputIt first, InputIt last,
1363  
        InputIt first, InputIt last,
1364  
        storage_ptr sp,
1364  
        storage_ptr sp,
1365  
        std::input_iterator_tag);
1365  
        std::input_iterator_tag);
1366  

1366  

1367  
    template<class InputIt>
1367  
    template<class InputIt>
1368  
    array(
1368  
    array(
1369  
        InputIt first, InputIt last,
1369  
        InputIt first, InputIt last,
1370  
        storage_ptr sp,
1370  
        storage_ptr sp,
1371  
        std::forward_iterator_tag);
1371  
        std::forward_iterator_tag);
1372  

1372  

1373  
    inline
1373  
    inline
1374  
    std::size_t
1374  
    std::size_t
1375  
    growth(std::size_t new_size) const;
1375  
    growth(std::size_t new_size) const;
1376  

1376  

1377  
    BOOST_JSON_DECL
1377  
    BOOST_JSON_DECL
1378  
    void
1378  
    void
1379  
    reserve_impl(
1379  
    reserve_impl(
1380  
        std::size_t new_capacity);
1380  
        std::size_t new_capacity);
1381  

1381  

1382  
    BOOST_JSON_DECL
1382  
    BOOST_JSON_DECL
1383  
    value&
1383  
    value&
1384  
    push_back(
1384  
    push_back(
1385  
        pilfered<value> pv);
1385  
        pilfered<value> pv);
1386  

1386  

1387  
    BOOST_JSON_DECL
1387  
    BOOST_JSON_DECL
1388  
    iterator
1388  
    iterator
1389  
    insert(
1389  
    insert(
1390  
        const_iterator pos,
1390  
        const_iterator pos,
1391  
        pilfered<value> pv);
1391  
        pilfered<value> pv);
1392  

1392  

1393  
    template<class InputIt>
1393  
    template<class InputIt>
1394  
    iterator
1394  
    iterator
1395  
    insert(
1395  
    insert(
1396  
        const_iterator pos,
1396  
        const_iterator pos,
1397  
        InputIt first, InputIt last,
1397  
        InputIt first, InputIt last,
1398  
        std::input_iterator_tag);
1398  
        std::input_iterator_tag);
1399  

1399  

1400  
    template<class InputIt>
1400  
    template<class InputIt>
1401  
    iterator
1401  
    iterator
1402  
    insert(
1402  
    insert(
1403  
        const_iterator pos,
1403  
        const_iterator pos,
1404  
        InputIt first, InputIt last,
1404  
        InputIt first, InputIt last,
1405  
        std::forward_iterator_tag);
1405  
        std::forward_iterator_tag);
1406  

1406  

1407  
    BOOST_JSON_DECL
1407  
    BOOST_JSON_DECL
1408  
    bool
1408  
    bool
1409  
    equal(array const& other) const noexcept;
1409  
    equal(array const& other) const noexcept;
1410  
};
1410  
};
1411  

1411  

1412  
} // namespace json
1412  
} // namespace json
1413  
} // namespace boost
1413  
} // namespace boost
1414  

1414  

1415  
// std::hash specialization
1415  
// std::hash specialization
1416  
#ifndef BOOST_JSON_DOCS
1416  
#ifndef BOOST_JSON_DOCS
1417  
namespace std {
1417  
namespace std {
1418  
template <>
1418  
template <>
1419  
struct hash< ::boost::json::array > {
1419  
struct hash< ::boost::json::array > {
1420  
    BOOST_JSON_DECL
1420  
    BOOST_JSON_DECL
1421  
    std::size_t
1421  
    std::size_t
1422  
    operator()(::boost::json::array const& ja) const noexcept;
1422  
    operator()(::boost::json::array const& ja) const noexcept;
1423  
};
1423  
};
1424  
} // std
1424  
} // std
1425  
#endif
1425  
#endif
1426  

1426  

1427  
// Must be included here for this file to stand alone
1427  
// Must be included here for this file to stand alone
1428  
#include <boost/json/value.hpp>
1428  
#include <boost/json/value.hpp>
1429  

1429  

1430  
// includes are at the bottom of <boost/json/value.hpp>
1430  
// includes are at the bottom of <boost/json/value.hpp>
1431  

1431  

1432  
#endif
1432  
#endif