]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/json/object.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / json / object.hpp
CommitLineData
20effc67
TL
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/kind.hpp>
15#include <boost/json/pilfer.hpp>
16#include <boost/json/storage_ptr.hpp>
17#include <boost/json/string_view.hpp>
18#include <boost/json/detail/object.hpp>
19#include <boost/json/detail/value.hpp>
20#include <cstdlib>
21#include <initializer_list>
22#include <iterator>
23#include <type_traits>
24#include <utility>
25
26BOOST_JSON_NS_BEGIN
27
28class value;
29class value_ref;
30class key_value_pair;
31
32/** A dynamically sized associative container of JSON key/value pairs.
33
34 This is an associative container whose elements
35 are key/value pairs with unique keys.
36\n
37 The elements are stored contiguously; iterators are
38 ordinary pointers, allowing random access pointer
39 arithmetic for retrieving elements.
40 In addition, the container maintains an internal
41 index to speed up find operations, reducing the
42 average complexity for most lookups and insertions.
43\n
44 Reallocations are usually costly operations in terms of
45 performance, as elements are copied and the internal
46 index must be rebuilt. The @ref reserve function can
47 be used to eliminate reallocations if the number of
48 elements is known beforehand.
49
50 @par Allocators
51
52 All elements stored in the container, and their
53 children if any, will use the same memory resource that
54 was used to construct the container.
55
56 @par Thread Safety
57
58 Non-const member functions may not be called
59 concurrently with any other member functions.
60
61 @par Satisfies
62 <a href="https://en.cppreference.com/w/cpp/named_req/ContiguousContainer"><em>ContiguousContainer</em></a>,
63 <a href="https://en.cppreference.com/w/cpp/named_req/ReversibleContainer"><em>ReversibleContainer</em></a>, and
64 <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>.
65*/
66class object
67{
68 struct table;
69 class revert_construct;
70 class revert_insert;
71 friend class value;
72 friend class object_test;
73 using access = detail::access;
74 using index_t = std::uint32_t;
75 static index_t constexpr null_index_ =
76 std::uint32_t(-1);
77
78 storage_ptr sp_; // must come first
79 kind k_ = kind::object; // must come second
80 table* t_;
81
82 BOOST_JSON_DECL
83 static table empty_;
84
85 template<class T>
86 using is_inputit = typename std::enable_if<
87 std::is_constructible<key_value_pair,
88 typename std::iterator_traits<T>::value_type
89 >::value>::type;
90
91 BOOST_JSON_DECL
92 explicit
93 object(detail::unchecked_object&& uo);
94
95public:
96 /** The type of _Allocator_ returned by @ref get_allocator
97
98 This type is a @ref polymorphic_allocator.
99 */
100#ifdef BOOST_JSON_DOCS
101 // VFALCO doc toolchain renders this incorrectly
102 using allocator_type = __see_below__;
103#else
104 using allocator_type = polymorphic_allocator<value>;
105#endif
106
107 /** The type of keys.
108
109 The function @ref string::max_size returns the
110 maximum allowed size of strings used as keys.
111 */
112 using key_type = string_view;
113
114 /// The type of mapped values
115 using mapped_type = value;
116
117 /// The element type
118 using value_type = key_value_pair;
119
120 /// The type used to represent unsigned integers
121 using size_type = std::size_t;
122
123 /// The type used to represent signed integers
124 using difference_type = std::ptrdiff_t;
125
126 /// A reference to an element
127 using reference = value_type&;
128
129 /// A const reference to an element
130 using const_reference = value_type const&;
131
132 /// A pointer to an element
133 using pointer = value_type*;
134
135 /// A const pointer to an element
136 using const_pointer = value_type const*;
137
138 /// A random access iterator to an element
139 using iterator = value_type*;
140
141 /// A const random access iterator to an element
142 using const_iterator = value_type const*;
143
144 /// A reverse random access iterator to an element
145 using reverse_iterator =
146 std::reverse_iterator<iterator>;
147
148 /// A const reverse random access iterator to an element
149 using const_reverse_iterator =
150 std::reverse_iterator<const_iterator>;
151
152 //------------------------------------------------------
153
154 /** Destructor.
155
156 The destructor for each element is called if needed,
157 any used memory is deallocated, and shared ownership
158 of the @ref memory_resource is released.
159
160 @par Complexity
161 Constant, or linear in @ref size().
162
163 @par Exception Safety
164 No-throw guarantee.
165 */
166 BOOST_JSON_DECL
167 ~object();
168
169 //------------------------------------------------------
170
171 /** Default constructor.
172
173 The constructed object is empty with zero
174 capacity, using the default memory resource.
175
176 @par Complexity
177 Constant.
178
179 @par Exception Safety
180 No-throw guarantee.
181 */
182 object() noexcept
183 : t_(&empty_)
184 {
185 }
186
187 /** Constructor.
188
189 The constructed object is empty with zero
190 capacity, using the specified memory resource.
191
192 @par Complexity
193 Constant.
194
195 @par Exception Safety
196 No-throw guarantee.
197
198 @param sp A pointer to the @ref memory_resource
199 to use. The container will acquire shared
200 ownership of the memory resource.
201 */
202 explicit
203 object(storage_ptr sp) noexcept
204 : sp_(std::move(sp))
205 , t_(&empty_)
206 {
207 }
208
209 /** Constructor.
210
211 The constructed object is empty with capacity
212 equal to the specified minimum capacity,
213 using the specified memory resource.
214
215 @par Complexity
216 Constant.
217
218 @par Exception Safety
219 Strong guarantee.
220 Calls to `memory_resource::allocate` may throw.
221
222 @param min_capacity The minimum number
223 of elements for which capacity is guaranteed
224 without a subsequent reallocation.
225
226 @param sp A pointer to the @ref memory_resource
227 to use. The container will acquire shared
228 ownership of the memory resource.
229 */
230 BOOST_JSON_DECL
231 object(
232 std::size_t min_capacity,
233 storage_ptr sp = {});
234
235 /** Constructor.
236
237 The object is constructed with the elements
238 in the range `{first, last)`, preserving order,
239 using the specified memory resource.
240 If there are elements with duplicate keys; that
241 is, if multiple elements in the range have keys
242 that compare equal, only the first equivalent
243 element will be inserted.
244
245 @par Constraints
246 @code
247 std::is_constructible_v<
248 key_value_pair,
249 std::iterator_traits<InputIt>::value_type>
250 @endcode
251
252 @par Complexity
253 Linear in `std::distance(first, last)`.
254
255 @par Exception Safety
256 Strong guarantee.
257 Calls to `memory_resource::allocate` may throw.
258
259 @param first An input iterator pointing to the
260 first element to insert, or pointing to the end
261 of the range.
262
263 @param last An input iterator pointing to the end
264 of the range.
265
266 @param min_capacity The minimum number
267 of elements for which capacity is guaranteed
268 without a subsequent reallocation.
269 Upon construction, @ref capacity() will be greater
270 than or equal to this number.
271
272 @param sp A pointer to the @ref memory_resource
273 to use. The container will acquire shared
274 ownership of the memory resource.
275
276 @tparam InputIt a type satisfying the requirements
277 of __InputIterator__.
278 */
279 template<
280 class InputIt
281 #ifndef BOOST_JSON_DOCS
282 ,class = is_inputit<InputIt>
283 #endif
284 >
285 object(
286 InputIt first,
287 InputIt last,
288 std::size_t min_capacity = 0,
289 storage_ptr sp = {})
290 : sp_(std::move(sp))
291 , t_(&empty_)
292 {
293 construct(
294 first, last,
295 min_capacity,
296 typename std::iterator_traits<
297 InputIt>::iterator_category{});
298 }
299
300 /** Move constructor.
301
302 The object is constructed by acquiring ownership of
303 the contents of `other` and shared ownership
304 of `other`'s memory resource.
305
306 @note
307
308 After construction, the moved-from object behaves
309 as if newly constructed with its current memory resource.
310
311 @par Complexity
312 Constant.
313
314 @par Exception Safety
315 No-throw guarantee.
316
317 @param other The object to move.
318 */
319 BOOST_JSON_DECL
320 object(object&& other) noexcept;
321
322 /** Move constructor.
323
324 The object is constructed with the contents of
325 `other` by move semantics, using the specified
326 memory resource:
327
328 @li If `*other.storage() == *sp`, ownership of
329 the underlying memory is transferred in constant
330 time, with no possibility of exceptions.
331 After construction, the moved-from object behaves
332 as if newly constructed with its current storage
333 pointer.
334
335 @li If `*other.storage() != *sp`, an
336 element-wise copy is performed, which may throw.
337 In this case, the moved-from object is not
338 changed.
339
340 @par Complexity
341 Constant or linear in `other.size()`.
342
343 @par Exception Safety
344 Strong guarantee.
345 Calls to `memory_resource::allocate` may throw.
346
347 @param other The object to move.
348
349 @param sp A pointer to the @ref memory_resource
350 to use. The container will acquire shared
351 ownership of the memory resource.
352 */
353 BOOST_JSON_DECL
354 object(
355 object&& other,
356 storage_ptr sp);
357
358 /** Pilfer constructor.
359
360 The object is constructed by acquiring ownership
361 of the contents of `other` using pilfer semantics.
362 This is more efficient than move construction, when
363 it is known that the moved-from object will be
364 immediately destroyed afterwards.
365
366 @par Complexity
367 Constant.
368
369 @par Exception Safety
370 No-throw guarantee.
371
372 @param other The value to pilfer. After pilfer
373 construction, `other` is not in a usable state
374 and may only be destroyed.
375
376 @see @ref pilfer,
377 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
378 Valueless Variants Considered Harmful</a>
379 */
380 object(pilfered<object> other) noexcept
381 : sp_(std::move(other.get().sp_))
382 , t_(detail::exchange(
383 other.get().t_, &empty_))
384 {
385 }
386
387 /** Copy constructor.
388
389 The object is constructed with a copy of the
390 contents of `other`, using `other`'s memory resource.
391
392 @par Complexity
393 Linear in `other.size()`.
394
395 @par Exception Safety
396 Strong guarantee.
397 Calls to `memory_resource::allocate` may throw.
398
399 @param other The object to copy.
400 */
401 object(
402 object const& other)
403 : object(other, other.sp_)
404 {
405 }
406
407 /** Copy constructor.
408
409 The object is constructed with a copy of the
410 contents of `other`, using the specified memory resource.
411
412 @par Complexity
413 Linear in `other.size()`.
414
415 @par Exception Safety
416 Strong guarantee.
417 Calls to `memory_resource::allocate` may throw.
418
419 @param other The object to copy.
420
421 @param sp A pointer to the @ref memory_resource
422 to use. The container will acquire shared
423 ownership of the memory resource.
424 */
425 BOOST_JSON_DECL
426 object(
427 object const& other,
428 storage_ptr sp);
429
430 /** Construct from initializer-list.
431
432 The object is constructed with a copy of the values
433 in the initializer-list in order, using the
434 specified memory resource.
435 If there are elements with duplicate keys; that
436 is, if multiple elements in the range have keys
437 that compare equal, only the first equivalent
438 element will be inserted.
439
440 @par Complexity
441 Linear in `init.size()`.
442
443 @par Exception Safety
444 Strong guarantee.
445 Calls to `memory_resource::allocate` may throw.
446
447 @param init The initializer list to insert.
448
449 @param sp A pointer to the @ref memory_resource
450 to use. The container will acquire shared
451 ownership of the memory resource.
452 */
453 object(
454 std::initializer_list<
455 std::pair<string_view, value_ref>> init,
456 storage_ptr sp = {})
457 : object(init, 0, std::move(sp))
458 {
459 }
460
461 /** Construct from initializer-list.
462
463 Storage for at least `min_capacity` elements is
464 reserved, and then
465 the object is constructed with a copy of the values
466 in the initializer-list in order, using the
467 specified memory resource.
468 If there are elements with duplicate keys; that
469 is, if multiple elements in the range have keys
470 that compare equal, only the first equivalent
471 element will be inserted.
472
473 @par Complexity
474 Linear in `init.size()`.
475
476 @par Exception Safety
477 Strong guarantee.
478 Calls to `memory_resource::allocate` may throw.
479
480 @param init The initializer list to insert.
481
482 @param min_capacity The minimum number
483 of elements for which capacity is guaranteed
484 without a subsequent reallocation.
485 Upon construction, @ref capacity() will be greater
486 than or equal to this number.
487
488 @param sp A pointer to the @ref memory_resource
489 to use. The container will acquire shared
490 ownership of the memory resource.
491 */
492 BOOST_JSON_DECL
493 object(
494 std::initializer_list<
495 std::pair<string_view, value_ref>> init,
496 std::size_t min_capacity,
497 storage_ptr sp = {});
498
499 //------------------------------------------------------
500 //
501 // Assignment
502 //
503 //------------------------------------------------------
504
505 /** Copy assignment.
506
507 The contents of the object are replaced with an
508 element-wise copy of `other`.
509
510 @par Complexity
511 Linear in @ref size() plus `other.size()`.
512
513 @par Exception Safety
514 Strong guarantee.
515 Calls to `memory_resource::allocate` may throw.
516
517 @param other The object to copy.
518 */
519 BOOST_JSON_DECL
520 object&
521 operator=(object const& other);
522
523 /** Move assignment.
524
525 The contents of the object are replaced with the
526 contents of `other` using move semantics:
527
528 @li If `*other.storage() == *sp`, ownership of
529 the underlying memory is transferred in constant
530 time, with no possibility of exceptions.
531 After assignment, the moved-from object behaves
532 as if newly constructed with its current storage
533 pointer.
534
535 @li If `*other.storage() != *sp`, an
536 element-wise copy is performed, which may throw.
537 In this case, the moved-from object is not
538 changed.
539
540 @par Complexity
541 Constant or linear in @ref size() plus `other.size()`.
542
543 @par Exception Safety
544 Strong guarantee.
545 Calls to `memory_resource::allocate` may throw.
546
547 @param other The object to move.
548 */
549 BOOST_JSON_DECL
550 object&
551 operator=(object&& other);
552
553 /** Assignment.
554
555 Replaces the contents with the contents of an
556 initializer list.
557
558 @par Complexity
559 Linear in @ref size() plus
560 average case linear in `init.size()`,
561 worst case quadratic in `init.size()`.
562
563 @par Exception Safety
564 Strong guarantee.
565 Calls to `memory_resource::allocate` may throw.
566
567 @param init The initializer list to copy.
568 */
569 BOOST_JSON_DECL
570 object&
571 operator=(std::initializer_list<
572 std::pair<string_view, value_ref>> init);
573
574 //------------------------------------------------------
575
576 /** Return the associated @ref memory_resource
577
578 This returns the @ref memory_resource used by
579 the container.
580
581 @par Complexity
582 Constant.
583
584 @par Exception Safety
585 No-throw guarantee.
586 */
587 storage_ptr const&
588 storage() const noexcept
589 {
590 return sp_;
591 }
592
593 /** Return the associated @ref memory_resource
594
595 This function returns an instance of
596 @ref polymorphic_allocator constructed from the
597 associated @ref memory_resource.
598
599 @par Complexity
600 Constant.
601
602 @par Exception Safety
603 No-throw guarantee.
604 */
605 allocator_type
606 get_allocator() const noexcept
607 {
608 return sp_.get();
609 }
610
611 //------------------------------------------------------
612 //
613 // Iterators
614 //
615 //------------------------------------------------------
616
617 /** Return an iterator to the first element.
618
619 If the container is empty, @ref end() is returned.
620
621 @par Complexity
622 Constant.
623
624 @par Exception Safety
625 No-throw guarantee.
626 */
627 inline
628 iterator
629 begin() noexcept;
630
631 /** Return a const iterator to the first element.
632
633 If the container is empty, @ref end() is returned.
634
635 @par Complexity
636 Constant.
637
638 @par Exception Safety
639 No-throw guarantee.
640 */
641 inline
642 const_iterator
643 begin() const noexcept;
644
645 /** Return a const iterator to the first element.
646
647 If the container is empty, @ref cend() is returned.
648
649 @par Complexity
650 Constant.
651
652 @par Exception Safety
653 No-throw guarantee.
654 */
655 inline
656 const_iterator
657 cbegin() const noexcept;
658
659 /** Return an iterator to the element following the last element.
660
661 The element acts as a placeholder; attempting
662 to access it results in undefined behavior.
663
664 @par Complexity
665 Constant.
666
667 @par Exception Safety
668 No-throw guarantee.
669 */
670 inline
671 iterator
672 end() noexcept;
673
674 /** Return a const iterator to the element following the last element.
675
676 The element acts as a placeholder; attempting
677 to access it results in undefined behavior.
678
679 @par Complexity
680 Constant.
681
682 @par Exception Safety
683 No-throw guarantee.
684 */
685 inline
686 const_iterator
687 end() const noexcept;
688
689 /** Return a const iterator to the element following the last element.
690
691 The element acts as a placeholder; attempting
692 to access it results in undefined behavior.
693
694 @par Complexity
695 Constant.
696
697 @par Exception Safety
698 No-throw guarantee.
699 */
700 inline
701 const_iterator
702 cend() const noexcept;
703
704 /** Return a reverse iterator to the first element of the reversed container.
705
706 The pointed-to element corresponds to the
707 last element of the non-reversed container.
708 If the container is empty, @ref rend() is returned.
709
710 @par Complexity
711 Constant.
712
713 @par Exception Safety
714 No-throw guarantee.
715 */
716 inline
717 reverse_iterator
718 rbegin() noexcept;
719
720 /** Return a const reverse iterator to the first element of the reversed container.
721
722 The pointed-to element corresponds to the
723 last element of the non-reversed container.
724 If the container is empty, @ref rend() is returned.
725
726 @par Complexity
727 Constant.
728
729 @par Exception Safety
730 No-throw guarantee.
731 */
732 inline
733 const_reverse_iterator
734 rbegin() const noexcept;
735
736 /** Return a const reverse iterator to the first element of the reversed container.
737
738 The pointed-to element corresponds to the
739 last element of the non-reversed container.
740 If the container is empty, @ref crend() is returned.
741
742 @par Complexity
743 Constant.
744
745 @par Exception Safety
746 No-throw guarantee.
747 */
748 inline
749 const_reverse_iterator
750 crbegin() const noexcept;
751
752 /** Return a reverse iterator to the element following the last element of the reversed container.
753
754 The pointed-to element corresponds to the element
755 preceding the first element of the non-reversed container.
756 This element acts as a placeholder, attempting
757 to access it results in undefined behavior.
758
759 @par Complexity
760 Constant.
761
762 @par Exception Safety
763 No-throw guarantee.
764 */
765 inline
766 reverse_iterator
767 rend() noexcept;
768
769 /** Return a const reverse iterator to the element following the last element of the reversed container.
770
771 The pointed-to element corresponds to the element
772 preceding the first element of the non-reversed container.
773 This element acts as a placeholder, attempting
774 to access it results in undefined behavior.
775
776 @par Complexity
777 Constant.
778
779 @par Exception Safety
780 No-throw guarantee.
781 */
782 inline
783 const_reverse_iterator
784 rend() const noexcept;
785
786 /** Return a const reverse iterator to the element following the last element of the reversed container.
787
788 The pointed-to element corresponds to the element
789 preceding the first element of the non-reversed container.
790 This element acts as a placeholder, attempting
791 to access it results in undefined behavior.
792
793 @par Complexity
794 Constant.
795
796 @par Exception Safety
797 No-throw guarantee.
798 */
799 inline
800 const_reverse_iterator
801 crend() const noexcept;
802
803 //------------------------------------------------------
804 //
805 // Capacity
806 //
807 //------------------------------------------------------
808
809 /** Return whether there are no elements.
810
811 Returns `true` if there are no elements in
812 the container, i.e. @ref size() returns 0.
813
814 @par Complexity
815 Constant.
816
817 @par Exception Safety
818 No-throw guarantee.
819 */
820 inline
821 bool
822 empty() const noexcept;
823
824 /** Return the number of elements.
825
826 This returns the number of elements in the container.
827
828 @par Complexity
829 Constant.
830
831 @par Exception Safety
832 No-throw guarantee.
833 */
834 inline
835 std::size_t
836 size() const noexcept;
837
838 /** Return the maximum number of elements any object can hold
839
840 The maximum is an implementation-defined number dependent
841 on system or library implementation. This value is a
842 theoretical limit; at runtime, the actual maximum size
843 may be less due to resource limits.
844
845 @par Complexity
846 Constant.
847
848 @par Exception Safety
849 No-throw guarantee.
850 */
851 static
852 constexpr
853 std::size_t
854 max_size() noexcept;
855
856 /** Return the number of elements that can be held in currently allocated memory
857
858 This number may be larger than the value returned
859 by @ref size().
860
861 @par Complexity
862 Constant.
863
864 @par Exception Safety
865 No-throw guarantee.
866 */
867 inline
868 std::size_t
869 capacity() const noexcept;
870
871 /** Increase the capacity to at least a certain amount.
872
873 This increases the @ref capacity() to a value
874 that is greater than or equal to `new_capacity`.
875 If `new_capacity > capacity()`, new memory is
876 allocated. Otherwise, the call has no effect.
877 The number of elements and therefore the
878 @ref size() of the container is not changed.
879 \n
880 If new memory is allocated, all iterators
881 including any past-the-end iterators, and all
882 references to the elements are invalidated.
883 Otherwise, no iterators or references are
884 invalidated.
885
886 @par Complexity
887 Constant or average case linear in
888 @ref size(), worst case quadratic.
889
890 @par Exception Safety
891 Strong guarantee.
892 Calls to `memory_resource::allocate` may throw.
893
894 @param new_capacity The new minimum capacity.
895
896 @throw std::length_error `new_capacity > max_size()`
897 */
898 void
899 reserve(std::size_t new_capacity)
900 {
901 if(new_capacity <= capacity())
902 return;
903 rehash(new_capacity);
904 }
905
906 //------------------------------------------------------
907 //
908 // Modifiers
909 //
910 //------------------------------------------------------
911
912 /** Erase all elements.
913
914 Erases all elements from the container without
915 changing the capacity.
916 After this call, @ref size() returns zero.
917 All references, pointers, and iterators are
918 invalidated.
919
920 @par Complexity
921 Linear in @ref size().
922
923 @par Exception Safety
924 No-throw guarantee.
925 */
926 BOOST_JSON_DECL
927 void
928 clear() noexcept;
929
930 /** Insert elements.
931
932 Inserts `p`, from which @ref value_type must
933 be constructible.
934
935 @par Constraints
936 @code
937 std::is_constructible_v<value_type, P>
938 @endcode
939
940 @par Complexity
941 Average case amortized constant,
942 worst case linear in @ref size().
943
944 @par Exception Safety
945 Strong guarantee.
946 Calls to `memory_resource::allocate` may throw.
947
948 @param p The value to insert.
949
950 @throw std::length_error key is too long.
951
952 @throw std::length_error @ref size() >= max_size().
953
954 @return A pair where `first` is an iterator
955 to the existing or inserted element, and `second`
956 is `true` if the insertion took place or `false` if
957 the assignment took place.
958 */
959 template<class P
960#ifndef BOOST_JSON_DOCS
961 ,class = typename std::enable_if<
962 std::is_constructible<key_value_pair,
963 P, storage_ptr>::value>::type
964#endif
965 >
966 std::pair<iterator, bool>
967 insert(P&& p);
968
969 /** Insert elements.
970
971 The elements in the range `{first, last)` whose
972 keys are unique are inserted one at a time, in order.
973 If there are elements with duplicate keys; that
974 is, if multiple elements in the range have keys
975 that compare equal, only the first equivalent
976 element will be inserted.
977
978 @par Precondition
979 `first` and `last` are not iterators into `*this`.
980
981 @par Constraints
982 @code
983 std::is_constructible_v<value_type, std::iterator_traits<InputIt>::value_type>
984 @endcode
985
986 @par Complexity
987 Linear in `std::distance(first, last)`.
988
989 @par Exception Safety
990 Strong guarantee.
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 insert(InputIt first, InputIt last)
1010 {
1011 insert(first, last, typename
1012 std::iterator_traits<InputIt
1013 >::iterator_category{});
1014 }
1015
1016 /** Insert elements.
1017
1018 The elements in the initializer list whose
1019 keys are unique are inserted one at a time, in order.
1020 If there are elements with duplicate keys; that
1021 is, if multiple elements in the range have keys
1022 that compare equal, only the first equivalent
1023 element will be inserted.
1024
1025 @par Complexity
1026 Linear in `init.size()`.
1027
1028 @par Exception Safety
1029 Strong guarantee.
1030 Calls to `memory_resource::allocate` may throw.
1031
1032 @param init The initializer list to insert
1033 */
1034 BOOST_JSON_DECL
1035 void
1036 insert(std::initializer_list<
1037 std::pair<string_view, value_ref>> init);
1038
1039 /** Insert an element or assign to the current element if the key already exists.
1040
1041 If the key equivalent to `key` already exists in the
1042 container. assigns `std::forward<M>(obj)` to the
1043 `mapped type` corresponding to the key. Otherwise,
1044 inserts the new value at the end as if by insert,
1045 constructing it from
1046 `value_type(key, std::forward<M>(obj))`.
1047
1048 If the insertion occurs and results in a rehashing
1049 of the container, all iterators are invalidated.
1050 Otherwise, iterators are not affected.
1051 References are not invalidated.
1052 Rehashing occurs only if the new number of elements
1053 is 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 std::length_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 The element is inserted after all the existing
1084 elements.
1085
1086 If the insertion occurs and results in a rehashing
1087 of the container, all iterators are invalidated.
1088 Otherwise, iterators are not affected.
1089 References are not invalidated.
1090 Rehashing occurs only if the new number of elements
1091 is greater than @ref capacity().
1092
1093 @par Complexity
1094 Amortized constant on average, worst case linear in @ref size().
1095
1096 @par Exception Safety
1097 Strong guarantee.
1098 Calls to `memory_resource::allocate` may throw.
1099
1100 @return A `std::pair` where `first` is an iterator
1101 to the existing or inserted element, and `second`
1102 is `true` if the insertion took place or `false` if
1103 the assignment took place.
1104
1105 @param key The key used for lookup and insertion
1106
1107 @param arg The argument used to construct the value.
1108 This will be passed as `std::forward<Arg>(arg)` to
1109 the @ref value constructor.
1110
1111 @throw std::length_error if key is too long
1112 */
1113 template<class Arg>
1114 std::pair<iterator, bool>
1115 emplace(string_view key, Arg&& arg);
1116
1117 /** Erase an element
1118
1119 Remove the element pointed to by `pos`, which must
1120 be valid and dereferenceable. Thus the @ref end()
1121 iterator (which is valid but cannot be dereferenced)
1122 cannot be used as a value for `pos`.
1123 References and iterators to the erased element are
1124 invalidated. Other iterators and references are not
1125 invalidated.
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 last 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 /** Swap two objects.
1165
1166 Exchanges the contents of this object with another
1167 object. Ownership of the respective @ref memory_resource
1168 objects is not transferred.
1169
1170 @li If `*other.storage() == *this->storage()`,
1171 ownership of the underlying memory is swapped in
1172 constant time, with no possibility of exceptions.
1173 All iterators and references remain valid.
1174
1175 @li If `*other.storage() != *this->storage()`,
1176 the contents are logically swapped by making copies,
1177 which can throw. In this case all iterators and
1178 references are invalidated.
1179
1180 @par Complexity
1181 Constant or linear in @ref size() plus `other.size()`.
1182
1183 @par Exception Safety
1184 Strong guarantee.
1185 Calls to `memory_resource::allocate` may throw.
1186
1187 @param other The object to swap with.
1188 If `this == &other`, this function call has no effect.
1189 */
1190 BOOST_JSON_DECL
1191 void
1192 swap(object& other);
1193
1194 /** Swap two objects.
1195
1196 Exchanges the contents of the object `lhs` with
1197 another object `rhs`. Ownership of the respective
1198 @ref memory_resource objects is not transferred.
1199
1200 @li If `*lhs.storage() == *rhs.storage()`,
1201 ownership of the underlying memory is swapped in
1202 constant time, with no possibility of exceptions.
1203 All iterators and references remain valid.
1204
1205 @li If `*lhs.storage() != *rhs.storage()`,
1206 the contents are logically swapped by making a copy,
1207 which can throw. In this case all iterators and
1208 references are invalidated.
1209
1210 @par Effects
1211 @code
1212 lhs.swap( rhs );
1213 @endcode
1214
1215 @par Complexity
1216 Constant or linear in `lhs.size() + rhs.size()`.
1217
1218 @par Exception Safety
1219 Strong guarantee.
1220 Calls to `memory_resource::allocate` may throw.
1221
1222 @param lhs The object to exchange.
1223
1224 @param rhs The object to exchange.
1225 If `&lhs == &rhs`, this function call has no effect.
1226
1227 @see @ref object::swap
1228 */
1229 friend
1230 void
1231 swap(object& lhs, object& rhs)
1232 {
1233 lhs.swap(rhs);
1234 }
1235
1236 //------------------------------------------------------
1237 //
1238 // Lookup
1239 //
1240 //------------------------------------------------------
1241
1242 /** Access the specified element, with bounds checking.
1243
1244 Returns a reference to the mapped value of the element
1245 that matches `key`, otherwise throws.
1246
1247 @par Complexity
1248 Constant on average, worst case linear in @ref size().
1249
1250 @par Exception Safety
1251 Strong guarantee.
1252
1253 @return A reference to the mapped value.
1254
1255 @param key The key of the element to find.
1256
1257 @throw std::out_of_range if no such element exists.
1258 */
1259 inline
1260 value&
1261 at(string_view key);
1262
1263 /** Access the specified element, with bounds checking.
1264
1265 Returns a constant reference to the mapped value of
1266 the element that matches `key`, otherwise throws.
1267
1268 @par Complexity
1269 Constant on average, worst case linear in @ref size().
1270
1271 @par Exception Safety
1272 Strong guarantee.
1273
1274 @return A reference to the mapped value.
1275
1276 @param key The key of the element to find.
1277
1278 @throw std::out_of_range if no such element exists.
1279 */
1280 inline
1281 value const&
1282 at(string_view key) const;
1283
1284 /** Access or insert the specified element
1285
1286 Returns a reference to the value that is mapped
1287 to a key equivalent to key, performing an insertion
1288 of a null value if such key does not already exist.
1289 \n
1290 If an insertion occurs and results in a rehashing of
1291 the container, all iterators are invalidated. Otherwise
1292 iterators are not affected. References are not
1293 invalidated. Rehashing occurs only if the new
1294 number of elements is greater than @ref capacity().
1295
1296 @par Complexity
1297 Constant on average, worst case linear in @ref size().
1298
1299 @par Exception Safety
1300 Strong guarantee.
1301 Calls to `memory_resource::allocate` may throw.
1302
1303 @return A reference to the mapped value.
1304
1305 @param key The key of the element to find.
1306 */
1307 BOOST_JSON_DECL
1308 value&
1309 operator[](string_view key);
1310
1311 /** Count the number of elements with a specific key
1312
1313 This function returns the count of the number of
1314 elements match `key`. The only possible return values
1315 are 0 and 1.
1316
1317 @par Complexity
1318 Constant on average, worst case linear in @ref size().
1319
1320 @par Exception Safety
1321 No-throw guarantee.
1322
1323 @param key The key of the element to find.
1324 */
1325 BOOST_JSON_DECL
1326 std::size_t
1327 count(string_view key) const noexcept;
1328
1329 /** Find an element with a specific key
1330
1331 This function returns an iterator to the element
1332 matching `key` if it exists, otherwise returns
1333 @ref end().
1334
1335 @par Complexity
1336 Constant on average, worst case linear in @ref size().
1337
1338 @par Exception Safety
1339 No-throw guarantee.
1340
1341 @param key The key of the element to find.
1342 */
1343 BOOST_JSON_DECL
1344 iterator
1345 find(string_view key) noexcept;
1346
1347 /** Find an element with a specific key
1348
1349 This function returns a constant iterator to
1350 the element matching `key` if it exists,
1351 otherwise returns @ref end().
1352
1353 @par Complexity
1354 Constant on average, worst case linear in @ref size().
1355
1356 @par Exception Safety
1357 No-throw guarantee.
1358
1359 @param key The key of the element to find.
1360 */
1361 BOOST_JSON_DECL
1362 const_iterator
1363 find(string_view key) const noexcept;
1364
1365 /** Return `true` if the key is found
1366
1367 This function returns `true` if a key with the
1368 specified string is found.
1369
1370 @par Effects
1371 @code
1372 return this->find(key) != this->end();
1373 @endcode
1374
1375 @par Complexity
1376 Constant on average, worst case linear in @ref size().
1377
1378 @par Exception Safety
1379 No-throw guarantee.
1380
1381 @param key The key of the element to find.
1382
1383 @see @ref find
1384 */
1385 BOOST_JSON_DECL
1386 bool
1387 contains(string_view key) const noexcept;
1388
1389 /** Return a pointer to the value if the key is found, or null
1390
1391 This function searches for a value with the given
1392 key, and returns a pointer to it if found. Otherwise
1393 it returns null.
1394
1395 @par Example
1396 @code
1397 if( auto p = obj.if_contains( "key" ) )
1398 std::cout << *p;
1399 @endcode
1400
1401 @par Complexity
1402 Constant on average, worst case linear in @ref size().
1403
1404 @par Exception Safety
1405 No-throw guarantee.
1406
1407 @param key The key of the element to find.
1408
1409 @see @ref find
1410 */
1411 BOOST_JSON_DECL
1412 value const*
1413 if_contains(string_view key) const noexcept;
1414
1415 /** Return a pointer to the value if the key is found, or null
1416
1417 This function searches for a value with the given
1418 key, and returns a pointer to it if found. Otherwise
1419 it returns null.
1420
1421 @par Example
1422 @code
1423 if( auto p = obj.if_contains( "key" ) )
1424 std::cout << *p;
1425 @endcode
1426
1427 @par Complexity
1428 Constant on average, worst case linear in @ref size().
1429
1430 @par Exception Safety
1431 No-throw guarantee.
1432
1433 @param key The key of the element to find.
1434
1435 @see @ref find
1436 */
1437 BOOST_JSON_DECL
1438 value*
1439 if_contains(string_view key) noexcept;
1440
1441 /** Return `true` if two objects are equal.
1442
1443 Objects are equal when their sizes are the same,
1444 and when for each key in `lhs` there is a matching
1445 key in `rhs` with the same value.
1446
1447 @par Complexity
1448 Constant, or linear (worst case quadratic) in `lhs.size()`.
1449
1450 @par Exception Safety
1451 No-throw guarantee.
1452 */
1453 // inline friend speeds up overload resolution
1454 friend
1455 bool
1456 operator==(
1457 object const& lhs,
1458 object const& rhs) noexcept
1459 {
1460 return lhs.equal(rhs);
1461 }
1462
1463 /** Return `true` if two objects are not equal.
1464
1465 Objects are equal when their sizes are the same,
1466 and when for each key in `lhs` there is a matching
1467 key in `rhs` with the same value.
1468
1469 @par Complexity
1470 Constant, or linear (worst case quadratic) in `lhs.size()`.
1471
1472 @par Exception Safety
1473 No-throw guarantee.
1474 */
1475 // inline friend speeds up overload resolution
1476 friend
1477 bool
1478 operator!=(
1479 object const& lhs,
1480 object const& rhs) noexcept
1481 {
1482 return ! (lhs == rhs);
1483 }
1484
1485private:
1486 template<class InputIt>
1487 void
1488 construct(
1489 InputIt first,
1490 InputIt last,
1491 std::size_t min_capacity,
1492 std::input_iterator_tag);
1493
1494 template<class InputIt>
1495 void
1496 construct(
1497 InputIt first,
1498 InputIt last,
1499 std::size_t min_capacity,
1500 std::forward_iterator_tag);
1501
1502 template<class InputIt>
1503 void
1504 insert(
1505 InputIt first,
1506 InputIt last,
1507 std::input_iterator_tag);
1508
1509 template<class InputIt>
1510 void
1511 insert(
1512 InputIt first,
1513 InputIt last,
1514 std::forward_iterator_tag);
1515
1516 BOOST_JSON_DECL
1517 std::pair<key_value_pair*, std::size_t>
1518 find_impl(string_view key) const noexcept;
1519
1520 BOOST_JSON_DECL
1521 std::pair<iterator, bool>
1522 insert_impl(
1523 pilfered<key_value_pair> p);
1524
1525 BOOST_JSON_DECL
1526 key_value_pair*
1527 insert_impl(
1528 pilfered<key_value_pair> p,
1529 std::size_t hash);
1530
1531 BOOST_JSON_DECL
1532 void
1533 rehash(std::size_t new_capacity);
1534
1535 BOOST_JSON_DECL
1536 bool
1537 equal(object const& other) const noexcept;
1538
1539 inline
1540 std::size_t
1541 growth(
1542 std::size_t new_size) const;
1543
1544 inline
1545 void
1546 remove(
1547 index_t& head,
1548 key_value_pair& p) noexcept;
1549
1550 inline
1551 void
1552 destroy() noexcept;
1553
1554 inline
1555 void
1556 destroy(
1557 key_value_pair* first,
1558 key_value_pair* last) noexcept;
1559};
1560
1561BOOST_JSON_NS_END
1562
1563// Must be included here for this file to stand alone
1564#include <boost/json/value.hpp>
1565
1566// includes are at the bottom of <boost/json/value.hpp>
1567
1568#endif