Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:34:47

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 
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 
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 
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         @n
0973 
0974         Insertion may result in rehashing of the container. In that case all
0975         iterators and references are invalidated. Otherwise, they are not
0976         affected.
0977 
0978         @par Precondition
0979         `first` and `last` are not iterators into `*this`.
0980         `first` and `last` form a valid range.
0981 
0982         @par Constraints
0983         @code
0984         std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
0985         @endcode
0986 
0987         @par Complexity
0988         Linear in `std::distance(first, last)`.
0989 
0990         @par Exception Safety
0991         Strong guarantee for forward iterators, basic guarantee for input
0992         iterators.
0993         Calls to `memory_resource::allocate` may throw.
0994 
0995         @param first An input iterator pointing to the first
0996         element to insert, or pointing to the end of the range.
0997 
0998         @param last An input iterator pointing to the end
0999         of the range.
1000 
1001         @tparam InputIt a type satisfying the requirements
1002         of __InputIterator__.
1003     */
1004     template<
1005         class InputIt
1006     #ifndef BOOST_JSON_DOCS
1007         ,class = is_inputit<InputIt>
1008     #endif
1009     >
1010     void
1011     insert(InputIt first, InputIt last)
1012     {
1013         insert(first, last, typename
1014             std::iterator_traits<InputIt
1015                 >::iterator_category{});
1016     }
1017 
1018     /** Insert elements.
1019 
1020         The elements in the initializer list are inserted one at a time, in
1021         order. Any element with key that is a duplicate of a key already
1022         present in container will be skipped. This also means, that if there
1023         are two keys within the initializer list that are equal to each other,
1024         only the first will be inserted.
1025 
1026         Insertion may result in rehashing of the container. In that case all
1027         iterators and references are invalidated. Otherwise, they are not
1028         affected.
1029 
1030         @par Complexity
1031         Linear in `init.size()`.
1032 
1033         @par Exception Safety
1034         Basic guarantee.
1035         Calls to `memory_resource::allocate` may throw.
1036 
1037         @param init The initializer list to insert
1038     */
1039     BOOST_JSON_DECL
1040     void
1041     insert(std::initializer_list<
1042         std::pair<string_view, value_ref>> init);
1043 
1044     /** Insert an element or assign to the current element if the key already exists.
1045 
1046         If the key equivalent to `key` already exists in the
1047         container, assigns `std::forward<M>(m)` to the
1048         `mapped_type` corresponding to the key. Otherwise,
1049         inserts the new value at the end as if by insert,
1050         constructing it from `value_type(key, std::forward<M>(m))`.
1051 
1052         If the insertion occurs and results in a rehashing of the container,
1053         all iterators and references are invalidated. Otherwise, they are not
1054         affected. Rehashing occurs only if the new number of elements is
1055         greater than @ref capacity().
1056 
1057         @par Complexity
1058         Amortized constant on average, worst case linear in @ref size().
1059 
1060         @par Exception Safety
1061         Strong guarantee.
1062         Calls to `memory_resource::allocate` may throw.
1063 
1064         @return A `std::pair` where `first` is an iterator
1065         to the existing or inserted element, and `second`
1066         is `true` if the insertion took place or `false` if
1067         the assignment took place.
1068 
1069         @param key The key used for lookup and insertion
1070 
1071         @param m The value to insert or assign
1072 
1073         @throw `boost::system::system_error` if key is too long.
1074     */
1075     template<class M>
1076     std::pair<iterator, bool>
1077     insert_or_assign(
1078         string_view key, M&& m);
1079 
1080     /** Construct an element in-place.
1081 
1082         Inserts a new element into the container constructed
1083         in-place with the given argument if there is no
1084         element with the `key` in the container.
1085 
1086         If the insertion occurs and results in a rehashing of the container,
1087         all iterators and references are invalidated. Otherwise, they are not
1088         affected. Rehashing occurs only if the new number of elements is
1089         greater than @ref capacity().
1090 
1091         @par Complexity
1092         Amortized constant on average, worst case linear in @ref size().
1093 
1094         @par Exception Safety
1095         Strong guarantee.
1096         Calls to `memory_resource::allocate` may throw.
1097 
1098         @return A `std::pair` where `first` is an iterator
1099         to the existing or inserted element, and `second`
1100         is `true` if the insertion took place or `false` otherwise.
1101 
1102         @param key The key used for lookup and insertion
1103 
1104         @param arg The argument used to construct the value.
1105         This will be passed as `std::forward<Arg>(arg)` to
1106         the @ref value constructor.
1107 
1108         @throw `boost::system::system_error` if key is too long.
1109     */
1110     template<class Arg>
1111     std::pair<iterator, bool>
1112     emplace(string_view key, Arg&& arg);
1113 
1114     /** Erase an element
1115 
1116         Remove the element pointed to by `pos`, which must
1117         be valid and dereferenceable.
1118         References and iterators to the erased element are
1119         invalidated. Other iterators and references are not
1120         invalidated.
1121 
1122         @note
1123 
1124         The @ref end() iterator (which is valid but cannot be
1125         dereferenced) cannot be used as a value for `pos`.
1126 
1127         @par Complexity
1128         Constant on average, worst case linear in @ref size().
1129 
1130         @par Exception Safety
1131         No-throw guarantee.
1132 
1133         @return An iterator following the removed element.
1134 
1135         @param pos An iterator pointing to the element to be
1136         removed.
1137     */
1138     BOOST_JSON_DECL
1139     iterator
1140     erase(const_iterator pos) noexcept;
1141 
1142     /** Erase an element
1143 
1144         Remove the element which matches `key`, if it exists.
1145         References and iterators to the erased element are
1146         invalidated. Other iterators and references are not
1147         invalidated.
1148 
1149         @par Complexity
1150         Constant on average, worst case linear in @ref size().
1151 
1152         @par Exception Safety
1153         No-throw guarantee.
1154 
1155         @return The number of elements removed, which will
1156         be either 0 or 1.
1157 
1158         @param key The key to match.
1159     */
1160     BOOST_JSON_DECL
1161     std::size_t
1162     erase(string_view key) noexcept;
1163 
1164     /** Erase an element preserving order
1165 
1166         Remove the element pointed to by `pos`, which must be valid and
1167         dereferenceable. References and iterators from `pos` to @ref end(),
1168         both included, are invalidated. Other iterators and references are not
1169         invalidated. The relative order of remaining elements is preserved.
1170 
1171         @note
1172         The @ref end() iterator (which is valid but cannot be dereferenced)
1173         cannot be used as a value for `pos`.
1174 
1175         @par Complexity
1176         Linear in @ref size().
1177 
1178         @par Exception Safety
1179         No-throw guarantee.
1180 
1181         @return An iterator following the removed element.
1182 
1183         @param pos An iterator pointing to the element to be
1184         removed.
1185     */
1186     BOOST_JSON_DECL
1187     iterator
1188     stable_erase(const_iterator pos) noexcept;
1189 
1190     /** Erase an element preserving order
1191 
1192         Remove the element which matches `key`, if it exists.
1193         All references and iterators are invalidated.
1194         The relative order of remaining elements is preserved.
1195 
1196         @par Complexity
1197         Linear in @ref size().
1198 
1199         @par Exception Safety
1200         No-throw guarantee.
1201 
1202         @return The number of elements removed, which will
1203         be either 0 or 1.
1204 
1205         @param key The key to match.
1206     */
1207     BOOST_JSON_DECL
1208     std::size_t
1209     stable_erase(string_view key) noexcept;
1210 
1211     /** Swap two objects.
1212 
1213         Exchanges the contents of this object with another object. Ownership of
1214         the respective `boost::container::pmr::memory_resource` objects is not
1215         transferred.
1216 
1217         @li If `*other.storage() == *this->storage()`,
1218         ownership of the underlying memory is swapped in
1219         constant time, with no possibility of exceptions.
1220         All iterators and references remain valid.
1221 
1222         @li If `*other.storage() != *this->storage()`,
1223         the contents are logically swapped by making copies,
1224         which can throw. In this case all iterators and
1225         references are invalidated.
1226 
1227         @par Complexity
1228         Constant or linear in @ref size() plus `other.size()`.
1229 
1230         @par Exception Safety
1231         Strong guarantee.
1232         Calls to `memory_resource::allocate` may throw.
1233 
1234         @param other The object to swap with.
1235         If `this == &other`, this function call has no effect.
1236     */
1237     BOOST_JSON_DECL
1238     void
1239     swap(object& other);
1240 
1241     /** Swap two objects.
1242 
1243         Exchanges the contents of the object `lhs` with another object `rhs`.
1244         Ownership of the respective `boost::container::pmr::memory_resource`
1245         objects is not transferred.
1246 
1247         @li If `*lhs.storage() == *rhs.storage()`,
1248         ownership of the underlying memory is swapped in
1249         constant time, with no possibility of exceptions.
1250         All iterators and references remain valid.
1251 
1252         @li If `*lhs.storage() != *rhs.storage()`,
1253         the contents are logically swapped by making a copy,
1254         which can throw. In this case all iterators and
1255         references are invalidated.
1256 
1257         @par Effects
1258         @code
1259         lhs.swap( rhs );
1260         @endcode
1261 
1262         @par Complexity
1263         Constant or linear in `lhs.size() + rhs.size()`.
1264 
1265         @par Exception Safety
1266         Strong guarantee.
1267         Calls to `memory_resource::allocate` may throw.
1268 
1269         @param lhs The object to exchange.
1270 
1271         @param rhs The object to exchange.
1272         If `&lhs == &rhs`, this function call has no effect.
1273 
1274         @see @ref object::swap
1275     */
1276     friend
1277     void
1278     swap(object& lhs, object& rhs)
1279     {
1280         lhs.swap(rhs);
1281     }
1282 
1283     //------------------------------------------------------
1284     //
1285     // Lookup
1286     //
1287     //------------------------------------------------------
1288 
1289     /** Access the specified element, with bounds checking.
1290 
1291         Returns `boost::system::result` containing a reference to the
1292         mapped value of the element that matches `key`. Otherwise the result
1293         contains an `error_code`.
1294 
1295         @par Exception Safety
1296         No-throw guarantee.
1297 
1298         @param key The key of the element to find.
1299 
1300         @par Complexity
1301         Constant on average, worst case linear in @ref size().
1302     */
1303     /** @{ */
1304     BOOST_JSON_DECL
1305     system::result<value&>
1306     try_at(string_view key) noexcept;
1307 
1308     BOOST_JSON_DECL
1309     system::result<value const&>
1310     try_at(string_view key) const noexcept;
1311     /** @} */
1312 
1313     /** Access the specified element, with bounds checking.
1314 
1315         Returns a reference to the mapped value of the element
1316         that matches `key`, otherwise throws.
1317 
1318         @par Complexity
1319         Constant on average, worst case linear in @ref size().
1320 
1321         @par Exception Safety
1322         Strong guarantee.
1323 
1324         @return A reference to the mapped value.
1325 
1326         @param key The key of the element to find.
1327 
1328         @param loc `source_location` to use in thrown exception; the source
1329             location of the call site by default.
1330 
1331         @throw `boost::system::system_error` if no such element exists.
1332     */
1333     /** @{ */
1334     inline
1335     value&
1336     at(
1337         string_view key,
1338         source_location const& loc = BOOST_CURRENT_LOCATION) &;
1339 
1340     inline
1341     value&&
1342     at(
1343         string_view key,
1344         source_location const& loc = BOOST_CURRENT_LOCATION) &&;
1345 
1346     BOOST_JSON_DECL
1347     value const&
1348     at(
1349         string_view key,
1350         source_location const& loc = BOOST_CURRENT_LOCATION) const&;
1351     /** @} */
1352 
1353     /** Access or insert the specified element
1354 
1355         Returns a reference to the value that is mapped
1356         to a key equivalent to key, performing an insertion
1357         of a null value if such key does not already exist.
1358 
1359         If an insertion occurs and results in a rehashing of the container, all
1360         iterators including any past-the-end iterators, and all references to
1361         the elements are invalidated. Otherwise, no iterators or references are
1362         invalidated.
1363 
1364         @par Complexity
1365         Constant on average, worst case linear in @ref size().
1366 
1367         @par Exception Safety
1368         Strong guarantee.
1369         Calls to `memory_resource::allocate` may throw.
1370 
1371         @return A reference to the mapped value.
1372 
1373         @param key The key of the element to find.
1374     */
1375     BOOST_JSON_DECL
1376     value&
1377     operator[](string_view key);
1378 
1379     /** Count the number of elements with a specific key
1380 
1381         This function returns the count of the number of
1382         elements match `key`. The only possible return values
1383         are 0 and 1.
1384 
1385         @par Complexity
1386         Constant on average, worst case linear in @ref size().
1387 
1388         @par Exception Safety
1389         No-throw guarantee.
1390 
1391         @param key The key of the element to find.
1392     */
1393     BOOST_JSON_DECL
1394     std::size_t
1395     count(string_view key) const noexcept;
1396 
1397     /** Find an element with a specific key
1398 
1399         This function returns an iterator to the element
1400         matching `key` if it exists, otherwise returns
1401         @ref end().
1402 
1403         @par Complexity
1404         Constant on average, worst case linear in @ref size().
1405 
1406         @par Exception Safety
1407         No-throw guarantee.
1408 
1409         @param key The key of the element to find.
1410     */
1411     BOOST_JSON_DECL
1412     iterator
1413     find(string_view key) noexcept;
1414 
1415     /** Find an element with a specific key
1416 
1417         This function returns a constant iterator to
1418         the element matching `key` if it exists,
1419         otherwise returns @ref end().
1420 
1421         @par Complexity
1422         Constant on average, worst case linear in @ref size().
1423 
1424         @par Exception Safety
1425         No-throw guarantee.
1426 
1427         @param key The key of the element to find.
1428     */
1429     BOOST_JSON_DECL
1430     const_iterator
1431     find(string_view key) const noexcept;
1432 
1433     /** Return `true` if the key is found
1434 
1435         This function returns `true` if a key with the
1436         specified string is found.
1437 
1438         @par Effects
1439         @code
1440         return this->find(key) != this->end();
1441         @endcode
1442 
1443         @par Complexity
1444         Constant on average, worst case linear in @ref size().
1445 
1446         @par Exception Safety
1447         No-throw guarantee.
1448 
1449         @param key The key of the element to find.
1450 
1451         @see @ref find
1452     */
1453     BOOST_JSON_DECL
1454     bool
1455     contains(string_view key) const noexcept;
1456 
1457     /** Return a pointer to the value if the key is found, or null
1458 
1459         This function searches for a value with the given
1460         key, and returns a pointer to it if found. Otherwise
1461         it returns null.
1462 
1463         @par Example
1464         @code
1465         if( auto p = obj.if_contains( "key" ) )
1466             std::cout << *p;
1467         @endcode
1468 
1469         @par Complexity
1470         Constant on average, worst case linear in @ref size().
1471 
1472         @par Exception Safety
1473         No-throw guarantee.
1474 
1475         @param key The key of the element to find.
1476 
1477         @see @ref find
1478     */
1479     BOOST_JSON_DECL
1480     value const*
1481     if_contains(string_view key) const noexcept;
1482 
1483     /** Return a pointer to the value if the key is found, or null
1484 
1485         This function searches for a value with the given
1486         key, and returns a pointer to it if found. Otherwise
1487         it returns null.
1488 
1489         @par Example
1490         @code
1491         if( auto p = obj.if_contains( "key" ) )
1492             std::cout << *p;
1493         @endcode
1494 
1495         @par Complexity
1496         Constant on average, worst case linear in @ref size().
1497 
1498         @par Exception Safety
1499         No-throw guarantee.
1500 
1501         @param key The key of the element to find.
1502 
1503         @see @ref find
1504     */
1505     BOOST_JSON_DECL
1506     value*
1507     if_contains(string_view key) noexcept;
1508 
1509     /** Return `true` if two objects are 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.equal(rhs);
1529     }
1530 
1531     /** Return `true` if two objects are not equal.
1532 
1533         Objects are equal when their sizes are the same,
1534         and when for each key in `lhs` there is a matching
1535         key in `rhs` with the same value.
1536 
1537         @par Complexity
1538         Constant, or linear (worst case quadratic) in `lhs.size()`.
1539 
1540         @par Exception Safety
1541         No-throw guarantee.
1542     */
1543     // inline friend speeds up overload resolution
1544     friend
1545     bool
1546     operator!=(
1547         object const& lhs,
1548         object const& rhs) noexcept
1549     {
1550         return ! (lhs == rhs);
1551     }
1552 
1553     /** Serialize @ref object to an output stream.
1554 
1555         This function serializes an `object` as JSON into the output stream.
1556 
1557         @return Reference to `os`.
1558 
1559         @par Complexity
1560         Constant or linear in the size of `obj`.
1561 
1562         @par Exception Safety
1563         Strong guarantee.
1564         Calls to `memory_resource::allocate` may throw.
1565 
1566         @param os The output stream to serialize to.
1567 
1568         @param obj The value to serialize.
1569     */
1570     BOOST_JSON_DECL
1571     friend
1572     std::ostream&
1573     operator<<(
1574         std::ostream& os,
1575         object const& obj);
1576 private:
1577 #ifndef BOOST_JSON_DOCS
1578     // VFALCO friending a detail function makes it public
1579     template<class CharRange>
1580     friend
1581     std::pair<key_value_pair*, std::size_t>
1582     detail::find_in_object(
1583         object const& obj,
1584         CharRange key) noexcept;
1585 #endif
1586 
1587     template<class InputIt>
1588     void
1589     construct(
1590         InputIt first,
1591         InputIt last,
1592         std::size_t min_capacity,
1593         std::input_iterator_tag);
1594 
1595     template<class InputIt>
1596     void
1597     construct(
1598         InputIt first,
1599         InputIt last,
1600         std::size_t min_capacity,
1601         std::forward_iterator_tag);
1602 
1603     template<class InputIt>
1604     void
1605     insert(
1606         InputIt first,
1607         InputIt last,
1608         std::input_iterator_tag);
1609 
1610     template<class InputIt>
1611     void
1612     insert(
1613         InputIt first,
1614         InputIt last,
1615         std::forward_iterator_tag);
1616 
1617     template< class... Args >
1618     std::pair<iterator, bool>
1619     emplace_impl(string_view key, Args&& ... args );
1620 
1621     BOOST_JSON_DECL
1622     key_value_pair*
1623     insert_impl(
1624         pilfered<key_value_pair> p,
1625         std::size_t hash);
1626 
1627     BOOST_JSON_DECL
1628     table*
1629     reserve_impl(std::size_t new_capacity);
1630 
1631     BOOST_JSON_DECL
1632     bool
1633     equal(object const& other) const noexcept;
1634 
1635     inline
1636     std::size_t
1637     growth(
1638         std::size_t new_size) const;
1639 
1640     inline
1641     void
1642     remove(
1643         index_t& head,
1644         key_value_pair& p) noexcept;
1645 
1646     inline
1647     void
1648     destroy() noexcept;
1649 
1650     inline
1651     void
1652     destroy(
1653         key_value_pair* first,
1654         key_value_pair* last) noexcept;
1655 
1656     template<class FS, class FB>
1657     auto
1658     do_erase(
1659         const_iterator pos,
1660         FS small_reloc,
1661         FB big_reloc) noexcept
1662         -> iterator;
1663 
1664     inline
1665     void
1666     reindex_relocate(
1667         key_value_pair* src,
1668         key_value_pair* dst) noexcept;
1669 };
1670 
1671 } // namespace json
1672 } // namespace boost
1673 
1674 #ifndef BOOST_JSON_DOCS
1675 // boost::hash trait
1676 namespace boost
1677 {
1678 namespace container_hash
1679 {
1680 
1681 template< class T > struct is_unordered_range;
1682 
1683 template<>
1684 struct is_unordered_range< json::object >
1685     : std::true_type
1686 {};
1687 
1688 } // namespace container_hash
1689 } // namespace boost
1690 
1691 // std::hash specialization
1692 namespace std {
1693 template <>
1694 struct hash< ::boost::json::object > {
1695     BOOST_JSON_DECL
1696     std::size_t
1697     operator()(::boost::json::object const& jo) const noexcept;
1698 };
1699 } // std
1700 #endif
1701 
1702 
1703 // Must be included here for this file to stand alone
1704 #include <boost/json/value.hpp>
1705 
1706 // includes are at the bottom of <boost/json/value.hpp>
1707 
1708 #endif