Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:14:59

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/json
0008 //
0009 
0010 #ifndef BOOST_JSON_OBJECT_HPP
0011 #define BOOST_JSON_OBJECT_HPP
0012 
0013 #include <boost/json/detail/config.hpp>
0014 #include <boost/json/kind.hpp>
0015 #include <boost/json/pilfer.hpp>
0016 #include <boost/json/storage_ptr.hpp>
0017 #include <boost/json/string_view.hpp>
0018 #include <boost/json/detail/object.hpp>
0019 #include <boost/json/detail/value.hpp>
0020 #include <cstdlib>
0021 #include <initializer_list>
0022 #include <iterator>
0023 #include <type_traits>
0024 #include <utility>
0025 
0026 namespace boost {
0027 namespace json {
0028 
0029 class value;
0030 class value_ref;
0031 class key_value_pair;
0032 
0033 /** A dynamically sized associative container of JSON key/value pairs.
0034 
0035     This is an associative container whose elements
0036     are key/value pairs with unique keys.
0037 \n
0038     The elements are stored contiguously; iterators are
0039     ordinary pointers, allowing random access pointer
0040     arithmetic for retrieving elements.
0041     In addition, the container maintains an internal
0042     index to speed up find operations, reducing the
0043     average complexity for most lookups and insertions.
0044 \n
0045     Reallocations are usually costly operations in terms of
0046     performance, as elements are copied and the internal
0047     index must be rebuilt. The @ref reserve function can
0048     be used to eliminate reallocations if the number of
0049     elements is known beforehand.
0050 
0051     @par Allocators
0052 
0053     All elements stored in the container, and their
0054     children if any, will use the same memory resource that
0055     was used to construct the container.
0056 
0057     @par Thread Safety
0058 
0059     Non-const member functions may not be called
0060     concurrently with any other member functions.
0061 
0062     @par Satisfies
0063         <a href="https://en.cppreference.com/w/cpp/named_req/ContiguousContainer"><em>ContiguousContainer</em></a>,
0064         <a href="https://en.cppreference.com/w/cpp/named_req/ReversibleContainer"><em>ReversibleContainer</em></a>, and
0065         <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>.
0066 */
0067 class object
0068 {
0069     struct table;
0070     class revert_construct;
0071     class revert_insert;
0072     friend class value;
0073     friend class object_test;
0074     using access = detail::access;
0075     using index_t = std::uint32_t;
0076     static index_t constexpr null_index_ =
0077         std::uint32_t(-1);
0078 
0079     storage_ptr sp_;            // must come first
0080     kind k_ = kind::object;     // must come second
0081     table* t_;
0082 
0083     BOOST_JSON_DECL
0084     static table empty_;
0085 
0086     template<class T>
0087     using is_inputit = typename std::enable_if<
0088         std::is_constructible<key_value_pair,
0089         typename std::iterator_traits<T>::reference
0090             >::value>::type;
0091 
0092     BOOST_JSON_DECL
0093     explicit
0094     object(detail::unchecked_object&& uo);
0095 
0096 public:
0097     /** The type of _Allocator_ returned by @ref get_allocator
0098 
0099         This type is a @ref polymorphic_allocator.
0100     */
0101 #ifdef BOOST_JSON_DOCS
0102     // VFALCO doc toolchain renders this incorrectly
0103     using allocator_type = __see_below__;
0104 #else
0105     using allocator_type = polymorphic_allocator<value>;
0106 #endif
0107 
0108     /** The type of keys.
0109 
0110         The function @ref string::max_size returns the
0111         maximum allowed size of strings used as keys.
0112     */
0113     using key_type = string_view;
0114 
0115     /// The type of mapped values
0116     using mapped_type = value;
0117 
0118     /// The element type
0119     using value_type = key_value_pair;
0120 
0121     /// The type used to represent unsigned integers
0122     using size_type = std::size_t;
0123 
0124     /// The type used to represent signed integers
0125     using difference_type = std::ptrdiff_t;
0126 
0127     /// A reference to an element
0128     using reference = value_type&;
0129 
0130     /// A const reference to an element
0131     using const_reference = value_type const&;
0132 
0133     /// A pointer to an element
0134     using pointer = value_type*;
0135 
0136     /// A const pointer to an element
0137     using const_pointer = value_type const*;
0138 
0139     /// A random access iterator to an element
0140     using iterator = value_type*;
0141 
0142     /// A const random access iterator to an element
0143     using const_iterator = value_type const*;
0144 
0145     /// A reverse random access iterator to an element
0146     using reverse_iterator =
0147         std::reverse_iterator<iterator>;
0148 
0149     /// A const reverse random access iterator to an element
0150     using const_reverse_iterator =
0151         std::reverse_iterator<const_iterator>;
0152 
0153     //------------------------------------------------------
0154 
0155     /** Destructor.
0156 
0157         The destructor for each element is called if needed,
0158         any used memory is deallocated, and shared ownership
0159         of the @ref memory_resource is released.
0160 
0161         @par Complexity
0162         Constant, or linear in @ref size().
0163 
0164         @par Exception Safety
0165         No-throw guarantee.
0166     */
0167     BOOST_JSON_DECL
0168     ~object() noexcept;
0169 
0170     //------------------------------------------------------
0171 
0172     /** Default constructor.
0173 
0174         The constructed object is empty with zero
0175         capacity, using the [default memory resource].
0176 
0177         @par Complexity
0178         Constant.
0179 
0180         @par Exception Safety
0181         No-throw guarantee.
0182 
0183         [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
0184     */
0185     object() noexcept
0186         : t_(&empty_)
0187     {
0188     }
0189 
0190     /** Constructor.
0191 
0192         The constructed object is empty with zero
0193         capacity, using the specified memory resource.
0194 
0195         @par Complexity
0196         Constant.
0197 
0198         @par Exception Safety
0199         No-throw guarantee.
0200 
0201         @param sp A pointer to the @ref memory_resource
0202         to use. The container will acquire shared
0203         ownership of the memory resource.
0204     */
0205     explicit
0206     object(storage_ptr sp) noexcept
0207         : sp_(std::move(sp))
0208         , t_(&empty_)
0209     {
0210     }
0211 
0212     /** Constructor.
0213 
0214         The constructed object is empty with capacity
0215         equal to the specified minimum capacity,
0216         using the specified memory resource.
0217 
0218         @par Complexity
0219         Constant.
0220 
0221         @par Exception Safety
0222         Strong guarantee.
0223         Calls to `memory_resource::allocate` may throw.
0224 
0225         @param min_capacity The minimum number
0226         of elements for which capacity is guaranteed
0227         without a subsequent reallocation.
0228 
0229         @param sp A pointer to the @ref memory_resource
0230         to use. The container will acquire shared
0231         ownership of the memory resource.
0232     */
0233     BOOST_JSON_DECL
0234     object(
0235         std::size_t min_capacity,
0236         storage_ptr sp = {});
0237 
0238     /** Constructor.
0239 
0240         The object is constructed with the elements
0241         in the range `{first, last)`, preserving order,
0242         using the specified memory resource.
0243         If there are elements with duplicate keys; that
0244         is, if multiple elements in the range have keys
0245         that compare equal, only the first equivalent
0246         element will be inserted.
0247 
0248         @par Constraints
0249         @code
0250         std::is_constructible_v<
0251             key_value_pair,
0252             std::iterator_traits<InputIt>::reference>
0253         @endcode
0254 
0255         @par Complexity
0256         Linear in `std::distance(first, last)`.
0257 
0258         @par Exception Safety
0259         Strong guarantee.
0260         Calls to `memory_resource::allocate` may throw.
0261 
0262         @param first An input iterator pointing to the
0263         first element to insert, or pointing to the end
0264         of the range.
0265 
0266         @param last An input iterator pointing to the end
0267         of the range.
0268 
0269         @param min_capacity The minimum number
0270         of elements for which capacity is guaranteed
0271         without a subsequent reallocation.
0272         Upon construction, @ref capacity() will be greater
0273         than or equal to this number.
0274 
0275         @param sp A pointer to the @ref memory_resource
0276         to use. The container will acquire shared
0277         ownership of the memory resource.
0278 
0279         @tparam InputIt a type satisfying the requirements
0280         of __InputIterator__.
0281     */
0282     template<
0283         class InputIt
0284     #ifndef BOOST_JSON_DOCS
0285         ,class = is_inputit<InputIt>
0286     #endif
0287     >
0288     object(
0289         InputIt first,
0290         InputIt last,
0291         std::size_t min_capacity = 0,
0292         storage_ptr sp = {})
0293         : sp_(std::move(sp))
0294         , t_(&empty_)
0295     {
0296         construct(
0297             first, last,
0298             min_capacity,
0299             typename std::iterator_traits<
0300                 InputIt>::iterator_category{});
0301     }
0302 
0303     /** Move constructor.
0304 
0305         The object is constructed by acquiring ownership of
0306         the contents of `other` and shared ownership
0307         of `other`'s memory resource.
0308 
0309         @note
0310 
0311         After construction, the moved-from object behaves
0312         as if newly constructed with its current memory resource.
0313 
0314         @par Complexity
0315         Constant.
0316 
0317         @par Exception Safety
0318         No-throw guarantee.
0319 
0320         @param other The object to move.
0321     */
0322     BOOST_JSON_DECL
0323     object(object&& other) noexcept;
0324 
0325     /** Move constructor.
0326 
0327         The object is constructed with the contents of
0328         `other` by move semantics, using the specified
0329         memory resource:
0330 
0331         @li If `*other.storage() == *sp`, ownership of
0332         the underlying memory is transferred in constant
0333         time, with no possibility of exceptions.
0334         After construction, the moved-from object behaves
0335         as if newly constructed with its current storage
0336         pointer.
0337 
0338         @li If `*other.storage() != *sp`, an
0339         element-wise copy is performed, which may throw.
0340         In this case, the moved-from object is not
0341         changed.
0342 
0343         @par Complexity
0344         Constant or linear in `other.size()`.
0345 
0346         @par Exception Safety
0347         Strong guarantee.
0348         Calls to `memory_resource::allocate` may throw.
0349 
0350         @param other The object to move.
0351 
0352         @param sp A pointer to the @ref memory_resource
0353         to use. The container will acquire shared
0354         ownership of the memory resource.
0355     */
0356     BOOST_JSON_DECL
0357     object(
0358         object&& other,
0359         storage_ptr sp);
0360 
0361     /** Pilfer constructor.
0362 
0363         The object is constructed by acquiring ownership
0364         of the contents of `other` using pilfer semantics.
0365         This is more efficient than move construction, when
0366         it is known that the moved-from object will be
0367         immediately destroyed afterwards.
0368 
0369         @par Complexity
0370         Constant.
0371 
0372         @par Exception Safety
0373         No-throw guarantee.
0374 
0375         @param other The value to pilfer. After pilfer
0376         construction, `other` is not in a usable state
0377         and may only be destroyed.
0378 
0379         @see @ref pilfer,
0380             <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
0381                 Valueless Variants Considered Harmful</a>
0382     */
0383     object(pilfered<object> other) noexcept
0384         : sp_(std::move(other.get().sp_))
0385         , t_(detail::exchange(
0386             other.get().t_, &empty_))
0387     {
0388     }
0389 
0390     /** Copy constructor.
0391 
0392         The object is constructed with a copy of the
0393         contents of `other`, using `other`'s memory resource.
0394 
0395         @par Complexity
0396         Linear in `other.size()`.
0397 
0398         @par Exception Safety
0399         Strong guarantee.
0400         Calls to `memory_resource::allocate` may throw.
0401 
0402         @param other The object to copy.
0403     */
0404     object(
0405         object const& other)
0406         : object(other, other.sp_)
0407     {
0408     }
0409 
0410     /** Copy constructor.
0411 
0412         The object is constructed with a copy of the
0413         contents of `other`, using the specified memory resource.
0414 
0415         @par Complexity
0416         Linear in `other.size()`.
0417 
0418         @par Exception Safety
0419         Strong guarantee.
0420         Calls to `memory_resource::allocate` may throw.
0421 
0422         @param other The object to copy.
0423 
0424         @param sp A pointer to the @ref memory_resource
0425         to use. The container will acquire shared
0426         ownership of the memory resource.
0427     */
0428     BOOST_JSON_DECL
0429     object(
0430         object const& other,
0431         storage_ptr sp);
0432 
0433     /** Construct from initializer-list.
0434 
0435         The object is constructed with a copy of the values
0436         in the initializer-list in order, using the
0437         specified memory resource.
0438         If there are elements with duplicate keys; that
0439         is, if multiple elements in the range have keys
0440         that compare equal, only the first equivalent
0441         element will be inserted.
0442 
0443         @par Complexity
0444         Linear in `init.size()`.
0445 
0446         @par Exception Safety
0447         Strong guarantee.
0448         Calls to `memory_resource::allocate` may throw.
0449 
0450         @param init The initializer list to insert.
0451 
0452         @param sp A pointer to the @ref memory_resource
0453         to use. The container will acquire shared
0454         ownership of the memory resource.
0455     */
0456     object(
0457         std::initializer_list<
0458             std::pair<string_view, value_ref>> init,
0459         storage_ptr sp = {})
0460         : object(init, 0, std::move(sp))
0461     {
0462     }
0463 
0464     /** Construct from initializer-list.
0465 
0466         Storage for at least `min_capacity` elements is
0467         reserved, and then
0468         the object is constructed with a copy of the values
0469         in the initializer-list in order, using the
0470         specified memory resource.
0471         If there are elements with duplicate keys; that
0472         is, if multiple elements in the range have keys
0473         that compare equal, only the first equivalent
0474         element will be inserted.
0475 
0476         @par Complexity
0477         Linear in `init.size()`.
0478 
0479         @par Exception Safety
0480         Strong guarantee.
0481         Calls to `memory_resource::allocate` may throw.
0482 
0483         @param init The initializer list to insert.
0484 
0485         @param min_capacity The minimum number
0486         of elements for which capacity is guaranteed
0487         without a subsequent reallocation.
0488         Upon construction, @ref capacity() will be greater
0489         than or equal to this number.
0490 
0491         @param sp A pointer to the @ref memory_resource
0492         to use. The container will acquire shared
0493         ownership of the memory resource.
0494     */
0495     BOOST_JSON_DECL
0496     object(
0497         std::initializer_list<
0498             std::pair<string_view, value_ref>> init,
0499         std::size_t min_capacity,
0500         storage_ptr sp = {});
0501 
0502     //------------------------------------------------------
0503     //
0504     // Assignment
0505     //
0506     //------------------------------------------------------
0507 
0508     /** Copy assignment.
0509 
0510         The contents of the object are replaced with an
0511         element-wise copy of `other`.
0512 
0513         @par Complexity
0514         Linear in @ref size() plus `other.size()`.
0515 
0516         @par Exception Safety
0517         Strong guarantee.
0518         Calls to `memory_resource::allocate` may throw.
0519 
0520         @param other The object to copy.
0521     */
0522     BOOST_JSON_DECL
0523     object&
0524     operator=(object const& other);
0525 
0526     /** Move assignment.
0527 
0528         The contents of the object are replaced with the
0529         contents of `other` using move semantics:
0530 
0531         @li If `*other.storage() == *sp`, ownership of
0532         the underlying memory is transferred in constant
0533         time, with no possibility of exceptions.
0534         After assignment, the moved-from object behaves
0535         as if newly constructed with its current storage
0536         pointer.
0537 
0538         @li If `*other.storage() != *sp`, an
0539         element-wise copy is performed, which may throw.
0540         In this case, the moved-from object is not
0541         changed.
0542 
0543         @par Complexity
0544         Constant or linear in @ref size() plus `other.size()`.
0545 
0546         @par Exception Safety
0547         Strong guarantee.
0548         Calls to `memory_resource::allocate` may throw.
0549 
0550         @param other The object to move.
0551     */
0552     BOOST_JSON_DECL
0553     object&
0554     operator=(object&& other);
0555 
0556     /** Assignment.
0557 
0558         Replaces the contents with the contents of an
0559         initializer list.
0560 
0561         @par Complexity
0562         Linear in @ref size() plus
0563         average case linear in `init.size()`,
0564         worst case quadratic in `init.size()`.
0565 
0566         @par Exception Safety
0567         Strong guarantee.
0568         Calls to `memory_resource::allocate` may throw.
0569 
0570         @param init The initializer list to copy.
0571     */
0572     BOOST_JSON_DECL
0573     object&
0574     operator=(std::initializer_list<
0575         std::pair<string_view, value_ref>> init);
0576 
0577     //------------------------------------------------------
0578 
0579     /** Return the associated @ref memory_resource
0580 
0581         This returns the @ref memory_resource used by
0582         the container.
0583 
0584         @par Complexity
0585         Constant.
0586 
0587         @par Exception Safety
0588         No-throw guarantee.
0589     */
0590     storage_ptr const&
0591     storage() const noexcept
0592     {
0593         return sp_;
0594     }
0595 
0596     /** Return the associated @ref memory_resource
0597 
0598         This function returns an instance of
0599         @ref polymorphic_allocator constructed from the
0600         associated @ref memory_resource.
0601 
0602         @par Complexity
0603         Constant.
0604 
0605         @par Exception Safety
0606         No-throw guarantee.
0607     */
0608     allocator_type
0609     get_allocator() const noexcept
0610     {
0611         return sp_.get();
0612     }
0613 
0614     //------------------------------------------------------
0615     //
0616     // Iterators
0617     //
0618     //------------------------------------------------------
0619 
0620     /** Return an iterator to the first element.
0621 
0622         If the container is empty, @ref end() is returned.
0623 
0624         @par Complexity
0625         Constant.
0626 
0627         @par Exception Safety
0628         No-throw guarantee.
0629     */
0630     inline
0631     iterator
0632     begin() noexcept;
0633 
0634     /** Return a const iterator to the first element.
0635 
0636         If the container is empty, @ref end() is returned.
0637 
0638         @par Complexity
0639         Constant.
0640 
0641         @par Exception Safety
0642         No-throw guarantee.
0643     */
0644     inline
0645     const_iterator
0646     begin() const noexcept;
0647 
0648     /** Return a const iterator to the first element.
0649 
0650         If the container is empty, @ref cend() is returned.
0651 
0652         @par Complexity
0653         Constant.
0654 
0655         @par Exception Safety
0656         No-throw guarantee.
0657     */
0658     inline
0659     const_iterator
0660     cbegin() const noexcept;
0661 
0662     /** Return an iterator to the element following the last element.
0663 
0664         The element acts as a placeholder; attempting
0665         to access it results in undefined behavior.
0666 
0667         @par Complexity
0668         Constant.
0669 
0670         @par Exception Safety
0671         No-throw guarantee.
0672     */
0673     inline
0674     iterator
0675     end() noexcept;
0676 
0677     /** Return a const iterator to the element following the last element.
0678 
0679         The element acts as a placeholder; attempting
0680         to access it results in undefined behavior.
0681 
0682         @par Complexity
0683         Constant.
0684 
0685         @par Exception Safety
0686         No-throw guarantee.
0687     */
0688     inline
0689     const_iterator
0690     end() const noexcept;
0691 
0692     /** Return a const iterator to the element following the last element.
0693 
0694         The element acts as a placeholder; attempting
0695         to access it results in undefined behavior.
0696 
0697         @par Complexity
0698         Constant.
0699 
0700         @par Exception Safety
0701         No-throw guarantee.
0702     */
0703     inline
0704     const_iterator
0705     cend() const noexcept;
0706 
0707     /** Return a reverse iterator to the first element of the reversed container.
0708 
0709         The pointed-to element corresponds to the
0710         last element of the non-reversed container.
0711         If the container is empty, @ref rend() is returned.
0712 
0713         @par Complexity
0714         Constant.
0715 
0716         @par Exception Safety
0717         No-throw guarantee.
0718     */
0719     inline
0720     reverse_iterator
0721     rbegin() noexcept;
0722 
0723     /** Return a const reverse iterator to the first element of the reversed container.
0724 
0725         The pointed-to element corresponds to the
0726         last element of the non-reversed container.
0727         If the container is empty, @ref rend() is returned.
0728 
0729         @par Complexity
0730         Constant.
0731 
0732         @par Exception Safety
0733         No-throw guarantee.
0734     */
0735     inline
0736     const_reverse_iterator
0737     rbegin() const noexcept;
0738 
0739     /** Return a const reverse iterator to the first element of the reversed container.
0740 
0741         The pointed-to element corresponds to the
0742         last element of the non-reversed container.
0743         If the container is empty, @ref crend() is returned.
0744 
0745         @par Complexity
0746         Constant.
0747 
0748         @par Exception Safety
0749         No-throw guarantee.
0750     */
0751     inline
0752     const_reverse_iterator
0753     crbegin() const noexcept;
0754 
0755     /** Return a reverse iterator to the element following the last element of the reversed container.
0756 
0757         The pointed-to element corresponds to the element
0758         preceding the first element of the non-reversed container.
0759         This element acts as a placeholder, attempting
0760         to access it results in undefined behavior.
0761 
0762         @par Complexity
0763         Constant.
0764 
0765         @par Exception Safety
0766         No-throw guarantee.
0767     */
0768     inline
0769     reverse_iterator
0770     rend() noexcept;
0771 
0772     /** Return a const reverse iterator to the element following the last element of the reversed container.
0773 
0774         The pointed-to element corresponds to the element
0775         preceding the first element of the non-reversed container.
0776         This element acts as a placeholder, attempting
0777         to access it results in undefined behavior.
0778 
0779         @par Complexity
0780         Constant.
0781 
0782         @par Exception Safety
0783         No-throw guarantee.
0784     */
0785     inline
0786     const_reverse_iterator
0787     rend() const noexcept;
0788 
0789     /** Return a const reverse iterator to the element following the last element of the reversed container.
0790 
0791         The pointed-to element corresponds to the element
0792         preceding the first element of the non-reversed container.
0793         This element acts as a placeholder, attempting
0794         to access it results in undefined behavior.
0795 
0796         @par Complexity
0797         Constant.
0798 
0799         @par Exception Safety
0800         No-throw guarantee.
0801     */
0802     inline
0803     const_reverse_iterator
0804     crend() const noexcept;
0805 
0806     //------------------------------------------------------
0807     //
0808     // Capacity
0809     //
0810     //------------------------------------------------------
0811 
0812     /** Return whether there are no elements.
0813 
0814         Returns `true` if there are no elements in
0815         the container, i.e. @ref size() returns 0.
0816 
0817         @par Complexity
0818         Constant.
0819 
0820         @par Exception Safety
0821         No-throw guarantee.
0822     */
0823     inline
0824     bool
0825     empty() const noexcept;
0826 
0827     /** Return the number of elements.
0828 
0829         This returns the number of elements in the container.
0830 
0831         @par Complexity
0832         Constant.
0833 
0834         @par Exception Safety
0835         No-throw guarantee.
0836     */
0837     inline
0838     std::size_t
0839     size() const noexcept;
0840 
0841     /** Return the maximum number of elements any object can hold
0842 
0843         The maximum is an implementation-defined number dependent
0844         on system or library implementation. This value is a
0845         theoretical limit; at runtime, the actual maximum size
0846         may be less due to resource limits.
0847 
0848         @par Complexity
0849         Constant.
0850 
0851         @par Exception Safety
0852         No-throw guarantee.
0853     */
0854     static
0855     constexpr
0856     std::size_t
0857     max_size() noexcept;
0858 
0859     /** Return the number of elements that can be held in currently allocated memory
0860 
0861         This number may be larger than the value returned
0862         by @ref size().
0863 
0864         @par Complexity
0865         Constant.
0866 
0867         @par Exception Safety
0868         No-throw guarantee.
0869     */
0870     inline
0871     std::size_t
0872     capacity() const noexcept;
0873 
0874     /** Increase the capacity to at least a certain amount.
0875 
0876         This increases the @ref capacity() to a value
0877         that is greater than or equal to `new_capacity`.
0878         If `new_capacity > capacity()`, new memory is
0879         allocated. Otherwise, the call has no effect.
0880         The number of elements and therefore the
0881         @ref size() of the container is not changed.
0882     \n
0883         If new memory is allocated, all iterators
0884         including any past-the-end iterators, and all
0885         references to the elements are invalidated.
0886         Otherwise, no iterators or references are
0887         invalidated.
0888 
0889         @par Complexity
0890         Constant or average case linear in
0891         @ref size(), worst case quadratic.
0892 
0893         @par Exception Safety
0894         Strong guarantee.
0895         Calls to `memory_resource::allocate` may throw.
0896 
0897         @param new_capacity The new minimum capacity.
0898 
0899         @throw system_error `new_capacity > max_size()`
0900     */
0901     inline
0902     void
0903     reserve(std::size_t new_capacity);
0904 
0905     //------------------------------------------------------
0906     //
0907     // Modifiers
0908     //
0909     //------------------------------------------------------
0910 
0911     /** Erase all elements.
0912 
0913         Erases all elements from the container without
0914         changing the capacity.
0915         After this call, @ref size() returns zero.
0916         All references, pointers, and iterators are
0917         invalidated.
0918 
0919         @par Complexity
0920         Linear in @ref size().
0921 
0922         @par Exception Safety
0923         No-throw guarantee.
0924     */
0925     BOOST_JSON_DECL
0926     void
0927     clear() noexcept;
0928 
0929     /** Insert elements.
0930 
0931         Inserts `p` if `this->contains(value_type(p).key())` is `false`.
0932         @ref value_type must be constructible from `p`.
0933 
0934         If the insertion occurs and results in a rehashing
0935         of the container, all iterators and references are invalidated.
0936         Otherwise, they are not affected.
0937         Rehashing occurs only if the new number of elements
0938         is greater than @ref capacity().
0939 
0940         @par Constraints
0941         @code
0942         std::is_constructible_v<value_type, P>
0943         @endcode
0944 
0945         @par Complexity
0946         Average case amortized constant,
0947         worst case linear in @ref size().
0948 
0949         @par Exception Safety
0950         Strong guarantee.
0951         Calls to `memory_resource::allocate` may throw.
0952 
0953         @param p The value to insert.
0954 
0955         @throw system_error key is too long.
0956 
0957         @throw system_error @ref size() >= max_size().
0958 
0959         @return A pair where `first` is an iterator
0960         to the existing or inserted element, and `second`
0961         is `true` if the insertion took place or `false` otherwise.
0962     */
0963     template<class P
0964 #ifndef BOOST_JSON_DOCS
0965         ,class = typename std::enable_if<
0966             std::is_constructible<key_value_pair,
0967                 P, storage_ptr>::value>::type
0968 #endif
0969     >
0970     std::pair<iterator, bool>
0971     insert(P&& p);
0972 
0973     /** Insert elements.
0974 
0975         The elements in the range `[first, last)` are inserted one at a time,
0976         in order. Any element with key that is a duplicate of a key already
0977         present in container will be skipped. This also means, that if there
0978         are two keys within the range that are equal to each other, only the
0979         first will be inserted.
0980 
0981         Insertion may result in rehashing of the container. In that case all
0982         iterators and references are invalidated. Otherwise, they are not
0983         affected.
0984 
0985         @par Precondition
0986         `first` and `last` are not iterators into `*this`.
0987         `first` and `last` form a valid range.
0988 
0989         @par Constraints
0990         @code
0991         std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
0992         @endcode
0993 
0994         @par Complexity
0995         Linear in `std::distance(first, last)`.
0996 
0997         @par Exception Safety
0998         Strong guarantee for forward iterators, basic guarantee for input
0999         iterators.
1000         Calls to `memory_resource::allocate` may throw.
1001 
1002         @param first An input iterator pointing to the first
1003         element to insert, or pointing to the end of the range.
1004 
1005         @param last An input iterator pointing to the end
1006         of the range.
1007 
1008         @tparam InputIt a type satisfying the requirements
1009         of __InputIterator__.
1010     */
1011     template<
1012         class InputIt
1013     #ifndef BOOST_JSON_DOCS
1014         ,class = is_inputit<InputIt>
1015     #endif
1016     >
1017     void
1018     insert(InputIt first, InputIt last)
1019     {
1020         insert(first, last, typename
1021             std::iterator_traits<InputIt
1022                 >::iterator_category{});
1023     }
1024 
1025     /** Insert elements.
1026 
1027         The elements in the initializer list are inserted one at a time, in
1028         order. Any element with key that is a duplicate of a key already
1029         present in container will be skipped. This also means, that if there
1030         are two keys within the initializer list that are equal to each other,
1031         only the first will be inserted.
1032 
1033         Insertion may result in rehashing of the container. In that case all
1034         iterators and references are invalidated. Otherwise, they are not
1035         affected.
1036 
1037         @par Complexity
1038         Linear in `init.size()`.
1039 
1040         @par Exception Safety
1041         Basic guarantee.
1042         Calls to `memory_resource::allocate` may throw.
1043 
1044         @param init The initializer list to insert
1045     */
1046     BOOST_JSON_DECL
1047     void
1048     insert(std::initializer_list<
1049         std::pair<string_view, value_ref>> init);
1050 
1051     /** Insert an element or assign to the current element if the key already exists.
1052 
1053         If the key equivalent to `key` already exists in the
1054         container, assigns `std::forward<M>(m)` to the
1055         `mapped_type` corresponding to the key. Otherwise,
1056         inserts the new value at the end as if by insert,
1057         constructing it from `value_type(key, std::forward<M>(m))`.
1058 
1059         If the insertion occurs and results in a rehashing of the container,
1060         all iterators and references are invalidated. Otherwise, they are not
1061         affected. Rehashing occurs only if the new number of elements is
1062         greater than @ref capacity().
1063 
1064         @par Complexity
1065         Amortized constant on average, worst case linear in @ref size().
1066 
1067         @par Exception Safety
1068         Strong guarantee.
1069         Calls to `memory_resource::allocate` may throw.
1070 
1071         @return A `std::pair` where `first` is an iterator
1072         to the existing or inserted element, and `second`
1073         is `true` if the insertion took place or `false` if
1074         the assignment took place.
1075 
1076         @param key The key used for lookup and insertion
1077 
1078         @param m The value to insert or assign
1079 
1080         @throw system_error if key is too long
1081     */
1082     template<class M>
1083     std::pair<iterator, bool>
1084     insert_or_assign(
1085         string_view key, M&& m);
1086 
1087     /** Construct an element in-place.
1088 
1089         Inserts a new element into the container constructed
1090         in-place with the given argument if there is no
1091         element with the `key` in the container.
1092 
1093         If the insertion occurs and results in a rehashing of the container,
1094         all iterators and references are invalidated. Otherwise, they are not
1095         affected. Rehashing occurs only if the new number of elements is
1096         greater than @ref capacity().
1097 
1098         @par Complexity
1099         Amortized constant on average, worst case linear in @ref size().
1100 
1101         @par Exception Safety
1102         Strong guarantee.
1103         Calls to `memory_resource::allocate` may throw.
1104 
1105         @return A `std::pair` where `first` is an iterator
1106         to the existing or inserted element, and `second`
1107         is `true` if the insertion took place or `false` otherwise.
1108 
1109         @param key The key used for lookup and insertion
1110 
1111         @param arg The argument used to construct the value.
1112         This will be passed as `std::forward<Arg>(arg)` to
1113         the @ref value constructor.
1114 
1115         @throw system_error if key is too long
1116     */
1117     template<class Arg>
1118     std::pair<iterator, bool>
1119     emplace(string_view key, Arg&& arg);
1120 
1121     /** Erase an element
1122 
1123         Remove the element pointed to by `pos`, which must
1124         be valid and dereferenceable.
1125         References and iterators to the erased element are
1126         invalidated. Other iterators and references are not
1127         invalidated.
1128 
1129         @note
1130 
1131         The @ref end() iterator (which is valid but cannot be
1132         dereferenced) cannot be used as a value for `pos`.
1133 
1134         @par Complexity
1135         Constant on average, worst case linear in @ref size().
1136 
1137         @par Exception Safety
1138         No-throw guarantee.
1139 
1140         @return An iterator following the removed element.
1141 
1142         @param pos An iterator pointing to the element to be
1143         removed.
1144     */
1145     BOOST_JSON_DECL
1146     iterator
1147     erase(const_iterator pos) noexcept;
1148 
1149     /** Erase an element
1150 
1151         Remove the element which matches `key`, if it exists.
1152         References and iterators to the erased element are
1153         invalidated. Other iterators and references are not
1154         invalidated.
1155 
1156         @par Complexity
1157         Constant on average, worst case linear in @ref size().
1158 
1159         @par Exception Safety
1160         No-throw guarantee.
1161 
1162         @return The number of elements removed, which will
1163         be either 0 or 1.
1164 
1165         @param key The key to match.
1166     */
1167     BOOST_JSON_DECL
1168     std::size_t
1169     erase(string_view key) noexcept;
1170 
1171     /** Erase an element preserving order
1172 
1173         Remove the element pointed to by `pos`, which must
1174         be valid and dereferenceable.
1175         References and iterators from `pos` to `end()`, both
1176         included, are invalidated. Other iterators and references
1177         are not invalidated.
1178         The relative order of remaining elements is preserved.
1179 
1180         @note
1181 
1182         The @ref end() iterator (which is valid but cannot be
1183         dereferenced) cannot be used as a value for `pos`.
1184 
1185         @par Complexity
1186         Linear in @ref size().
1187 
1188         @par Exception Safety
1189         No-throw guarantee.
1190 
1191         @return An iterator following the removed element.
1192 
1193         @param pos An iterator pointing to the element to be
1194         removed.
1195     */
1196     BOOST_JSON_DECL
1197     iterator
1198     stable_erase(const_iterator pos) noexcept;
1199 
1200     /** Erase an element preserving order
1201 
1202         Remove the element which matches `key`, if it exists.
1203         All references and iterators are invalidated.
1204         The relative order of remaining elements is preserved.
1205 
1206         @par Complexity
1207         Linear in @ref size().
1208 
1209         @par Exception Safety
1210         No-throw guarantee.
1211 
1212         @return The number of elements removed, which will
1213         be either 0 or 1.
1214 
1215         @param key The key to match.
1216     */
1217     BOOST_JSON_DECL
1218     std::size_t
1219     stable_erase(string_view key) noexcept;
1220 
1221     /** Swap two objects.
1222 
1223         Exchanges the contents of this object with another
1224         object. Ownership of the respective @ref memory_resource
1225         objects is not transferred.
1226 
1227         @li If `*other.storage() == *this->storage()`,
1228         ownership of the underlying memory is swapped in
1229         constant time, with no possibility of exceptions.
1230         All iterators and references remain valid.
1231 
1232         @li If `*other.storage() != *this->storage()`,
1233         the contents are logically swapped by making copies,
1234         which can throw. In this case all iterators and
1235         references are invalidated.
1236 
1237         @par Complexity
1238         Constant or linear in @ref size() plus `other.size()`.
1239 
1240         @par Exception Safety
1241         Strong guarantee.
1242         Calls to `memory_resource::allocate` may throw.
1243 
1244         @param other The object to swap with.
1245         If `this == &other`, this function call has no effect.
1246     */
1247     BOOST_JSON_DECL
1248     void
1249     swap(object& other);
1250 
1251     /** Swap two objects.
1252 
1253         Exchanges the contents of the object `lhs` with
1254         another object `rhs`. Ownership of the respective
1255         @ref memory_resource objects is not transferred.
1256 
1257         @li If `*lhs.storage() == *rhs.storage()`,
1258         ownership of the underlying memory is swapped in
1259         constant time, with no possibility of exceptions.
1260         All iterators and references remain valid.
1261 
1262         @li If `*lhs.storage() != *rhs.storage()`,
1263         the contents are logically swapped by making a copy,
1264         which can throw. In this case all iterators and
1265         references are invalidated.
1266 
1267         @par Effects
1268         @code
1269         lhs.swap( rhs );
1270         @endcode
1271 
1272         @par Complexity
1273         Constant or linear in `lhs.size() + rhs.size()`.
1274 
1275         @par Exception Safety
1276         Strong guarantee.
1277         Calls to `memory_resource::allocate` may throw.
1278 
1279         @param lhs The object to exchange.
1280 
1281         @param rhs The object to exchange.
1282         If `&lhs == &rhs`, this function call has no effect.
1283 
1284         @see @ref object::swap
1285     */
1286     friend
1287     void
1288     swap(object& lhs, object& rhs)
1289     {
1290         lhs.swap(rhs);
1291     }
1292 
1293     //------------------------------------------------------
1294     //
1295     // Lookup
1296     //
1297     //------------------------------------------------------
1298 
1299     /** Access the specified element, with bounds checking.
1300 
1301         Returns a reference to the mapped value of the element
1302         that matches `key`, otherwise throws.
1303 
1304         @par Complexity
1305         Constant on average, worst case linear in @ref size().
1306 
1307         @par Exception Safety
1308         Strong guarantee.
1309 
1310         @return A reference to the mapped value.
1311 
1312         @param key The key of the element to find.
1313 
1314         @throw system_error if no such element exists.
1315     */
1316     /* @{ */
1317     inline
1318     value&
1319     at(string_view key) &;
1320 
1321     inline
1322     value&&
1323     at(string_view key) &&;
1324 
1325     inline
1326     value const&
1327     at(string_view key) const&;
1328     /* @} */
1329 
1330     /** Access or insert the specified element
1331 
1332         Returns a reference to the value that is mapped
1333         to a key equivalent to key, performing an insertion
1334         of a null value if such key does not already exist.
1335     \n
1336         If an insertion occurs and results in a rehashing of
1337         the container, all iterators are invalidated. Otherwise
1338         iterators are not affected. References are not
1339         invalidated. Rehashing occurs only if the new
1340         number of elements is greater than @ref capacity().
1341 
1342         @par Complexity
1343         Constant on average, worst case linear in @ref size().
1344 
1345         @par Exception Safety
1346         Strong guarantee.
1347         Calls to `memory_resource::allocate` may throw.
1348 
1349         @return A reference to the mapped value.
1350 
1351         @param key The key of the element to find.
1352     */
1353     BOOST_JSON_DECL
1354     value&
1355     operator[](string_view key);
1356 
1357     /** Count the number of elements with a specific key
1358 
1359         This function returns the count of the number of
1360         elements match `key`. The only possible return values
1361         are 0 and 1.
1362 
1363         @par Complexity
1364         Constant on average, worst case linear in @ref size().
1365 
1366         @par Exception Safety
1367         No-throw guarantee.
1368 
1369         @param key The key of the element to find.
1370     */
1371     BOOST_JSON_DECL
1372     std::size_t
1373     count(string_view key) const noexcept;
1374 
1375     /** Find an element with a specific key
1376 
1377         This function returns an iterator to the element
1378         matching `key` if it exists, otherwise returns
1379         @ref end().
1380 
1381         @par Complexity
1382         Constant on average, worst case linear in @ref size().
1383 
1384         @par Exception Safety
1385         No-throw guarantee.
1386 
1387         @param key The key of the element to find.
1388     */
1389     BOOST_JSON_DECL
1390     iterator
1391     find(string_view key) noexcept;
1392 
1393     /** Find an element with a specific key
1394 
1395         This function returns a constant iterator to
1396         the element matching `key` if it exists,
1397         otherwise returns @ref end().
1398 
1399         @par Complexity
1400         Constant on average, worst case linear in @ref size().
1401 
1402         @par Exception Safety
1403         No-throw guarantee.
1404 
1405         @param key The key of the element to find.
1406     */
1407     BOOST_JSON_DECL
1408     const_iterator
1409     find(string_view key) const noexcept;
1410 
1411     /** Return `true` if the key is found
1412 
1413         This function returns `true` if a key with the
1414         specified string is found.
1415 
1416         @par Effects
1417         @code
1418         return this->find(key) != this->end();
1419         @endcode
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 
1429         @see @ref find
1430     */
1431     BOOST_JSON_DECL
1432     bool
1433     contains(string_view key) const noexcept;
1434 
1435     /** Return a pointer to the value if the key is found, or null
1436 
1437         This function searches for a value with the given
1438         key, and returns a pointer to it if found. Otherwise
1439         it returns null.
1440 
1441         @par Example
1442         @code
1443         if( auto p = obj.if_contains( "key" ) )
1444             std::cout << *p;
1445         @endcode
1446 
1447         @par Complexity
1448         Constant on average, worst case linear in @ref size().
1449 
1450         @par Exception Safety
1451         No-throw guarantee.
1452 
1453         @param key The key of the element to find.
1454 
1455         @see @ref find
1456     */
1457     BOOST_JSON_DECL
1458     value const*
1459     if_contains(string_view key) const noexcept;
1460 
1461     /** Return a pointer to the value if the key is found, or null
1462 
1463         This function searches for a value with the given
1464         key, and returns a pointer to it if found. Otherwise
1465         it returns null.
1466 
1467         @par Example
1468         @code
1469         if( auto p = obj.if_contains( "key" ) )
1470             std::cout << *p;
1471         @endcode
1472 
1473         @par Complexity
1474         Constant on average, worst case linear in @ref size().
1475 
1476         @par Exception Safety
1477         No-throw guarantee.
1478 
1479         @param key The key of the element to find.
1480 
1481         @see @ref find
1482     */
1483     BOOST_JSON_DECL
1484     value*
1485     if_contains(string_view key) noexcept;
1486 
1487     /** Return `true` if two objects are equal.
1488 
1489         Objects are equal when their sizes are the same,
1490         and when for each key in `lhs` there is a matching
1491         key in `rhs` with the same value.
1492 
1493         @par Complexity
1494         Constant, or linear (worst case quadratic) in `lhs.size()`.
1495 
1496         @par Exception Safety
1497         No-throw guarantee.
1498     */
1499     // inline friend speeds up overload resolution
1500     friend
1501     bool
1502     operator==(
1503         object const& lhs,
1504         object const& rhs) noexcept
1505     {
1506         return lhs.equal(rhs);
1507     }
1508 
1509     /** Return `true` if two objects are not equal.
1510 
1511         Objects are equal when their sizes are the same,
1512         and when for each key in `lhs` there is a matching
1513         key in `rhs` with the same value.
1514 
1515         @par Complexity
1516         Constant, or linear (worst case quadratic) in `lhs.size()`.
1517 
1518         @par Exception Safety
1519         No-throw guarantee.
1520     */
1521     // inline friend speeds up overload resolution
1522     friend
1523     bool
1524     operator!=(
1525         object const& lhs,
1526         object const& rhs) noexcept
1527     {
1528         return ! (lhs == rhs);
1529     }
1530 
1531     /** Serialize @ref object to an output stream.
1532 
1533         This function serializes an `object` as JSON into the output stream.
1534 
1535         @return Reference to `os`.
1536 
1537         @par Complexity
1538         Constant or linear in the size of `obj`.
1539 
1540         @par Exception Safety
1541         Strong guarantee.
1542         Calls to `memory_resource::allocate` may throw.
1543 
1544         @param os The output stream to serialize to.
1545 
1546         @param obj The value to serialize.
1547     */
1548     BOOST_JSON_DECL
1549     friend
1550     std::ostream&
1551     operator<<(
1552         std::ostream& os,
1553         object const& obj);
1554 private:
1555 #ifndef BOOST_JSON_DOCS
1556     // VFALCO friending a detail function makes it public
1557     template<class CharRange>
1558     friend
1559     std::pair<key_value_pair*, std::size_t>
1560     detail::find_in_object(
1561         object const& obj,
1562         CharRange key) noexcept;
1563 #endif
1564 
1565     template<class InputIt>
1566     void
1567     construct(
1568         InputIt first,
1569         InputIt last,
1570         std::size_t min_capacity,
1571         std::input_iterator_tag);
1572 
1573     template<class InputIt>
1574     void
1575     construct(
1576         InputIt first,
1577         InputIt last,
1578         std::size_t min_capacity,
1579         std::forward_iterator_tag);
1580 
1581     template<class InputIt>
1582     void
1583     insert(
1584         InputIt first,
1585         InputIt last,
1586         std::input_iterator_tag);
1587 
1588     template<class InputIt>
1589     void
1590     insert(
1591         InputIt first,
1592         InputIt last,
1593         std::forward_iterator_tag);
1594 
1595     template< class... Args >
1596     std::pair<iterator, bool>
1597     emplace_impl(string_view key, Args&& ... args );
1598 
1599     BOOST_JSON_DECL
1600     key_value_pair*
1601     insert_impl(
1602         pilfered<key_value_pair> p,
1603         std::size_t hash);
1604 
1605     BOOST_JSON_DECL
1606     table*
1607     reserve_impl(std::size_t new_capacity);
1608 
1609     BOOST_JSON_DECL
1610     bool
1611     equal(object const& other) const noexcept;
1612 
1613     inline
1614     std::size_t
1615     growth(
1616         std::size_t new_size) const;
1617 
1618     inline
1619     void
1620     remove(
1621         index_t& head,
1622         key_value_pair& p) noexcept;
1623 
1624     inline
1625     void
1626     destroy() noexcept;
1627 
1628     inline
1629     void
1630     destroy(
1631         key_value_pair* first,
1632         key_value_pair* last) noexcept;
1633 
1634     template<class FS, class FB>
1635     auto
1636     do_erase(
1637         const_iterator pos,
1638         FS small_reloc,
1639         FB big_reloc) noexcept
1640         -> iterator;
1641 
1642     inline
1643     void
1644     reindex_relocate(
1645         key_value_pair* src,
1646         key_value_pair* dst) noexcept;
1647 };
1648 
1649 } // namespace json
1650 } // namespace boost
1651 
1652 #ifndef BOOST_JSON_DOCS
1653 // boost::hash trait
1654 namespace boost
1655 {
1656 namespace container_hash
1657 {
1658 
1659 template< class T > struct is_unordered_range;
1660 
1661 template<>
1662 struct is_unordered_range< json::object >
1663     : std::true_type
1664 {};
1665 
1666 } // namespace container_hash
1667 } // namespace boost
1668 
1669 // std::hash specialization
1670 namespace std {
1671 template <>
1672 struct hash< ::boost::json::object > {
1673     BOOST_JSON_DECL
1674     std::size_t
1675     operator()(::boost::json::object const& jo) const noexcept;
1676 };
1677 } // std
1678 #endif
1679 
1680 
1681 // Must be included here for this file to stand alone
1682 #include <boost/json/value.hpp>
1683 
1684 // includes are at the bottom of <boost/json/value.hpp>
1685 
1686 #endif