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
37 -
    unique keys.
37 +
    are key/value pairs with unique keys.
38  

38  

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

45  

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

51  

50  
    @par Allocators
52  
    @par Allocators
51 -
    All elements stored in the container, and their children if any, will use
53 +

52 -
    the same memory resource that was used to construct the container.
54 +
    All elements stored in the container, and their
 
55 +
    children if any, will use the same memory resource that
 
56 +
    was used to construct the container.
53  

57  

54  
    @par Thread Safety
58  
    @par Thread Safety
55 -
    Non-const member functions may not be called concurrently with any other
59 +

56 -
    member functions.
60 +
    Non-const member functions may not be called
 
61 +
    concurrently with any other member functions.
57  

62  

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

79  

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

83  

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

86  

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

92  

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

96  

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

100  

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

102  

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

107  

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

110  

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

113  

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

116  

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

119  

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

122  

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

125  

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

128  

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

131  

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

134  

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

137  

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

141  

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

145  

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

147  

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

149  

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

153  

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

156  

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

162  

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

164  

160 -
    /** Constructors.
165 +
    /** Default constructor.
161 -

 
162 -
        Constructs an object.
 
163 -

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

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

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

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

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

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

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

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

 
189 -
        With **(2)**--**(6)**, **(8)**, **(10)** the constructed object 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
 
192 -
        ownership of the memory resource. With **(1)** it uses the
 
193 -
        \<\<default_memory_resource,default memory resource\>\>.
 
194 -

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

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

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

166  

204 -
        @par Constraints
167 +
        The constructed object is empty with zero
205 -
        @code
168 +
        capacity, using the [default memory resource].
206 -
        std::is_constructible_v<
 
207 -
            key_value_pair,
 
208 -
            std::iterator_traits<InputIt>::reference>
 
209 -
        @endcode
 
210  

169  

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

172  

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

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

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

175  

230 -
        @{
176 +
        [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
231  
    */
177  
    */
232  
    object() noexcept
178  
    object() noexcept
233  
        : t_(&empty_)
179  
        : t_(&empty_)
234  
    {
180  
    {
235  
    }
181  
    }
236  

182  

237 -
    /** Overload
183 +
    /** Constructor.
238  

184  

239 -
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
185 +
        The constructed object is empty with zero
240 -
               to use.
186 +
        capacity, using the specified memory resource.
 
187 +

 
188 +
        @par Complexity
 
189 +
        Constant.
 
190 +

 
191 +
        @par Exception Safety
 
192 +
        No-throw guarantee.
 
193 +

 
194 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
195 +
        use. The container will acquire shared ownership of the memory
 
196 +
        resource.
241  
    */
197  
    */
242  
    explicit
198  
    explicit
243  
    object(storage_ptr sp) noexcept
199  
    object(storage_ptr sp) noexcept
244  
        : sp_(std::move(sp))
200  
        : sp_(std::move(sp))
245  
        , t_(&empty_)
201  
        , t_(&empty_)
246  
    {
202  
    {
247  
    }
203  
    }
248  

204  

249 -
    /** Overload
205 +
    /** Constructor.
250  

206  

251 -
        @param min_capacity The minimum number of elements for which capacity
207 +
        The constructed object is empty with capacity
252 -
               is guaranteed without a subsequent reallocation.
208 +
        equal to the specified minimum capacity,
253 -
        @param sp
209 +
        using the specified memory resource.
 
210 +

 
211 +
        @par Complexity
 
212 +
        Constant.
 
213 +

 
214 +
        @par Exception Safety
 
215 +
        Strong guarantee.
 
216 +
        Calls to `memory_resource::allocate` may throw.
 
217 +

 
218 +
        @param min_capacity The minimum number
 
219 +
        of elements for which capacity is guaranteed
 
220 +
        without a subsequent reallocation.
 
221 +

 
222 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
223 +
        use. The container will acquire shared ownership of the memory
 
224 +
        resource.
254  
    */
225  
    */
255  
    BOOST_JSON_DECL
226  
    BOOST_JSON_DECL
256  
    object(
227  
    object(
257  
        std::size_t min_capacity,
228  
        std::size_t min_capacity,
258  
        storage_ptr sp = {});
229  
        storage_ptr sp = {});
259  

230  

260 -
    /** Overload
231 +
    /** Constructor.
261  

232  

262 -
        @param first An input iterator pointing to the first element to insert,
233 +
        The object is constructed with the elements
263 -
               or pointing to the end of the range.
234 +
        in the range `{first, last)`, preserving order,
264 -
        @param last An input iterator pointing to the end of the range.
235 +
        using the specified memory resource.
265 -
        @param min_capacity
236 +
        If there are elements with duplicate keys; that
266 -
        @param sp
237 +
        is, if multiple elements in the range have keys
 
238 +
        that compare equal, only the first equivalent
 
239 +
        element will be inserted.
267  

240  

268 -
        @tparam InputIt a type satisfying the requirements of
241 +
        @par Constraints
269 -
                {req_InputIterator}.
242 +
        @code
 
243 +
        std::is_constructible_v<
 
244 +
            key_value_pair,
 
245 +
            std::iterator_traits<InputIt>::reference>
 
246 +
        @endcode
 
247 +

 
248 +
        @par Complexity
 
249 +
        Linear in `std::distance(first, last)`.
 
250 +

 
251 +
        @par Exception Safety
 
252 +
        Strong guarantee.
 
253 +
        Calls to `memory_resource::allocate` may throw.
 
254 +

 
255 +
        @param first An input iterator pointing to the
 
256 +
        first element to insert, or pointing to the end
 
257 +
        of the range.
 
258 +

 
259 +
        @param last An input iterator pointing to the end
 
260 +
        of the range.
 
261 +

 
262 +
        @param min_capacity The minimum number
 
263 +
        of elements for which capacity is guaranteed
 
264 +
        without a subsequent reallocation.
 
265 +
        Upon construction, @ref capacity() will be greater
 
266 +
        than or equal to this number.
 
267 +

 
268 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
269 +
        use. The container will acquire shared ownership of the memory
 
270 +
        resource.
 
271 +

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

295  

292 -
    /** Overload
296 +
    /** Move constructor.
293  

297  

294 -
        @param init The initializer list to insert.
298 +
        The object is constructed by acquiring ownership of
295 -
        @param sp
299 +
        the contents of `other` and shared ownership
 
300 +
        of `other`'s memory resource.
 
301 +

 
302 +
        @note
 
303 +

 
304 +
        After construction, the moved-from object behaves
 
305 +
        as if newly constructed with its current memory resource.
 
306 +

 
307 +
        @par Complexity
 
308 +
        Constant.
 
309 +

 
310 +
        @par Exception Safety
 
311 +
        No-throw guarantee.
 
312 +

 
313 +
        @param other The object to move.
296  
    */
314  
    */
297 -
    object(
315 +
    BOOST_JSON_DECL
298 -
        std::initializer_list<
316 +
    object(object&& other) noexcept;
299 -
            std::pair<string_view, value_ref>> init,
 
300 -
        storage_ptr sp = {})
 
301 -
        : object(init, 0, std::move(sp))
 
