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_OBJECT_HPP
10  
#ifndef BOOST_JSON_OBJECT_HPP
11  
#define BOOST_JSON_OBJECT_HPP
11  
#define BOOST_JSON_OBJECT_HPP
12  

12  

13  
#include <boost/json/detail/config.hpp>
13  
#include <boost/json/detail/config.hpp>
14  
#include <boost/json/detail/object.hpp>
14  
#include <boost/json/detail/object.hpp>
15  
#include <boost/json/detail/value.hpp>
15  
#include <boost/json/detail/value.hpp>
16  
#include <boost/json/kind.hpp>
16  
#include <boost/json/kind.hpp>
17  
#include <boost/json/pilfer.hpp>
17  
#include <boost/json/pilfer.hpp>
18  
#include <boost/system/result.hpp>
18  
#include <boost/system/result.hpp>
19  
#include <boost/json/storage_ptr.hpp>
19  
#include <boost/json/storage_ptr.hpp>
20  
#include <boost/json/string_view.hpp>
20  
#include <boost/json/string_view.hpp>
21  
#include <cstdlib>
21  
#include <cstdlib>
22  
#include <initializer_list>
22  
#include <initializer_list>
23  
#include <iterator>
23  
#include <iterator>
24  
#include <type_traits>
24  
#include <type_traits>
25  
#include <utility>
25  
#include <utility>
26  

26  

