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  
    */
242  
    array() noexcept
243  
    array() noexcept
243  
        : t_(&empty_)
244  
        : t_(&empty_)
244  
    {
245  
    {
245  
    }
246  
    }
246  

247  

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

260  

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

271  

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

277  

277  
    /** Overload
278  
    /** Overload
278  

279  

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

284  

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

299  

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

308  

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

314  

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

320  

320  
    /// Overload
321  
    /// Overload
 
322 +
    array(pilfered<array> other) noexcept
 
323 +
        : sp_(std::move(other.get().sp_))
 
324 +
        , t_(detail::exchange(
 
325 +
            other.get().t_, &empty_))
 
326 +
    {
 
327 +
    }
 
328 +

 
329 +
    /// Overload
321  
    array(array&& other) noexcept
330  
    array(array&& other) noexcept
322  
        : sp_(other.sp_)
331  
        : sp_(other.sp_)
323  
        , t_(detail::exchange(
332  
        , t_(detail::exchange(
324  
            other.t_, &empty_))
333  
            other.t_, &empty_))
325  
    {
334  
    {
326  
    }
335  
    }
327  

336  

328  
    /// Overload
337  
    /// Overload
329  
    BOOST_JSON_DECL
338  
    BOOST_JSON_DECL
330  
    array(
339  
    array(
331  
        array&& other,
340  
        array&& other,
332 -

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

343  

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

345  

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

353  

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

356  

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

362  

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

368  

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

370  

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

372  

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

378  

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

385  

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

394  

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

396  

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

399  

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

402  

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

411  

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

413  

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

416  

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

419  

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

428  

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

434  

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

436  

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

440  

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

443  

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

445  

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

448  

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

454  

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

459  

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

461  

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

465  

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

468  

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

470  

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

473  

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

475  

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

483  

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

489  

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

496  

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

498  

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

501  

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

503  

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

506  

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

508  

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

514  

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

518  

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

523  

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

525  

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

527  

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

529  

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

532  

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

538  

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

542  

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

547  

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

549  

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

551  

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

553  

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

556  

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

562  

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

566  

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

571  

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

573  

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

577  

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

581  

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

584  

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

587  

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

593  

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

598  

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

600  

600  
        This function returns a pointer to the element at index `pos` when the
601  
        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
602  
        index is less then the size of the container. Otherwise it returns
602  
        null.
603  
        null.
603  

604  

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

610  

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

613  

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

616  

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

618  

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

624  

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

629  

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

635  

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

637  

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

639  

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

642  

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

645  

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

651  

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

656  

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

658  

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

660  

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

663  

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

670  

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

672  

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

675  

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

678  

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

681  

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

687  

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

692  

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

694  

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

697  

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

700  

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

707  

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

709  

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

713  

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

716  

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

719  

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

725  

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

730  

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

732  

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

736  

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

739  

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

746  

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

748  

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

753  

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

756  

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

759  

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

765  

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

770  

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

772  

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

776  

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

779  

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

786  

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

792  

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

794  

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

798  

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

801  

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

808  

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

810  

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

814  

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

817  

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

826  

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

828  

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

832  

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

835  

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

842  

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

844  

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

847  

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

850  

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

857  

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

859  

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

864  

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

868  

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

871  

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

875  

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

877  

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

883  

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

885  

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

893  

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

896  

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

903  

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

909  

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

911  

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

915  

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

918  

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

925  

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

927  

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

936  

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

939  

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

942  

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

948  

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

951  

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

957  

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

964  

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

970  

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

973  

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

977  

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

980  

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

988  

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

995  

995  

996  

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

1008  

1008  
    /** Overload
1009  
    /** Overload
1009  

1010  

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

1015  

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

1032  

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

1043  

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

1045  

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

1055  

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

1058  

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

1062  

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

1065  

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

1068  

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

1076  

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

1078  

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

1081  

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

1085  

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

1088  

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

1090  

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

1093  

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

1099  

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

1112  

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

1114  

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

1118  

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

1122  

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

1125  

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

1128  

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

1132  

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

1134  

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

1140  

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

1145  

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

1147  

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

1158  

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

1161  

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

1165  

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

1168  

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

1174  

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

1176  

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

1178  

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

1181  

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

1188  

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

1190  

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

1192  

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

1197  

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

1201  

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

1204  

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

1208  

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

1210  

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

1216  

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

1227  

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

1229  

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

1233  

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

1236  

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

1240  

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

1244  

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

1248  

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

1254  

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

1256  

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

1261  

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

1264  

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

1268  

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

1272  

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

1276  

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

1278  

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

1281  

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

1290  

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

1292  

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

1295  

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

1298  

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

1311  

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

1313  

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

1316  

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

1319  

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

1332  

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

1334  

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

1336  

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

1338  

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

1341  

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

1345  

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

1347  

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

1356  

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

1361  

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

1367  

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

1373  

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

1377  

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

1382  

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

1387  

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

1393  

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

1400  

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

1407  

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

1412  

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

1415  

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

1427  

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

1430  

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

1432  

1432  
#endif
1433  
#endif