302 -
    {
 
303 -
    }
 
304  

317  

305 -
    /** Overload
318 +
    /** Move constructor.
306  

319  

307 -
        @param init
320 +
        The object is constructed with the contents of
308 -
        @param min_capacity
321 +
        `other` by move semantics, using the specified
309 -
        @param sp
322 +
        memory resource:
 
323 +

 
324 +
        @li If `*other.storage() == *sp`, ownership of
 
325 +
        the underlying memory is transferred in constant
 
326 +
        time, with no possibility of exceptions.
 
327 +
        After construction, the moved-from object behaves
 
328 +
        as if newly constructed with its current storage
 
329 +
        pointer.
 
330 +

 
331 +
        @li If `*other.storage() != *sp`, an
 
332 +
        element-wise copy is performed, which may throw.
 
333 +
        In this case, the moved-from object is not
 
334 +
        changed.
 
335 +

 
336 +
        @par Complexity
 
337 +
        Constant or linear in `other.size()`.
 
338 +

 
339 +
        @par Exception Safety
 
340 +
        Strong guarantee.
 
341 +
        Calls to `memory_resource::allocate` may throw.
 
342 +

 
343 +
        @param other The object to move.
 
344 +

 
345 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
346 +
        use. The container will acquire shared ownership of the memory
 
347 +
        resource.
310  
    */
348  
    */
311  
    BOOST_JSON_DECL
349  
    BOOST_JSON_DECL
312  
    object(
350  
    object(
313 -
        std::initializer_list<
351 +
        object&& other,
314 -
            std::pair<string_view, value_ref>> init,
352 +
        storage_ptr sp);
315 -
        std::size_t min_capacity,
 
316 -
        storage_ptr sp = {});
 
317  

353  

318 -
    /** Overload
354 +
    /** Pilfer constructor.
319  

355  

320 -
        @param other Another object.
356 +
        The object is constructed by acquiring ownership
 
357 +
        of the contents of `other` using pilfer semantics.
 
358 +
        This is more efficient than move construction, when
 
359 +
        it is known that the moved-from object will be
 
360 +
        immediately destroyed afterwards.
 
361 +

 
362 +
        @par Complexity
 
363 +
        Constant.
 
364 +

 
365 +
        @par Exception Safety
 
366 +
        No-throw guarantee.
 
367 +

 
368 +
        @param other The value to pilfer. After pilfer
 
369 +
        construction, `other` is not in a usable state
 
370 +
        and may only be destroyed.
 
371 +

 
372 +
        @see @ref pilfer,
 
373 +
            <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
 
374 +
                Valueless Variants Considered Harmful</a>
 
375 +
    */
 
376 +
    object(pilfered<object> other) noexcept
 
377 +
        : sp_(std::move(other.get().sp_))
 
378 +
        , t_(detail::exchange(
 
379 +
            other.get().t_, &empty_))
 
380 +
    {
 
381 +
    }
 
382 +

 
383 +
    /** Copy constructor.
 
384 +

 
385 +
        The object is constructed with a copy of the
 
386 +
        contents of `other`, using `other`'s memory resource.
 
387 +

 
388 +
        @par Complexity
 
389 +
        Linear in `other.size()`.
 
390 +

 
391 +
        @par Exception Safety
 
392 +
        Strong guarantee.
 
393 +
        Calls to `memory_resource::allocate` may throw.
 
394 +

 
395 +
        @param other The object to copy.
321  
    */
396  
    */
322  
    object(
397  
    object(
323  
        object const& other)
398  
        object const& other)
324  
        : object(other, other.sp_)
399  
        : object(other, other.sp_)
325  
    {
400  
    {
326  
    }
401  
    }
327  

402  

328 -
    /** Overload
403 +
    /** Copy constructor.
329  

404  

330 -
        @param other
405 +
        The object is constructed with a copy of the
331 -
        @param sp
406 +
        contents of `other`, using the specified memory resource.
 
407 +

 
408 +
        @par Complexity
 
409 +
        Linear in `other.size()`.
 
410 +

 
411 +
        @par Exception Safety
 
412 +
        Strong guarantee.
 
413 +
        Calls to `memory_resource::allocate` may throw.
 
414 +

 
415 +
        @param other The object to copy.
 
416 +

 
417 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
418 +
        use. The container will acquire shared ownership of the memory
 
419 +
        resource.
332  
    */
420  
    */
333  
    BOOST_JSON_DECL
421  
    BOOST_JSON_DECL
334  
    object(
422  
    object(
335  
        object const& other,
423  
        object const& other,
336  
        storage_ptr sp);
424  
        storage_ptr sp);
337  

425  

338 -
    /** Overload
426 +
    /** Construct from initializer-list.
339  

427  

340 -
        @param other
428 +
        The object is constructed with a copy of the values
341 -
    */
429 +
        in the initializer-list in order, using the
342 -
    BOOST_JSON_DECL
430 +
        specified memory resource.
343 -
    object(object&& other) noexcept;
431 +
        If there are elements with duplicate keys; that
 
432 +
        is, if multiple elements in the range have keys
 
433 +
        that compare equal, only the first equivalent
 
434 +
        element will be inserted.
344  

435  

345 -
    /** Overload
436 +
        @par Complexity
 
437 +
        Linear in `init.size()`.
346  

438  

347 -
        @param other
439 +
        @par Exception Safety
348 -
        @param sp
440 +
        Strong guarantee.
349 -
    */
441 +
        Calls to `memory_resource::allocate` may throw.
350 -
    BOOST_JSON_DECL
 
351 -
    object(
 
352 -
        object&& other,
 
353 -
        storage_ptr sp);
 
354  

442  

355 -
    /** Overload
443 +
        @param init The initializer list to insert.
356  

444  

357 -
        @param other
445 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
446 +
        use. The container will acquire shared ownership of the memory
 
447 +
        resource.
358  
    */
448  
    */
359 -
    object(pilfered<object> other) noexcept
449 +
    object(
360 -
        : sp_(std::move(other.get().sp_))
450 +
        std::initializer_list<
361 -
        , t_(detail::exchange(
451 +
            std::pair<string_view, value_ref>> init,
362 -
            other.get().t_, &empty_))
452 +
        storage_ptr sp = {})
 
453 +
        : object(init, 0, std::move(sp))
363  
    {
454  
    {
364  
    }
455  
    }
365 -
    /// @}
456 +

 
457 +
    /** Construct from initializer-list.
 
458 +

 
459 +
        Storage for at least `min_capacity` elements is
 
460 +
        reserved, and then
 
461 +
        the object is constructed with a copy of the values
 
462 +
        in the initializer-list in order, using the
 
463 +
        specified memory resource.
 
464 +
        If there are elements with duplicate keys; that
 
465 +
        is, if multiple elements in the range have keys
 
466 +
        that compare equal, only the first equivalent
 
467 +
        element will be inserted.
 
468 +

 
469 +
        @par Complexity
 
470 +
        Linear in `init.size()`.
 
471 +

 
472 +
        @par Exception Safety
 
473 +
        Strong guarantee.
 
474 +
        Calls to `memory_resource::allocate` may throw.
 
475 +

 
476 +
        @param init The initializer list to insert.
 
477 +

 
478 +
        @param min_capacity The minimum number
 
479 +
        of elements for which capacity is guaranteed
 
480 +
        without a subsequent reallocation.
 
481 +
        Upon construction, @ref capacity() will be greater
 
482 +
        than or equal to this number.
 
483 +

 
484 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
485 +
        use. The container will acquire shared ownership of the memory
 
486 +
        resource.
 
487 +
    */
 
