Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:14:26

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