Line data Source code
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 160 : object(
282 : InputIt first,
283 : InputIt last,
284 : std::size_t min_capacity = 0,
285 : storage_ptr sp = {})
286 160 : : sp_(std::move(sp))
287 160 : , t_(&empty_)
288 : {
289 160 : construct(
290 : first, last,
291 : min_capacity,
292 : typename std::iterator_traits<
293 : InputIt>::iterator_category{});
294 160 : }
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 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 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 174 : insert(InputIt first, InputIt last)
1010 : {
1011 174 : insert(first, last, typename
1012 : std::iterator_traits<InputIt
1013 : >::iterator_category{});
1014 8 : }
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
|