488 +
    BOOST_JSON_DECL
 
489 +
    object(
 
490 +
        std::initializer_list<
 
491 +
            std::pair<string_view, value_ref>> init,
 
492 +
        std::size_t min_capacity,
 
493 +
        storage_ptr sp = {});
366  

494  

367  
    //------------------------------------------------------
495  
    //------------------------------------------------------
368  
    //
496  
    //
369  
    // Assignment
497  
    // Assignment
370  
    //
498  
    //
371  
    //------------------------------------------------------
499  
    //------------------------------------------------------
372  

500  

373 -
    /** Assignment operators.
501 +
    /** Copy assignment.
374 -

 
375 -
        Replaces the contents of this object.
 
376  

502  

377 -
        @li **(1)** replaces with the copies of the elements of `other`.
503 +
        The contents of the object are replaced with an
378 -
        @li **(2)** takes ownership of `other`'s element storage if
504 +
        element-wise copy of `other`.
379 -
            `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
 
380 -
        @li **(3)** replaces with the elements of `init`.
 
381  

505  

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

508  

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

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

512  

396 -
        @par Complexity
513 +
        @param other The object to copy.
397 -

 
398 -
        @param other Another object.
 
399 -

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

518  

 
519 +
    /** Move assignment.
 
520 +

 
521 +
        The contents of the object are replaced with the
 
522 +
        contents of `other` using move semantics:
 
523 +

 
524 +
        @li If `*other.storage() == *sp`, ownership of
 
525 +
        the underlying memory is transferred in constant
 
526 +
        time, with no possibility of exceptions.
 
527 +
        After assignment, the moved-from object behaves
 
528 +
        as if newly constructed with its current storage
 
529 +
        pointer.
 
530 +

 
531 +
        @li If `*other.storage() != *sp`, an
 
532 +
        element-wise copy is performed, which may throw.
 
533 +
        In this case, the moved-from object is not
 
534 +
        changed.
 
535 +

 
536 +
        @par Complexity
 
537 +
        Constant or linear in @ref size() plus `other.size()`.
 
538 +

 
539 +
        @par Exception Safety
 
540 +
        Strong guarantee.
 
541 +
        Calls to `memory_resource::allocate` may throw.
 
542 +

 
543 +
        @param other The object to move.
 
544 +
    */
406  
    BOOST_JSON_DECL
545  
    BOOST_JSON_DECL
407  
    object&
546  
    object&
408  
    operator=(object&& other);
547  
    operator=(object&& other);
409  

548  

410 -
    /** Overload
549 +
    /** Assignment.
 
550 +

 
551 +
        Replaces the contents with the contents of an
 
552 +
        initializer list.
 
553 +

 
554 +
        @par Complexity
 
555 +
        Linear in @ref size() plus
 
556 +
        average case linear in `init.size()`,
 
557 +
        worst case quadratic in `init.size()`.
 
558 +

 
559 +
        @par Exception Safety
 
560 +
        Strong guarantee.
 
561 +
        Calls to `memory_resource::allocate` may throw.
411  

562  

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

569  

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

571  

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

573  

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

576  

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

579  

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

588  

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

590  

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

593  

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

596  

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

605  

456  
    //------------------------------------------------------
606  
    //------------------------------------------------------
457  
    //
607  
    //
458  
    // Iterators
608  
    // Iterators
459  
    //
609  
    //
460  
    //------------------------------------------------------
610  
    //------------------------------------------------------
461  

611  

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

613  

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

615  

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

618  

469  
        @par Exception Safety
619  
        @par Exception Safety
470 -

 
471 -
        @{
 
472  
        No-throw guarantee.
620  
        No-throw guarantee.
473  
    */
621  
    */
474  
    inline
622  
    inline
475  
    iterator
623  
    iterator
476  
    begin() noexcept;
624  
    begin() noexcept;
477  

625  

 
626 +
    /** Return a const iterator to the first element.
 
627 +

 
628 +
        If the container is empty, @ref end() is returned.
 
629 +

 
630 +
        @par Complexity
 
631 +
        Constant.
 
632 +

 
633 +
        @par Exception Safety
 
634 +
        No-throw guarantee.
 
635 +
    */
478  
    inline
636  
    inline
479  
    const_iterator
637  
    const_iterator
480 -
    /// @}
 
481  
    begin() const noexcept;
638  
    begin() const noexcept;
482  

639  

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

641  

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

643  

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

646  

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

653  

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

655  

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

658  

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

661  

505  
        @par Exception Safety
662  
        @par Exception Safety
