GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: object.hpp
Date: 2025-12-23 17:20:53
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
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
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 502 object(storage_ptr sp) noexcept
200 502 : sp_(std::move(sp))
201 502 , t_(&empty_)
202 {
203 502 }
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 347 object(
450 std::initializer_list<
451 std::pair<string_view, value_ref>> init,
452 storage_ptr sp = {})
453
1/1
✓ Branch 3 taken 254 times.
347 : object(init, 0, std::move(sp))
454 {
455 254 }
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 722 storage() const noexcept
585 {
586 722 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
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 @n
973
974 Insertion may result in rehashing of the container. In that case all
975 iterators and references are invalidated. Otherwise, they are not
976 affected.
977
978 @par Precondition
979 `first` and `last` are not iterators into `*this`.
980 `first` and `last` form a valid range.
981
982 @par Constraints
983 @code
984 std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
985 @endcode
986
987 @par Complexity
988 Linear in `std::distance(first, last)`.
989
990 @par Exception Safety
991 Strong guarantee for forward iterators, basic guarantee for input
992 iterators.
993 Calls to `memory_resource::allocate` may throw.
994
995 @param first An input iterator pointing to the first
996 element to insert, or pointing to the end of the range.
997
998 @param last An input iterator pointing to the end
999 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 348 insert(InputIt first, InputIt last)
1012 {
1013
1/1
✓ Branch 1 taken 4 times.
348 insert(first, last, typename
1014 std::iterator_traits<InputIt
1015 >::iterator_category{});
1016 16 }
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 11 swap(object& lhs, object& rhs)
1279 {
1280 11 lhs.swap(rhs);
1281 3 }
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 83 operator==(
1525 object const& lhs,
1526 object const& rhs) noexcept
1527 {
1528 83 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 6 operator!=(
1547 object const& lhs,
1548 object const& rhs) noexcept
1549 {
1550 6 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
1709