27  
namespace boost {
27  
namespace boost {
28  
namespace json {
28  
namespace json {
29  

29  

30  
class value;
30  
class value;
31  
class value_ref;
31  
class value_ref;
32  
class key_value_pair;
32  
class key_value_pair;
33  

33  

34  
/** A dynamically sized associative container of JSON key/value pairs.
34  
/** A dynamically sized associative container of JSON key/value pairs.
35  

35  

36  
    This is an associative container whose elements are key/value pairs with
36  
    This is an associative container whose elements are key/value pairs with
37  
    unique keys.
37  
    unique keys.
38  

38  

39  
    The elements are stored contiguously; iterators are ordinary pointers,
39  
    The elements are stored contiguously; iterators are ordinary pointers,
40  
    allowing random access pointer arithmetic for retrieving elements. In
40  
    allowing random access pointer arithmetic for retrieving elements. In
41  
    addition, the container maintains an internal index to speed up find
41  
    addition, the container maintains an internal index to speed up find
42  
    operations, reducing the average complexity for most lookups and
42  
    operations, reducing the average complexity for most lookups and
43  
    insertions.
43  
    insertions.
44  

44  

45  
    Reallocations are usually costly operations in terms of performance, as
45  
    Reallocations are usually costly operations in terms of performance, as
46  
    elements are copied and the internal index must be rebuilt. The @ref
46  
    elements are copied and the internal index must be rebuilt. The @ref
47  
    reserve function can be used to eliminate reallocations if the number of
47  
    reserve function can be used to eliminate reallocations if the number of
48  
    elements is known beforehand.
48  
    elements is known beforehand.
49  

49  

50  
    @par Allocators
50  
    @par Allocators
51  
    All elements stored in the container, and their children if any, will use
51  
    All elements stored in the container, and their children if any, will use
52  
    the same memory resource that was used to construct the container.
52  
    the same memory resource that was used to construct the container.
53  

53  

54  
    @par Thread Safety
54  
    @par Thread Safety
55  
    Non-const member functions may not be called concurrently with any other
55  
    Non-const member functions may not be called concurrently with any other
56  
    member functions.
56  
    member functions.
57  

57  

58  
    @par Satisfies
58  
    @par Satisfies
59  
        [ContiguousContainer](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
59  
        [ContiguousContainer](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
60  
        [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and
60  
        [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and
61  
        {req_SequenceContainer}.
61  
        {req_SequenceContainer}.
62  
*/
62  
*/
63  
class object
63  
class object
64  
{
64  
{
65  
    struct table;
65  
    struct table;
66  
    class revert_construct;
66  
    class revert_construct;
67  
    class revert_insert;
67  
    class revert_insert;
68  
    friend class value;
68  
    friend class value;
69  
    friend class object_test;
69  
    friend class object_test;
70  
    using access = detail::access;
70  
    using access = detail::access;
71  
    using index_t = std::uint32_t;
71  
    using index_t = std::uint32_t;
72  
    static index_t constexpr null_index_ =
72  
    static index_t constexpr null_index_ =
73  
        std::uint32_t(-1);
73  
        std::uint32_t(-1);
74  

74  

75  
    storage_ptr sp_;            // must come first
75  
    storage_ptr sp_;            // must come first
76  
    kind k_ = kind::object;     // must come second
76  
    kind k_ = kind::object;     // must come second
77  
    table* t_;
77  
    table* t_;
78  

78  

79  
    BOOST_JSON_DECL
79  
    BOOST_JSON_DECL
80  
    static table empty_;
80  
    static table empty_;
81  

81  

82  
    template<class T>
82  
    template<class T>
83  
    using is_inputit = typename std::enable_if<
83  
    using is_inputit = typename std::enable_if<
84  
        std::is_constructible<key_value_pair,
84  
        std::is_constructible<key_value_pair,
85  
        typename std::iterator_traits<T>::reference
85  
        typename std::iterator_traits<T>::reference
86  
            >::value>::type;
86  
            >::value>::type;
87  

87  

88  
    BOOST_JSON_DECL
88  
    BOOST_JSON_DECL
89  
    explicit
89  
    explicit
90  
    object(detail::unchecked_object&& uo);
90  
    object(detail::unchecked_object&& uo);
91  

91  

92  
public:
92  
public:
93  
    /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
93  
    /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
94  
    using allocator_type = container::pmr::polymorphic_allocator<value>;
94  
    using allocator_type = container::pmr::polymorphic_allocator<value>;
95  

95  

96  
    /** The type of keys.
96  
    /** The type of keys.
97  

97  

98  
        The function @ref string::max_size returns the
98  
        The function @ref string::max_size returns the
99  
        maximum allowed size of strings used as keys.
99  
        maximum allowed size of strings used as keys.
100  
    */
100  
    */
101  
    using key_type = string_view;
101  
    using key_type = string_view;
102  

102  

103  
    /// The type of mapped values
103  
    /// The type of mapped values
104  
    using mapped_type = value;
104  
    using mapped_type = value;
105  

105  

106  
    /// The element type
106  
    /// The element type
107  
    using value_type = key_value_pair;
107  
    using value_type = key_value_pair;
108  

108  

109  
    /// The type used to represent unsigned integers
109  
    /// The type used to represent unsigned integers
110  
    using size_type = std::size_t;
110  
    using size_type = std::size_t;
111  

111  

112  
    /// The type used to represent signed integers
112  
    /// The type used to represent signed integers
113  
    using difference_type = std::ptrdiff_t;
113  
    using difference_type = std::ptrdiff_t;
114  

114  

115  
    /// A reference to an element
115  
    /// A reference to an element
116  
    using reference = value_type&;
116  
    using reference = value_type&;
117  

117  

118  
    /// A const reference to an element
118  
    /// A const reference to an element
119  
    using const_reference = value_type const&;
119  
    using const_reference = value_type const&;
120  

120  

121  
    /// A pointer to an element
121  
    /// A pointer to an element
122  
    using pointer = value_type*;
122  
    using pointer = value_type*;
123  

123  

124  
    /// A const pointer to an element
124  
    /// A const pointer to an element
125  
    using const_pointer = value_type const*;
125  
    using const_pointer = value_type const*;
126  

126  

127  
    /// A random access iterator to an element
127  
    /// A random access iterator to an element
128  
    using iterator = value_type*;
128  
    using iterator = value_type*;
129  

129  

130  
    /// A const random access iterator to an element
130  
    /// A const random access iterator to an element
131  
    using const_iterator = value_type const*;
131  
    using const_iterator = value_type const*;
132  

132  

133  
    /// A reverse random access iterator to an element
133  
    /// A reverse random access iterator to an element
134  
    using reverse_iterator =
134  
    using reverse_iterator =
135  
        std::reverse_iterator<iterator>;
135  
        std::reverse_iterator<iterator>;
136  

136  

137  
    /// A const reverse random access iterator to an element
137  
    /// A const reverse random access iterator to an element
138  
    using const_reverse_iterator =
138  
    using const_reverse_iterator =
139  
        std::reverse_iterator<const_iterator>;
139  
        std::reverse_iterator<const_iterator>;
140  

140  

141  
    //------------------------------------------------------
141  
    //------------------------------------------------------
142  

142  

143  
    /** Destructor.
143  
    /** Destructor.
144  

144  

145  
        The destructor for each element is called if needed, any used memory is
145  
        The destructor for each element is called if needed, any used memory is
146  
        deallocated, and shared ownership of the
146  
        deallocated, and shared ownership of the
147  
        @ref boost::container::pmr::memory_resource is released.
147  
        @ref boost::container::pmr::memory_resource is released.
148  

148  

149  
        @par Complexity
149  
        @par Complexity
150  
        Constant, or linear in @ref size().
150  
        Constant, or linear in @ref size().
151  

151  

152  
        @par Exception Safety
152  
        @par Exception Safety
153  
        No-throw guarantee.
153  
        No-throw guarantee.
154  
    */
154  
    */
155  
    BOOST_JSON_DECL
155  
    BOOST_JSON_DECL
156  
    ~object() noexcept;
156  
    ~object() noexcept;
157  

157  

158  
    //------------------------------------------------------
158  
    //------------------------------------------------------
159  

159  

160  
    /** Constructors.
160  
    /** Constructors.
161  

161  

162  
        Constructs an object.
162  
        Constructs an object.
163  

163  

164  
        @li **(1)**--**(3)** the object is empty.
164  
        @li **(1)**--**(3)** the object is empty.
165  

165  

166  
        @li **(4)** the object is filled with values in the range
166  
        @li **(4)** the object is filled with values in the range
167  
            `[first, last)`.
167  
            `[first, last)`.
168  

168  

169  
        @li **(5)**, **(6)** the object is filled with copies of the values in
169  
        @li **(5)**, **(6)** the object is filled with copies of the values in
170  
            `init`.
170  
            `init`.
171  

171  

172  
        @li **(7)**, **(8)** the object is filled with copies of the elements
172  
        @li **(7)**, **(8)** the object is filled with copies of the elements
173  
            of `other`.
173  
            of `other`.
174  

174  

175  
        @li **(9)** the object acquires ownership of the contents of `other`.
175  
        @li **(9)** the object acquires ownership of the contents of `other`.
176  

176  

177  
        @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`;
177  
        @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`;
178  
            otherwise equivalent to **(8)**.
178  
            otherwise equivalent to **(8)**.
179  

179  

180  
        @li **(11)** the object acquires ownership of the contents of `other`
180  
        @li **(11)** the object acquires ownership of the contents of `other`
181  
            using pilfer semantics. This is more efficient than move
181  
            using pilfer semantics. This is more efficient than move
182  
            construction, when it is known that the moved-from object will be
182  
            construction, when it is known that the moved-from object will be
183  
            immediately destroyed afterwards.
183  
            immediately destroyed afterwards.
184  

184  

185  
        Upon construction, @ref capacity() will be large enough to store the
185  
        Upon construction, @ref capacity() will be large enough to store the
186  
        object's elements. In addition, with **(3)**, **(4)**, and **(6)** the
186  
        object's elements. In addition, with **(3)**, **(4)**, and **(6)** the
187  
        capacity will not be smaller than `min_capacity`.
187  
        capacity will not be smaller than `min_capacity`.
188  

188  

189  
        With **(2)**--**(6)**, **(8)**, **(10)** the constructed object uses
189  
        With **(2)**--**(6)**, **(8)**, **(10)** the constructed object uses
190  
        memory resource of `sp`. With **(7)**, **(9)**, **(11)** it uses
190  
        memory resource of `sp`. With **(7)**, **(9)**, **(11)** it uses
191  
        `other`'s memory resource. In either case the object will share the
191  
        `other`'s memory resource. In either case the object will share the
192  
        ownership of the memory resource. With **(1)** it uses the
192  
        ownership of the memory resource. With **(1)** it uses the
193  
        \<\<default_memory_resource,default memory resource\>\>.
193  
        \<\<default_memory_resource,default memory resource\>\>.
194  

194  

195  
        After **(9)** `other` behaves as if newly constructed with its current
195  
        After **(9)** `other` behaves as if newly constructed with its current
196  
        storage pointer.
196  
        storage pointer.
197  

197  

198  
        After **(11)** `other` is not in a usable state and may only be
198  
        After **(11)** `other` is not in a usable state and may only be
199  
        destroyed.
199  
        destroyed.
200  

200  

201  
        If `init` or `[first, last)` have elements with duplicate keys, only
201  
        If `init` or `[first, last)` have elements with duplicate keys, only
202  
        the first of those equivalent elements will be inserted.
202  
        the first of those equivalent elements will be inserted.
203  

203  

204  
        @par Constraints
204  
        @par Constraints
205  
        @code
205  
        @code
206  
        std::is_constructible_v<
206  
        std::is_constructible_v<
207  
            key_value_pair,
207  
            key_value_pair,
208  
            std::iterator_traits<InputIt>::reference>
208  
            std::iterator_traits<InputIt>::reference>
209  
        @endcode
209  
        @endcode
210  

210  

211  
        @par Complexity
211  
        @par Complexity
212  
        @li **(1)**--**(3)**, **(9)**, **(11)** constant.
212  
        @li **(1)**--**(3)**, **(9)**, **(11)** constant.
213  
        @li **(4)** linear in `std::distance(first, last)`.
213  
        @li **(4)** linear in `std::distance(first, last)`.
214  
        @li **(5)**, **(6)** linear in `init.size()`.
214  
        @li **(5)**, **(6)** linear in `init.size()`.
215  
        @li **(7)**, **(8)** linear in `other.size()`.
215  
        @li **(7)**, **(8)** linear in `other.size()`.
216  
        @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in
216  
        @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in
217  
            `other.size()`.
217  
            `other.size()`.
218  

218  

219  
        @par Exception Safety
219  
        @par Exception Safety
220  
        @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee.
220  
        @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee.
221  
        @li **(3)**, **(5)**, **(6)**--**(8)**, **(10)** strong guarantee.
221  
        @li **(3)**, **(5)**, **(6)**--**(8)**, **(10)** strong guarantee.
222  
        @li **(4)** strong guarantee if `InputIt` satisfies
222  
        @li **(4)** strong guarantee if `InputIt` satisfies
223  
            {req_ForwardIterator}, basic guarantee otherwise.
223  
            {req_ForwardIterator}, basic guarantee otherwise.
224  

224  

225  
        Calls to `memory_resource::allocate` may throw.
225  
        Calls to `memory_resource::allocate` may throw.
226  

226  

227  
        @see @ref pilfer,
227  
        @see @ref pilfer,
228  
             [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
228  
             [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
229  

229  

230  
        @{
230  
        @{
231  
    */
231  
    */
232  
    object() noexcept
232  
    object() noexcept
233  
        : t_(&empty_)
233  
        : t_(&empty_)
234  
    {
234  
    {
235  
    }
235  
    }
236  

236  

237  
    /** Overload
237  
    /** Overload
238  

238  

239  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
239  
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
240  
               to use.
240  
               to use.
241  
    */
241  
    */
242  
    explicit
242  
    explicit
243  
    object(storage_ptr sp) noexcept
243  
    object(storage_ptr sp) noexcept
244  
        : sp_(std::move(sp))
244  
        : sp_(std::move(sp))
245  
        , t_(&empty_)
245  
        , t_(&empty_)
246  
    {
246  
    {
247  
    }
247  
    }
248  

248  

249  
    /** Overload
249  
    /** Overload
250  

250  

251  
        @param min_capacity The minimum number of elements for which capacity
251  
        @param min_capacity The minimum number of elements for which capacity
252  
               is guaranteed without a subsequent reallocation.
252  
               is guaranteed without a subsequent reallocation.
253  
        @param sp
253  
        @param sp
254  
    */
254  
    */
255  
    BOOST_JSON_DECL
255  
    BOOST_JSON_DECL
256  
    object(
256  
    object(
257  
        std::size_t min_capacity,
257  
        std::size_t min_capacity,
258  
        storage_ptr sp = {});
258  
        storage_ptr sp = {});
259  

259  

260  
    /** Overload
260  
    /** Overload
261  

261  

262  
        @param first An input iterator pointing to the first element to insert,
262  
        @param first An input iterator pointing to the first element to insert,
263  
               or pointing to the end of the range.
263  
               or pointing to the end of the range.
264  
        @param last An input iterator pointing to the end of the range.
264  
        @param last An input iterator pointing to the end of the range.
265  
        @param min_capacity
265  
        @param min_capacity
266  
        @param sp
266  
        @param sp
267  

267  

268  
        @tparam InputIt a type satisfying the requirements of
268  
        @tparam InputIt a type satisfying the requirements of
269  
                {req_InputIterator}.
269  
                {req_InputIterator}.
270  
    */
270  
    */
271  
    template<
271  
    template<
272  
        class InputIt
272  
        class InputIt
273  
    #ifndef BOOST_JSON_DOCS
273  
    #ifndef BOOST_JSON_DOCS
274  
        ,class = is_inputit<InputIt>
274  
        ,class = is_inputit<InputIt>
275  
    #endif
275  
    #endif
276  
    >
276  
    >
277  
    object(
277  
    object(
278  
        InputIt first,
278  
        InputIt first,
279  
        InputIt last,
279  
        InputIt last,
280  
        std::size_t min_capacity = 0,
280  
        std::size_t min_capacity = 0,
281  
        storage_ptr sp = {})
281  
        storage_ptr sp = {})
282  
        : sp_(std::move(sp))
282  
        : sp_(std::move(sp))
283  
        , t_(&empty_)
283  
        , t_(&empty_)
284  
    {
284  
    {
285  
        construct(
285  
        construct(
286  
            first, last,
286  
            first, last,
287  
            min_capacity,
287  
            min_capacity,
288  
            typename std::iterator_traits<
288  
            typename std::iterator_traits<
289  
                InputIt>::iterator_category{});
289  
                InputIt>::iterator_category{});
290  
    }
290  
    }
291  

291  

292  
    /** Overload
292  
    /** Overload
293  

293  

294  
        @param init The initializer list to insert.
294  
        @param init The initializer list to insert.
295  
        @param sp
295  
        @param sp
296  
    */
296  
    */
297  
    object(
297  
    object(
298  
        std::initializer_list<
298  
        std::initializer_list<
299  
            std::pair<string_view, value_ref>> init,
299  
            std::pair<string_view, value_ref>> init,
300  
        storage_ptr sp = {})
300  
        storage_ptr sp = {})
301  
        : object(init, 0, std::move(sp))
301  
        : object(init, 0, std::move(sp))
302  
    {
302  
    {
303  
    }
303  
    }
304  

304  

305  
    /** Overload
305  
    /** Overload
306  

306  

307  
        @param init
307  
        @param init
308  
        @param min_capacity
308  
        @param min_capacity
309  
        @param sp
309  
        @param sp
310  
    */
310  
    */
311  
    BOOST_JSON_DECL
311  
    BOOST_JSON_DECL
312  
    object(
312  
    object(
313  
        std::initializer_list<
313  
        std::initializer_list<
314  
            std::pair<string_view, value_ref>> init,
314  
            std::pair<string_view, value_ref>> init,
315  
        std::size_t min_capacity,
315  
        std::size_t min_capacity,
316  
        storage_ptr sp = {});
316  
        storage_ptr sp = {});
317  

317  

318  
    /** Overload
318  
    /** Overload
319  

319  

320  
        @param other Another object.
320  
        @param other Another object.
321  
    */
321  
    */
322  
    object(
322  
    object(
323  
        object const& other)
323  
        object const& other)
324  
        : object(other, other.sp_)
324  
        : object(other, other.sp_)
325  
    {
325  
    {
326  
    }
326  
    }
327  

327  

328  
    /** Overload
328  
    /** Overload
329  

329  

330  
        @param other
330  
        @param other
331  
        @param sp
331  
        @param sp
332  
    */
332  
    */
333  
    BOOST_JSON_DECL
333  
    BOOST_JSON_DECL
334  
    object(
334  
    object(
335  
        object const& other,
335  
        object const& other,
336  
        storage_ptr sp);
336  
        storage_ptr sp);
337  

337  

338  
    /** Overload
338  
    /** Overload
339  

339  

340  
        @param other
340  
        @param other
341  
    */
341  
    */
342  
    BOOST_JSON_DECL
342  
    BOOST_JSON_DECL
343  
    object(object&& other) noexcept;
343  
    object(object&& other) noexcept;
344  

344  

345  
    /** Overload
345  
    /** Overload
346  

346  

347  
        @param other
347  
        @param other
348  
        @param sp
348  
        @param sp
349  
    */
349  
    */
350  
    BOOST_JSON_DECL
350  
    BOOST_JSON_DECL
351  
    object(
351  
    object(
352  
        object&& other,
352  
        object&& other,
353  
        storage_ptr sp);
353  
        storage_ptr sp);
354  

354  

355  
    /** Overload
355  
    /** Overload
356  

356  

357  
        @param other
357  
        @param other
358  
    */
358  
    */
359  
    object(pilfered<object> other) noexcept
359  
    object(pilfered<object> other) noexcept
360  
        : sp_(std::move(other.get().sp_))
360  
        : sp_(std::move(other.get().sp_))
361  
        , t_(detail::exchange(
361  
        , t_(detail::exchange(
362  
            other.get().t_, &empty_))
362  
            other.get().t_, &empty_))
363  
    {
363  
    {
364  
    }
364  
    }
365  
    /// @}
365  
    /// @}
366  

366  

367  
    //------------------------------------------------------
367  
    //------------------------------------------------------
368  
    //
368  
    //
369  
    // Assignment
369  
    // Assignment
370  
    //
370  
    //
371  
    //------------------------------------------------------
371  
    //------------------------------------------------------
372  

372  

373  
    /** Assignment operators.
373  
    /** Assignment operators.
374  

374  

375  
        Replaces the contents of this object.
375  
        Replaces the contents of this object.
376  

376  

377  
        @li **(1)** replaces with the copies of the elements of `other`.
377  
        @li **(1)** replaces with the copies of the elements of `other`.
378  
        @li **(2)** takes ownership of `other`'s element storage if
378  
        @li **(2)** takes ownership of `other`'s element storage if
379  
            `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
379  
            `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
380  
        @li **(3)** replaces with the elements of `init`.
380  
        @li **(3)** replaces with the elements of `init`.
381  

381  

382  
        @par Complexity
382  
        @par Complexity
383  
        @li **(1)** linear in `size() + other.size()`.
383  
        @li **(1)** linear in `size() + other.size()`.
384  
        @li **(2)** constant if `*storage() == *other.storage()`; otherwise
384  
        @li **(2)** constant if `*storage() == *other.storage()`; otherwise
385  
            linear in `size() + other.size()`.
385  
            linear in `size() + other.size()`.
386  
        @li **(3)** average case linear in `size() + init.size()`, worst case
386  
        @li **(3)** average case linear in `size() + init.size()`, worst case
387  
            quadratic in `init.size()`.
387  
            quadratic in `init.size()`.
388  

388  

389  
        @par Exception Safety
389  
        @par Exception Safety
390  
        @li **(1)**, **(3)** strong guarantee.
390  
        @li **(1)**, **(3)** strong guarantee.
391  
        @li **(2)** no-throw guarantee if `*storage() == *other.storage()`;
391  
        @li **(2)** no-throw guarantee if `*storage() == *other.storage()`;
392  
            otherwise strong guarantee.
392  
            otherwise strong guarantee.
393  

393  

394  
        Calls to `memory_resource::allocate` may throw.
394  
        Calls to `memory_resource::allocate` may throw.
395  

395  

396  
        @par Complexity
396  
        @par Complexity
397  

397  

398  
        @param other Another object.
398  
        @param other Another object.
399  

399  

400  
        @{
400  
        @{
401  
    */
401  
    */
402  
    BOOST_JSON_DECL
402  
    BOOST_JSON_DECL
403  
    object&
403  
    object&
404  
    operator=(object const& other);
404  
    operator=(object const& other);
405  

405  

406  
    BOOST_JSON_DECL
406  
    BOOST_JSON_DECL
407  
    object&
407  
    object&
408  
    operator=(object&& other);
408  
    operator=(object&& other);
409  

409  

410  
    /** Overload
410  
    /** Overload
411  

411  

412  
        @param init The initializer list to copy.
412  
        @param init The initializer list to copy.
413  
    */
413  
    */
414  
    BOOST_JSON_DECL
414  
    BOOST_JSON_DECL
415  
    object&
415  
    object&
416  
    operator=(std::initializer_list<
416  
    operator=(std::initializer_list<
417  
        std::pair<string_view, value_ref>> init);
417  
        std::pair<string_view, value_ref>> init);
418  
    /// @}
418  
    /// @}
419  

419  

420  
    //------------------------------------------------------
420  
    //------------------------------------------------------
421  

421  

422  
    /** Return the associated memory resource.
422  
    /** Return the associated memory resource.
423  

423  

424  
        This function returns a smart pointer to the
424  
        This function returns a smart pointer to the
425  
        @ref boost::container::pmr::memory_resource used by the container.
425  
        @ref boost::container::pmr::memory_resource used by the container.
426  

426  

427  
        @par Complexity
427  
        @par Complexity
428  
        Constant.
428  
        Constant.
429  

429  

430  
        @par Exception Safety
430  
        @par Exception Safety
431  
        No-throw guarantee.
431  
        No-throw guarantee.
432  
    */
432  
    */
433  
    storage_ptr const&
433  
    storage_ptr const&
434  
    storage() const noexcept
434  
    storage() const noexcept
435  
    {
435  
    {
436  
        return sp_;
436  
        return sp_;
437  
    }
437  
    }
438  

438  

439  
    /** Return the associated allocator.
439  
    /** Return the associated allocator.
440  

440  

441  
        This function returns an instance of @ref allocator_type constructed
441  
        This function returns an instance of @ref allocator_type constructed
442  
        from the associated @ref boost::container::pmr::memory_resource.
442  
        from the associated @ref boost::container::pmr::memory_resource.
443  

443  

444  
        @par Complexity
444  
        @par Complexity
445  
        Constant.
445  
        Constant.
446  

446  

447  
        @par Exception Safety
447  
        @par Exception Safety
448  
        No-throw guarantee.
448  
        No-throw guarantee.
449  
    */
449  
    */
450  
    allocator_type
450  
    allocator_type
451  
    get_allocator() const noexcept
451  
    get_allocator() const noexcept
452  
    {
452  
    {
453  
        return sp_.get();
453  
        return sp_.get();
454  
    }
454  
    }
455  

455  

456  
    //------------------------------------------------------
456  
    //------------------------------------------------------
457  
    //
457  
    //
458  
    // Iterators
458  
    // Iterators
459  
    //
459  
    //
460  
    //------------------------------------------------------
460  
    //------------------------------------------------------
461  

461  

462  
    /** Return an iterator to the first element.
462  
    /** Return an iterator to the first element.
463  

463  

464  
        If the container is empty, @ref end() is returned.
464  
        If the container is empty, @ref end() is returned.
465  

465  

466  
        @par Complexity
466  
        @par Complexity
467  
        Constant.
467  
        Constant.
468  

468  

469  
        @par Exception Safety
469  
        @par Exception Safety
470  
        No-throw guarantee.
470  
        No-throw guarantee.
471  

471  

472  
        @{
472  
        @{
473  
    */
473  
    */
474  
    inline
474  
    inline
475  
    iterator
475  
    iterator
476  
    begin() noexcept;
476  
    begin() noexcept;
477  

477  

478  
    inline
478  
    inline
479  
    const_iterator
479  
    const_iterator
480  
    begin() const noexcept;
480  
    begin() const noexcept;
481  
    /// @}
481  
    /// @}
482  

482  

483  
    /** Return a const iterator to the first element.
483  
    /** Return a const iterator to the first element.
484  

484  

485  
        If the container is empty, @ref cend() is returned.
485  
        If the container is empty, @ref cend() is returned.
486  

486  

487  
        @par Complexity
487  
        @par Complexity
488  
        Constant.
488  
        Constant.
489  

489  

490  
        @par Exception Safety
490  
        @par Exception Safety
491  
        No-throw guarantee.
491  
        No-throw guarantee.
492  
    */
492  
    */
493  
    inline
493  
    inline
494  
    const_iterator
494  
    const_iterator
495  
    cbegin() const noexcept;
495  
    cbegin() const noexcept;
496  

496  

497  
    /** Return an iterator to the element following the last element.
497  
    /** Return an iterator to the element following the last element.
498  

498  

499  
        The element acts as a placeholder; attempting
499  
        The element acts as a placeholder; attempting
500  
        to access it results in undefined behavior.
500  
        to access it results in undefined behavior.
501  

501  

502  
        @par Complexity
502  
        @par Complexity
503  
        Constant.
503  
        Constant.
504  

504  

505  
        @par Exception Safety
505  
        @par Exception Safety
506  
        No-throw guarantee.
506  
        No-throw guarantee.
507  

507  

508  
        @{
508  
        @{
509  
    */
509  
    */
510  
    inline
510  
    inline
511  
    iterator
511  
    iterator
512  
    end() noexcept;
512  
    end() noexcept;
513  

513  

514  
    inline
514  
    inline
515  
    const_iterator
515  
    const_iterator
516  
    end() const noexcept;
516  
    end() const noexcept;
517  
    /// @}
517  
    /// @}
518  

518  

519  
    /** Return a const iterator to the element following the last element.
519  
    /** Return a const iterator to the element following the last element.
520  

520  

521  
        The element acts as a placeholder; attempting
521  
        The element acts as a placeholder; attempting
522  
        to access it results in undefined behavior.
522  
        to access it results in undefined behavior.
523  

523  

524  
        @par Complexity
524  
        @par Complexity
525  
        Constant.
525  
        Constant.
526  

526  

527  
        @par Exception Safety
527  
        @par Exception Safety
528  
        No-throw guarantee.
528  
        No-throw guarantee.
529  
    */
529  
    */
530  
    inline
530  
    inline
531  
    const_iterator
531  
    const_iterator
532  
    cend() const noexcept;
532  
    cend() const noexcept;
533  

533  

534  
    /** Return a reverse iterator to the first element of the reversed container.
534  
    /** Return a reverse iterator to the first element of the reversed container.
535  

535  

536  
        The pointed-to element corresponds to the last element of the
536  
        The pointed-to element corresponds to the last element of the
537  
        non-reversed container. If the container is empty, @ref rend() is
537  
        non-reversed container. If the container is empty, @ref rend() is
538  
        returned.
538  
        returned.
539  

539  

540  
        @par Complexity
540  
        @par Complexity
541  
        Constant.
541  
        Constant.
542  

542  

543  
        @par Exception Safety
543  
        @par Exception Safety
544  
        No-throw guarantee.
544  
        No-throw guarantee.
545  

545  

546  
        @{
546  
        @{
547  
    */
547  
    */
548  
    inline
548  
    inline
549  
    reverse_iterator
549  
    reverse_iterator
550  
    rbegin() noexcept;
550  
    rbegin() noexcept;
551  

551  

552  
    inline
552  
    inline
553  
    const_reverse_iterator
553  
    const_reverse_iterator
554  
    rbegin() const noexcept;
554  
    rbegin() const noexcept;
555  
    /// @}
555  
    /// @}
556  

556  

557  
    /** Return a const reverse iterator to the first element of the reversed container.
557  
    /** Return a const reverse iterator to the first element of the reversed container.
558  

558  

559  
        The pointed-to element corresponds to the
559  
        The pointed-to element corresponds to the
560  
        last element of the non-reversed container.
560  
        last element of the non-reversed container.
561  
        If the container is empty, @ref crend() is returned.
561  
        If the container is empty, @ref crend() is returned.
562  

562  

563  
        @par Complexity
563  
        @par Complexity
564  
        Constant.
564  
        Constant.
565  

565  

566  
        @par Exception Safety
566  
        @par Exception Safety
567  
        No-throw guarantee.
567  
        No-throw guarantee.
568  
    */
568  
    */
569  
    inline
569  
    inline
570  
    const_reverse_iterator
570  
    const_reverse_iterator
571  
    crbegin() const noexcept;
571  
    crbegin() const noexcept;
572  

572  

573  
    /** Return a reverse iterator to the element following the last element of the reversed container.
573  
    /** Return a reverse iterator to the element following the last element of the reversed container.
574  

574  

575  
        The pointed-to element corresponds to the element preceding the first
575  
        The pointed-to element corresponds to the element preceding the first
576  
        element of the non-reversed container. The returned iterator only acts
576  
        element of the non-reversed container. The returned iterator only acts
577  
        as a sentinel. Dereferencing it results in undefined behavior.
577  
        as a sentinel. Dereferencing it results in undefined behavior.
578  

578  

579  
        @par Complexity
579  
        @par Complexity
580  
        Constant.
580  
        Constant.
581  

581  

582  
        @par Exception Safety
582  
        @par Exception Safety
583  
        No-throw guarantee.
583  
        No-throw guarantee.
584  

584  

585  
        @{
585  
        @{
586  
    */
586  
    */
587  
    inline
587  
    inline
588  
    reverse_iterator
588  
    reverse_iterator
589  
    rend() noexcept;
589  
    rend() noexcept;
590  

590  

591  
    inline
591  
    inline
592  
    const_reverse_iterator
592  
    const_reverse_iterator
593  
    rend() const noexcept;
593  
    rend() const noexcept;
594  
    /// @}
594  
    /// @}
595  

595  

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

597  

598  
        The pointed-to element corresponds to the element preceding the first
598  
        The pointed-to element corresponds to the element preceding the first
599  
        element of the non-reversed container. The returned iterator only acts
599  
        element of the non-reversed container. The returned iterator only acts
600  
        as a sentinel. Dereferencing it results in undefined behavior.
600  
        as a sentinel. Dereferencing it results in undefined behavior.
601  

601  

602  
        @par Complexity
602  
        @par Complexity
603  
        Constant.
603  
        Constant.
604  

604  

605  
        @par Exception Safety
605  
        @par Exception Safety
606  
        No-throw guarantee.
606  
        No-throw guarantee.
607  
    */
607  
    */
608  
    inline
608  
    inline
609  
    const_reverse_iterator
609  
    const_reverse_iterator
610  
    crend() const noexcept;
610  
    crend() const noexcept;
611  

611  

612  
    //------------------------------------------------------
612  
    //------------------------------------------------------
613  
    //
613  
    //
614  
    // Capacity
614  
    // Capacity
615  
    //
615  
    //
616  
    //------------------------------------------------------
616  
    //------------------------------------------------------
617  

617  

618  
    /** Return whether there are no elements.
618  
    /** Return whether there are no elements.
619  

619  

620  
        Returns `true` if there are no elements in
620  
        Returns `true` if there are no elements in
621  
        the container, i.e. @ref size() returns 0.
621  
        the container, i.e. @ref size() returns 0.
622  

622  

623  
        @par Complexity
623  
        @par Complexity
624  
        Constant.
624  
        Constant.
625  

625  

626  
        @par Exception Safety
626  
        @par Exception Safety
627  
        No-throw guarantee.
627  
        No-throw guarantee.
628  
    */
628  
    */
629  
    inline
629  
    inline
630  
    bool
630  
    bool
631  
    empty() const noexcept;
631  
    empty() const noexcept;
632  

632  

633  
    /** Return the number of elements.
633  
    /** Return the number of elements.
634  

634  

635  
        This returns the number of elements in the container.
635  
        This returns the number of elements in the container.
636  

636  

637  
        @par Complexity
637  
        @par Complexity
638  
        Constant.
638  
        Constant.
639  

639  

640  
        @par Exception Safety
640  
        @par Exception Safety
641  
        No-throw guarantee.
641  
        No-throw guarantee.
642  
    */
642  
    */
643  
    inline
643  
    inline
644  
    std::size_t
644  
    std::size_t
645  
    size() const noexcept;
645  
    size() const noexcept;
646  

646  

647  
    /** The maximum number of elements an object can hold.
647  
    /** The maximum number of elements an object can hold.
648  

648  

649  
        The maximum is an implementation-defined number dependent on system or
649  
        The maximum is an implementation-defined number dependent on system or
650  
        library implementation. This value is a theoretical limit; at runtime,
650  
        library implementation. This value is a theoretical limit; at runtime,
651  
        the actual maximum size may be less due to resource limits.
651  
        the actual maximum size may be less due to resource limits.
652  

652  

653  
        @par Complexity
653  
        @par Complexity
654  
        Constant.
654  
        Constant.
655  

655  

656  
        @par Exception Safety
656  
        @par Exception Safety
657  
        No-throw guarantee.
657  
        No-throw guarantee.
658  
    */
658  
    */
659  
    static
659  
    static
660  
    constexpr
660  
    constexpr
661  
    std::size_t
661  
    std::size_t
662  
    max_size() noexcept;
662  
    max_size() noexcept;
663  

663  

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

665  

666  
        Returns the number of elements that the container has currently
666  
        Returns the number of elements that the container has currently
667  
        allocated space for. This number is never smaller than the value
667  
        allocated space for. This number is never smaller than the value
668  
        returned by @ref size().
668  
        returned by @ref size().
669  

669  

670  
        @par Complexity
670  
        @par Complexity
671  
        Constant.
671  
        Constant.
672  

672  

673  
        @par Exception Safety
673  
        @par Exception Safety
674  
        No-throw guarantee.
674  
        No-throw guarantee.
675  
    */
675  
    */
676  
    inline
676  
    inline
677  
    std::size_t
677  
    std::size_t
678  
    capacity() const noexcept;
678  
    capacity() const noexcept;
679  

679  

680  
    /** Increase the capacity to at least a certain amount.
680  
    /** Increase the capacity to at least a certain amount.
681  

681  

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

686  

687  
        If new memory is allocated, all iterators including any past-the-end
687  
        If new memory is allocated, all iterators including any past-the-end
688  
        iterators, and all references to the elements are invalidated.
688  
        iterators, and all references to the elements are invalidated.
689  
        Otherwise, no iterators or references are invalidated.
689  
        Otherwise, no iterators or references are invalidated.
690  

690  

691  
        @par Complexity
691  
        @par Complexity
692  
        Constant if no reallocation occurs. Otherwise, average case linear in
692  
        Constant if no reallocation occurs. Otherwise, average case linear in
693  
        @ref size(), worst case quadratic in @ref size().
693  
        @ref size(), worst case quadratic in @ref size().
694  

694  

695  
        @par Exception Safety
695  
        @par Exception Safety
696  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
696  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
697  

697  

698  
        @param new_capacity The new minimum capacity.
698  
        @param new_capacity The new minimum capacity.
699  

699  

700  
        @throw boost::system::system_error  `new_capacity >` @ref max_size().
700  
        @throw boost::system::system_error  `new_capacity >` @ref max_size().
701  
    */
701  
    */
702  
    inline
702  
    inline
703  
    void
703  
    void
704  
    reserve(std::size_t new_capacity);
704  
    reserve(std::size_t new_capacity);
705  

705  

706  
    //------------------------------------------------------
706  
    //------------------------------------------------------
707  
    //
707  
    //
708  
    // Modifiers
708  
    // Modifiers
709  
    //
709  
    //
710  
    //------------------------------------------------------
710  
    //------------------------------------------------------
711  

711  

712  
    /** Erase all elements.
712  
    /** Erase all elements.
713  

713  

714  
        Erases all elements from the container. After this call, @ref size()
714  
        Erases all elements from the container. After this call, @ref size()
715  
        returns zero but @ref capacity() is unchanged. All references,
715  
        returns zero but @ref capacity() is unchanged. All references,
716  
        pointers, and iterators are invalidated.
716  
        pointers, and iterators are invalidated.
717  

717  

718  
        @par Complexity
718  
        @par Complexity
719  
        Linear in @ref size().
719  
        Linear in @ref size().
720  

720  

721  
        @par Exception Safety
721  
        @par Exception Safety
722  
        No-throw guarantee.
722  
        No-throw guarantee.
723  
    */
723  
    */
724  
    BOOST_JSON_DECL
724  
    BOOST_JSON_DECL
725  
    void
725  
    void
726  
    clear() noexcept;
726  
    clear() noexcept;
727  

727  

728  
    /** Insert elements.
728  
    /** Insert elements.
729  

729  

730  
        @li **(1)** inserts a new element constructed as if via
730  
        @li **(1)** inserts a new element constructed as if via
731  
            `value_type( std::forward<P>(p) )`.
731  
            `value_type( std::forward<P>(p) )`.
732  
        @li **(2)** the elements in the range `[first, last)` are inserted one
732  
        @li **(2)** the elements in the range `[first, last)` are inserted one
733  
            at a time, in order.
733  
            at a time, in order.
734  
        @li **(3)** the elements in the initializer list are inserted one at a
734  
        @li **(3)** the elements in the initializer list are inserted one at a
735  
            time, in order.
735  
            time, in order.
736  

736  

737  
        Any element with key that is a duplicate of a key already present in
737  
        Any element with key that is a duplicate of a key already present in
738  
        container will be skipped. This also means, that if there are two keys
738  
        container will be skipped. This also means, that if there are two keys
739  
        within the inserted range that are equal to each other, only the
739  
        within the inserted range that are equal to each other, only the
740  
        first will be inserted.
740  
        first will be inserted.
741  

741  

742  
        If an insertion would result in the new number of elements exceeding
742  
        If an insertion would result in the new number of elements exceeding
743  
        @ref capacity(), a reallocation and a rehashing occur. In that case all
743  
        @ref capacity(), a reallocation and a rehashing occur. In that case all
744  
        iterators and references are invalidated. Otherwise, they are not
744  
        iterators and references are invalidated. Otherwise, they are not
745  
        affected.
745  
        affected.
746  

746  

747  
        @pre
747  
        @pre
748  
        `first` and `last` are not iterators into `*this`. `first` and `last`
748  
        `first` and `last` are not iterators into `*this`. `first` and `last`
749  
        form a valid range.
749  
        form a valid range.
750  

750  

751  
        @par Constraints
751  
        @par Constraints
752  
        @code
752  
        @code
753  
        std::is_constructible_v<value_type, P>
753  
        std::is_constructible_v<value_type, P>
754  
        std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
754  
        std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
755  
        @endcode
755  
        @endcode
756  

756  

757  
        @par Complexity
757  
        @par Complexity
758  
        @li **(1)** constant on average, worst case linear in @ref size().
758  
        @li **(1)** constant on average, worst case linear in @ref size().
759  
        @li **(2)** linear in `std::distance(first, last)`.
759  
        @li **(2)** linear in `std::distance(first, last)`.
760  
        @li **(3)** linear in `init.size()`.
760  
        @li **(3)** linear in `init.size()`.
761  

761  

762  
        @par Exception Safety
762  
        @par Exception Safety
763  
        @li **(1)** strong guarantee.
763  
        @li **(1)** strong guarantee.
764  
        @li **(2)** strong guarantee if `InputIt` satisfies
764  
        @li **(2)** strong guarantee if `InputIt` satisfies
765  
            {req_ForwardIterator}, basic guarantee otherwise.
765  
            {req_ForwardIterator}, basic guarantee otherwise.
766  
        @li **(3)** basic guarantee.
766  
        @li **(3)** basic guarantee.
767  

767  

768  
        Calls to `memory_resource::allocate` may throw.
768  
        Calls to `memory_resource::allocate` may throw.
769  

769  

770  
        @param p The value to insert.
770  
        @param p The value to insert.
771  

771  

772  
        @throw boost::system::system_error The size of a key would exceed
772  
        @throw boost::system::system_error The size of a key would exceed
773  
               @ref string::max_size.
773  
               @ref string::max_size.
774  
        @throw `boost::system::system_error` @ref size() >= @ref max_size().
774  
        @throw `boost::system::system_error` @ref size() >= @ref max_size().
775  

775  

776  
        @return **(1)** returns a @ref std::pair where `first` is an iterator
776  
        @return **(1)** returns a @ref std::pair where `first` is an iterator
777  
        to the existing or inserted element, and `second` is `true` if the
777  
        to the existing or inserted element, and `second` is `true` if the
778  
        insertion took place or `false` otherwise. **(2)** returns `void`.
778  
        insertion took place or `false` otherwise. **(2)** returns `void`.
779  

779  

780  
        @{
780  
        @{
781  
    */
781  
    */
782  
    template<class P
782  
    template<class P
783  
#ifndef BOOST_JSON_DOCS
783  
#ifndef BOOST_JSON_DOCS
784  
        ,class = typename std::enable_if<
784  
        ,class = typename std::enable_if<
785  
            std::is_constructible<key_value_pair,
785  
            std::is_constructible<key_value_pair,
786  
                P, storage_ptr>::value>::type
786  
                P, storage_ptr>::value>::type
787  
#endif
787  
#endif
788  
    >
788  
    >
789  
    std::pair<iterator, bool>
789  
    std::pair<iterator, bool>
790  
    insert(P&& p);
790  
    insert(P&& p);
791  

791  

792  
    /** Overload
792  
    /** Overload
793  

793  

794  
        @param first An input iterator pointing to the first element to insert,
794  
        @param first An input iterator pointing to the first element to insert,
795  
               or pointing to the end of the range.
795  
               or pointing to the end of the range.
796  

796  

797  
        @param last An input iterator pointing to the end of the range.
797  
        @param last An input iterator pointing to the end of the range.
798  

798  

799  
        @tparam InputIt a type satisfying the requirements
799  
        @tparam InputIt a type satisfying the requirements
800  
                of {req_InputIterator}.
800  
                of {req_InputIterator}.
801  
    */
801  
    */
802  
    template<
802  
    template<
803  
        class InputIt
803  
        class InputIt
804  
    #ifndef BOOST_JSON_DOCS
804  
    #ifndef BOOST_JSON_DOCS
805  
        ,class = is_inputit<InputIt>
805  
        ,class = is_inputit<InputIt>
806  
    #endif
806  
    #endif
807  
    >
807  
    >
808  
    void
808  
    void
809  
    insert(InputIt first, InputIt last)
809  
    insert(InputIt first, InputIt last)
810  
    {
810  
    {
811  
        insert(first, last, typename
811  
        insert(first, last, typename
812  
            std::iterator_traits<InputIt
812  
            std::iterator_traits<InputIt
813  
                >::iterator_category{});
813  
                >::iterator_category{});
814  
    }
814  
    }
815  

815  

816  
    /** Overload
816  
    /** Overload
817  

817  

818  
        @param init The initializer list to insert.
818  
        @param init The initializer list to insert.
819  
    */
819  
    */
820  
    BOOST_JSON_DECL
820  
    BOOST_JSON_DECL
821  
    void
821  
    void
822  
    insert(std::initializer_list<
822  
    insert(std::initializer_list<
823  
        std::pair<string_view, value_ref>> init);
823  
        std::pair<string_view, value_ref>> init);
824  
    /// @}
824  
    /// @}
825  

825  

826  
    /** Insert an element or assign to an existing element.
826  
    /** Insert an element or assign to an existing element.
827  

827  

828  
        If the key equal to `key` already exists in the container, assigns
828  
        If the key equal to `key` already exists in the container, assigns
829  
        `std::forward<M>(m)` to the @ref mapped_type corresponding to that key.
829  
        `std::forward<M>(m)` to the @ref mapped_type corresponding to that key.
830  
        Otherwise, inserts the as if by @ref insert, constructing it using
830  
        Otherwise, inserts the as if by @ref insert, constructing it using
831  
        `value_type(key, std::forward<M>(m))`.
831  
        `value_type(key, std::forward<M>(m))`.
832  

832  

833  
        If insertion would result in the new number of elements exceeding
833  
        If insertion would result in the new number of elements exceeding
834  
        @ref capacity(), a reallocation and a rehashing occur. In that case all
834  
        @ref capacity(), a reallocation and a rehashing occur. In that case all
835  
        iterators and references are invalidated. Otherwise, they are not
835  
        iterators and references are invalidated. Otherwise, they are not
836  
        affected.
836  
        affected.
837  

837  

838  
        @par Complexity
838  
        @par Complexity
839  
        Constant on average, worst case linear in @ref size().
839  
        Constant on average, worst case linear in @ref size().
840  

840  

841  
        @par Exception Safety
841  
        @par Exception Safety
842  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
842  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
843  

843  

844  
        @return A @ref std::pair where `first` is an iterator to the existing
844  
        @return A @ref std::pair where `first` is an iterator to the existing
845  
        or inserted element, and `second` is `true` if the insertion took place
845  
        or inserted element, and `second` is `true` if the insertion took place
846  
        or `false` if the assignment took place.
846  
        or `false` if the assignment took place.
847  

847  

848  
        @param key The key used for lookup and insertion.
848  
        @param key The key used for lookup and insertion.
849  
        @param m The value to insert or assign.
849  
        @param m The value to insert or assign.
850  

850  

851  
        @throw boost::system::system_error The size of a key would exceed
851  
        @throw boost::system::system_error The size of a key would exceed
852  
               @ref string::max_size.
852  
               @ref string::max_size.
853  
    */
853  
    */
854  
    template<class M>
854  
    template<class M>
855  
    std::pair<iterator, bool>
855  
    std::pair<iterator, bool>
856  
    insert_or_assign(
856  
    insert_or_assign(
857  
        string_view key, M&& m);
857  
        string_view key, M&& m);
858  

858  

859  
    /** Construct an element in-place.
859  
    /** Construct an element in-place.
860  

860  

861  
        Inserts a new element into the container constructed
861  
        Inserts a new element into the container constructed
862  
        in-place with the given argument if there is no
862  
        in-place with the given argument if there is no
863  
        element with the `key` in the container.
863  
        element with the `key` in the container.
864  

864  

865  
        If the insertion occurs and results in a rehashing of the container,
865  
        If the insertion occurs and results in a rehashing of the container,
866  
        all iterators and references are invalidated. Otherwise, they are not
866  
        all iterators and references are invalidated. Otherwise, they are not
867  
        affected. Rehashing occurs only if the new number of elements is
867  
        affected. Rehashing occurs only if the new number of elements is
868  
        greater than @ref capacity().
868  
        greater than @ref capacity().
869  

869  

870  
        @par Complexity
870  
        @par Complexity
871  
        Constant on average, worst case linear in @ref size().
871  
        Constant on average, worst case linear in @ref size().
872  

872  

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

876  

877  
        @return A @ref std::pair where `first` is an iterator
877  
        @return A @ref std::pair where `first` is an iterator
878  
        to the existing or inserted element, and `second`
878  
        to the existing or inserted element, and `second`
879  
        is `true` if the insertion took place or `false` otherwise.
879  
        is `true` if the insertion took place or `false` otherwise.
880  

880  

881  
        @param key The key used for lookup and insertion.
881  
        @param key The key used for lookup and insertion.
882  

882  

883  
        @param arg The argument used to construct the value.
883  
        @param arg The argument used to construct the value.
884  
        This will be passed as `std::forward<Arg>(arg)` to
884  
        This will be passed as `std::forward<Arg>(arg)` to
885  
        the @ref value constructor.
885  
        the @ref value constructor.
886  

886  

887  
        @throw boost::system::system_error The size of the key would exceed
887  
        @throw boost::system::system_error The size of the key would exceed
888  
               @ref string::max_size.
888  
               @ref string::max_size.
889  

889  

890  
    */
890  
    */
891  
    template<class Arg>
891  
    template<class Arg>
892  
    std::pair<iterator, bool>
892  
    std::pair<iterator, bool>
893  
    emplace(string_view key, Arg&& arg);
893  
    emplace(string_view key, Arg&& arg);
894  

894  

895  
    /** Remove an element.
895  
    /** Remove an element.
896  

896  

897  
        @li **(1)** the element at `pos` is removed.
897  
        @li **(1)** the element at `pos` is removed.
898  
        @li **(2)** the element with the key `key` is removed, if it exists.
898  
        @li **(2)** the element with the key `key` is removed, if it exists.
899  

899  

900  
        `pos` must be valid and dereferenceable. References and iterators to
900  
        `pos` must be valid and dereferenceable. References and iterators to
901  
        the erased element are invalidated. Other iterators and references are
901  
        the erased element are invalidated. Other iterators and references are
902  
        not invalidated.
902  
        not invalidated.
903  

903  

904  
        @attention The @ref end() iterator (which is valid but cannot be
904  
        @attention The @ref end() iterator (which is valid but cannot be
905  
        dereferenced) cannot be used as a value for `pos`.
905  
        dereferenced) cannot be used as a value for `pos`.
906  

906  

907  
        @par Complexity
907  
        @par Complexity
908  
        Constant on average, worst case linear in @ref size().
908  
        Constant on average, worst case linear in @ref size().
909  

909  

910  
        @par Exception Safety
910  
        @par Exception Safety
911  
        No-throw guarantee.
911  
        No-throw guarantee.
912  

912  

913  
        @return
913  
        @return
914  
        @li **(1)** an iterator following the removed element.
914  
        @li **(1)** an iterator following the removed element.
915  
        @li **(2)** the number of elements removed, which will be either
915  
        @li **(2)** the number of elements removed, which will be either
916  
            0 or 1.
916  
            0 or 1.
917  

917  

918  
        @param pos An iterator pointing to the element to be removed.
918  
        @param pos An iterator pointing to the element to be removed.
919  

919  

920  
        @{
920  
        @{
921  
    */
921  
    */
922  
    BOOST_JSON_DECL
922  
    BOOST_JSON_DECL
923  
    iterator
923  
    iterator
924  
    erase(const_iterator pos) noexcept;
924  
    erase(const_iterator pos) noexcept;
925  

925  

926  
    /** Overload
926  
    /** Overload
927  

927  

928  
        @param key The key to match.
928  
        @param key The key to match.
929  
    */
929  
    */
930  
    BOOST_JSON_DECL
930  
    BOOST_JSON_DECL
931  
    std::size_t
931  
    std::size_t
932  
    erase(string_view key) noexcept;
932  
    erase(string_view key) noexcept;
933  
    /// @}
933  
    /// @}
934  

934  

935  
    /** Erase an element preserving order.
935  
    /** Erase an element preserving order.
936  

936  

937  
        @li **(1)** Remove the element pointed to by `pos`, which must be valid
937  
        @li **(1)** Remove the element pointed to by `pos`, which must be valid
938  
        and dereferenceable. References and iterators from `pos` to @ref end(),
938  
        and dereferenceable. References and iterators from `pos` to @ref end(),
939  
        both included, are invalidated. Other iterators and references are not
939  
        both included, are invalidated. Other iterators and references are not
940  
        invalidated.
940  
        invalidated.
941  
        @li **(2)** Remove the element which matches `key`, if it exists. All
941  
        @li **(2)** Remove the element which matches `key`, if it exists. All
942  
        references and iterators are invalidated.
942  
        references and iterators are invalidated.
943  

943  

944  
        The relative order of remaining elements is preserved.
944  
        The relative order of remaining elements is preserved.
945  

945  

946  
        @attention The @ref end() iterator (which is valid but cannot be
946  
        @attention The @ref end() iterator (which is valid but cannot be
947  
        dereferenced) cannot be used as a value for `pos`.
947  
        dereferenced) cannot be used as a value for `pos`.
948  

948  

949  
        @par Complexity
949  
        @par Complexity
950  
        Linear in @ref size().
950  
        Linear in @ref size().
951  

951  

952  
        @par Exception Safety
952  
        @par Exception Safety
953  
        No-throw guarantee.
953  
        No-throw guarantee.
954  

954  

955  
        @return
955  
        @return
956  
        @li An iterator following the removed element.
956  
        @li An iterator following the removed element.
957  
        @li The number of elements removed, which will be either 0 or 1.
957  
        @li The number of elements removed, which will be either 0 or 1.
958  

958  

959  
        @param pos An iterator pointing to the element to be
959  
        @param pos An iterator pointing to the element to be
960  
        removed.
960  
        removed.
961  

961  

962  
        @{
962  
        @{
963  
    */
963  
    */
964  
    BOOST_JSON_DECL
964  
    BOOST_JSON_DECL
965  
    iterator
965  
    iterator
966  
    stable_erase(const_iterator pos) noexcept;
966  
    stable_erase(const_iterator pos) noexcept;
967  

967  

968  
    /** Overload
968  
    /** Overload
969  

969  

970  
        @param key The key to match.
970  
        @param key The key to match.
971  
    */
971  
    */
972  
    BOOST_JSON_DECL
972  
    BOOST_JSON_DECL
973  
    std::size_t
973  
    std::size_t
974  
    stable_erase(string_view key) noexcept;
974  
    stable_erase(string_view key) noexcept;
975  
    /// @}
975  
    /// @}
976  

976  

977  
    /** Swap two objects.
977  
    /** Swap two objects.
978  

978  

979  
        Exchanges the contents of this object with another object. Ownership of
979  
        Exchanges the contents of this object with another object. Ownership of
980  
        the respective @ref boost::container::pmr::memory_resource objects is
980  
        the respective @ref boost::container::pmr::memory_resource objects is
981  
        not transferred. If `this == &other`, this function call has no effect.
981  
        not transferred. If `this == &other`, this function call has no effect.
982  

982  

983  
        @li If `*storage() == *other.storage()` all iterators and references
983  
        @li If `*storage() == *other.storage()` all iterators and references
984  
        remain valid.
984  
        remain valid.
985  

985  

986  
        @li Otherwise, the contents are logically swapped by making copies,
986  
        @li Otherwise, the contents are logically swapped by making copies,
987  
        which can throw. In this case all iterators and references are
987  
        which can throw. In this case all iterators and references are
988  
        invalidated.
988  
        invalidated.
989  

989  

990  
        @par Complexity
990  
        @par Complexity
991  
        If `*storage() == *other.storage()`, then constant; otherwise linear in
991  
        If `*storage() == *other.storage()`, then constant; otherwise linear in
992  
        `size() + other.size()`.
992  
        `size() + other.size()`.
993  

993  

994  
        @par Exception Safety
994  
        @par Exception Safety
995  
        No-throw guarantee if `*storage() == *other.storage()`. Otherwise
995  
        No-throw guarantee if `*storage() == *other.storage()`. Otherwise
996  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
996  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
997  

997  

998  
        @param other The object to swap with.
998  
        @param other The object to swap with.
999  
    */
999  
    */
1000  
    BOOST_JSON_DECL
1000  
    BOOST_JSON_DECL
1001  
    void
1001  
    void
1002  
    swap(object& other);
1002  
    swap(object& other);
1003  

1003  

1004  
    /** Swap two objects.
1004  
    /** Swap two objects.
1005  

1005  

1006  
        Exchanges the contents of the object `lhs` with another object `rhs`.
1006  
        Exchanges the contents of the object `lhs` with another object `rhs`.
1007  
        Ownership of the respective @ref boost::container::pmr::memory_resource
1007  
        Ownership of the respective @ref boost::container::pmr::memory_resource
1008  
        objects is not transferred. If `&lhs == &rhs`, this function call has
1008  
        objects is not transferred. If `&lhs == &rhs`, this function call has
1009  
        no effect.
1009  
        no effect.
1010  

1010  

1011  
        @li If `*lhs.storage() == *rhs.storage()` all iterators and references
1011  
        @li If `*lhs.storage() == *rhs.storage()` all iterators and references
1012  
        remain valid.
1012  
        remain valid.
1013  

1013  

1014  
        @li Otherwise, the contents are logically swapped by making copies,
1014  
        @li Otherwise, the contents are logically swapped by making copies,
1015  
        which can throw. In this case all iterators and references are
1015  
        which can throw. In this case all iterators and references are
1016  
        invalidated.
1016  
        invalidated.
1017  

1017  

1018  
        @par Complexity
1018  
        @par Complexity
1019  
        If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear
1019  
        If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear
1020  
        in `lhs.size() + rhs.size()`.
1020  
        in `lhs.size() + rhs.size()`.
1021  

1021  

1022  
        @par Exception Safety
1022  
        @par Exception Safety
1023  
        No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise
1023  
        No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise
1024  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
1024  
        strong guarantee. Calls to `memory_resource::allocate` may throw.
1025  

1025  

1026  
        @param lhs The object to exchange.
1026  
        @param lhs The object to exchange.
1027  

1027  

1028  
        @param rhs The object to exchange.
1028  
        @param rhs The object to exchange.
1029  

1029  

1030  
        @see @ref object::swap
1030  
        @see @ref object::swap
1031  
    */
1031  
    */
1032  
    friend
1032  
    friend
1033  
    void
1033  
    void
1034  
    swap(object& lhs, object& rhs)
1034  
    swap(object& lhs, object& rhs)
1035  
    {
1035  
    {
1036  
        lhs.swap(rhs);
1036  
        lhs.swap(rhs);
1037  
    }
1037  
    }
1038  

1038  

1039  
    //------------------------------------------------------
1039  
    //------------------------------------------------------
1040  
    //
1040  
    //
1041  
    // Lookup
1041  
    // Lookup
1042  
    //
1042  
    //
1043  
    //------------------------------------------------------
1043  
    //------------------------------------------------------
1044  

1044  

1045  
    /** Access the specified element, with bounds checking.
1045  
    /** Access the specified element, with bounds checking.
1046  

1046  

1047  
        Returns @ref boost::system::result containing a reference to the
1047  
        Returns @ref boost::system::result containing a reference to the
1048  
        mapped value of the element that matches `key`. Otherwise the result
1048  
        mapped value of the element that matches `key`. Otherwise the result
1049  
        contains an `error_code`.
1049  
        contains an `error_code`.
1050  

1050  

1051  
        @par Exception Safety
1051  
        @par Exception Safety
1052  
        No-throw guarantee.
1052  
        No-throw guarantee.
1053  

1053  

1054  
        @param key The key of the element to find.
1054  
        @param key The key of the element to find.
1055  

1055  

1056  
        @par Complexity
1056  
        @par Complexity
1057  
        Constant on average, worst case linear in @ref size().
1057  
        Constant on average, worst case linear in @ref size().
1058  

1058  

1059  
        @{
1059  
        @{
1060  
    */
1060  
    */
1061  
    BOOST_JSON_DECL
1061  
    BOOST_JSON_DECL
1062  
    system::result<value&>
1062  
    system::result<value&>
1063  
    try_at(string_view key) noexcept;
1063  
    try_at(string_view key) noexcept;
1064  

1064  

1065  
    BOOST_JSON_DECL
1065  
    BOOST_JSON_DECL
1066  
    system::result<value const&>
1066  
    system::result<value const&>
1067  
    try_at(string_view key) const noexcept;
1067  
    try_at(string_view key) const noexcept;
1068  
    /// @}
1068  
    /// @}
1069  

1069  

1070  
    /** Access the specified element, with bounds checking.
1070  
    /** Access the specified element, with bounds checking.
1071  

1071  

1072  
        Returns a reference to the mapped value of the element that matches
1072  
        Returns a reference to the mapped value of the element that matches
1073  
        `key`, otherwise throws.
1073  
        `key`, otherwise throws.
1074  

1074  

1075  
        @par Complexity
1075  
        @par Complexity
1076  
        Constant on average, worst case linear in @ref size().
1076  
        Constant on average, worst case linear in @ref size().
1077  

1077  

1078  
        @par Exception Safety
1078  
        @par Exception Safety
1079  
        Strong guarantee.
1079  
        Strong guarantee.
1080  

1080  

1081  
        @return A reference to the mapped value.
1081  
        @return A reference to the mapped value.
1082  

1082  

1083  
        @param key The key of the element to find.
1083  
        @param key The key of the element to find.
1084  
        @param loc @ref boost::source_location to use in thrown exception; the
1084  
        @param loc @ref boost::source_location to use in thrown exception; the
1085  
               source location of the call site by default.
1085  
               source location of the call site by default.
1086  

1086  

1087  
        @throw `boost::system::system_error` if no such element exists.
1087  
        @throw `boost::system::system_error` if no such element exists.
1088  

1088  

1089  
        @see @ref operator[], @ref try_at.
1089  
        @see @ref operator[], @ref try_at.
1090  

1090  

1091  
        @{
1091  
        @{
1092  
    */
1092  
    */
1093  
    inline
1093  
    inline
1094  
    value&
1094  
    value&
1095  
    at(
1095  
    at(
1096  
        string_view key,
1096  
        string_view key,
1097  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
1097  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
1098  

1098  

1099  
    inline
1099  
    inline
1100  
    value&&
1100  
    value&&
1101  
    at(
1101  
    at(
1102  
        string_view key,
1102  
        string_view key,
1103  
        source_location const& loc = BOOST_CURRENT_LOCATION) &&;
1103  
        source_location const& loc = BOOST_CURRENT_LOCATION) &&;
1104  

1104  

1105  
    BOOST_JSON_DECL
1105  
    BOOST_JSON_DECL
1106  
    value const&
1106  
    value const&
1107  
    at(
1107  
    at(
1108  
        string_view key,
1108  
        string_view key,
1109  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
1109  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
1110  
    /// @}
1110  
    /// @}
1111  

1111  

1112  
    /** Access or insert an element.
1112  
    /** Access or insert an element.
1113  

1113  

1114  
        Returns a reference to the value that is mapped to `key`. If such value
1114  
        Returns a reference to the value that is mapped to `key`. If such value
1115  
        does not already exist, performs an insertion of a null value.
1115  
        does not already exist, performs an insertion of a null value.
1116  

1116  

1117  
        If an insertion occurs and results in a rehashing of the container, all
1117  
        If an insertion occurs and results in a rehashing of the container, all
1118  
        iterators including any past-the-end iterators, and all references to
1118  
        iterators including any past-the-end iterators, and all references to
1119  
        the elements are invalidated. Otherwise, no iterators or references are
1119  
        the elements are invalidated. Otherwise, no iterators or references are
1120  
        invalidated.
1120  
        invalidated.
1121  

1121  

1122  
        @par Complexity
1122  
        @par Complexity
1123  
        Constant on average, worst case linear in @ref size().
1123  
        Constant on average, worst case linear in @ref size().
1124  

1124  

1125  
        @par Exception Safety
1125  
        @par Exception Safety
1126  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1126  
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1127  

1127  

1128  
        @return A reference to the mapped value.
1128  
        @return A reference to the mapped value.
1129  

1129  

1130  
        @param key The key of the element to find.
1130  
        @param key The key of the element to find.
1131  
    */
1131  
    */
1132  
    BOOST_JSON_DECL
1132  
    BOOST_JSON_DECL
1133  
    value&
1133  
    value&
1134  
    operator[](string_view key);
1134  
    operator[](string_view key);
1135  

1135  

1136  
    /** Count the number of elements with a specific key.
1136  
    /** Count the number of elements with a specific key.
1137  

1137  

1138  
        Returns the number of elements with keys equal to `key`. The only
1138  
        Returns the number of elements with keys equal to `key`. The only
1139  
        possible return values are 0 and 1.
1139  
        possible return values are 0 and 1.
1140  

1140  

1141  
        @par Complexity
1141  
        @par Complexity
1142  
        Constant on average, worst case linear in @ref size().
1142  
        Constant on average, worst case linear in @ref size().
1143  

1143  

1144  
        @par Exception Safety
1144  
        @par Exception Safety
1145  
        No-throw guarantee.
1145  
        No-throw guarantee.
1146  

1146  

1147  
        @param key The key of the element to find.
1147  
        @param key The key of the element to find.
1148  
    */
1148  
    */
1149  
    BOOST_JSON_DECL
1149  
    BOOST_JSON_DECL
1150  
    std::size_t
1150  
    std::size_t
1151  
    count(string_view key) const noexcept;
1151  
    count(string_view key) const noexcept;
1152  

1152  

1153  
    /** Find an element with a specific key.
1153  
    /** Find an element with a specific key.
1154  

1154  

1155  
        This function returns an iterator to the element
1155  
        This function returns an iterator to the element
1156  
        matching `key` if it exists, otherwise returns
1156  
        matching `key` if it exists, otherwise returns
1157  
        @ref end().
1157  
        @ref end().
1158  

1158  

1159  
        @par Complexity
1159  
        @par Complexity
1160  
        Constant on average, worst case linear in @ref size().
1160  
        Constant on average, worst case linear in @ref size().
1161  

1161  

1162  
        @par Exception Safety
1162  
        @par Exception Safety
1163  
        No-throw guarantee.
1163  
        No-throw guarantee.
1164  

1164  

1165  
        @param key The key of the element to find.
1165  
        @param key The key of the element to find.
1166  

1166  

1167  
        @{
1167  
        @{
1168  
    */
1168  
    */
1169  
    BOOST_JSON_DECL
1169  
    BOOST_JSON_DECL
1170  
    iterator
1170  
    iterator
1171  
    find(string_view key) noexcept;
1171  
    find(string_view key) noexcept;
1172  

1172  

1173  
    BOOST_JSON_DECL
1173  
    BOOST_JSON_DECL
1174  
    const_iterator
1174  
    const_iterator
1175  
    find(string_view key) const noexcept;
1175  
    find(string_view key) const noexcept;
1176  
    /// @}
1176  
    /// @}
1177  

1177  

1178  
    /** Return `true` if the key is found.
1178  
    /** Return `true` if the key is found.
1179  

1179  

1180  
        Checks if there is an element with key equal to `key`.
1180  
        Checks if there is an element with key equal to `key`.
1181  

1181  

1182  
        @par Effects
1182  
        @par Effects
1183  
        @code
1183  
        @code
1184  
        return find(key) != end();
1184  
        return find(key) != end();
1185  
        @endcode
1185  
        @endcode
1186  

1186  

1187  
        @par Complexity
1187  
        @par Complexity
1188  
        Constant on average, worst case linear in @ref size().
1188  
        Constant on average, worst case linear in @ref size().
1189  

1189  

1190  
        @par Exception Safety
1190  
        @par Exception Safety
1191  
        No-throw guarantee.
1191  
        No-throw guarantee.
1192  

1192  

1193  
        @param key The key of the element to find.
1193  
        @param key The key of the element to find.
1194  

1194  

1195  
        @see @ref find.
1195  
        @see @ref find.
1196  
    */
1196  
    */
1197  
    BOOST_JSON_DECL
1197  
    BOOST_JSON_DECL
1198  
    bool
1198  
    bool
1199  
    contains(string_view key) const noexcept;
1199  
    contains(string_view key) const noexcept;
1200  

1200  

1201  
    /** Return a pointer to the value if the key is found, or null
1201  
    /** Return a pointer to the value if the key is found, or null
1202  

1202  

1203  
        This function searches for a value with the given
1203  
        This function searches for a value with the given
1204  
        key, and returns a pointer to it if found. Otherwise
1204  
        key, and returns a pointer to it if found. Otherwise
1205  
        it returns null.
1205  
        it returns null.
1206  

1206  

1207  
        @par Example
1207  
        @par Example
1208  
        @code
1208  
        @code
1209  
        if( auto p = obj.if_contains( "key" ) )
1209  
        if( auto p = obj.if_contains( "key" ) )
1210  
            std::cout << *p;
1210  
            std::cout << *p;
1211  
        @endcode
1211  
        @endcode
1212  

1212  

1213  
        @par Complexity
1213  
        @par Complexity
1214  
        Constant on average, worst case linear in @ref size().
1214  
        Constant on average, worst case linear in @ref size().
1215  

1215  

1216  
        @par Exception Safety
1216  
        @par Exception Safety
1217  
        No-throw guarantee.
1217  
        No-throw guarantee.
1218  

1218  

1219  
        @param key The key of the element to find.
1219  
        @param key The key of the element to find.
1220  

1220  

1221  
        @see @ref find.
1221  
        @see @ref find.
1222  

1222  

1223  
        @{
1223  
        @{
1224  
    */
1224  
    */
1225  
    BOOST_JSON_DECL
1225  
    BOOST_JSON_DECL
1226  
    value const*
1226  
    value const*
1227  
    if_contains(string_view key) const noexcept;
1227  
    if_contains(string_view key) const noexcept;
1228  

1228  

1229  
    BOOST_JSON_DECL
1229  
    BOOST_JSON_DECL
1230  
    value*
1230  
    value*
1231  
    if_contains(string_view key) noexcept;
1231  
    if_contains(string_view key) noexcept;
1232  
    /// @}
1232  
    /// @}
1233  

1233  

1234  
    /** Compare two objects for equality.
1234  
    /** Compare two objects for equality.
1235  

1235  

1236  
        Objects are equal when their sizes are the same,
1236  
        Objects are equal when their sizes are the same,
1237  
        and when for each key in `lhs` there is a matching
1237  
        and when for each key in `lhs` there is a matching
1238  
        key in `rhs` with the same value.
1238  
        key in `rhs` with the same value.
1239  

1239  

1240  
        @par Complexity
1240  
        @par Complexity
1241  
        Average case linear and worst case quadratic in `lhs.size()`.
1241  
        Average case linear and worst case quadratic in `lhs.size()`.
1242  

1242  

1243  
        @par Exception Safety
1243  
        @par Exception Safety
1244  
        No-throw guarantee.
1244  
        No-throw guarantee.
1245  
    */
1245  
    */
1246  
    // inline friend speeds up overload resolution
1246  
    // inline friend speeds up overload resolution
1247  
    friend
1247  
    friend
1248  
    bool
1248  
    bool
1249  
    operator==(
1249  
    operator==(
1250  
        object const& lhs,
1250  
        object const& lhs,
1251  
        object const& rhs) noexcept
1251  
        object const& rhs) noexcept
1252  
    {
1252  
    {
1253  
        return lhs.equal(rhs);
1253  
        return lhs.equal(rhs);
1254  
    }
1254  
    }
1255  

1255  

1256  
    /** Compare two objects for inequality.
1256  
    /** Compare two objects for inequality.
1257  

1257  

1258  
        Objects are equal when their sizes are the same, and when for each key
1258  
        Objects are equal when their sizes are the same, and when for each key
1259  
        in `lhs` there is a matching key in `rhs` with the same value.
1259  
        in `lhs` there is a matching key in `rhs` with the same value.
1260  

1260  

1261  
        @par Complexity
1261  
        @par Complexity
1262  
        Average casee linear and worst case quadratic in `lhs.size()`.
1262  
        Average casee linear and worst case quadratic in `lhs.size()`.
1263  

1263  

1264  
        @par Exception Safety
1264  
        @par Exception Safety
1265  
        No-throw guarantee.
1265  
        No-throw guarantee.
1266  
    */
1266  
    */
1267  
    // inline friend speeds up overload resolution
1267  
    // inline friend speeds up overload resolution
1268  
    friend
1268  
    friend
1269  
    bool
1269  
    bool
1270  
    operator!=(
1270  
    operator!=(
1271  
        object const& lhs,
1271  
        object const& lhs,
1272  
        object const& rhs) noexcept
1272  
        object const& rhs) noexcept
1273  
    {
1273  
    {
1274  
        return ! (lhs == rhs);
1274  
        return ! (lhs == rhs);
1275  
    }
1275  
    }
1276  

1276  

1277  
    /** Serialize to an output stream.
1277  
    /** Serialize to an output stream.
1278  

1278  

1279  
        This function serializes an `object` as JSON into the output stream.
1279  
        This function serializes an `object` as JSON into the output stream.
1280  

1280  

1281  
        @return Reference to `os`.
1281  
        @return Reference to `os`.
1282  

1282  

1283  
        @par Complexity
1283  
        @par Complexity
1284  
        Constant or linear in the size of `obj`.
1284  
        Constant or linear in the size of `obj`.
1285  

1285  

1286  
        @par Exception Safety
1286  
        @par Exception Safety
1287  
        Strong guarantee.
1287  
        Strong guarantee.
1288  
        Calls to `memory_resource::allocate` may throw.
1288  
        Calls to `memory_resource::allocate` may throw.
1289  

1289  

1290  
        @param os The output stream to serialize to.
1290  
        @param os The output stream to serialize to.
1291  

1291  

1292  
        @param obj The value to serialize.
1292  
        @param obj The value to serialize.
1293  
    */
1293  
    */
1294  
    BOOST_JSON_DECL
1294  
    BOOST_JSON_DECL
1295  
    friend
1295  
    friend
1296  
    std::ostream&
1296  
    std::ostream&
1297  
    operator<<(
1297  
    operator<<(
1298  
        std::ostream& os,
1298  
        std::ostream& os,
1299  
        object const& obj);
1299  
        object const& obj);
1300  
private:
1300  
private:
1301  
#ifndef BOOST_JSON_DOCS
1301  
#ifndef BOOST_JSON_DOCS
1302  
    // VFALCO friending a detail function makes it public
1302  
    // VFALCO friending a detail function makes it public
1303  
    template<class CharRange>
1303  
    template<class CharRange>
1304  
    friend
1304  
    friend
1305  
    std::pair<key_value_pair*, std::size_t>
1305  
    std::pair<key_value_pair*, std::size_t>
1306  
    detail::find_in_object(
1306  
    detail::find_in_object(
1307  
        object const& obj,
1307  
        object const& obj,
1308  
        CharRange key) noexcept;
1308  
        CharRange key) noexcept;
1309  
#endif
1309  
#endif
1310  

1310  

1311  
    template<class InputIt>
1311  
    template<class InputIt>
1312  
    void
1312  
    void
1313  
    construct(
1313  
    construct(
1314  
        InputIt first,
1314  
        InputIt first,
1315  
        InputIt last,
1315  
        InputIt last,
1316  
        std::size_t min_capacity,
1316  
        std::size_t min_capacity,
1317  
        std::input_iterator_tag);
1317  
        std::input_iterator_tag);
1318  

1318  

1319  
    template<class InputIt>
1319  
    template<class InputIt>
1320  
    void
1320  
    void
1321  
    construct(
1321  
    construct(
1322  
        InputIt first,
1322  
        InputIt first,
1323  
        InputIt last,
1323  
        InputIt last,
1324  
        std::size_t min_capacity,
1324  
        std::size_t min_capacity,
1325  
        std::forward_iterator_tag);
1325  
        std::forward_iterator_tag);
1326  

1326  

1327  
    template<class InputIt>
1327  
    template<class InputIt>
1328  
    void
1328  
    void
1329  
    insert(
1329  
    insert(
1330  
        InputIt first,
1330  
        InputIt first,
1331  
        InputIt last,
1331  
        InputIt last,
1332  
        std::input_iterator_tag);
1332  
        std::input_iterator_tag);
1333  

1333  

1334  
    template<class InputIt>
1334  
    template<class InputIt>
1335  
    void
1335  
    void
1336  
    insert(
1336  
    insert(
1337  
        InputIt first,
1337  
        InputIt first,
1338  
        InputIt last,
1338  
        InputIt last,
1339  
        std::forward_iterator_tag);
1339  
        std::forward_iterator_tag);
1340  

1340  

1341  
    template< class... Args >
1341  
    template< class... Args >
1342  
    std::pair<iterator, bool>
1342  
    std::pair<iterator, bool>
1343  
    emplace_impl(string_view key, Args&& ... args );
1343  
    emplace_impl(string_view key, Args&& ... args );
1344  

1344  

1345  
    BOOST_JSON_DECL
1345  
    BOOST_JSON_DECL
1346  
    key_value_pair*
1346  
    key_value_pair*
1347  
    insert_impl(
1347  
    insert_impl(
1348  
        pilfered<key_value_pair> p,
1348  
        pilfered<key_value_pair> p,
1349  
        std::size_t hash);
1349  
        std::size_t hash);
1350  

1350  

1351  
    BOOST_JSON_DECL
1351  
    BOOST_JSON_DECL
1352  
    table*
1352  
    table*
1353  
    reserve_impl(std::size_t new_capacity);
1353  
    reserve_impl(std::size_t new_capacity);
1354  

1354  

1355  
    BOOST_JSON_DECL
1355  
    BOOST_JSON_DECL
1356  
    bool
1356  
    bool
1357  
    equal(object const& other) const noexcept;
1357  
    equal(object const& other) const noexcept;
1358  

1358  

1359  
    inline
1359  
    inline
1360  
    std::size_t
1360  
    std::size_t
1361  
    growth(
1361  
    growth(
1362  
        std::size_t new_size) const;
1362  
        std::size_t new_size) const;
1363  

1363  

1364  
    inline
1364  
    inline
1365  
    void
1365  
    void
1366  
    remove(
1366  
    remove(
1367  
        index_t& head,
1367  
        index_t& head,
1368  
        key_value_pair& p) noexcept;
1368  
        key_value_pair& p) noexcept;
1369  

1369  

1370  
    inline
1370  
    inline
1371  
    void
1371  
    void
1372  
    destroy() noexcept;
1372  
    destroy() noexcept;
1373  

1373  

1374  
    inline
1374  
    inline
1375  
    void
1375  
    void
1376  
    destroy(
1376  
    destroy(
1377  
        key_value_pair* first,
1377  
        key_value_pair* first,
1378  
        key_value_pair* last) noexcept;
1378  
        key_value_pair* last) noexcept;
1379  

1379  

1380  
    template<class FS, class FB>
1380  
    template<class FS, class FB>
1381  
    auto
1381  
    auto
1382  
    do_erase(
1382  
    do_erase(
1383  
        const_iterator pos,
1383  
        const_iterator pos,
1384  
        FS small_reloc,
1384  
        FS small_reloc,
1385  
        FB big_reloc) noexcept
1385  
        FB big_reloc) noexcept
1386  
        -> iterator;
1386  
        -> iterator;
1387  

1387  

1388  
    inline
1388  
    inline
1389  
    void
1389  
    void
1390  
    reindex_relocate(
1390  
    reindex_relocate(
1391  
        key_value_pair* src,
1391  
        key_value_pair* src,
1392  
        key_value_pair* dst) noexcept;
1392  
        key_value_pair* dst) noexcept;
1393  
};
1393  
};
1394  

1394  

1395  
} // namespace json
1395  
} // namespace json
1396  
} // namespace boost
1396  
} // namespace boost
1397  

1397  

1398  
#ifndef BOOST_JSON_DOCS
1398  
#ifndef BOOST_JSON_DOCS
1399  
// boost::hash trait
1399  
// boost::hash trait
1400  
namespace boost
1400  
namespace boost
1401  
{
1401  
{
1402  
namespace container_hash
1402  
namespace container_hash
1403  
{
1403  
{
1404  

1404  

1405  
template< class T > struct is_unordered_range;
1405  
template< class T > struct is_unordered_range;
1406  

1406  

1407  
template<>
1407  
template<>
1408  
struct is_unordered_range< json::object >
1408  
struct is_unordered_range< json::object >
1409  
    : std::true_type
1409  
    : std::true_type
1410  
{};
1410  
{};
1411  

1411  

1412  
} // namespace container_hash
1412  
} // namespace container_hash
1413  
} // namespace boost
1413  
} // namespace boost
1414  

1414  

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

1425  

1426  

1426  

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

1429  

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

1431  

1432  
#endif
1432  
#endif