100.00% Lines (37/37) 100.00% Functions (12/12)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/boostorg/json 7   // Official repository: https://github.com/boostorg/json
8   // 8   //
9   9  
10   #ifndef BOOST_JSON_OBJECT_HPP 10   #ifndef BOOST_JSON_OBJECT_HPP
11   #define BOOST_JSON_OBJECT_HPP 11   #define BOOST_JSON_OBJECT_HPP
12   12  
13   #include <boost/json/detail/config.hpp> 13   #include <boost/json/detail/config.hpp>
14   #include <boost/json/detail/object.hpp> 14   #include <boost/json/detail/object.hpp>
15   #include <boost/json/detail/value.hpp> 15   #include <boost/json/detail/value.hpp>
16   #include <boost/json/kind.hpp> 16   #include <boost/json/kind.hpp>
17   #include <boost/json/pilfer.hpp> 17   #include <boost/json/pilfer.hpp>
18   #include <boost/system/result.hpp> 18   #include <boost/system/result.hpp>
19   #include <boost/json/storage_ptr.hpp> 19   #include <boost/json/storage_ptr.hpp>
20   #include <boost/json/string_view.hpp> 20   #include <boost/json/string_view.hpp>
21   #include <cstdlib> 21   #include <cstdlib>
22   #include <initializer_list> 22   #include <initializer_list>
23   #include <iterator> 23   #include <iterator>
24   #include <type_traits> 24   #include <type_traits>
25   #include <utility> 25   #include <utility>
26   26  
27   namespace boost { 27   namespace boost {
28   namespace json { 28   namespace json {
29   29  
30   class value; 30   class value;
31   class value_ref; 31   class value_ref;
32   class key_value_pair; 32   class key_value_pair;
33   33  
34   /** A dynamically sized associative container of JSON key/value pairs. 34   /** A dynamically sized associative container of JSON key/value pairs.
35   35  
36   This is an associative container whose elements are key/value pairs with 36   This is an associative container whose elements are key/value pairs with
37   unique keys. 37   unique keys.
38   38  
39   The elements are stored contiguously; iterators are ordinary pointers, 39   The elements are stored contiguously; iterators are ordinary pointers,
40   allowing random access pointer arithmetic for retrieving elements. In 40   allowing random access pointer arithmetic for retrieving elements. In
41   addition, the container maintains an internal index to speed up find 41   addition, the container maintains an internal index to speed up find
42   operations, reducing the average complexity for most lookups and 42   operations, reducing the average complexity for most lookups and
43   insertions. 43   insertions.
44   44  
45   Reallocations are usually costly operations in terms of performance, as 45   Reallocations are usually costly operations in terms of performance, as
46   elements are copied and the internal index must be rebuilt. The @ref 46   elements are copied and the internal index must be rebuilt. The @ref
47   reserve function can be used to eliminate reallocations if the number of 47   reserve function can be used to eliminate reallocations if the number of
48   elements is known beforehand. 48   elements is known beforehand.
49   49  
50   @par Allocators 50   @par Allocators
51   All elements stored in the container, and their children if any, will use 51   All elements stored in the container, and their children if any, will use
52   the same memory resource that was used to construct the container. 52   the same memory resource that was used to construct the container.
53   53  
54   @par Thread Safety 54   @par Thread Safety
55   Non-const member functions may not be called concurrently with any other 55   Non-const member functions may not be called concurrently with any other
56   member functions. 56   member functions.
57   57  
58   @par Satisfies 58   @par Satisfies
59   [ContiguousContainer](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer), 59   [ContiguousContainer](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
60   [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and 60   [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and
61   {req_SequenceContainer}. 61   {req_SequenceContainer}.
62   */ 62   */
63   class object 63   class object
64   { 64   {
65   struct table; 65   struct table;
66   class revert_construct; 66   class revert_construct;
67   class revert_insert; 67   class revert_insert;
68   friend class value; 68   friend class value;
69   friend class object_test; 69   friend class object_test;
70   using access = detail::access; 70   using access = detail::access;
71   using index_t = std::uint32_t; 71   using index_t = std::uint32_t;
72   static index_t constexpr null_index_ = 72   static index_t constexpr null_index_ =
73   std::uint32_t(-1); 73   std::uint32_t(-1);
74   74  
75   storage_ptr sp_; // must come first 75   storage_ptr sp_; // must come first
76   kind k_ = kind::object; // must come second 76   kind k_ = kind::object; // must come second
77   table* t_; 77   table* t_;
78   78  
79   BOOST_JSON_DECL 79   BOOST_JSON_DECL
80   static table empty_; 80   static table empty_;
81   81  
82   template<class T> 82   template<class T>
83   using is_inputit = typename std::enable_if< 83   using is_inputit = typename std::enable_if<
84   std::is_constructible<key_value_pair, 84   std::is_constructible<key_value_pair,
85   typename std::iterator_traits<T>::reference 85   typename std::iterator_traits<T>::reference
86   >::value>::type; 86   >::value>::type;
87   87  
88   BOOST_JSON_DECL 88   BOOST_JSON_DECL
89   explicit 89   explicit
90   object(detail::unchecked_object&& uo); 90   object(detail::unchecked_object&& uo);
91   91  
92   public: 92   public:
93   /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator) 93   /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
94   using allocator_type = container::pmr::polymorphic_allocator<value>; 94   using allocator_type = container::pmr::polymorphic_allocator<value>;
95   95  
96   /** The type of keys. 96   /** The type of keys.
97   97  
98   The function @ref string::max_size returns the 98   The function @ref string::max_size returns the
99   maximum allowed size of strings used as keys. 99   maximum allowed size of strings used as keys.
100   */ 100   */
101   using key_type = string_view; 101   using key_type = string_view;
102   102  
103   /// The type of mapped values 103   /// The type of mapped values
104   using mapped_type = value; 104   using mapped_type = value;
105   105  
106   /// The element type 106   /// The element type
107   using value_type = key_value_pair; 107   using value_type = key_value_pair;
108   108  
109   /// The type used to represent unsigned integers 109   /// The type used to represent unsigned integers
110   using size_type = std::size_t; 110   using size_type = std::size_t;
111   111  
112   /// The type used to represent signed integers 112   /// The type used to represent signed integers
113   using difference_type = std::ptrdiff_t; 113   using difference_type = std::ptrdiff_t;
114   114  
115   /// A reference to an element 115   /// A reference to an element
116   using reference = value_type&; 116   using reference = value_type&;
117   117  
118   /// A const reference to an element 118   /// A const reference to an element
119   using const_reference = value_type const&; 119   using const_reference = value_type const&;
120   120  
121   /// A pointer to an element 121   /// A pointer to an element
122   using pointer = value_type*; 122   using pointer = value_type*;
123   123  
124   /// A const pointer to an element 124   /// A const pointer to an element
125   using const_pointer = value_type const*; 125   using const_pointer = value_type const*;
126   126  
127   /// A random access iterator to an element 127   /// A random access iterator to an element
128   using iterator = value_type*; 128   using iterator = value_type*;
129   129  
130   /// A const random access iterator to an element 130   /// A const random access iterator to an element
131   using const_iterator = value_type const*; 131   using const_iterator = value_type const*;
132   132  
133   /// A reverse random access iterator to an element 133   /// A reverse random access iterator to an element
134   using reverse_iterator = 134   using reverse_iterator =
135   std::reverse_iterator<iterator>; 135   std::reverse_iterator<iterator>;
136   136  
137   /// A const reverse random access iterator to an element 137   /// A const reverse random access iterator to an element
138   using const_reverse_iterator = 138   using const_reverse_iterator =
139   std::reverse_iterator<const_iterator>; 139   std::reverse_iterator<const_iterator>;
140   140  
141   //------------------------------------------------------ 141   //------------------------------------------------------
142   142  
143   /** Destructor. 143   /** Destructor.
144   144  
145   The destructor for each element is called if needed, any used memory is 145   The destructor for each element is called if needed, any used memory is
146   deallocated, and shared ownership of the 146   deallocated, and shared ownership of the
147   @ref boost::container::pmr::memory_resource is released. 147   @ref boost::container::pmr::memory_resource is released.
148   148  
149   @par Complexity 149   @par Complexity
150   Constant, or linear in @ref size(). 150   Constant, or linear in @ref size().
151   151  
152   @par Exception Safety 152   @par Exception Safety
153   No-throw guarantee. 153   No-throw guarantee.
154   */ 154   */
155   BOOST_JSON_DECL 155   BOOST_JSON_DECL
156   ~object() noexcept; 156   ~object() noexcept;
157   157  
158   //------------------------------------------------------ 158   //------------------------------------------------------
159   159  
160   /** Constructors. 160   /** Constructors.
161   161  
162   Constructs an object. 162   Constructs an object.
163   163  
164   @li **(1)**--**(3)** the object is empty. 164   @li **(1)**--**(3)** the object is empty.
165   165  
166   @li **(4)** the object is filled with values in the range 166   @li **(4)** the object is filled with values in the range
167   `[first, last)`. 167   `[first, last)`.
168   168  
169   @li **(5)**, **(6)** the object is filled with copies of the values in 169   @li **(5)**, **(6)** the object is filled with copies of the values in
170   `init`. 170   `init`.
171   171  
172   @li **(7)**, **(8)** the object is filled with copies of the elements 172   @li **(7)**, **(8)** the object is filled with copies of the elements
173   of `other`. 173   of `other`.
174   174  
175   @li **(9)** the object acquires ownership of the contents of `other`. 175   @li **(9)** the object acquires ownership of the contents of `other`.
176   176  
177   @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`; 177   @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`;
178   otherwise equivalent to **(8)**. 178   otherwise equivalent to **(8)**.
179   179  
180   @li **(11)** the object acquires ownership of the contents of `other` 180   @li **(11)** the object acquires ownership of the contents of `other`
181   using pilfer semantics. This is more efficient than move 181   using pilfer semantics. This is more efficient than move
182   construction, when it is known that the moved-from object will be 182   construction, when it is known that the moved-from object will be
183   immediately destroyed afterwards. 183   immediately destroyed afterwards.
184   184  
185   Upon construction, @ref capacity() will be large enough to store the 185   Upon construction, @ref capacity() will be large enough to store the
186   object's elements. In addition, with **(3)**, **(4)**, and **(6)** the 186   object's elements. In addition, with **(3)**, **(4)**, and **(6)** the
187   capacity will not be smaller than `min_capacity`. 187   capacity will not be smaller than `min_capacity`.
188   188  
189   With **(2)**--**(6)**, **(8)**, **(10)** the constructed object uses 189   With **(2)**--**(6)**, **(8)**, **(10)** the constructed object uses
190   memory resource of `sp`. With **(7)**, **(9)**, **(11)** it uses 190   memory resource of `sp`. With **(7)**, **(9)**, **(11)** it uses
191   `other`'s memory resource. In either case the object will share the 191   `other`'s memory resource. In either case the object will share the
192   ownership of the memory resource. With **(1)** it uses the 192   ownership of the memory resource. With **(1)** it uses the
193   \<\<default_memory_resource,default memory resource\>\>. 193   \<\<default_memory_resource,default memory resource\>\>.
194   194  
195   After **(9)** `other` behaves as if newly constructed with its current 195   After **(9)** `other` behaves as if newly constructed with its current
196   storage pointer. 196   storage pointer.
197   197  
198   After **(11)** `other` is not in a usable state and may only be 198   After **(11)** `other` is not in a usable state and may only be
199   destroyed. 199   destroyed.
200   200  
201   If `init` or `[first, last)` have elements with duplicate keys, only 201   If `init` or `[first, last)` have elements with duplicate keys, only
202   the first of those equivalent elements will be inserted. 202   the first of those equivalent elements will be inserted.
203   203  
204   @par Constraints 204   @par Constraints
205   @code 205   @code
206   std::is_constructible_v< 206   std::is_constructible_v<
207   key_value_pair, 207   key_value_pair,
208   std::iterator_traits<InputIt>::reference> 208   std::iterator_traits<InputIt>::reference>
209   @endcode 209   @endcode
210   210  
211   @par Complexity 211   @par Complexity
212   @li **(1)**--**(3)**, **(9)**, **(11)** constant. 212   @li **(1)**--**(3)**, **(9)**, **(11)** constant.
213   @li **(4)** linear in `std::distance(first, last)`. 213   @li **(4)** linear in `std::distance(first, last)`.
214   @li **(5)**, **(6)** linear in `init.size()`. 214   @li **(5)**, **(6)** linear in `init.size()`.
215   @li **(7)**, **(8)** linear in `other.size()`. 215   @li **(7)**, **(8)** linear in `other.size()`.
216   @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in 216   @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in
217   `other.size()`. 217   `other.size()`.
218   218  
219   @par Exception Safety 219   @par Exception Safety
220   @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee. 220   @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee.
221   @li **(3)**, **(5)**, **(6)**--**(8)**, **(10)** strong guarantee. 221   @li **(3)**, **(5)**, **(6)**--**(8)**, **(10)** strong guarantee.
222   @li **(4)** strong guarantee if `InputIt` satisfies 222   @li **(4)** strong guarantee if `InputIt` satisfies
223   {req_ForwardIterator}, basic guarantee otherwise. 223   {req_ForwardIterator}, basic guarantee otherwise.
224   224  
225   Calls to `memory_resource::allocate` may throw. 225   Calls to `memory_resource::allocate` may throw.
226   226  
227   @see @ref pilfer, 227   @see @ref pilfer,
228   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html). 228   [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
229   229  
230   @{ 230   @{
231   */ 231   */
HITCBC 232   77 object() noexcept 232   77 object() noexcept
HITCBC 233   77 : t_(&empty_) 233   77 : t_(&empty_)
234   { 234   {
HITCBC 235   77 } 235   77 }
236   236  
237   /** Overload 237   /** Overload
238   238  
239   @param sp A pointer to the @ref boost::container::pmr::memory_resource 239   @param sp A pointer to the @ref boost::container::pmr::memory_resource
240   to use. 240   to use.
241   */ 241   */
242   explicit 242   explicit
HITCBC 243   487 object(storage_ptr sp) noexcept 243   487 object(storage_ptr sp) noexcept
HITCBC 244   487 : sp_(std::move(sp)) 244   487 : sp_(std::move(sp))
HITCBC 245   487 , t_(&empty_) 245   487 , t_(&empty_)
246   { 246   {
HITCBC 247   487 } 247   487 }
248   248  
249   /** Overload 249   /** Overload
250   250  
251   @param min_capacity The minimum number of elements for which capacity 251   @param min_capacity The minimum number of elements for which capacity
252   is guaranteed without a subsequent reallocation. 252   is guaranteed without a subsequent reallocation.
253   @param sp 253   @param sp
254   */ 254   */
255   BOOST_JSON_DECL 255   BOOST_JSON_DECL
256   object( 256   object(
257   std::size_t min_capacity, 257   std::size_t min_capacity,
258   storage_ptr sp = {}); 258   storage_ptr sp = {});
259   259  
260   /** Overload 260   /** Overload
261   261  
262   @param first An input iterator pointing to the first element to insert, 262   @param first An input iterator pointing to the first element to insert,
263   or pointing to the end of the range. 263   or pointing to the end of the range.
264   @param last An input iterator pointing to the end of the range. 264   @param last An input iterator pointing to the end of the range.
265   @param min_capacity 265   @param min_capacity
266   @param sp 266   @param sp
267   267  
268   @tparam InputIt a type satisfying the requirements of 268   @tparam InputIt a type satisfying the requirements of
269   {req_InputIterator}. 269   {req_InputIterator}.
270   */ 270   */
271   template< 271   template<
272   class InputIt 272   class InputIt
273   #ifndef BOOST_JSON_DOCS 273   #ifndef BOOST_JSON_DOCS
274   ,class = is_inputit<InputIt> 274   ,class = is_inputit<InputIt>
275   #endif 275   #endif
276   > 276   >
HITCBC 277   160 object( 277   160 object(
278   InputIt first, 278   InputIt first,
279   InputIt last, 279   InputIt last,
280   std::size_t min_capacity = 0, 280   std::size_t min_capacity = 0,
281   storage_ptr sp = {}) 281   storage_ptr sp = {})
HITCBC 282   160 : sp_(std::move(sp)) 282   160 : sp_(std::move(sp))
HITCBC 283   160 , t_(&empty_) 283   160 , t_(&empty_)
284   { 284   {
HITCBC 285   160 construct( 285   160 construct(
286   first, last, 286   first, last,
287   min_capacity, 287   min_capacity,
288   typename std::iterator_traits< 288   typename std::iterator_traits<
289   InputIt>::iterator_category{}); 289   InputIt>::iterator_category{});
HITCBC 290   160 } 290   160 }
291   291  
292   /** Overload 292   /** Overload
293   293  
294   @param init The initializer list to insert. 294   @param init The initializer list to insert.
295   @param sp 295   @param sp
296   */ 296   */
HITCBC 297   339 object( 297   339 object(
298   std::initializer_list< 298   std::initializer_list<
299   std::pair<string_view, value_ref>> init, 299   std::pair<string_view, value_ref>> init,
300   storage_ptr sp = {}) 300   storage_ptr sp = {})
HITCBC 301   339 : object(init, 0, std::move(sp)) 301   339 : object(init, 0, std::move(sp))
302   { 302   {
HITCBC 303   246 } 303   246 }
304   304  
305   /** Overload 305   /** Overload
306   306  
307   @param init 307   @param init
308   @param min_capacity 308   @param min_capacity
309   @param sp 309   @param sp
310   */ 310   */
311   BOOST_JSON_DECL 311   BOOST_JSON_DECL
312   object( 312   object(
313   std::initializer_list< 313   std::initializer_list<
314   std::pair<string_view, value_ref>> init, 314   std::pair<string_view, value_ref>> init,
315   std::size_t min_capacity, 315   std::size_t min_capacity,
316   storage_ptr sp = {}); 316   storage_ptr sp = {});
317   317  
318   /** Overload 318   /** Overload
319   319  
320   @param other Another object. 320   @param other Another object.
321   */ 321   */
HITCBC 322   13 object( 322   13 object(
323   object const& other) 323   object const& other)
HITCBC 324   13 : object(other, other.sp_) 324   13 : object(other, other.sp_)
325   { 325   {
HITCBC 326   13 } 326   13 }
327   327  
328   /** Overload 328   /** Overload
329   329  
330   @param other 330   @param other
331   @param sp 331   @param sp
332   */ 332   */
333   BOOST_JSON_DECL 333   BOOST_JSON_DECL
334   object( 334   object(
335   object const& other, 335   object const& other,
336   storage_ptr sp); 336   storage_ptr sp);
337   337  
338   /** Overload 338   /** Overload
339   339  
340   @param other 340   @param other
341   */ 341   */
342   BOOST_JSON_DECL 342   BOOST_JSON_DECL
343   object(object&& other) noexcept; 343   object(object&& other) noexcept;
344   344  
345   /** Overload 345   /** Overload
346   346  
347   @param other 347   @param other
348   @param sp 348   @param sp
349   */ 349   */
350   BOOST_JSON_DECL 350   BOOST_JSON_DECL
351   object( 351   object(
352   object&& other, 352   object&& other,
353   storage_ptr sp); 353   storage_ptr sp);
354   354  
355   /** Overload 355   /** Overload
356   356  
357   @param other 357   @param other
358   */ 358   */
HITCBC 359   17 object(pilfered<object> other) noexcept 359   17 object(pilfered<object> other) noexcept
HITCBC 360   17 : sp_(std::move(other.get().sp_)) 360   17 : sp_(std::move(other.get().sp_))
HITCBC 361   34 , t_(detail::exchange( 361   34 , t_(detail::exchange(
HITCBC 362   17 other.get().t_, &empty_)) 362   17 other.get().t_, &empty_))
363   { 363   {
HITCBC 364   17 } 364   17 }
365   /// @} 365   /// @}
366   366  
367   //------------------------------------------------------ 367   //------------------------------------------------------
368   // 368   //
369   // Assignment 369   // Assignment
370   // 370   //
371   //------------------------------------------------------ 371   //------------------------------------------------------
372   372  
373   /** Assignment operators. 373   /** Assignment operators.
374   374  
375   Replaces the contents of this object. 375   Replaces the contents of this object.
376   376  
377   @li **(1)** replaces with the copies of the elements of `other`. 377   @li **(1)** replaces with the copies of the elements of `other`.
378   @li **(2)** takes ownership of `other`'s element storage if 378   @li **(2)** takes ownership of `other`'s element storage if
379   `*storage() == *other.storage()`; otherwise equivalent to **(1)**. 379   `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
380   @li **(3)** replaces with the elements of `init`. 380   @li **(3)** replaces with the elements of `init`.
381   381  
382   @par Complexity 382   @par Complexity
383   @li **(1)** linear in `size() + other.size()`. 383   @li **(1)** linear in `size() + other.size()`.
384   @li **(2)** constant if `*storage() == *other.storage()`; otherwise 384   @li **(2)** constant if `*storage() == *other.storage()`; otherwise
385   linear in `size() + other.size()`. 385   linear in `size() + other.size()`.
386   @li **(3)** average case linear in `size() + init.size()`, worst case 386   @li **(3)** average case linear in `size() + init.size()`, worst case
387   quadratic in `init.size()`. 387   quadratic in `init.size()`.
388   388  
389   @par Exception Safety 389   @par Exception Safety
390   @li **(1)**, **(3)** strong guarantee. 390   @li **(1)**, **(3)** strong guarantee.
391   @li **(2)** no-throw guarantee if `*storage() == *other.storage()`; 391   @li **(2)** no-throw guarantee if `*storage() == *other.storage()`;
392   otherwise strong guarantee. 392   otherwise strong guarantee.
393   393  
394   Calls to `memory_resource::allocate` may throw. 394   Calls to `memory_resource::allocate` may throw.
395   395  
396   @par Complexity 396   @par Complexity
397   397  
398   @param other Another object. 398   @param other Another object.
399   399  
400   @{ 400   @{
401   */ 401   */
402   BOOST_JSON_DECL 402   BOOST_JSON_DECL
403   object& 403   object&
404   operator=(object const& other); 404   operator=(object const& other);
405   405  
406   BOOST_JSON_DECL 406   BOOST_JSON_DECL
407   object& 407   object&
408   operator=(object&& other); 408   operator=(object&& other);
409   409  
410   /** Overload 410   /** Overload
411   411  
412   @param init The initializer list to copy. 412   @param init The initializer list to copy.
413   */ 413   */
414   BOOST_JSON_DECL 414   BOOST_JSON_DECL
415   object& 415   object&
416   operator=(std::initializer_list< 416   operator=(std::initializer_list<
417   std::pair<string_view, value_ref>> init); 417   std::pair<string_view, value_ref>> init);
418   /// @} 418   /// @}
419   419  
420   //------------------------------------------------------ 420   //------------------------------------------------------
421   421  
422   /** Return the associated memory resource. 422   /** Return the associated memory resource.
423   423  
424   This function returns a smart pointer to the 424   This function returns a smart pointer to the
425   @ref boost::container::pmr::memory_resource used by the container. 425   @ref boost::container::pmr::memory_resource used by the container.
426   426  
427   @par Complexity 427   @par Complexity
428   Constant. 428   Constant.
429   429  
430   @par Exception Safety 430   @par Exception Safety
431   No-throw guarantee. 431   No-throw guarantee.
432   */ 432   */
433   storage_ptr const& 433   storage_ptr const&
HITCBC 434   683 storage() const noexcept 434   683 storage() const noexcept
435   { 435   {
HITCBC 436   683 return sp_; 436   683 return sp_;
437   } 437   }
438   438  
439   /** Return the associated allocator. 439   /** Return the associated allocator.
440   440  
441   This function returns an instance of @ref allocator_type constructed 441   This function returns an instance of @ref allocator_type constructed
442   from the associated @ref boost::container::pmr::memory_resource. 442   from the associated @ref boost::container::pmr::memory_resource.
443   443  
444   @par Complexity 444   @par Complexity
445   Constant. 445   Constant.
446   446  
447   @par Exception Safety 447   @par Exception Safety
448   No-throw guarantee. 448   No-throw guarantee.
449   */ 449   */
450   allocator_type 450   allocator_type
HITCBC 451   1 get_allocator() const noexcept 451   1 get_allocator() const noexcept
452   { 452   {
HITCBC 453   1 return sp_.get(); 453   1 return sp_.get();
454   } 454   }
455   455  
456   //------------------------------------------------------ 456   //------------------------------------------------------
457   // 457   //
458   // Iterators 458   // Iterators
459   // 459   //
460   //------------------------------------------------------ 460   //------------------------------------------------------
461   461  
462   /** Return an iterator to the first element. 462   /** Return an iterator to the first element.
463   463  
464   If the container is empty, @ref end() is returned. 464   If the container is empty, @ref end() is returned.
465   465  
466   @par Complexity 466   @par Complexity
467   Constant. 467   Constant.
468   468  
469   @par Exception Safety 469   @par Exception Safety
470   No-throw guarantee. 470   No-throw guarantee.
471   471  
472   @{ 472   @{
473   */ 473   */
474   inline 474   inline
475   iterator 475   iterator
476   begin() noexcept; 476   begin() noexcept;
477   477  
478   inline 478   inline
479   const_iterator 479   const_iterator
480   begin() const noexcept; 480   begin() const noexcept;
481   /// @} 481   /// @}
482   482  
483   /** Return a const iterator to the first element. 483   /** Return a const iterator to the first element.
484   484  
485   If the container is empty, @ref cend() is returned. 485   If the container is empty, @ref cend() is returned.
486   486  
487   @par Complexity 487   @par Complexity
488   Constant. 488   Constant.
489   489  
490   @par Exception Safety 490   @par Exception Safety
491   No-throw guarantee. 491   No-throw guarantee.
492   */ 492   */
493   inline 493   inline
494   const_iterator 494   const_iterator
495   cbegin() const noexcept; 495   cbegin() const noexcept;
496   496  
497   /** Return an iterator to the element following the last element. 497   /** Return an iterator to the element following the last element.
498   498  
499   The element acts as a placeholder; attempting 499   The element acts as a placeholder; attempting
500   to access it results in undefined behavior. 500   to access it results in undefined behavior.
501   501  
502   @par Complexity 502   @par Complexity
503   Constant. 503   Constant.
504   504  
505   @par Exception Safety 505   @par Exception Safety
506   No-throw guarantee. 506   No-throw guarantee.
507   507  
508   @{ 508   @{
509   */ 509   */
510   inline 510   inline
511   iterator 511   iterator
512   end() noexcept; 512   end() noexcept;
513   513  
514   inline 514   inline
515   const_iterator 515   const_iterator
516   end() const noexcept; 516   end() const noexcept;
517   /// @} 517   /// @}
518   518  
519   /** Return a const iterator to the element following the last element. 519   /** Return a const iterator to the element following the last element.
520   520  
521   The element acts as a placeholder; attempting 521   The element acts as a placeholder; attempting
522   to access it results in undefined behavior. 522   to access it results in undefined behavior.
523   523  
524   @par Complexity 524   @par Complexity
525   Constant. 525   Constant.
526   526  
527   @par Exception Safety 527   @par Exception Safety
528   No-throw guarantee. 528   No-throw guarantee.
529   */ 529   */
530   inline 530   inline
531   const_iterator 531   const_iterator
532   cend() const noexcept; 532   cend() const noexcept;
533   533  
534   /** Return a reverse iterator to the first element of the reversed container. 534   /** Return a reverse iterator to the first element of the reversed container.
535   535  
536   The pointed-to element corresponds to the last element of the 536   The pointed-to element corresponds to the last element of the
537   non-reversed container. If the container is empty, @ref rend() is 537   non-reversed container. If the container is empty, @ref rend() is
538   returned. 538   returned.
539   539  
540   @par Complexity 540   @par Complexity
541   Constant. 541   Constant.
542   542  
543   @par Exception Safety 543   @par Exception Safety
544   No-throw guarantee. 544   No-throw guarantee.
545   545  
546   @{ 546   @{
547   */ 547   */
548   inline 548   inline
549   reverse_iterator 549   reverse_iterator
550   rbegin() noexcept; 550   rbegin() noexcept;
551   551  
552   inline 552   inline
553   const_reverse_iterator 553   const_reverse_iterator
554   rbegin() const noexcept; 554   rbegin() const noexcept;
555   /// @} 555   /// @}
556   556  
557   /** Return a const reverse iterator to the first element of the reversed container. 557   /** Return a const reverse iterator to the first element of the reversed container.
558   558  
559   The pointed-to element corresponds to the 559   The pointed-to element corresponds to the
560   last element of the non-reversed container. 560   last element of the non-reversed container.
561   If the container is empty, @ref crend() is returned. 561   If the container is empty, @ref crend() is returned.
562   562  
563   @par Complexity 563   @par Complexity
564   Constant. 564   Constant.
565   565  
566   @par Exception Safety 566   @par Exception Safety
567   No-throw guarantee. 567   No-throw guarantee.
568   */ 568   */
569   inline 569   inline
570   const_reverse_iterator 570   const_reverse_iterator
571   crbegin() const noexcept; 571   crbegin() const noexcept;
572   572  
573   /** Return a reverse iterator to the element following the last element of the reversed container. 573   /** Return a reverse iterator to the element following the last element of the reversed container.
574   574  
575   The pointed-to element corresponds to the element preceding the first 575   The pointed-to element corresponds to the element preceding the first
576   element of the non-reversed container. The returned iterator only acts 576   element of the non-reversed container. The returned iterator only acts
577   as a sentinel. Dereferencing it results in undefined behavior. 577   as a sentinel. Dereferencing it results in undefined behavior.
578   578  
579   @par Complexity 579   @par Complexity
580   Constant. 580   Constant.
581   581  
582   @par Exception Safety 582   @par Exception Safety
583   No-throw guarantee. 583   No-throw guarantee.
584   584  
585   @{ 585   @{
586   */ 586   */
587   inline 587   inline
588   reverse_iterator 588   reverse_iterator
589   rend() noexcept; 589   rend() noexcept;
590   590  
591   inline 591   inline
592   const_reverse_iterator 592   const_reverse_iterator
593   rend() const noexcept; 593   rend() const noexcept;
594   /// @} 594   /// @}
595   595  
596   /** Return a const reverse iterator to the element following the last element of the reversed container. 596   /** Return a const reverse iterator to the element following the last element of the reversed container.
597   597  
598   The pointed-to element corresponds to the element preceding the first 598   The pointed-to element corresponds to the element preceding the first
599   element of the non-reversed container. The returned iterator only acts 599   element of the non-reversed container. The returned iterator only acts
600   as a sentinel. Dereferencing it results in undefined behavior. 600   as a sentinel. Dereferencing it results in undefined behavior.
601   601  
602   @par Complexity 602   @par Complexity
603   Constant. 603   Constant.
604   604  
605   @par Exception Safety 605   @par Exception Safety
606   No-throw guarantee. 606   No-throw guarantee.
607   */ 607   */
608   inline 608   inline
609   const_reverse_iterator 609   const_reverse_iterator
610   crend() const noexcept; 610   crend() const noexcept;
611   611  
612   //------------------------------------------------------ 612   //------------------------------------------------------
613   // 613   //
614   // Capacity 614   // Capacity
615   // 615   //
616   //------------------------------------------------------ 616   //------------------------------------------------------
617   617  
618   /** Return whether there are no elements. 618   /** Return whether there are no elements.
619   619  
620   Returns `true` if there are no elements in 620   Returns `true` if there are no elements in
621   the container, i.e. @ref size() returns 0. 621   the container, i.e. @ref size() returns 0.
622   622  
623   @par Complexity 623   @par Complexity
624   Constant. 624   Constant.
625   625  
626   @par Exception Safety 626   @par Exception Safety
627   No-throw guarantee. 627   No-throw guarantee.
628   */ 628   */
629   inline 629   inline
630   bool 630   bool
631   empty() const noexcept; 631   empty() const noexcept;
632   632  
633   /** Return the number of elements. 633   /** Return the number of elements.
634   634  
635   This returns the number of elements in the container. 635   This returns the number of elements in the container.
636   636  
637   @par Complexity 637   @par Complexity
638   Constant. 638   Constant.
639   639  
640   @par Exception Safety 640   @par Exception Safety
641   No-throw guarantee. 641   No-throw guarantee.
642   */ 642   */
643   inline 643   inline
644   std::size_t 644   std::size_t
645   size() const noexcept; 645   size() const noexcept;
646   646  
647   /** The maximum number of elements an object can hold. 647   /** The maximum number of elements an object can hold.
648   648  
649   The maximum is an implementation-defined number dependent on system or 649   The maximum is an implementation-defined number dependent on system or
650   library implementation. This value is a theoretical limit; at runtime, 650   library implementation. This value is a theoretical limit; at runtime,
651   the actual maximum size may be less due to resource limits. 651   the actual maximum size may be less due to resource limits.
652   652  
653   @par Complexity 653   @par Complexity
654   Constant. 654   Constant.
655   655  
656   @par Exception Safety 656   @par Exception Safety
657   No-throw guarantee. 657   No-throw guarantee.
658   */ 658   */
659   static 659   static
660   constexpr 660   constexpr
661   std::size_t 661   std::size_t
662   max_size() noexcept; 662   max_size() noexcept;
663   663  
664   /** Return the number of elements that can be held in currently allocated memory. 664   /** Return the number of elements that can be held in currently allocated memory.
665   665  
666   Returns the number of elements that the container has currently 666   Returns the number of elements that the container has currently
667   allocated space for. This number is never smaller than the value 667   allocated space for. This number is never smaller than the value
668   returned by @ref size(). 668   returned by @ref size().
669   669  
670   @par Complexity 670   @par Complexity
671   Constant. 671   Constant.
672   672  
673   @par Exception Safety 673   @par Exception Safety
674   No-throw guarantee. 674   No-throw guarantee.
675   */ 675   */
676   inline 676   inline
677   std::size_t 677   std::size_t
678   capacity() const noexcept; 678   capacity() const noexcept;
679   679  
680   /** Increase the capacity to at least a certain amount. 680   /** Increase the capacity to at least a certain amount.
681   681  
682   This increases the @ref capacity() to a value that is greater than or 682   This increases the @ref capacity() to a value that is greater than or
683   equal to `new_capacity`. If `new_capacity > capacity()`, new memory is 683   equal to `new_capacity`. If `new_capacity > capacity()`, new memory is
684   allocated. Otherwise, the call has no effect. The number of elements 684   allocated. Otherwise, the call has no effect. The number of elements
685   and therefore the @ref size() of the container is not changed. 685   and therefore the @ref size() of the container is not changed.
686   686  
687   If new memory is allocated, all iterators including any past-the-end 687   If new memory is allocated, all iterators including any past-the-end
688   iterators, and all references to the elements are invalidated. 688   iterators, and all references to the elements are invalidated.
689   Otherwise, no iterators or references are invalidated. 689   Otherwise, no iterators or references are invalidated.
690   690  
691   @par Complexity 691   @par Complexity
692   Constant if no reallocation occurs. Otherwise, average case linear in 692   Constant if no reallocation occurs. Otherwise, average case linear in
693   @ref size(), worst case quadratic in @ref size(). 693   @ref size(), worst case quadratic in @ref size().
694   694  
695   @par Exception Safety 695   @par Exception Safety
696   Strong guarantee. Calls to `memory_resource::allocate` may throw. 696   Strong guarantee. Calls to `memory_resource::allocate` may throw.
697   697  
698   @param new_capacity The new minimum capacity. 698   @param new_capacity The new minimum capacity.
699   699  
700   @throw boost::system::system_error `new_capacity >` @ref max_size(). 700   @throw boost::system::system_error `new_capacity >` @ref max_size().
701   */ 701   */
702   inline 702   inline
703   void 703   void
704   reserve(std::size_t new_capacity); 704   reserve(std::size_t new_capacity);
705   705  
706   //------------------------------------------------------ 706   //------------------------------------------------------
707   // 707   //
708   // Modifiers 708   // Modifiers
709   // 709   //
710   //------------------------------------------------------ 710   //------------------------------------------------------
711   711  
712   /** Erase all elements. 712   /** Erase all elements.
713   713  
714   Erases all elements from the container. After this call, @ref size() 714   Erases all elements from the container. After this call, @ref size()
715   returns zero but @ref capacity() is unchanged. All references, 715   returns zero but @ref capacity() is unchanged. All references,
716   pointers, and iterators are invalidated. 716   pointers, and iterators are invalidated.
717   717  
718   @par Complexity 718   @par Complexity
719   Linear in @ref size(). 719   Linear in @ref size().
720   720  
721   @par Exception Safety 721   @par Exception Safety
722   No-throw guarantee. 722   No-throw guarantee.
723   */ 723   */
724   BOOST_JSON_DECL 724   BOOST_JSON_DECL
725   void 725   void
726   clear() noexcept; 726   clear() noexcept;
727   727  
728   /** Insert elements. 728   /** Insert elements.
729   729  
730   @li **(1)** inserts a new element constructed as if via 730   @li **(1)** inserts a new element constructed as if via
731   `value_type( std::forward<P>(p) )`. 731   `value_type( std::forward<P>(p) )`.
732   @li **(2)** the elements in the range `[first, last)` are inserted one 732   @li **(2)** the elements in the range `[first, last)` are inserted one
733   at a time, in order. 733   at a time, in order.
734   @li **(3)** the elements in the initializer list are inserted one at a 734   @li **(3)** the elements in the initializer list are inserted one at a
735   time, in order. 735   time, in order.
736   736  
737   Any element with key that is a duplicate of a key already present in 737   Any element with key that is a duplicate of a key already present in
738   container will be skipped. This also means, that if there are two keys 738   container will be skipped. This also means, that if there are two keys
739   within the inserted range that are equal to each other, only the 739   within the inserted range that are equal to each other, only the
740   first will be inserted. 740   first will be inserted.
741   741  
742   If an insertion would result in the new number of elements exceeding 742   If an insertion would result in the new number of elements exceeding
743   @ref capacity(), a reallocation and a rehashing occur. In that case all 743   @ref capacity(), a reallocation and a rehashing occur. In that case all
744   iterators and references are invalidated. Otherwise, they are not 744   iterators and references are invalidated. Otherwise, they are not
745   affected. 745   affected.
746   746  
747   @pre 747   @pre
748   `first` and `last` are not iterators into `*this`. `first` and `last` 748   `first` and `last` are not iterators into `*this`. `first` and `last`
749   form a valid range. 749   form a valid range.
750   750  
751   @par Constraints 751   @par Constraints
752   @code 752   @code
753   std::is_constructible_v<value_type, P> 753   std::is_constructible_v<value_type, P>
754   std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference> 754   std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
755   @endcode 755   @endcode
756   756  
757   @par Complexity 757   @par Complexity
758   @li **(1)** constant on average, worst case linear in @ref size(). 758   @li **(1)** constant on average, worst case linear in @ref size().
759   @li **(2)** linear in `std::distance(first, last)`. 759   @li **(2)** linear in `std::distance(first, last)`.
760   @li **(3)** linear in `init.size()`. 760   @li **(3)** linear in `init.size()`.
761   761  
762   @par Exception Safety 762   @par Exception Safety
763   @li **(1)** strong guarantee. 763   @li **(1)** strong guarantee.
764   @li **(2)** strong guarantee if `InputIt` satisfies 764   @li **(2)** strong guarantee if `InputIt` satisfies
765   {req_ForwardIterator}, basic guarantee otherwise. 765   {req_ForwardIterator}, basic guarantee otherwise.
766   @li **(3)** basic guarantee. 766   @li **(3)** basic guarantee.
767   767  
768   Calls to `memory_resource::allocate` may throw. 768   Calls to `memory_resource::allocate` may throw.
769   769  
770   @param p The value to insert. 770   @param p The value to insert.
771   771  
772   @throw boost::system::system_error The size of a key would exceed 772   @throw boost::system::system_error The size of a key would exceed
773   @ref string::max_size. 773   @ref string::max_size.
774   @throw `boost::system::system_error` @ref size() >= @ref max_size(). 774   @throw `boost::system::system_error` @ref size() >= @ref max_size().
775   775  
776   @return **(1)** returns a @ref std::pair where `first` is an iterator 776   @return **(1)** returns a @ref std::pair where `first` is an iterator
777   to the existing or inserted element, and `second` is `true` if the 777   to the existing or inserted element, and `second` is `true` if the
778   insertion took place or `false` otherwise. **(2)** returns `void`. 778   insertion took place or `false` otherwise. **(2)** returns `void`.
779   779  
780   @{ 780   @{
781   */ 781   */
782   template<class P 782   template<class P
783   #ifndef BOOST_JSON_DOCS 783   #ifndef BOOST_JSON_DOCS
784   ,class = typename std::enable_if< 784   ,class = typename std::enable_if<
785   std::is_constructible<key_value_pair, 785   std::is_constructible<key_value_pair,
786   P, storage_ptr>::value>::type 786   P, storage_ptr>::value>::type
787   #endif 787   #endif
788   > 788   >
789   std::pair<iterator, bool> 789   std::pair<iterator, bool>
790   insert(P&& p); 790   insert(P&& p);
791   791  
792   /** Overload 792   /** Overload
793   793  
794   @param first An input iterator pointing to the first element to insert, 794   @param first An input iterator pointing to the first element to insert,
795   or pointing to the end of the range. 795   or pointing to the end of the range.
796   796  
797   @param last An input iterator pointing to the end of the range. 797   @param last An input iterator pointing to the end of the range.
798   798  
799   @tparam InputIt a type satisfying the requirements 799   @tparam InputIt a type satisfying the requirements
800   of {req_InputIterator}. 800   of {req_InputIterator}.
801   */ 801   */
802   template< 802   template<
803   class InputIt 803   class InputIt
804   #ifndef BOOST_JSON_DOCS 804   #ifndef BOOST_JSON_DOCS
805   ,class = is_inputit<InputIt> 805   ,class = is_inputit<InputIt>
806   #endif 806   #endif
807   > 807   >
808   void 808   void
HITCBC 809   174 insert(InputIt first, InputIt last) 809   174 insert(InputIt first, InputIt last)
810   { 810   {
HITCBC 811   174 insert(first, last, typename 811   174 insert(first, last, typename
812   std::iterator_traits<InputIt 812   std::iterator_traits<InputIt
813   >::iterator_category{}); 813   >::iterator_category{});
HITCBC 814   8 } 814   8 }
815   815  
816   /** Overload 816   /** Overload
817   817  
818   @param init The initializer list to insert. 818   @param init The initializer list to insert.
819   */ 819   */
820   BOOST_JSON_DECL 820   BOOST_JSON_DECL
821   void 821   void
822   insert(std::initializer_list< 822   insert(std::initializer_list<
823   std::pair<string_view, value_ref>> init); 823   std::pair<string_view, value_ref>> init);
824   /// @} 824   /// @}
825   825  
826   /** Insert an element or assign to an existing element. 826   /** Insert an element or assign to an existing element.
827   827  
828   If the key equal to `key` already exists in the container, assigns 828   If the key equal to `key` already exists in the container, assigns
829   `std::forward<M>(m)` to the @ref mapped_type corresponding to that key. 829   `std::forward<M>(m)` to the @ref mapped_type corresponding to that key.
830   Otherwise, inserts the as if by @ref insert, constructing it using 830   Otherwise, inserts the as if by @ref insert, constructing it using
831   `value_type(key, std::forward<M>(m))`. 831   `value_type(key, std::forward<M>(m))`.
832   832  
833   If insertion would result in the new number of elements exceeding 833   If insertion would result in the new number of elements exceeding
834   @ref capacity(), a reallocation and a rehashing occur. In that case all 834   @ref capacity(), a reallocation and a rehashing occur. In that case all
835   iterators and references are invalidated. Otherwise, they are not 835   iterators and references are invalidated. Otherwise, they are not
836   affected. 836   affected.
837   837  
838   @par Complexity 838   @par Complexity
839   Constant on average, worst case linear in @ref size(). 839   Constant on average, worst case linear in @ref size().
840   840  
841   @par Exception Safety 841   @par Exception Safety
842   Strong guarantee. Calls to `memory_resource::allocate` may throw. 842   Strong guarantee. Calls to `memory_resource::allocate` may throw.
843   843  
844   @return A @ref std::pair where `first` is an iterator to the existing 844   @return A @ref std::pair where `first` is an iterator to the existing
845   or inserted element, and `second` is `true` if the insertion took place 845   or inserted element, and `second` is `true` if the insertion took place
846   or `false` if the assignment took place. 846   or `false` if the assignment took place.
847   847  
848   @param key The key used for lookup and insertion. 848   @param key The key used for lookup and insertion.
849   @param m The value to insert or assign. 849   @param m The value to insert or assign.
850   850  
851   @throw boost::system::system_error The size of a key would exceed 851   @throw boost::system::system_error The size of a key would exceed
852   @ref string::max_size. 852   @ref string::max_size.
853   */ 853   */
854   template<class M> 854   template<class M>
855   std::pair<iterator, bool> 855   std::pair<iterator, bool>
856   insert_or_assign( 856   insert_or_assign(
857   string_view key, M&& m); 857   string_view key, M&& m);
858   858  
859   /** Construct an element in-place. 859   /** Construct an element in-place.
860   860  
861   Inserts a new element into the container constructed 861   Inserts a new element into the container constructed
862   in-place with the given argument if there is no 862   in-place with the given argument if there is no
863   element with the `key` in the container. 863   element with the `key` in the container.
864   864  
865   If the insertion occurs and results in a rehashing of the container, 865   If the insertion occurs and results in a rehashing of the container,
866   all iterators and references are invalidated. Otherwise, they are not 866   all iterators and references are invalidated. Otherwise, they are not
867   affected. Rehashing occurs only if the new number of elements is 867   affected. Rehashing occurs only if the new number of elements is
868   greater than @ref capacity(). 868   greater than @ref capacity().
869   869  
870   @par Complexity 870   @par Complexity
871   Constant on average, worst case linear in @ref size(). 871   Constant on average, worst case linear in @ref size().
872   872  
873   @par Exception Safety 873   @par Exception Safety
874   Strong guarantee. 874   Strong guarantee.
875   Calls to `memory_resource::allocate` may throw. 875   Calls to `memory_resource::allocate` may throw.
876   876  
877   @return A @ref std::pair where `first` is an iterator 877   @return A @ref std::pair where `first` is an iterator
878   to the existing or inserted element, and `second` 878   to the existing or inserted element, and `second`
879   is `true` if the insertion took place or `false` otherwise. 879   is `true` if the insertion took place or `false` otherwise.
880   880  
881   @param key The key used for lookup and insertion. 881   @param key The key used for lookup and insertion.
882   882  
883   @param arg The argument used to construct the value. 883   @param arg The argument used to construct the value.
884   This will be passed as `std::forward<Arg>(arg)` to 884   This will be passed as `std::forward<Arg>(arg)` to
885   the @ref value constructor. 885   the @ref value constructor.
886   886  
887   @throw boost::system::system_error The size of the key would exceed 887   @throw boost::system::system_error The size of the key would exceed
888   @ref string::max_size. 888   @ref string::max_size.
889   889  
890   */ 890   */
891   template<class Arg> 891   template<class Arg>
892   std::pair<iterator, bool> 892   std::pair<iterator, bool>
893   emplace(string_view key, Arg&& arg); 893   emplace(string_view key, Arg&& arg);
894   894  
895   /** Remove an element. 895   /** Remove an element.
896   896  
897   @li **(1)** the element at `pos` is removed. 897   @li **(1)** the element at `pos` is removed.
898   @li **(2)** the element with the key `key` is removed, if it exists. 898   @li **(2)** the element with the key `key` is removed, if it exists.
899   899  
900   `pos` must be valid and dereferenceable. References and iterators to 900   `pos` must be valid and dereferenceable. References and iterators to
901   the erased element are invalidated. Other iterators and references are 901   the erased element are invalidated. Other iterators and references are
902   not invalidated. 902   not invalidated.
903   903  
904   @attention The @ref end() iterator (which is valid but cannot be 904   @attention The @ref end() iterator (which is valid but cannot be
905   dereferenced) cannot be used as a value for `pos`. 905   dereferenced) cannot be used as a value for `pos`.
906   906  
907   @par Complexity 907   @par Complexity
908   Constant on average, worst case linear in @ref size(). 908   Constant on average, worst case linear in @ref size().
909   909  
910   @par Exception Safety 910   @par Exception Safety
911   No-throw guarantee. 911   No-throw guarantee.
912   912  
913   @return 913   @return
914   @li **(1)** an iterator following the removed element. 914   @li **(1)** an iterator following the removed element.
915   @li **(2)** the number of elements removed, which will be either 915   @li **(2)** the number of elements removed, which will be either
916   0 or 1. 916   0 or 1.
917   917  
918   @param pos An iterator pointing to the element to be removed. 918   @param pos An iterator pointing to the element to be removed.
919   919  
920   @{ 920   @{
921   */ 921   */
922   BOOST_JSON_DECL 922   BOOST_JSON_DECL
923   iterator 923   iterator
924   erase(const_iterator pos) noexcept; 924   erase(const_iterator pos) noexcept;
925   925  
926   /** Overload 926   /** Overload
927   927  
928   @param key The key to match. 928   @param key The key to match.
929   */ 929   */
930   BOOST_JSON_DECL 930   BOOST_JSON_DECL
931   std::size_t 931   std::size_t
932   erase(string_view key) noexcept; 932   erase(string_view key) noexcept;
933   /// @} 933   /// @}
934   934  
935   /** Erase an element preserving order. 935   /** Erase an element preserving order.
936   936  
937   @li **(1)** Remove the element pointed to by `pos`, which must be valid 937   @li **(1)** Remove the element pointed to by `pos`, which must be valid
938   and dereferenceable. References and iterators from `pos` to @ref end(), 938   and dereferenceable. References and iterators from `pos` to @ref end(),
939   both included, are invalidated. Other iterators and references are not 939   both included, are invalidated. Other iterators and references are not
940   invalidated. 940   invalidated.
941   @li **(2)** Remove the element which matches `key`, if it exists. All 941   @li **(2)** Remove the element which matches `key`, if it exists. All
942   references and iterators are invalidated. 942   references and iterators are invalidated.
943   943  
944   The relative order of remaining elements is preserved. 944   The relative order of remaining elements is preserved.
945   945  
946   @attention The @ref end() iterator (which is valid but cannot be 946   @attention The @ref end() iterator (which is valid but cannot be
947   dereferenced) cannot be used as a value for `pos`. 947   dereferenced) cannot be used as a value for `pos`.
948   948  
949   @par Complexity 949   @par Complexity
950   Linear in @ref size(). 950   Linear in @ref size().
951   951  
952   @par Exception Safety 952   @par Exception Safety
953   No-throw guarantee. 953   No-throw guarantee.
954   954  
955   @return 955   @return
956   @li An iterator following the removed element. 956   @li An iterator following the removed element.
957   @li The number of elements removed, which will be either 0 or 1. 957   @li The number of elements removed, which will be either 0 or 1.
958   958  
959   @param pos An iterator pointing to the element to be 959   @param pos An iterator pointing to the element to be
960   removed. 960   removed.
961   961  
962   @{ 962   @{
963   */ 963   */
964   BOOST_JSON_DECL 964   BOOST_JSON_DECL
965   iterator 965   iterator
966   stable_erase(const_iterator pos) noexcept; 966   stable_erase(const_iterator pos) noexcept;
967   967  
968   /** Overload 968   /** Overload
969   969  
970   @param key The key to match. 970   @param key The key to match.
971   */ 971   */
972   BOOST_JSON_DECL 972   BOOST_JSON_DECL
973   std::size_t 973   std::size_t
974   stable_erase(string_view key) noexcept; 974   stable_erase(string_view key) noexcept;
975   /// @} 975   /// @}
976   976  
977   /** Swap two objects. 977   /** Swap two objects.
978   978  
979   Exchanges the contents of this object with another object. Ownership of 979   Exchanges the contents of this object with another object. Ownership of
980   the respective @ref boost::container::pmr::memory_resource objects is 980   the respective @ref boost::container::pmr::memory_resource objects is
981   not transferred. If `this == &other`, this function call has no effect. 981   not transferred. If `this == &other`, this function call has no effect.
982   982  
983   @li If `*storage() == *other.storage()` all iterators and references 983   @li If `*storage() == *other.storage()` all iterators and references
984   remain valid. 984   remain valid.
985   985  
986   @li Otherwise, the contents are logically swapped by making copies, 986   @li Otherwise, the contents are logically swapped by making copies,
987   which can throw. In this case all iterators and references are 987   which can throw. In this case all iterators and references are
988   invalidated. 988   invalidated.
989   989  
990   @par Complexity 990   @par Complexity
991   If `*storage() == *other.storage()`, then constant; otherwise linear in 991   If `*storage() == *other.storage()`, then constant; otherwise linear in
992   `size() + other.size()`. 992   `size() + other.size()`.
993   993  
994   @par Exception Safety 994   @par Exception Safety
995   No-throw guarantee if `*storage() == *other.storage()`. Otherwise 995   No-throw guarantee if `*storage() == *other.storage()`. Otherwise
996   strong guarantee. Calls to `memory_resource::allocate` may throw. 996   strong guarantee. Calls to `memory_resource::allocate` may throw.
997   997  
998   @param other The object to swap with. 998   @param other The object to swap with.
999   */ 999   */
1000   BOOST_JSON_DECL 1000   BOOST_JSON_DECL
1001   void 1001   void
1002   swap(object& other); 1002   swap(object& other);
1003   1003  
1004   /** Swap two objects. 1004   /** Swap two objects.
1005   1005  
1006   Exchanges the contents of the object `lhs` with another object `rhs`. 1006   Exchanges the contents of the object `lhs` with another object `rhs`.
1007   Ownership of the respective @ref boost::container::pmr::memory_resource 1007   Ownership of the respective @ref boost::container::pmr::memory_resource
1008   objects is not transferred. If `&lhs == &rhs`, this function call has 1008   objects is not transferred. If `&lhs == &rhs`, this function call has
1009   no effect. 1009   no effect.
1010   1010  
1011   @li If `*lhs.storage() == *rhs.storage()` all iterators and references 1011   @li If `*lhs.storage() == *rhs.storage()` all iterators and references
1012   remain valid. 1012   remain valid.
1013   1013  
1014   @li Otherwise, the contents are logically swapped by making copies, 1014   @li Otherwise, the contents are logically swapped by making copies,
1015   which can throw. In this case all iterators and references are 1015   which can throw. In this case all iterators and references are
1016   invalidated. 1016   invalidated.
1017   1017  
1018   @par Complexity 1018   @par Complexity
1019   If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear 1019   If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear
1020   in `lhs.size() + rhs.size()`. 1020   in `lhs.size() + rhs.size()`.
1021   1021  
1022   @par Exception Safety 1022   @par Exception Safety
1023   No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise 1023   No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise
1024   strong guarantee. Calls to `memory_resource::allocate` may throw. 1024   strong guarantee. Calls to `memory_resource::allocate` may throw.
1025   1025  
1026   @param lhs The object to exchange. 1026   @param lhs The object to exchange.
1027   1027  
1028   @param rhs The object to exchange. 1028   @param rhs The object to exchange.
1029   1029  
1030   @see @ref object::swap 1030   @see @ref object::swap
1031   */ 1031   */
1032   friend 1032   friend
1033   void 1033   void
HITCBC 1034   11 swap(object& lhs, object& rhs) 1034   11 swap(object& lhs, object& rhs)
1035   { 1035   {
HITCBC 1036   11 lhs.swap(rhs); 1036   11 lhs.swap(rhs);
HITCBC 1037   3 } 1037   3 }
1038   1038  
1039   //------------------------------------------------------ 1039   //------------------------------------------------------
1040   // 1040   //
1041   // Lookup 1041   // Lookup
1042   // 1042   //
1043   //------------------------------------------------------ 1043   //------------------------------------------------------
1044   1044  
1045   /** Access the specified element, with bounds checking. 1045   /** Access the specified element, with bounds checking.
1046   1046  
1047   Returns @ref boost::system::result containing a reference to the 1047   Returns @ref boost::system::result containing a reference to the
1048   mapped value of the element that matches `key`. Otherwise the result 1048   mapped value of the element that matches `key`. Otherwise the result
1049   contains an `error_code`. 1049   contains an `error_code`.
1050   1050  
1051   @par Exception Safety 1051   @par Exception Safety
1052   No-throw guarantee. 1052   No-throw guarantee.
1053   1053  
1054   @param key The key of the element to find. 1054   @param key The key of the element to find.
1055   1055  
1056   @par Complexity 1056   @par Complexity
1057   Constant on average, worst case linear in @ref size(). 1057   Constant on average, worst case linear in @ref size().
1058   1058  
1059   @{ 1059   @{
1060   */ 1060   */
1061   BOOST_JSON_DECL 1061   BOOST_JSON_DECL
1062   system::result<value&> 1062   system::result<value&>
1063   try_at(string_view key) noexcept; 1063   try_at(string_view key) noexcept;
1064   1064  
1065   BOOST_JSON_DECL 1065   BOOST_JSON_DECL
1066   system::result<value const&> 1066   system::result<value const&>
1067   try_at(string_view key) const noexcept; 1067   try_at(string_view key) const noexcept;
1068   /// @} 1068   /// @}
1069   1069  
1070   /** Access the specified element, with bounds checking. 1070   /** Access the specified element, with bounds checking.
1071   1071  
1072   Returns a reference to the mapped value of the element that matches 1072   Returns a reference to the mapped value of the element that matches
1073   `key`, otherwise throws. 1073   `key`, otherwise throws.
1074   1074  
1075   @par Complexity 1075   @par Complexity
1076   Constant on average, worst case linear in @ref size(). 1076   Constant on average, worst case linear in @ref size().
1077   1077  
1078   @par Exception Safety 1078   @par Exception Safety
1079   Strong guarantee. 1079   Strong guarantee.
1080   1080  
1081   @return A reference to the mapped value. 1081   @return A reference to the mapped value.
1082   1082  
1083   @param key The key of the element to find. 1083   @param key The key of the element to find.
1084   @param loc @ref boost::source_location to use in thrown exception; the 1084   @param loc @ref boost::source_location to use in thrown exception; the
1085   source location of the call site by default. 1085   source location of the call site by default.
1086   1086  
1087   @throw `boost::system::system_error` if no such element exists. 1087   @throw `boost::system::system_error` if no such element exists.
1088   1088  
1089   @see @ref operator[], @ref try_at. 1089   @see @ref operator[], @ref try_at.
1090   1090  
1091   @{ 1091   @{
1092   */ 1092   */
1093   inline 1093   inline
1094   value& 1094   value&
1095   at( 1095   at(
1096   string_view key, 1096   string_view key,
1097   source_location const& loc = BOOST_CURRENT_LOCATION) &; 1097   source_location const& loc = BOOST_CURRENT_LOCATION) &;
1098   1098  
1099   inline 1099   inline
1100   value&& 1100   value&&
1101   at( 1101   at(
1102   string_view key, 1102   string_view key,
1103   source_location const& loc = BOOST_CURRENT_LOCATION) &&; 1103   source_location const& loc = BOOST_CURRENT_LOCATION) &&;
1104   1104  
1105   BOOST_JSON_DECL 1105   BOOST_JSON_DECL
1106   value const& 1106   value const&
1107   at( 1107   at(
1108   string_view key, 1108   string_view key,
1109   source_location const& loc = BOOST_CURRENT_LOCATION) const&; 1109   source_location const& loc = BOOST_CURRENT_LOCATION) const&;
1110   /// @} 1110   /// @}
1111   1111  
1112   /** Access or insert an element. 1112   /** Access or insert an element.
1113   1113  
1114   Returns a reference to the value that is mapped to `key`. If such value 1114   Returns a reference to the value that is mapped to `key`. If such value
1115   does not already exist, performs an insertion of a null value. 1115   does not already exist, performs an insertion of a null value.
1116   1116  
1117   If an insertion occurs and results in a rehashing of the container, all 1117   If an insertion occurs and results in a rehashing of the container, all
1118   iterators including any past-the-end iterators, and all references to 1118   iterators including any past-the-end iterators, and all references to
1119   the elements are invalidated. Otherwise, no iterators or references are 1119   the elements are invalidated. Otherwise, no iterators or references are
1120   invalidated. 1120   invalidated.
1121   1121  
1122   @par Complexity 1122   @par Complexity
1123   Constant on average, worst case linear in @ref size(). 1123   Constant on average, worst case linear in @ref size().
1124   1124  
1125   @par Exception Safety 1125   @par Exception Safety
1126   Strong guarantee. Calls to `memory_resource::allocate` may throw. 1126   Strong guarantee. Calls to `memory_resource::allocate` may throw.
1127   1127  
1128   @return A reference to the mapped value. 1128   @return A reference to the mapped value.
1129   1129  
1130   @param key The key of the element to find. 1130   @param key The key of the element to find.
1131   */ 1131   */
1132   BOOST_JSON_DECL 1132   BOOST_JSON_DECL
1133   value& 1133   value&
1134   operator[](string_view key); 1134   operator[](string_view key);
1135   1135  
1136   /** Count the number of elements with a specific key. 1136   /** Count the number of elements with a specific key.
1137   1137  
1138   Returns the number of elements with keys equal to `key`. The only 1138   Returns the number of elements with keys equal to `key`. The only
1139   possible return values are 0 and 1. 1139   possible return values are 0 and 1.
1140   1140  
1141   @par Complexity 1141   @par Complexity
1142   Constant on average, worst case linear in @ref size(). 1142   Constant on average, worst case linear in @ref size().
1143   1143  
1144   @par Exception Safety 1144   @par Exception Safety
1145   No-throw guarantee. 1145   No-throw guarantee.
1146   1146  
1147   @param key The key of the element to find. 1147   @param key The key of the element to find.
1148   */ 1148   */
1149   BOOST_JSON_DECL 1149   BOOST_JSON_DECL
1150   std::size_t 1150   std::size_t
1151   count(string_view key) const noexcept; 1151   count(string_view key) const noexcept;
1152   1152  
1153   /** Find an element with a specific key. 1153   /** Find an element with a specific key.
1154   1154  
1155   This function returns an iterator to the element 1155   This function returns an iterator to the element
1156   matching `key` if it exists, otherwise returns 1156   matching `key` if it exists, otherwise returns
1157   @ref end(). 1157   @ref end().
1158   1158  
1159   @par Complexity 1159   @par Complexity
1160   Constant on average, worst case linear in @ref size(). 1160   Constant on average, worst case linear in @ref size().
1161   1161  
1162   @par Exception Safety 1162   @par Exception Safety
1163   No-throw guarantee. 1163   No-throw guarantee.
1164   1164  
1165   @param key The key of the element to find. 1165   @param key The key of the element to find.
1166   1166  
1167   @{ 1167   @{
1168   */ 1168   */
1169   BOOST_JSON_DECL 1169   BOOST_JSON_DECL
1170   iterator 1170   iterator
1171   find(string_view key) noexcept; 1171   find(string_view key) noexcept;
1172   1172  
1173   BOOST_JSON_DECL 1173   BOOST_JSON_DECL
1174   const_iterator 1174   const_iterator
1175   find(string_view key) const noexcept; 1175   find(string_view key) const noexcept;
1176   /// @} 1176   /// @}
1177   1177  
1178   /** Return `true` if the key is found. 1178   /** Return `true` if the key is found.
1179   1179  
1180   Checks if there is an element with key equal to `key`. 1180   Checks if there is an element with key equal to `key`.
1181   1181  
1182   @par Effects 1182   @par Effects
1183   @code 1183   @code
1184   return find(key) != end(); 1184   return find(key) != end();
1185   @endcode 1185   @endcode
1186   1186  
1187   @par Complexity 1187   @par Complexity
1188   Constant on average, worst case linear in @ref size(). 1188   Constant on average, worst case linear in @ref size().
1189   1189  
1190   @par Exception Safety 1190   @par Exception Safety
1191   No-throw guarantee. 1191   No-throw guarantee.
1192   1192  
1193   @param key The key of the element to find. 1193   @param key The key of the element to find.
1194   1194  
1195   @see @ref find. 1195   @see @ref find.
1196   */ 1196   */
1197   BOOST_JSON_DECL 1197   BOOST_JSON_DECL
1198   bool 1198   bool
1199   contains(string_view key) const noexcept; 1199   contains(string_view key) const noexcept;
1200   1200  
1201   /** Return a pointer to the value if the key is found, or null 1201   /** Return a pointer to the value if the key is found, or null
1202   1202  
1203   This function searches for a value with the given 1203   This function searches for a value with the given
1204   key, and returns a pointer to it if found. Otherwise 1204   key, and returns a pointer to it if found. Otherwise
1205   it returns null. 1205   it returns null.
1206   1206  
1207   @par Example 1207   @par Example
1208   @code 1208   @code
1209   if( auto p = obj.if_contains( "key" ) ) 1209   if( auto p = obj.if_contains( "key" ) )
1210   std::cout << *p; 1210   std::cout << *p;
1211   @endcode 1211   @endcode
1212   1212  
1213   @par Complexity 1213   @par Complexity
1214   Constant on average, worst case linear in @ref size(). 1214   Constant on average, worst case linear in @ref size().
1215   1215  
1216   @par Exception Safety 1216   @par Exception Safety
1217   No-throw guarantee. 1217   No-throw guarantee.
1218   1218  
1219   @param key The key of the element to find. 1219   @param key The key of the element to find.
1220   1220  
1221   @see @ref find. 1221   @see @ref find.
1222   1222  
1223   @{ 1223   @{
1224   */ 1224   */
1225   BOOST_JSON_DECL 1225   BOOST_JSON_DECL
1226   value const* 1226   value const*
1227   if_contains(string_view key) const noexcept; 1227   if_contains(string_view key) const noexcept;
1228   1228  
1229   BOOST_JSON_DECL 1229   BOOST_JSON_DECL
1230   value* 1230   value*
1231   if_contains(string_view key) noexcept; 1231   if_contains(string_view key) noexcept;
1232   /// @} 1232   /// @}
1233   1233  
1234   /** Compare two objects for equality. 1234   /** Compare two objects for equality.
1235   1235  
1236   Objects are equal when their sizes are the same, 1236   Objects are equal when their sizes are the same,
1237   and when for each key in `lhs` there is a matching 1237   and when for each key in `lhs` there is a matching
1238   key in `rhs` with the same value. 1238   key in `rhs` with the same value.
1239   1239  
1240   @par Complexity 1240   @par Complexity
1241   Average case linear and worst case quadratic in `lhs.size()`. 1241   Average case linear and worst case quadratic in `lhs.size()`.
1242   1242  
1243   @par Exception Safety 1243   @par Exception Safety
1244   No-throw guarantee. 1244   No-throw guarantee.
1245   */ 1245   */
1246   // inline friend speeds up overload resolution 1246   // inline friend speeds up overload resolution
1247   friend 1247   friend
1248   bool 1248   bool
HITCBC 1249   75 operator==( 1249   75 operator==(
1250   object const& lhs, 1250   object const& lhs,
1251   object const& rhs) noexcept 1251   object const& rhs) noexcept
1252   { 1252   {
HITCBC 1253   75 return lhs.equal(rhs); 1253   75 return lhs.equal(rhs);
1254   } 1254   }
1255   1255  
1256   /** Compare two objects for inequality. 1256   /** Compare two objects for inequality.
1257   1257  
1258   Objects are equal when their sizes are the same, and when for each key 1258   Objects are equal when their sizes are the same, and when for each key
1259   in `lhs` there is a matching key in `rhs` with the same value. 1259   in `lhs` there is a matching key in `rhs` with the same value.
1260   1260  
1261   @par Complexity 1261   @par Complexity
1262   Average casee linear and worst case quadratic in `lhs.size()`. 1262   Average casee linear and worst case quadratic in `lhs.size()`.
1263   1263  
1264   @par Exception Safety 1264   @par Exception Safety
1265   No-throw guarantee. 1265   No-throw guarantee.
1266   */ 1266   */
1267   // inline friend speeds up overload resolution 1267   // inline friend speeds up overload resolution
1268   friend 1268   friend
1269   bool 1269   bool
HITCBC 1270   6 operator!=( 1270   6 operator!=(
1271   object const& lhs, 1271   object const& lhs,
1272   object const& rhs) noexcept 1272   object const& rhs) noexcept
1273   { 1273   {
HITCBC 1274   6 return ! (lhs == rhs); 1274   6 return ! (lhs == rhs);
1275   } 1275   }
1276   1276  
1277   /** Serialize to an output stream. 1277   /** Serialize to an output stream.
1278   1278  
1279   This function serializes an `object` as JSON into the output stream. 1279   This function serializes an `object` as JSON into the output stream.
1280   1280  
1281   @return Reference to `os`. 1281   @return Reference to `os`.
1282   1282  
1283   @par Complexity 1283   @par Complexity
1284   Constant or linear in the size of `obj`. 1284   Constant or linear in the size of `obj`.
1285   1285  
1286   @par Exception Safety 1286   @par Exception Safety
1287   Strong guarantee. 1287   Strong guarantee.
1288   Calls to `memory_resource::allocate` may throw. 1288   Calls to `memory_resource::allocate` may throw.
1289   1289  
1290   @param os The output stream to serialize to. 1290   @param os The output stream to serialize to.
1291   1291  
1292   @param obj The value to serialize. 1292   @param obj The value to serialize.
1293   */ 1293   */
1294   BOOST_JSON_DECL 1294   BOOST_JSON_DECL
1295   friend 1295   friend
1296   std::ostream& 1296   std::ostream&
1297   operator<<( 1297   operator<<(
1298   std::ostream& os, 1298   std::ostream& os,
1299   object const& obj); 1299   object const& obj);
1300   private: 1300   private:
1301   #ifndef BOOST_JSON_DOCS 1301   #ifndef BOOST_JSON_DOCS
1302   // VFALCO friending a detail function makes it public 1302   // VFALCO friending a detail function makes it public
1303   template<class CharRange> 1303   template<class CharRange>
1304   friend 1304   friend
1305   std::pair<key_value_pair*, std::size_t> 1305   std::pair<key_value_pair*, std::size_t>
1306   detail::find_in_object( 1306   detail::find_in_object(
1307   object const& obj, 1307   object const& obj,
1308   CharRange key) noexcept; 1308   CharRange key) noexcept;
1309   #endif 1309   #endif
1310   1310  
1311   template<class InputIt> 1311   template<class InputIt>
1312   void 1312   void
1313   construct( 1313   construct(
1314   InputIt first, 1314   InputIt first,
1315   InputIt last, 1315   InputIt last,
1316   std::size_t min_capacity, 1316   std::size_t min_capacity,
1317   std::input_iterator_tag); 1317   std::input_iterator_tag);
1318   1318  
1319   template<class InputIt> 1319   template<class InputIt>
1320   void 1320   void
1321   construct( 1321   construct(
1322   InputIt first, 1322   InputIt first,
1323   InputIt last, 1323   InputIt last,
1324   std::size_t min_capacity, 1324   std::size_t min_capacity,
1325   std::forward_iterator_tag); 1325   std::forward_iterator_tag);
1326   1326  
1327   template<class InputIt> 1327   template<class InputIt>
1328   void 1328   void
1329   insert( 1329   insert(
1330   InputIt first, 1330   InputIt first,
1331   InputIt last, 1331   InputIt last,
1332   std::input_iterator_tag); 1332   std::input_iterator_tag);
1333   1333  
1334   template<class InputIt> 1334   template<class InputIt>
1335   void 1335   void
1336   insert( 1336   insert(
1337   InputIt first, 1337   InputIt first,
1338   InputIt last, 1338   InputIt last,
1339   std::forward_iterator_tag); 1339   std::forward_iterator_tag);
1340   1340  
1341   template< class... Args > 1341   template< class... Args >
1342   std::pair<iterator, bool> 1342   std::pair<iterator, bool>
1343   emplace_impl(string_view key, Args&& ... args ); 1343   emplace_impl(string_view key, Args&& ... args );
1344   1344  
1345   BOOST_JSON_DECL 1345   BOOST_JSON_DECL
1346   key_value_pair* 1346   key_value_pair*
1347   insert_impl( 1347   insert_impl(
1348   pilfered<key_value_pair> p, 1348   pilfered<key_value_pair> p,
1349   std::size_t hash); 1349   std::size_t hash);
1350   1350  
1351   BOOST_JSON_DECL 1351   BOOST_JSON_DECL
1352   table* 1352   table*
1353   reserve_impl(std::size_t new_capacity); 1353   reserve_impl(std::size_t new_capacity);
1354   1354  
1355   BOOST_JSON_DECL 1355   BOOST_JSON_DECL
1356   bool 1356   bool
1357   equal(object const& other) const noexcept; 1357   equal(object const& other) const noexcept;
1358   1358  
1359   inline 1359   inline
1360   std::size_t 1360   std::size_t
1361   growth( 1361   growth(
1362   std::size_t new_size) const; 1362   std::size_t new_size) const;
1363   1363  
1364   inline 1364   inline
1365   void 1365   void
1366   remove( 1366   remove(
1367   index_t& head, 1367   index_t& head,
1368   key_value_pair& p) noexcept; 1368   key_value_pair& p) noexcept;
1369   1369  
1370   inline 1370   inline
1371   void 1371   void
1372   destroy() noexcept; 1372   destroy() noexcept;
1373   1373  
1374   inline 1374   inline
1375   void 1375   void
1376   destroy( 1376   destroy(
1377   key_value_pair* first, 1377   key_value_pair* first,
1378   key_value_pair* last) noexcept; 1378   key_value_pair* last) noexcept;
1379   1379  
1380   template<class FS, class FB> 1380   template<class FS, class FB>
1381   auto 1381   auto
1382   do_erase( 1382   do_erase(
1383   const_iterator pos, 1383   const_iterator pos,
1384   FS small_reloc, 1384   FS small_reloc,
1385   FB big_reloc) noexcept 1385   FB big_reloc) noexcept
1386   -> iterator; 1386   -> iterator;
1387   1387  
1388   inline 1388   inline
1389   void 1389   void
1390   reindex_relocate( 1390   reindex_relocate(
1391   key_value_pair* src, 1391   key_value_pair* src,
1392   key_value_pair* dst) noexcept; 1392   key_value_pair* dst) noexcept;
1393   }; 1393   };
1394   1394  
1395   } // namespace json 1395   } // namespace json
1396   } // namespace boost 1396   } // namespace boost
1397   1397  
1398   #ifndef BOOST_JSON_DOCS 1398   #ifndef BOOST_JSON_DOCS
1399   // boost::hash trait 1399   // boost::hash trait
1400   namespace boost 1400   namespace boost
1401   { 1401   {
1402   namespace container_hash 1402   namespace container_hash
1403   { 1403   {
1404   1404  
1405   template< class T > struct is_unordered_range; 1405   template< class T > struct is_unordered_range;
1406   1406  
1407   template<> 1407   template<>
1408   struct is_unordered_range< json::object > 1408   struct is_unordered_range< json::object >
1409   : std::true_type 1409   : std::true_type
1410   {}; 1410   {};
1411   1411  
1412   } // namespace container_hash 1412   } // namespace container_hash
1413   } // namespace boost 1413   } // namespace boost
1414   1414  
1415   // std::hash specialization 1415   // std::hash specialization
1416   namespace std { 1416   namespace std {
1417   template <> 1417   template <>
1418   struct hash< ::boost::json::object > { 1418   struct hash< ::boost::json::object > {
1419   BOOST_JSON_DECL 1419   BOOST_JSON_DECL
1420   std::size_t 1420   std::size_t
1421   operator()(::boost::json::object const& jo) const noexcept; 1421   operator()(::boost::json::object const& jo) const noexcept;
1422   }; 1422   };
1423   } // std 1423   } // std
1424   #endif 1424   #endif
1425   1425  
1426   1426  
1427   // Must be included here for this file to stand alone 1427   // Must be included here for this file to stand alone
1428   #include <boost/json/value.hpp> 1428   #include <boost/json/value.hpp>
1429   1429  
1430   // includes are at the bottom of <boost/json/value.hpp> 1430   // includes are at the bottom of <boost/json/value.hpp>
1431   1431  
1432   #endif 1432   #endif