GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: object.hpp
Date: 2025-12-23 17:32:49
Exec Total Coverage
Lines: 37 37 100.0%
Functions: 19 19 100.0%
Branches: 4 4 100.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/json
8 //
9
10 #ifndef BOOST_JSON_OBJECT_HPP
11 #define BOOST_JSON_OBJECT_HPP
12
13 #include <boost/json/detail/config.hpp>
14 #include <boost/json/detail/object.hpp>
15 #include <boost/json/detail/value.hpp>
16 #include <boost/json/kind.hpp>
17 #include <boost/json/pilfer.hpp>
18 #include <boost/system/result.hpp>
19 #include <boost/json/storage_ptr.hpp>
20 #include <boost/json/string_view.hpp>
21 #include <cstdlib>
22 #include <initializer_list>
23 #include <iterator>
24 #include <type_traits>
25 #include <utility>
26
27 namespace boost {
28 namespace json {
29
30 class value;
31 class value_ref;
32 class key_value_pair;
33
34 /** A dynamically sized associative container of JSON key/value pairs.
35
36 This is an associative container whose elements
37 are key/value pairs with unique keys.
38 \n
39 The elements are stored contiguously; iterators are
40 ordinary pointers, allowing random access pointer
41 arithmetic for retrieving elements.
42 In addition, the container maintains an internal
43 index to speed up find operations, reducing the
44 average complexity for most lookups and insertions.
45 \n
46 Reallocations are usually costly operations in terms of
47 performance, as elements are copied and the internal
48 index must be rebuilt. The @ref reserve function can
49 be used to eliminate reallocations if the number of
50 elements is known beforehand.
51
52 @par Allocators
53
54 All elements stored in the container, and their
55 children if any, will use the same memory resource that
56 was used to construct the container.
57
58 @par Thread Safety
59
60 Non-const member functions may not be called
61 concurrently with any other member functions.
62
63 @par Satisfies
64 <a href="https://en.cppreference.com/w/cpp/named_req/ContiguousContainer"><em>ContiguousContainer</em></a>,
65 <a href="https://en.cppreference.com/w/cpp/named_req/ReversibleContainer"><em>ReversibleContainer</em></a>, and
66 <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>.
67 */
68 class object
69 {
70 struct table;
71 class revert_construct;
72 class revert_insert;
73 friend class value;
74 friend class object_test;
75 using access = detail::access;
76 using index_t = std::uint32_t;
77 static index_t constexpr null_index_ =
78 std::uint32_t(-1);
79
80 storage_ptr sp_; // must come first
81 kind k_ = kind::object; // must come second
82 table* t_;
83
84 BOOST_JSON_DECL
85 static table empty_;
86
87 template<class T>
88 using is_inputit = typename std::enable_if<
89 std::is_constructible<key_value_pair,
90 typename std::iterator_traits<T>::reference
91 >::value>::type;
92
93 BOOST_JSON_DECL
94 explicit
95 object(detail::unchecked_object&& uo);
96
97 public:
98 /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
99 using allocator_type = container::pmr::polymorphic_allocator<value>;
100
101 /** The type of keys.
102
103 The function @ref string::max_size returns the
104 maximum allowed size of strings used as keys.
105 */
106 using key_type = string_view;
107
108 /// The type of mapped values
109 using mapped_type = value;
110
111 /// The element type
112 using value_type = key_value_pair;
113
114 /// The type used to represent unsigned integers
115 using size_type = std::size_t;
116
117 /// The type used to represent signed integers
118 using difference_type = std::ptrdiff_t;
119
120 /// A reference to an element
121 using reference = value_type&;
122
123 /// A const reference to an element
124 using const_reference = value_type const&;
125
126 /// A pointer to an element
127 using pointer = value_type*;
128
129 /// A const pointer to an element
130 using const_pointer = value_type const*;
131
132 /// A random access iterator to an element
133 using iterator = value_type*;
134
135 /// A const random access iterator to an element
136 using const_iterator = value_type const*;
137
138 /// A reverse random access iterator to an element
139 using reverse_iterator =
140 std::reverse_iterator<iterator>;
141
142 /// A const reverse random access iterator to an element
143 using const_reverse_iterator =
144 std::reverse_iterator<const_iterator>;
145
146 //------------------------------------------------------
147
148 /** Destructor.
149
150 The destructor for each element is called if needed, any used memory is
151 deallocated, and shared ownership of the
152 `boost::container::pmr::memory_resource` is released.
153
154 @par Complexity
155 Constant, or linear in @ref size().
156
157 @par Exception Safety
158 No-throw guarantee.
159 */
160 BOOST_JSON_DECL
161 ~object() noexcept;
162
163 //------------------------------------------------------
164
165 /** Default constructor.
166
167 The constructed object is empty with zero
168 capacity, using the [default memory resource].
169
170 @par Complexity
171 Constant.
172
173 @par Exception Safety
174 No-throw guarantee.
175
176 [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
177 */
178 77 object() noexcept
179 77 : t_(&empty_)
180 {
181 77 }
182
183 /** Constructor.
184
185 The constructed object is empty with zero
186 capacity, using the specified memory resource.
187
188 @par Complexity
189 Constant.
190
191 @par Exception Safety
192 No-throw guarantee.
193
194 @param sp A pointer to the `boost::container::pmr::memory_resource` to
195 use. The container will acquire shared ownership of the memory
196 resource.
197 */
198 explicit
199 483 object(storage_ptr sp) noexcept
200 483 : sp_(std::move(sp))
201 483 , t_(&empty_)
202 {
203 483 }
204
205 /** Constructor.
206
207 The constructed object is empty with capacity
208 equal to the specified minimum capacity,
209 using the specified memory resource.
210
211 @par Complexity
212 Constant.
213
214 @par Exception Safety
215 Strong guarantee.
216 Calls to `memory_resource::allocate` may throw.
217
218 @param min_capacity The minimum number
219 of elements for which capacity is guaranteed
220 without a subsequent reallocation.
221
222 @param sp A pointer to the `boost::container::pmr::memory_resource` to
223 use. The container will acquire shared ownership of the memory
224 resource.
225 */
226 BOOST_JSON_DECL
227 object(
228 std::size_t min_capacity,
229 storage_ptr sp = {});
230
231 /** Constructor.
232
233 The object is constructed with the elements
234 in the range `{first, last)`, preserving order,
235 using the specified memory resource.
236 If there are elements with duplicate keys; that
237 is, if multiple elements in the range have keys
238 that compare equal, only the first equivalent
239 element will be inserted.
240
241 @par Constraints
242 @code
243 std::is_constructible_v<
244 key_value_pair,
245 std::iterator_traits<InputIt>::reference>
246 @endcode
247
248 @par Complexity
249 Linear in `std::distance(first, last)`.
250
251 @par Exception Safety
252 Strong guarantee.
253 Calls to `memory_resource::allocate` may throw.
254
255 @param first An input iterator pointing to the
256 first element to insert, or pointing to the end
257 of the range.
258
259 @param last An input iterator pointing to the end
260 of the range.
261
262 @param min_capacity The minimum number
263 of elements for which capacity is guaranteed
264 without a subsequent reallocation.
265 Upon construction, @ref capacity() will be greater
266 than or equal to this number.
267
268 @param sp A pointer to the `boost::container::pmr::memory_resource` to
269 use. The container will acquire shared ownership of the memory
270 resource.
271
272 @tparam InputIt a type satisfying the requirements
273 of __InputIterator__.
274 */
275 template<
276 class InputIt
277 #ifndef BOOST_JSON_DOCS
278 ,class = is_inputit<InputIt>
279 #endif
280 >
281 320 object(
282 InputIt first,
283 InputIt last,
284 std::size_t min_capacity = 0,
285 storage_ptr sp = {})
286 320 : sp_(std::move(sp))
287 320 , t_(&empty_)
288 {
289
1/1
✓ Branch 1 taken 10 times.
320 construct(
290 first, last,
291 min_capacity,
292 typename std::iterator_traits<
293 InputIt>::iterator_category{});
294 320 }
295
296 /** Move constructor.
297
298 The object is constructed by acquiring ownership of
299 the contents of `other` and shared ownership
300 of `other`'s memory resource.
301
302 @note
303
304 After construction, the moved-from object behaves
305 as if newly constructed with its current memory resource.
306
307 @par Complexity
308 Constant.
309
310 @par Exception Safety
311 No-throw guarantee.
312
313 @param other The object to move.
314 */
315 BOOST_JSON_DECL
316 object(object&& other) noexcept;
317
318 /** Move constructor.
319
320 The object is constructed with the contents of
321 `other` by move semantics, using the specified
322 memory resource:
323
324 @li If `*other.storage() == *sp`, ownership of
325 the underlying memory is transferred in constant
326 time, with no possibility of exceptions.
327 After construction, the moved-from object behaves
328 as if newly constructed with its current storage
329 pointer.
330
331 @li If `*other.storage() != *sp`, an
332 element-wise copy is performed, which may throw.
333 In this case, the moved-from object is not
334 changed.
335
336 @par Complexity
337 Constant or linear in `other.size()`.
338
339 @par Exception Safety
340 Strong guarantee.
341 Calls to `memory_resource::allocate` may throw.
342
343 @param other The object to move.
344
345 @param sp A pointer to the `boost::container::pmr::memory_resource` to
346 use. The container will acquire shared ownership of the memory
347 resource.
348 */
349 BOOST_JSON_DECL
350 object(
351 object&& other,
352 storage_ptr sp);
353
354 /** Pilfer constructor.
355
356 The object is constructed by acquiring ownership
357 of the contents of `other` using pilfer semantics.
358 This is more efficient than move construction, when
359 it is known that the moved-from object will be
360 immediately destroyed afterwards.
361
362 @par Complexity
363 Constant.
364
365 @par Exception Safety
366 No-throw guarantee.
367
368 @param other The value to pilfer. After pilfer
369 construction, `other` is not in a usable state
370 and may only be destroyed.
371
372 @see @ref pilfer,
373 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
374 Valueless Variants Considered Harmful</a>
375 */
376 17 object(pilfered<object> other) noexcept
377 17 : sp_(std::move(other.get().sp_))
378 34 , t_(detail::exchange(
379 17 other.get().t_, &empty_))
380 {
381 17 }
382
383 /** Copy constructor.
384
385 The object is constructed with a copy of the
386 contents of `other`, using `other`'s memory resource.
387
388 @par Complexity
389 Linear in `other.size()`.
390
391 @par Exception Safety
392 Strong guarantee.
393 Calls to `memory_resource::allocate` may throw.
394
395 @param other The object to copy.
396 */
397 13 object(
398 object const& other)
399
1/1
✓ Branch 2 taken 13 times.
13 : object(other, other.sp_)
400 {
401 13 }
402
403 /** Copy constructor.
404
405 The object is constructed with a copy of the
406 contents of `other`, using the specified memory resource.
407
408 @par Complexity
409 Linear in `other.size()`.
410
411 @par Exception Safety
412 Strong guarantee.
413 Calls to `memory_resource::allocate` may throw.
414
415 @param other The object to copy.
416
417 @param sp A pointer to the `boost::container::pmr::memory_resource` to
418 use. The container will acquire shared ownership of the memory
419 resource.
420 */
421 BOOST_JSON_DECL
422 object(
423 object const& other,
424 storage_ptr sp);
425
426 /** Construct from initializer-list.
427
428 The object is constructed with a copy of the values
429 in the initializer-list in order, using the
430 specified memory resource.
431 If there are elements with duplicate keys; that
432 is, if multiple elements in the range have keys
433 that compare equal, only the first equivalent
434 element will be inserted.
435
436 @par Complexity
437 Linear in `init.size()`.
438
439 @par Exception Safety
440 Strong guarantee.
441 Calls to `memory_resource::allocate` may throw.
442
443 @param init The initializer list to insert.
444
445 @param sp A pointer to the `boost::container::pmr::memory_resource` to
446 use. The container will acquire shared ownership of the memory
447 resource.
448 */
449 339 object(
450 std::initializer_list<
451 std::pair<string_view, value_ref>> init,
452 storage_ptr sp = {})
453
1/1
✓ Branch 3 taken 246 times.
339 : object(init, 0, std::move(sp))
454 {
455 246 }
456
457 /** Construct from initializer-list.
458
459 Storage for at least `min_capacity` elements is
460 reserved, and then
461 the object is constructed with a copy of the values
462 in the initializer-list in order, using the
463 specified memory resource.
464 If there are elements with duplicate keys; that
465 is, if multiple elements in the range have keys
466 that compare equal, only the first equivalent
467 element will be inserted.
468
469 @par Complexity
470 Linear in `init.size()`.
471
472 @par Exception Safety
473 Strong guarantee.
474 Calls to `memory_resource::allocate` may throw.
475
476 @param init The initializer list to insert.
477
478 @param min_capacity The minimum number
479 of elements for which capacity is guaranteed
480 without a subsequent reallocation.
481 Upon construction, @ref capacity() will be greater
482 than or equal to this number.
483
484 @param sp A pointer to the `boost::container::pmr::memory_resource` to
485 use. The container will acquire shared ownership of the memory
486 resource.
487 */
488 BOOST_JSON_DECL
489 object(
490 std::initializer_list<
491 std::pair<string_view, value_ref>> init,
492 std::size_t min_capacity,
493 storage_ptr sp = {});
494
495 //------------------------------------------------------
496 //
497 // Assignment
498 //
499 //------------------------------------------------------
500
501 /** Copy assignment.
502
503 The contents of the object are replaced with an
504 element-wise copy of `other`.
505
506 @par Complexity
507 Linear in @ref size() plus `other.size()`.
508
509 @par Exception Safety
510 Strong guarantee.
511 Calls to `memory_resource::allocate` may throw.
512
513 @param other The object to copy.
514 */
515 BOOST_JSON_DECL
516 object&
517 operator=(object const& other);
518
519 /** Move assignment.
520
521 The contents of the object are replaced with the
522 contents of `other` using move semantics:
523
524 @li If `*other.storage() == *sp`, ownership of
525 the underlying memory is transferred in constant
526 time, with no possibility of exceptions.
527 After assignment, the moved-from object behaves
528 as if newly constructed with its current storage
529 pointer.
530
531 @li If `*other.storage() != *sp`, an
532 element-wise copy is performed, which may throw.
533 In this case, the moved-from object is not
534 changed.
535
536 @par Complexity
537 Constant or linear in @ref size() plus `other.size()`.
538
539 @par Exception Safety
540 Strong guarantee.
541 Calls to `memory_resource::allocate` may throw.
542
543 @param other The object to move.
544 */
545 BOOST_JSON_DECL
546 object&
547 operator=(object&& other);
548
549 /** Assignment.
550
551 Replaces the contents with the contents of an
552 initializer list.
553
554 @par Complexity
555 Linear in @ref size() plus
556 average case linear in `init.size()`,
557 worst case quadratic in `init.size()`.
558
559 @par Exception Safety
560 Strong guarantee.
561 Calls to `memory_resource::allocate` may throw.
562
563 @param init The initializer list to copy.
564 */
565 BOOST_JSON_DECL
566 object&
567 operator=(std::initializer_list<
568 std::pair<string_view, value_ref>> init);
569
570 //------------------------------------------------------
571
572 /** Return the associated memory resource.
573
574 This function returns the `boost::container::pmr::memory_resource` used
575 by the container.
576
577 @par Complexity
578 Constant.
579
580 @par Exception Safety
581 No-throw guarantee.
582 */
583 storage_ptr const&
584 679 storage() const noexcept
585 {
586 679 return sp_;
587 }
588
589 /** Return the associated allocator.
590
591 This function returns an instance of @ref allocator_type constructed
592 from the associated `boost::container::pmr::memory_resource`.
593
594 @par Complexity
595 Constant.
596
597 @par Exception Safety
598 No-throw guarantee.
599 */
600 allocator_type
601 1 get_allocator() const noexcept
602 {
603 1 return sp_.get();
604 }
605
606 //------------------------------------------------------
607 //
608 // Iterators
609 //
610 //------------------------------------------------------
611
612 /** Return an iterator to the first element.
613
614 If the container is empty, @ref end() is returned.
615
616 @par Complexity
617 Constant.
618
619 @par Exception Safety
620 No-throw guarantee.
621 */
622 inline
623 iterator
624 begin() noexcept;
625
626 /** Return a const iterator to the first element.
627
628 If the container is empty, @ref end() is returned.
629
630 @par Complexity
631 Constant.
632
633 @par Exception Safety
634 No-throw guarantee.
635 */
636 inline
637 const_iterator
638 begin() const noexcept;
639
640 /** Return a const iterator to the first element.
641
642 If the container is empty, @ref cend() is returned.
643
644 @par Complexity
645 Constant.
646
647 @par Exception Safety
648 No-throw guarantee.
649 */
650 inline
651 const_iterator
652 cbegin() const noexcept;
653
654 /** Return an iterator to the element following the last element.
655
656 The element acts as a placeholder; attempting
657 to access it results in undefined behavior.
658
659 @par Complexity
660 Constant.
661
662 @par Exception Safety
663 No-throw guarantee.
664 */
665 inline
666 iterator
667 end() noexcept;
668
669 /** Return a const iterator to the element following the last element.
670
671 The element acts as a placeholder; attempting
672 to access it results in undefined behavior.
673
674 @par Complexity
675 Constant.
676
677 @par Exception Safety
678 No-throw guarantee.
679 */
680 inline
681 const_iterator
682 end() const noexcept;
683
684 /** Return a const iterator to the element following the last element.
685
686 The element acts as a placeholder; attempting
687 to access it results in undefined behavior.
688
689 @par Complexity
690 Constant.
691
692 @par Exception Safety
693 No-throw guarantee.
694 */
695 inline
696 const_iterator
697 cend() const noexcept;
698
699 /** Return a reverse iterator to the first element of the reversed container.
700
701 The pointed-to element corresponds to the
702 last element of the non-reversed container.
703 If the container is empty, @ref rend() is returned.
704
705 @par Complexity
706 Constant.
707
708 @par Exception Safety
709 No-throw guarantee.
710 */
711 inline
712 reverse_iterator
713 rbegin() noexcept;
714
715 /** Return a const reverse iterator to the first element of the reversed container.
716
717 The pointed-to element corresponds to the
718 last element of the non-reversed container.
719 If the container is empty, @ref rend() is returned.
720
721 @par Complexity
722 Constant.
723
724 @par Exception Safety
725 No-throw guarantee.
726 */
727 inline
728 const_reverse_iterator
729 rbegin() const noexcept;
730
731 /** Return a const reverse iterator to the first element of the reversed container.
732
733 The pointed-to element corresponds to the
734 last element of the non-reversed container.
735 If the container is empty, @ref crend() is returned.
736
737 @par Complexity
738 Constant.
739
740 @par Exception Safety
741 No-throw guarantee.
742 */
743 inline
744 const_reverse_iterator
745 crbegin() const noexcept;
746
747 /** Return a reverse iterator to the element following the last element of the reversed container.
748
749 The pointed-to element corresponds to the element
750 preceding the first element of the non-reversed container.
751 This element acts as a placeholder, attempting
752 to access it results in undefined behavior.
753
754 @par Complexity
755 Constant.
756
757 @par Exception Safety
758 No-throw guarantee.
759 */
760 inline
761 reverse_iterator
762 rend() noexcept;
763
764 /** Return a const reverse iterator to the element following the last element of the reversed container.
765
766 The pointed-to element corresponds to the element
767 preceding the first element of the non-reversed container.
768 This element acts as a placeholder, attempting
769 to access it results in undefined behavior.
770
771 @par Complexity
772 Constant.
773
774 @par Exception Safety
775 No-throw guarantee.
776 */
777 inline
778 const_reverse_iterator
779 rend() const noexcept;
780
781 /** Return a const reverse iterator to the element following the last element of the reversed container.
782
783 The pointed-to element corresponds to the element
784 preceding the first element of the non-reversed container.
785 This element acts as a placeholder, attempting
786 to access it results in undefined behavior.
787
788 @par Complexity
789 Constant.
790
791 @par Exception Safety
792 No-throw guarantee.
793 */
794 inline
795 const_reverse_iterator
796 crend() const noexcept;
797
798 //------------------------------------------------------
799 //
800 // Capacity
801 //
802 //------------------------------------------------------
803
804 /** Return whether there are no elements.
805
806 Returns `true` if there are no elements in
807 the container, i.e. @ref size() returns 0.
808
809 @par Complexity
810 Constant.
811
812 @par Exception Safety
813 No-throw guarantee.
814 */
815 inline
816 bool
817 empty() const noexcept;
818
819 /** Return the number of elements.
820
821 This returns the number of elements in the container.
822
823 @par Complexity
824 Constant.
825
826 @par Exception Safety
827 No-throw guarantee.
828 */
829 inline
830 std::size_t
831 size() const noexcept;
832
833 /** Return the maximum number of elements any object can hold
834
835 The maximum is an implementation-defined number dependent
836 on system or library implementation. This value is a
837 theoretical limit; at runtime, the actual maximum size
838 may be less due to resource limits.
839
840 @par Complexity
841 Constant.
842
843 @par Exception Safety
844 No-throw guarantee.
845 */
846 static
847 constexpr
848 std::size_t
849 max_size() noexcept;
850
851 /** Return the number of elements that can be held in currently allocated memory
852
853 This number may be larger than the value returned
854 by @ref size().
855
856 @par Complexity
857 Constant.
858
859 @par Exception Safety
860 No-throw guarantee.
861 */
862 inline
863 std::size_t
864 capacity() const noexcept;
865
866 /** Increase the capacity to at least a certain amount.
867
868 This increases the @ref capacity() to a value
869 that is greater than or equal to `new_capacity`.
870 If `new_capacity > capacity()`, new memory is
871 allocated. Otherwise, the call has no effect.
872 The number of elements and therefore the
873 @ref size() of the container is not changed.
874 \n
875 If new memory is allocated, all iterators
876 including any past-the-end iterators, and all
877 references to the elements are invalidated.
878 Otherwise, no iterators or references are
879 invalidated.
880
881 @par Complexity
882 Constant or average case linear in
883 @ref size(), worst case quadratic.
884
885 @par Exception Safety
886 Strong guarantee.
887 Calls to `memory_resource::allocate` may throw.
888
889 @param new_capacity The new minimum capacity.
890
891 @throw `boost::system::system_error` `new_capacity > max_size()`.
892 */
893 inline
894 void
895 reserve(std::size_t new_capacity);
896
897 //------------------------------------------------------
898 //
899 // Modifiers
900 //
901 //------------------------------------------------------
902
903 /** Erase all elements.
904
905 Erases all elements from the container without
906 changing the capacity.
907 After this call, @ref size() returns zero.
908 All references, pointers, and iterators are
909 invalidated.
910
911 @par Complexity
912 Linear in @ref size().
913
914 @par Exception Safety
915 No-throw guarantee.
916 */
917 BOOST_JSON_DECL
918 void
919 clear() noexcept;
920
921 /** Insert elements.
922
923 Inserts `p` if `this->contains(value_type(p).key())` is `false`.
924 @ref value_type must be constructible from `p`.
925
926 If the insertion occurs and results in a rehashing
927 of the container, all iterators and references are invalidated.
928 Otherwise, they are not affected.
929 Rehashing occurs only if the new number of elements
930 is greater than @ref capacity().
931
932 @par Constraints
933 @code
934 std::is_constructible_v<value_type, P>
935 @endcode
936
937 @par Complexity
938 Average case amortized constant,
939 worst case linear in @ref size().
940
941 @par Exception Safety
942 Strong guarantee.
943 Calls to `memory_resource::allocate` may throw.
944
945 @param p The value to insert.
946
947 @throw `boost::system::system_error` key is too long.
948 @throw `boost::system::system_error` @ref size() >= max_size().
949
950 @return A pair where `first` is an iterator
951 to the existing or inserted element, and `second`
952 is `true` if the insertion took place or `false` otherwise.
953 */
954 template<class P
955 #ifndef BOOST_JSON_DOCS
956 ,class = typename std::enable_if<
957 std::is_constructible<key_value_pair,
958 P, storage_ptr>::value>::type
959 #endif
960 >
961 std::pair<iterator, bool>
962 insert(P&& p);
963
964 /** Insert elements.
965
966 The elements in the range `[first, last)` are inserted one at a time,
967 in order. Any element with key that is a duplicate of a key already
968 present in container will be skipped. This also means, that if there
969 are two keys within the range that are equal to each other, only the
970 first will be inserted.
971
972 Insertion may result in rehashing of the container. In that case all
973 iterators and references are invalidated. Otherwise, they are not
974 affected.
975
976 @par Precondition
977 `first` and `last` are not iterators into `*this`.
978 `first` and `last` form a valid range.
979
980 @par Constraints
981 @code
982 std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
983 @endcode
984
985 @par Complexity
986 Linear in `std::distance(first, last)`.
987
988 @par Exception Safety
989 Strong guarantee for forward iterators, basic guarantee for input
990 iterators.
991 Calls to `memory_resource::allocate` may throw.
992
993 @param first An input iterator pointing to the first
994 element to insert, or pointing to the end of the range.
995
996 @param last An input iterator pointing to the end
997 of the range.
998
999 @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 348 insert(InputIt first, InputIt last)
1010 {
1011
1/1
✓ Branch 1 taken 4 times.
348 insert(first, last, typename
1012 std::iterator_traits<InputIt
1013 >::iterator_category{});
1014 16 }
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 11 swap(object& lhs, object& rhs)
1277 {
1278 11 lhs.swap(rhs);
1279 3 }
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 75 operator==(
1524 object const& lhs,
1525 object const& rhs) noexcept
1526 {
1527 75 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 6 operator!=(
1546 object const& lhs,
1547 object const& rhs) noexcept
1548 {
1549 6 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
1708