506 -

 
507 -
        @{
 
508  
        No-throw guarantee.
663  
        No-throw guarantee.
509  
    */
664  
    */
510  
    inline
665  
    inline
511  
    iterator
666  
    iterator
512  
    end() noexcept;
667  
    end() noexcept;
513  

668  

 
669 +
    /** Return a const iterator to the element following the last element.
 
670 +

 
671 +
        The element acts as a placeholder; attempting
 
672 +
        to access it results in undefined behavior.
 
673 +

 
674 +
        @par Complexity
 
675 +
        Constant.
 
676 +

 
677 +
        @par Exception Safety
 
678 +
        No-throw guarantee.
 
679 +
    */
514  
    inline
680  
    inline
515  
    const_iterator
681  
    const_iterator
516 -
    /// @}
 
517  
    end() const noexcept;
682  
    end() const noexcept;
518  

683  

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

685  

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

688  

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

691  

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

698  

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

700  

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

704  

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

707  

543  
        @par Exception Safety
708  
        @par Exception Safety
544 -

 
545 -
        @{
 
546  
        No-throw guarantee.
709  
        No-throw guarantee.
547  
    */
710  
    */
548  
    inline
711  
    inline
549  
    reverse_iterator
712  
    reverse_iterator
550  
    rbegin() noexcept;
713  
    rbegin() noexcept;
551  

714  

 
715 +
    /** Return a const reverse iterator to the first element of the reversed container.
 
716 +

 
717 +
        The pointed-to element corresponds to the
 
718 +
        last element of the non-reversed container.
 
719 +
        If the container is empty, @ref rend() is returned.
 
720 +

 
721 +
        @par Complexity
 
722 +
        Constant.
 
723 +

 
724 +
        @par Exception Safety
 
725 +
        No-throw guarantee.
 
726 +
    */
552  
    inline
727  
    inline
553  
    const_reverse_iterator
728  
    const_reverse_iterator
554 -
    /// @}
 
555  
    rbegin() const noexcept;
729  
    rbegin() const noexcept;
556  

730  

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

732  

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

736  

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

739  

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

746  

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

748  

575 -
        The pointed-to element corresponds to the element preceding the first
749 +
        The pointed-to element corresponds to the element
576 -
        element of the non-reversed container. The returned iterator only acts
750 +
        preceding the first element of the non-reversed container.
577 -
        as a sentinel. Dereferencing it results in undefined behavior.
751 +
        This element acts as a placeholder, attempting
 
752 +
        to access it results in undefined behavior.
578  

753  

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

756  

582  
        @par Exception Safety
757  
        @par Exception Safety
583 -

 
584 -
        @{
 
585  
        No-throw guarantee.
758  
        No-throw guarantee.
586  
    */
759  
    */
587  
    inline
760  
    inline
588  
    reverse_iterator
761  
    reverse_iterator
589  
    rend() noexcept;
762  
    rend() noexcept;
590  

763  

 
764 +
    /** Return a const reverse iterator to the element following the last element of the reversed container.
 
765 +

 
766 +
        The pointed-to element corresponds to the element
 
767 +
        preceding the first element of the non-reversed container.
 
768 +
        This element acts as a placeholder, attempting
 
769 +
        to access it results in undefined behavior.
 
770 +

 
771 +
        @par Complexity
 
772 +
        Constant.
 
773 +

 
774 +
        @par Exception Safety
 
775 +
        No-throw guarantee.
 
776 +
    */
591  
    inline
777  
    inline
592  
    const_reverse_iterator
778  
    const_reverse_iterator
593 -
    /// @}
 
594  
    rend() const noexcept;
779  
    rend() const noexcept;
595  

780  

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

782  

598 -
        The pointed-to element corresponds to the element preceding the first
783 +
        The pointed-to element corresponds to the element
599 -
        element of the non-reversed container. The returned iterator only acts
784 +
        preceding the first element of the non-reversed container.
600 -
        as a sentinel. Dereferencing it results in undefined behavior.
785 +
        This element acts as a placeholder, attempting
 
786 +
        to access it results in undefined behavior.
601  

787  

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

790  

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

797  

612  
    //------------------------------------------------------
798  
    //------------------------------------------------------
613  
    //
799  
    //
614  
    // Capacity
800  
    // Capacity
615  
    //
801  
    //
616  
    //------------------------------------------------------
802  
    //------------------------------------------------------
617  

803  

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

805  

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

808  

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

811  

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

818  

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

820  

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

822  

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

825  

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

832  

647 -
    /** The maximum number of elements an object can hold.
833 +
    /** Return the maximum number of elements any object can hold
648  

834  

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

839  

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

842  

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

850  

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

852  

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

855  

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

858  

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

865  

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

867  

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

874  

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

880  

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

884  

695  
        @par Exception Safety
885  
        @par Exception Safety
696 -
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
886 +
        Strong guarantee.
 
887 +
        Calls to `memory_resource::allocate` may throw.
697  

888  

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

890  

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

896  

706  
    //------------------------------------------------------
897  
    //------------------------------------------------------
707  
    //
898  
    //
708  
    // Modifiers
899  
    // Modifiers
709  
    //
900  
    //
710  
    //------------------------------------------------------
901  
    //------------------------------------------------------
711  

902  

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

904  

714 -
        Erases all elements from the container. After this call, @ref size()
905 +
        Erases all elements from the container without
715 -
        returns zero but @ref capacity() is unchanged. All references,
906 +
        changing the capacity.
716 -
        pointers, and iterators are invalidated.
907 +
        After this call, @ref size() returns zero.
 
908 +
        All references, pointers, and iterators are
 
909 +
        invalidated.
717  

910  

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

913  

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

920  

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

922  

730 -
        @li **(1)** inserts a new element constructed as if via
923 +
        Inserts `p` if `this->contains(value_type(p).key())` is `false`.
731 -
            `value_type( std::forward<P>(p) )`.
924 +
        @ref value_type must be constructible from `p`.
732 -
        @li **(2)** the elements in the range `[first, last)` are inserted one
 
733 -
            at a time, in order.
 
734 -
        @li **(3)** the elements in the initializer list are inserted one at a
 
735 -
            time, in order.
 
736 -

 
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
 
739 -
        within the inserted range that are equal to each other, only the
 
740 -
        first will be inserted.
 
741 -

 
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
 
744 -
        iterators and references are invalidated. Otherwise, they are not
 
745 -
        affected.
 
746  

925  

747 -
        @pre
926 +
        If the insertion occurs and results in a rehashing
748 -
        `first` and `last` are not iterators into `*this`. `first` and `last`
927 +
        of the container, all iterators and references are invalidated.
749 -
        form a valid range.
928 +
        Otherwise, they are not affected.
 
929 +
        Rehashing occurs only if the new number of elements
 
930 +
        is greater than @ref capacity().
750  

931  

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

936  

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

940  

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

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

944  

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

946  

772 -
        @throw boost::system::system_error The size of a key would exceed
947 +
        @throw `boost::system::system_error` key is too long.
773 -
               @ref string::max_size.
948 +
        @throw `boost::system::system_error` @ref size() >= max_size().
774 -
        @throw `boost::system::system_error` @ref size() >= @ref max_size().
 
775 -

 
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
 
778 -
        insertion took place or `false` otherwise. **(2)** returns `void`.
 
779  

949  

780 -
        @{
950 +
        @return A pair where `first` is an iterator
 
951 +
        to the existing or inserted element, and `second`
 
952 +
        is `true` if the insertion took place or `false` otherwise.
781  
    */
953  
    */
782  
    template<class P
954  
    template<class P
783  
#ifndef BOOST_JSON_DOCS
955  
#ifndef BOOST_JSON_DOCS
784  
        ,class = typename std::enable_if<
956  
        ,class = typename std::enable_if<
785  
            std::is_constructible<key_value_pair,
957  
            std::is_constructible<key_value_pair,
786  
                P, storage_ptr>::value>::type
958  
                P, storage_ptr>::value>::type
787  
#endif
959  
#endif
788  
    >
960  
    >
789  
    std::pair<iterator, bool>
961  
    std::pair<iterator, bool>
790  
    insert(P&& p);
962  
    insert(P&& p);
791  

963  

792 -
    /** Overload
964 +
    /** Insert elements.
793  

965  

794 -
        @param first An input iterator pointing to the first element to insert,
966 +
        The elements in the range `[first, last)` are inserted one at a time,
795 -
               or pointing to the end of the range.
967 +
        in order. Any element with key that is a duplicate of a key already
 
968 +
        present in container will be skipped. This also means, that if there
 
969 +
        are two keys within the range that are equal to each other, only the
 
970 +
        first will be inserted.
796  

971  

797 -
        @param last An input iterator pointing to the end of the range.
972 +
        @n
 
973 +

 
974 +
        Insertion may result in rehashing of the container. In that case all
 
975 +
        iterators and references are invalidated. Otherwise, they are not
 
976 +
        affected.
 
977 +

 
978 +
        @par Precondition
 
979 +
        `first` and `last` are not iterators into `*this`.
 
980 +
        `first` and `last` form a valid range.
 
981 +

 
982 +
        @par Constraints
 
983 +
        @code
 
984 +
        std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
 
985 +
        @endcode
 
986 +

 
987 +
        @par Complexity
 
988 +
        Linear in `std::distance(first, last)`.
 
989 +

 
990 +
        @par Exception Safety
 
991 +
        Strong guarantee for forward iterators, basic guarantee for input
 
992 +
        iterators.
 
993 +
        Calls to `memory_resource::allocate` may throw.
 
994 +

 
995 +
        @param first An input iterator pointing to the first
 
996 +
        element to insert, or pointing to the end of the range.
 
997 +

 
998 +
        @param last An input iterator pointing to the end
 
999 +
        of the range.
798  

1000  

799  
        @tparam InputIt a type satisfying the requirements
1001  
        @tparam InputIt a type satisfying the requirements
800 -
                of {req_InputIterator}.
1002 +
        of __InputIterator__.
801  
    */
1003  
    */
802  
    template<
1004  
    template<
803  
        class InputIt
1005  
        class InputIt
804  
    #ifndef BOOST_JSON_DOCS
1006  
    #ifndef BOOST_JSON_DOCS
805  
        ,class = is_inputit<InputIt>
1007  
        ,class = is_inputit<InputIt>
806  
    #endif
1008  
    #endif
807  
    >
1009  
    >
808  
    void
1010  
    void
809  
    insert(InputIt first, InputIt last)
1011  
    insert(InputIt first, InputIt last)
810  
    {
1012  
    {
811  
        insert(first, last, typename
1013  
        insert(first, last, typename
812  
            std::iterator_traits<InputIt
1014  
            std::iterator_traits<InputIt
813  
                >::iterator_category{});
1015  
                >::iterator_category{});
814  
    }
1016  
    }
815  

1017  

816 -
    /** Overload
1018 +
    /** Insert elements.
817  

1019  

818 -
        @param init The initializer list to insert.
1020 +
        The elements in the initializer list are inserted one at a time, in
 
1021 +
        order. Any element with key that is a duplicate of a key already
 
1022 +
        present in container will be skipped. This also means, that if there
 
1023 +
        are two keys within the initializer list that are equal to each other,
 
1024 +
        only the first will be inserted.
 
1025 +

 
1026 +
        Insertion may result in rehashing of the container. In that case all
 
1027 +
        iterators and references are invalidated. Otherwise, they are not
 
1028 +
        affected.
 
1029 +

 
1030 +
        @par Complexity
 
1031 +
        Linear in `init.size()`.
 
1032 +

 
1033 +
        @par Exception Safety
 
1034 +
        Basic guarantee.
 
1035 +
        Calls to `memory_resource::allocate` may throw.
 
1036 +

 
1037 +
        @param init The initializer list to insert
819  
    */
1038  
    */
820  
    BOOST_JSON_DECL
1039  
    BOOST_JSON_DECL
821  
    void
1040  
    void
822  
    insert(std::initializer_list<
1041  
    insert(std::initializer_list<
823 -
    /// @}
 
824  
        std::pair<string_view, value_ref>> init);
1042  
        std::pair<string_view, value_ref>> init);
825  

1043  

826 -
    /** Insert an element or assign to an existing element.
1044 +
    /** Insert an element or assign to the current element if the key already exists.
827  

1045  

828 -
        If the key equal to `key` already exists in the container, assigns
1046 +
        If the key equivalent to `key` already exists in the
829 -
        `std::forward<M>(m)` to the @ref mapped_type corresponding to that key.
1047 +
        container, assigns `std::forward<M>(m)` to the
830 -
        Otherwise, inserts the as if by @ref insert, constructing it using
1048 +
        `mapped_type` corresponding to the key. Otherwise,
831 -
        `value_type(key, std::forward<M>(m))`.
1049 +
        inserts the new value at the end as if by insert,
 
1050 +
        constructing it from `value_type(key, std::forward<M>(m))`.
832  

1051  

833 -
        If insertion would result in the new number of elements exceeding
1052 +
        If the insertion occurs and results in a rehashing of the container,
834 -
        @ref capacity(), a reallocation and a rehashing occur. In that case all
1053 +
        all iterators and references are invalidated. Otherwise, they are not
835 -
        iterators and references are invalidated. Otherwise, they are not
1054 +
        affected. Rehashing occurs only if the new number of elements is
836 -
        affected.
1055 +
        greater than @ref capacity().
837  

1056  

838  
        @par Complexity
1057  
        @par Complexity
839 -
        Constant on average, worst case linear in @ref size().
1058 +
        Amortized constant on average, worst case linear in @ref size().
840  

1059  

841  
        @par Exception Safety
1060  
        @par Exception Safety
842 -
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1061 +
        Strong guarantee.
 
1062 +
        Calls to `memory_resource::allocate` may throw.
843  

1063  

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

1068  

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

1070  

851 -
        @throw boost::system::system_error The size of a key would exceed
1071 +
        @param m The value to insert or assign
852 -
               @ref string::max_size.
1072 +

 
1073 +
        @throw `boost::system::system_error` if key is too long.
853  
    */
1074  
    */
854  
    template<class M>
1075  
    template<class M>
855  
    std::pair<iterator, bool>
1076  
    std::pair<iterator, bool>
856  
    insert_or_assign(
1077  
    insert_or_assign(
857  
        string_view key, M&& m);
1078  
        string_view key, M&& m);
858  

1079  

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

1081  

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

1085  

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

1090  

870  
        @par Complexity
1091  
        @par Complexity
871 -
        Constant on average, worst case linear in @ref size().
1092 +
        Amortized constant on average, worst case linear in @ref size().
872  

1093  

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

1097  

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

1101  

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

1103  

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

1107  

887 -
        @throw boost::system::system_error The size of the key would exceed
1108 +
        @throw `boost::system::system_error` if key is too long.
888 -
               @ref string::max_size.
 
889 -

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

1113  

895 -
    /** Remove an element.
1114 +
    /** Erase an element
896  

1115  

897 -
        @li **(1)** the element at `pos` is removed.
1116 +
        Remove the element pointed to by `pos`, which must
898 -
        @li **(2)** the element with the key `key` is removed, if it exists.
1117 +
        be valid and dereferenceable.
 
1118 +
        References and iterators to the erased element are
 
1119 +
        invalidated. Other iterators and references are not
 
1120 +
        invalidated.
899  

1121  

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

1123  

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

1126  

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

1129  

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

1132  

913 -
        @return
1133 +
        @return 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
 
916 -
            0 or 1.
 
917 -

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

1134  

920 -
        @{
1135 +
        @param pos An iterator pointing to the element to be
 
1136 +
        removed.
921  
    */
1137  
    */
922  
    BOOST_JSON_DECL
1138  
    BOOST_JSON_DECL
923  
    iterator
1139  
    iterator
924  
    erase(const_iterator pos) noexcept;
1140  
    erase(const_iterator pos) noexcept;
925  

1141  

926 -
    /** Overload
1142 +
    /** Erase an element
 
1143 +

 
1144 +
        Remove the element which matches `key`, if it exists.
 
1145 +
        References and iterators to the erased element are
 
1146 +
        invalidated. Other iterators and references are not
 
1147 +
        invalidated.
 
1148 +

 
1149 +
        @par Complexity
 
1150 +
        Constant on average, worst case linear in @ref size().
 
1151 +

 
1152 +
        @par Exception Safety
 
1153 +
        No-throw guarantee.
 
1154 +

 
1155 +
        @return The number of elements removed, which will
 
1156 +
        be either 0 or 1.
927  

1157  

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

1163  

935 -
    /** Erase an element preserving order.
1164 +
    /** Erase an element preserving order
936  

1165  

937 -
        @li **(1)** Remove the element pointed to by `pos`, which must be valid
1166 +
        Remove the element pointed to by `pos`, which must be valid and
938 -
        and dereferenceable. References and iterators from `pos` to @ref end(),
1167 +
        dereferenceable. References and iterators from `pos` to @ref end(),
939  
        both included, are invalidated. Other iterators and references are not
1168  
        both included, are invalidated. Other iterators and references are not
940 -
        invalidated.
1169 +
        invalidated. The relative order of remaining elements is preserved.
941 -
        @li **(2)** Remove the element which matches `key`, if it exists. All
 
942 -
        references and iterators are invalidated.
 
943 -

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

1170  

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

1174  

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

1177  

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

1180  

955 -
        @return
1181 +
        @return 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.
 
958  

1182  

959  
        @param pos An iterator pointing to the element to be
1183  
        @param pos An iterator pointing to the element to be
960 -

 
961 -
        @{
 
962  
        removed.
1184  
        removed.
963  
    */
1185  
    */
964  
    BOOST_JSON_DECL
1186  
    BOOST_JSON_DECL
965  
    iterator
1187  
    iterator
966  
    stable_erase(const_iterator pos) noexcept;
1188  
    stable_erase(const_iterator pos) noexcept;
967  

1189  

968 -
    /** Overload
1190 +
    /** Erase an element preserving order
 
1191 +

 
1192 +
        Remove the element which matches `key`, if it exists.
 
1193 +
        All references and iterators are invalidated.
 
1194 +
        The relative order of remaining elements is preserved.
 
1195 +

 
1196 +
        @par Complexity
 
1197 +
        Linear in @ref size().
 
1198 +

 
1199 +
        @par Exception Safety
 
1200 +
        No-throw guarantee.
 
1201 +

 
1202 +
        @return The number of elements removed, which will
 
1203 +
        be either 0 or 1.
969  

1204  

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

1210  

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

1212  

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

1216  

983 -
        @li If `*storage() == *other.storage()` all iterators and references
1217 +
        @li If `*other.storage() == *this->storage()`,
984 -
        remain valid.
1218 +
        ownership of the underlying memory is swapped in
 
1219 +
        constant time, with no possibility of exceptions.
 
1220 +
        All iterators and references remain valid.
985  

1221  

986 -
        @li Otherwise, the contents are logically swapped by making copies,
1222 +
        @li If `*other.storage() != *this->storage()`,
987 -
        which can throw. In this case all iterators and references are
1223 +
        the contents are logically swapped by making copies,
988 -
        invalidated.
1224 +
        which can throw. In this case all iterators and
 
1225 +
        references are invalidated.
989  

1226  

990  
        @par Complexity
1227  
        @par Complexity
991 -
        If `*storage() == *other.storage()`, then constant; otherwise linear in
1228 +
        Constant or linear in @ref size() plus `other.size()`.
992 -
        `size() + other.size()`.
 
993  

1229  

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

1233  

998  
        @param other The object to swap with.
1234  
        @param other The object to swap with.
 
1235 +
        If `this == &other`, this function call has no effect.
999  
    */
1236  
    */
1000  
    BOOST_JSON_DECL
1237  
    BOOST_JSON_DECL
1001  
    void
1238  
    void
1002  
    swap(object& other);
1239  
    swap(object& other);
1003  

1240  

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

1242  

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

1246  

1011 -
        @li If `*lhs.storage() == *rhs.storage()` all iterators and references
1247 +
        @li If `*lhs.storage() == *rhs.storage()`,
1012 -
        remain valid.
1248 +
        ownership of the underlying memory is swapped in
 
1249 +
        constant time, with no possibility of exceptions.
 
1250 +
        All iterators and references remain valid.
1013  

1251  

1014 -
        @li Otherwise, the contents are logically swapped by making copies,
1252 +
        @li If `*lhs.storage() != *rhs.storage()`,
1015 -
        which can throw. In this case all iterators and references are
1253 +
        the contents are logically swapped by making a copy,
1016 -
        invalidated.
1254 +
        which can throw. In this case all iterators and
 
1255 +
        references are invalidated.
 
1256 +

 
1257 +
        @par Effects
 
1258 +
        @code
 
1259 +
        lhs.swap( rhs );
 
1260 +
        @endcode
1017  

1261  

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

1264  

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

1268  

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

1270  

1028  
        @param rhs The object to exchange.
1271  
        @param rhs The object to exchange.
 
1272 +
        If `&lhs == &rhs`, this function call has no effect.
1029  

1273  

1030  
        @see @ref object::swap
1274  
        @see @ref object::swap
1031  
    */
1275  
    */
1032  
    friend
1276  
    friend
1033  
    void
1277  
    void
1034  
    swap(object& lhs, object& rhs)
1278  
    swap(object& lhs, object& rhs)
1035  
    {
1279  
    {
1036  
        lhs.swap(rhs);
1280  
        lhs.swap(rhs);
1037  
    }
1281  
    }
1038  

1282  

1039  
    //------------------------------------------------------
1283  
    //------------------------------------------------------
1040  
    //
1284  
    //
1041  
    // Lookup
1285  
    // Lookup
1042  
    //
1286  
    //
1043  
    //------------------------------------------------------
1287  
    //------------------------------------------------------
1044  

1288  

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

1290  

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

1294  

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

1297  

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

1299  

1056  
        @par Complexity
1300  
        @par Complexity
1057 -

 
1058 -
        @{
 
1059  
        Constant on average, worst case linear in @ref size().
1301  
        Constant on average, worst case linear in @ref size().
1060  
    */
1302  
    */
 
1303 +
    /** @{ */
1061  
    BOOST_JSON_DECL
1304  
    BOOST_JSON_DECL
1062  
    system::result<value&>
1305  
    system::result<value&>
1063  
    try_at(string_view key) noexcept;
1306  
    try_at(string_view key) noexcept;
1064  

1307  

1065  
    BOOST_JSON_DECL
1308  
    BOOST_JSON_DECL
1066  
    system::result<value const&>
1309  
    system::result<value const&>
1067  
    try_at(string_view key) const noexcept;
1310  
    try_at(string_view key) const noexcept;
1068 -
    /// @}
1311 +
    /** @} */
1069  

1312  

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

1314  

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

1317  

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

1320  

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

1323  

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

1325  

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

 
1086 -
        @throw `boost::system::system_error` if no such element exists.
 
1087  
        @param key The key of the element to find.
1326  
        @param key The key of the element to find.
1088  

1327  

1089 -
        @see @ref operator[], @ref try_at.
1328 +
        @param loc `source_location` to use in thrown exception; the source
 
1329 +
            location of the call site by default.
1090  

1330  

1091 -
        @{
1331 +
        @throw `boost::system::system_error` if no such element exists.
1092  
    */
1332  
    */
 
1333 +
    /** @{ */
1093  
    inline
1334  
    inline
1094  
    value&
1335  
    value&
1095  
    at(
1336  
    at(
1096  
        string_view key,
1337  
        string_view key,
1097  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
1338  
        source_location const& loc = BOOST_CURRENT_LOCATION) &;
1098  

1339  

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

1345  

1105  
    BOOST_JSON_DECL
1346  
    BOOST_JSON_DECL
1106  
    value const&
1347  
    value const&
1107  
    at(
1348  
    at(
1108  
        string_view key,
1349  
        string_view key,
1109  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
1350  
        source_location const& loc = BOOST_CURRENT_LOCATION) const&;
1110 -
    /// @}
1351 +
    /** @} */
1111  

1352  

1112 -
    /** Access or insert an element.
1353 +
    /** Access or insert the specified element
1113  

1354  

1114 -
        Returns a reference to the value that is mapped to `key`. If such value
1355 +
        Returns a reference to the value that is mapped
1115 -
        does not already exist, performs an insertion of a null value.
1356 +
        to a key equivalent to key, performing an insertion
 
1357 +
        of a null value if such key does not already exist.
1116  

1358  

1117  
        If an insertion occurs and results in a rehashing of the container, all
1359  
        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
1360  
        iterators including any past-the-end iterators, and all references to
1119  
        the elements are invalidated. Otherwise, no iterators or references are
1361  
        the elements are invalidated. Otherwise, no iterators or references are
1120  
        invalidated.
1362  
        invalidated.
1121  

1363  

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

1366  

1125  
        @par Exception Safety
1367  
        @par Exception Safety
1126 -
        Strong guarantee. Calls to `memory_resource::allocate` may throw.
1368 +
        Strong guarantee.
 
1369 +
        Calls to `memory_resource::allocate` may throw.
1127  

1370  

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

1372  

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

1378  

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

1380  

1138 -
        Returns the number of elements with keys equal to `key`. The only
1381 +
        This function returns the count of the number of
1139 -
        possible return values are 0 and 1.
1382 +
        elements match `key`. The only possible return values
 
1383 +
        are 0 and 1.
1140  

1384  

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

1387  

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

1390  

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

1396  

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

1398  

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

1402  

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

1405  

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

1408  

1165 -

 
1166 -
        @{
 
1167  
        @param key The key of the element to find.
1409  
        @param key The key of the element to find.
1168  
    */
1410  
    */
1169  
    BOOST_JSON_DECL
1411  
    BOOST_JSON_DECL
1170  
    iterator
1412  
    iterator
1171  
    find(string_view key) noexcept;
1413  
    find(string_view key) noexcept;
1172  

1414  

 
1415 +
    /** Find an element with a specific key
 
1416 +

 
1417 +
        This function returns a constant iterator to
 
1418 +
        the element matching `key` if it exists,
 
1419 +
        otherwise returns @ref end().
 
1420 +

 
1421 +
        @par Complexity
 
1422 +
        Constant on average, worst case linear in @ref size().
 
1423 +

 
1424 +
        @par Exception Safety
 
1425 +
        No-throw guarantee.
 
1426 +

 
1427 +
        @param key The key of the element to find.
 
1428 +
    */
1173  
    BOOST_JSON_DECL
1429  
    BOOST_JSON_DECL
1174  
    const_iterator
1430  
    const_iterator
1175 -
    /// @}
 
1176  
    find(string_view key) const noexcept;
1431  
    find(string_view key) const noexcept;
1177  

1432  

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

1434  

1180 -
        Checks if there is an element with key equal to `key`.
1435 +
        This function returns `true` if a key with the
 
1436 +
        specified string is found.
1181  

1437  

1182  
        @par Effects
1438  
        @par Effects
1183  
        @code
1439  
        @code
1184 -
        return find(key) != end();
1440 +
        return this->find(key) != this->end();
1185  
        @endcode
1441  
        @endcode
1186  

1442  

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

1445  

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

1448  

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

1450  

1195 -
        @see @ref find.
1451 +
        @see @ref find
1196  
    */
1452  
    */
1197  
    BOOST_JSON_DECL
1453  
    BOOST_JSON_DECL
1198  
    bool
1454  
    bool
1199  
    contains(string_view key) const noexcept;
1455  
    contains(string_view key) const noexcept;
1200  

1456  

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

1458  

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

1462  

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

1468  

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

1471  

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

1474  

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

1476  

1221 -
        @see @ref find.
1477 +
        @see @ref find
1222 -

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

1482  

 
1483 +
    /** Return a pointer to the value if the key is found, or null
 
1484 +

 
1485 +
        This function searches for a value with the given
 
1486 +
        key, and returns a pointer to it if found. Otherwise
 
1487 +
        it returns null.
 
1488 +

 
1489 +
        @par Example
 
1490 +
        @code
 
1491 +
        if( auto p = obj.if_contains( "key" ) )
 
1492 +
            std::cout << *p;
 
1493 +
        @endcode
 
1494 +

 
1495 +
        @par Complexity
 
1496 +
        Constant on average, worst case linear in @ref size().
 
1497 +

 
1498 +
        @par Exception Safety
 
1499 +
        No-throw guarantee.
 
1500 +

 
1501 +
        @param key The key of the element to find.
 
1502 +

 
1503 +
        @see @ref find
 
1504 +
    */
1229  
    BOOST_JSON_DECL
1505  
    BOOST_JSON_DECL
1230  
    value*
1506  
    value*
1231 -
    /// @}
 
1232  
    if_contains(string_view key) noexcept;
1507  
    if_contains(string_view key) noexcept;
1233  

1508  

1234 -
    /** Compare two objects for equality.
1509 +
    /** Return `true` if two objects are equal.
1235  

1510  

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

1514  

1240  
        @par Complexity
1515  
        @par Complexity
1241 -
        Average case linear and worst case quadratic in `lhs.size()`.
1516 +
        Constant, or linear (worst case quadratic) in `lhs.size()`.
1242  

1517  

1243  
        @par Exception Safety
1518  
        @par Exception Safety
1244  
        No-throw guarantee.
1519  
        No-throw guarantee.
1245  
    */
1520  
    */
1246  
    // inline friend speeds up overload resolution
1521  
    // inline friend speeds up overload resolution
1247  
    friend
1522  
    friend
1248  
    bool
1523  
    bool
1249  
    operator==(
1524  
    operator==(
1250  
        object const& lhs,
1525  
        object const& lhs,
1251  
        object const& rhs) noexcept
1526  
        object const& rhs) noexcept
1252  
    {
1527  
    {
1253  
        return lhs.equal(rhs);
1528  
        return lhs.equal(rhs);
1254  
    }
1529  
    }
1255  

1530  

1256 -
    /** Compare two objects for inequality.
1531 +
    /** Return `true` if two objects are not equal.
1257  

1532  

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

1536  

1261  
        @par Complexity
1537  
        @par Complexity
1262 -
        Average casee linear and worst case quadratic in `lhs.size()`.
1538 +
        Constant, or linear (worst case quadratic) in `lhs.size()`.
1263  

1539  

1264  
        @par Exception Safety
1540  
        @par Exception Safety
1265  
        No-throw guarantee.
1541  
        No-throw guarantee.
1266  
    */
1542  
    */
1267  
    // inline friend speeds up overload resolution
1543  
    // inline friend speeds up overload resolution
1268  
    friend
1544  
    friend
1269  
    bool
1545  
    bool
1270  
    operator!=(
1546  
    operator!=(
1271  
        object const& lhs,
1547  
        object const& lhs,
1272  
        object const& rhs) noexcept
1548  
        object const& rhs) noexcept
1273  
    {
1549  
    {
1274  
        return ! (lhs == rhs);
1550  
        return ! (lhs == rhs);
1275  
    }
1551  
    }
1276  

1552  

1277 -
    /** Serialize to an output stream.
1553 +
    /** Serialize @ref object to an output stream.
1278  

1554  

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

1556  

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

1558  

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

1561  

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

1565  

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

1567  

1292  
        @param obj The value to serialize.
1568  
        @param obj The value to serialize.
1293  
    */
1569  
    */
1294  
    BOOST_JSON_DECL
1570  
    BOOST_JSON_DECL
1295  
    friend
1571  
    friend
1296  
    std::ostream&
1572  
    std::ostream&
1297  
    operator<<(
1573  
    operator<<(
1298  
        std::ostream& os,
1574  
        std::ostream& os,
1299  
        object const& obj);
1575  
        object const& obj);
1300  
private:
1576  
private:
1301  
#ifndef BOOST_JSON_DOCS
1577  
#ifndef BOOST_JSON_DOCS
1302  
    // VFALCO friending a detail function makes it public
1578  
    // VFALCO friending a detail function makes it public
1303  
    template<class CharRange>
1579  
    template<class CharRange>
1304  
    friend
1580  
    friend
1305  
    std::pair<key_value_pair*, std::size_t>
1581  
    std::pair<key_value_pair*, std::size_t>
1306  
    detail::find_in_object(
1582  
    detail::find_in_object(
1307  
        object const& obj,
1583  
        object const& obj,
1308  
        CharRange key) noexcept;
1584  
        CharRange key) noexcept;
1309  
#endif
1585  
#endif
1310  

1586  

1311  
    template<class InputIt>
1587  
    template<class InputIt>
1312  
    void
1588  
    void
1313  
    construct(
1589  
    construct(
1314  
        InputIt first,
1590  
        InputIt first,
1315  
        InputIt last,
1591  
        InputIt last,
1316  
        std::size_t min_capacity,
1592  
        std::size_t min_capacity,
1317  
        std::input_iterator_tag);
1593  
        std::input_iterator_tag);
1318  

1594  

1319  
    template<class InputIt>
1595  
    template<class InputIt>
1320  
    void
1596  
    void
1321  
    construct(
1597  
    construct(
1322  
        InputIt first,
1598  
        InputIt first,
1323  
        InputIt last,
1599  
        InputIt last,
1324  
        std::size_t min_capacity,
1600  
        std::size_t min_capacity,
1325  
        std::forward_iterator_tag);
1601  
        std::forward_iterator_tag);
1326  

1602  

1327  
    template<class InputIt>
1603  
    template<class InputIt>
1328  
    void
1604  
    void
1329  
    insert(
1605  
    insert(
1330  
        InputIt first,
1606  
        InputIt first,
1331  
        InputIt last,
1607  
        InputIt last,
1332  
        std::input_iterator_tag);
1608  
        std::input_iterator_tag);
1333  

1609  

1334  
    template<class InputIt>
1610  
    template<class InputIt>
1335  
    void
1611  
    void
1336  
    insert(
1612  
    insert(
1337  
        InputIt first,
1613  
        InputIt first,
1338  
        InputIt last,
1614  
        InputIt last,
1339  
        std::forward_iterator_tag);
1615  
        std::forward_iterator_tag);
1340  

1616  

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

1620  

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

1626  

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

1630  

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

1634  

1359  
    inline
1635  
    inline
1360  
    std::size_t
1636  
    std::size_t
1361  
    growth(
1637  
    growth(
1362  
        std::size_t new_size) const;
1638  
        std::size_t new_size) const;
1363  

1639  

1364  
    inline
1640  
    inline
1365  
    void
1641  
    void
1366  
    remove(
1642  
    remove(
1367  
        index_t& head,
1643  
        index_t& head,
1368  
        key_value_pair& p) noexcept;
1644  
        key_value_pair& p) noexcept;
1369  

1645  

1370  
    inline
1646  
    inline
1371  
    void
1647  
    void
1372  
    destroy() noexcept;
1648  
    destroy() noexcept;
1373  

1649  

1374  
    inline
1650  
    inline
1375  
    void
1651  
    void
1376  
    destroy(
1652  
    destroy(
1377  
        key_value_pair* first,
1653  
        key_value_pair* first,
1378  
        key_value_pair* last) noexcept;
1654  
        key_value_pair* last) noexcept;
1379  

1655  

1380  
    template<class FS, class FB>
1656  
    template<class FS, class FB>
1381  
    auto
1657  
    auto
1382  
    do_erase(
1658  
    do_erase(
1383  
        const_iterator pos,
1659  
        const_iterator pos,
1384  
        FS small_reloc,
1660  
        FS small_reloc,
1385  
        FB big_reloc) noexcept
1661  
        FB big_reloc) noexcept
1386  
        -> iterator;
1662  
        -> iterator;
1387  

1663  

1388  
    inline
1664  
    inline
1389  
    void
1665  
    void
1390  
    reindex_relocate(
1666  
    reindex_relocate(
1391  
        key_value_pair* src,
1667  
        key_value_pair* src,
1392  
        key_value_pair* dst) noexcept;
1668  
        key_value_pair* dst) noexcept;
1393  
};
1669  
};
1394  

1670  

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

1673  

1398  
#ifndef BOOST_JSON_DOCS
1674  
#ifndef BOOST_JSON_DOCS
1399  
// boost::hash trait
1675  
// boost::hash trait
1400  
namespace boost
1676  
namespace boost
1401  
{
1677  
{
1402  
namespace container_hash
1678  
namespace container_hash
1403  
{
1679  
{
1404  

1680  

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

1682  

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

1687  

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

1690  

1415  
// std::hash specialization
1691  
// std::hash specialization
1416  
namespace std {
1692  
namespace std {
1417  
template <>
1693  
template <>
1418  
struct hash< ::boost::json::object > {
1694  
struct hash< ::boost::json::object > {
1419  
    BOOST_JSON_DECL
1695  
    BOOST_JSON_DECL
1420  
    std::size_t
1696  
    std::size_t
1421  
    operator()(::boost::json::object const& jo) const noexcept;
1697  
    operator()(::boost::json::object const& jo) const noexcept;
1422  
};
1698  
};
1423  
} // std
1699  
} // std
1424  
#endif
1700  
#endif
1425  

1701  

1426  

1702  

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

1705  

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

1707  

1432  
#endif
1708  
#endif