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 :
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 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 347 : object(
450 : std::initializer_list<
451 : std::pair<string_view, value_ref>> init,
452 : storage_ptr sp = {})
453 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 174 : insert(InputIt first, InputIt last)
1012 : {
1013 174 : insert(first, last, typename
1014 : std::iterator_traits<InputIt
1015 : >::iterator_category{});
1016 8 : }
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
|