Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/boostorg/json
9 : //
10 :
11 : #ifndef BOOST_JSON_VALUE_HPP
12 : #define BOOST_JSON_VALUE_HPP
13 :
14 : #include <boost/json/detail/config.hpp>
15 : #include <boost/json/array.hpp>
16 : #include <boost/json/kind.hpp>
17 : #include <boost/json/object.hpp>
18 : #include <boost/json/pilfer.hpp>
19 : #include <boost/json/set_pointer_options.hpp>
20 : #include <boost/json/storage_ptr.hpp>
21 : #include <boost/json/string.hpp>
22 : #include <boost/json/string_view.hpp>
23 : #include <boost/json/value_ref.hpp>
24 : #include <boost/json/detail/except.hpp>
25 : #include <boost/json/detail/value.hpp>
26 : #include <cstdlib>
27 : #include <cstring>
28 : #include <initializer_list>
29 : #include <iosfwd>
30 : #include <limits>
31 : #include <new>
32 : #include <type_traits>
33 : #include <utility>
34 :
35 : namespace boost {
36 : namespace json {
37 :
38 : //----------------------------------------------------------
39 :
40 : /** The type used to represent any JSON value
41 :
42 : This is a
43 : <a href="https://en.cppreference.com/w/cpp/concepts/regular"><em>Regular</em></a>
44 : type which works like
45 : a variant of the basic JSON data types: array,
46 : object, string, number, boolean, and null.
47 :
48 : @par Thread Safety
49 :
50 : Distinct instances may be accessed concurrently.
51 : Non-const member functions of a shared instance
52 : may not be called concurrently with any other
53 : member functions of that instance.
54 : */
55 : class value
56 : {
57 : #ifndef BOOST_JSON_DOCS
58 : using scalar = detail::scalar;
59 :
60 : union
61 : {
62 : storage_ptr sp_; // must come first
63 : array arr_;
64 : object obj_;
65 : string str_;
66 : scalar sca_;
67 : };
68 : #endif
69 :
70 : struct init_iter;
71 :
72 : #ifndef BOOST_JSON_DOCS
73 : // VFALCO doc toolchain incorrectly treats this as public
74 : friend struct detail::access;
75 : #endif
76 :
77 : explicit
78 2120 : value(
79 : detail::unchecked_array&& ua)
80 2120 : : arr_(std::move(ua))
81 : {
82 2082 : }
83 :
84 : explicit
85 34879 : value(
86 : detail::unchecked_object&& uo)
87 34879 : : obj_(std::move(uo))
88 : {
89 34840 : }
90 :
91 30296 : value(
92 : detail::key_t const&,
93 : string_view s,
94 : storage_ptr sp)
95 30296 : : str_(detail::key_t{}, s, std::move(sp))
96 : {
97 30236 : }
98 :
99 8060 : value(
100 : detail::key_t const&,
101 : string_view s1,
102 : string_view s2,
103 : storage_ptr sp)
104 8060 : : str_(detail::key_t{}, s1, s2, std::move(sp))
105 : {
106 8060 : }
107 :
108 6599 : inline bool is_scalar() const noexcept
109 : {
110 6599 : return sca_.k < json::kind::string;
111 : }
112 :
113 : public:
114 : /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
115 : using allocator_type = container::pmr::polymorphic_allocator<value>;
116 :
117 : /** Destructor.
118 :
119 : The value and all of its contents are destroyed.
120 : Any dynamically allocated memory that was allocated
121 : internally is freed.
122 :
123 : @par Complexity
124 : Constant, or linear in size for array or object.
125 :
126 : @par Exception Safety
127 : No-throw guarantee.
128 : */
129 : BOOST_JSON_DECL
130 : ~value() noexcept;
131 :
132 : /** Default constructor.
133 :
134 : The constructed value is null,
135 : using the [default memory resource].
136 :
137 : @par Complexity
138 : Constant.
139 :
140 : @par Exception Safety
141 : No-throw guarantee.
142 :
143 : [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
144 : */
145 206 : value() noexcept
146 206 : : sca_()
147 : {
148 206 : }
149 :
150 : /** Constructor.
151 :
152 : The constructed value is null, using the
153 : specified `boost::container::pmr::memory_resource`.
154 :
155 : @par Complexity
156 : Constant.
157 :
158 : @par Exception Safety
159 : No-throw guarantee.
160 :
161 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
162 : use. The container will acquire shared ownership of the memory
163 : resource.
164 : */
165 : explicit
166 7155 : value(storage_ptr sp) noexcept
167 7155 : : sca_(std::move(sp))
168 : {
169 7155 : }
170 :
171 : /** Pilfer constructor.
172 :
173 : The value is constructed by acquiring ownership
174 : of the contents of `other` using pilfer semantics.
175 : This is more efficient than move construction, when
176 : it is known that the moved-from object will be
177 : immediately destroyed afterwards.
178 :
179 : @par Complexity
180 : Constant.
181 :
182 : @par Exception Safety
183 : No-throw guarantee.
184 :
185 : @param other The value to pilfer. After pilfer
186 : construction, `other` is not in a usable state
187 : and may only be destroyed.
188 :
189 : @see @ref pilfer,
190 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
191 : Valueless Variants Considered Harmful</a>
192 : */
193 2129166 : value(pilfered<value> other) noexcept
194 2129166 : {
195 2129166 : relocate(this, other.get());
196 2129166 : ::new(&other.get().sca_) scalar();
197 2129166 : }
198 :
199 : /** Copy constructor.
200 :
201 : The value is constructed with a copy of the
202 : contents of `other`, using the same
203 : memory resource as `other`.
204 :
205 : @par Complexity
206 : Linear in the size of `other`.
207 :
208 : @par Exception Safety
209 : Strong guarantee.
210 : Calls to `memory_resource::allocate` may throw.
211 :
212 : @param other The value to copy.
213 : */
214 19 : value(value const& other)
215 19 : : value(other, other.storage())
216 : {
217 19 : }
218 :
219 : /** Copy constructor
220 :
221 : The value is constructed with a copy of the
222 : contents of `other`, using the
223 : specified memory resource.
224 :
225 : @par Complexity
226 : Linear in the size of `other`.
227 :
228 : @par Exception Safety
229 : Strong guarantee.
230 : Calls to `memory_resource::allocate` may throw.
231 :
232 : @param other The value to copy.
233 :
234 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
235 : use. The container will acquire shared ownership of the memory
236 : resource.
237 : */
238 : BOOST_JSON_DECL
239 : value(
240 : value const& other,
241 : storage_ptr sp);
242 :
243 : /** Move constructor
244 :
245 : The value is constructed by acquiring ownership of
246 : the contents of `other` and shared ownership of
247 : `other`'s memory resource.
248 :
249 : @note
250 :
251 : After construction, the moved-from value becomes a
252 : null value with its current storage pointer.
253 :
254 : @par Complexity
255 : Constant.
256 :
257 : @par Exception Safety
258 : No-throw guarantee.
259 :
260 : @param other The value to move.
261 : */
262 : BOOST_JSON_DECL
263 : value(value&& other) noexcept;
264 :
265 : /** Move constructor
266 :
267 : The value is constructed with the contents of
268 : `other` by move semantics, using the specified
269 : memory resource:
270 :
271 : @li If `*other.storage() == *sp`, ownership of
272 : the underlying memory is transferred in constant
273 : time, with no possibility of exceptions.
274 : After construction, the moved-from value becomes
275 : a null value with its current storage pointer.
276 :
277 : @li If `*other.storage() != *sp`, an
278 : element-wise copy is performed if
279 : `other.is_structured() == true`, which may throw.
280 : In this case, the moved-from value is not
281 : changed.
282 :
283 : @par Complexity
284 : Constant or linear in the size of `other`.
285 :
286 : @par Exception Safety
287 : Strong guarantee.
288 : Calls to `memory_resource::allocate` may throw.
289 :
290 : @param other The value to move.
291 :
292 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
293 : use. The container will acquire shared ownership of the memory
294 : resource.
295 : */
296 : BOOST_JSON_DECL
297 : value(
298 : value&& other,
299 : storage_ptr sp);
300 :
301 : //------------------------------------------------------
302 : //
303 : // Conversion
304 : //
305 : //------------------------------------------------------
306 :
307 : /** Construct a null.
308 :
309 : A null value is a monostate.
310 :
311 : @par Complexity
312 : Constant.
313 :
314 : @par Exception Safety
315 : No-throw guarantee.
316 :
317 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
318 : use. The container will acquire shared ownership of the memory
319 : resource.
320 : */
321 9563 : value(
322 : std::nullptr_t,
323 : storage_ptr sp = {}) noexcept
324 9563 : : sca_(std::move(sp))
325 : {
326 9563 : }
327 :
328 : /** Construct a bool.
329 :
330 : This constructs a `bool` value using
331 : the specified memory resource.
332 :
333 : @par Complexity
334 : Constant.
335 :
336 : @par Exception Safety
337 : No-throw guarantee.
338 :
339 : @param b The initial value.
340 :
341 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
342 : use. The container will acquire shared ownership of the memory
343 : resource.
344 : */
345 : #ifdef BOOST_JSON_DOCS
346 : value(
347 : bool b,
348 : storage_ptr sp = {}) noexcept;
349 : #else
350 : template<class T
351 : ,class = typename std::enable_if<
352 : std::is_same<T, bool>::value>::type
353 : >
354 774 : value(
355 : T b,
356 : storage_ptr sp = {}) noexcept
357 774 : : sca_(b, std::move(sp))
358 : {
359 774 : }
360 : #endif
361 :
362 : /** Construct a `std::int64_t`.
363 :
364 : @par Complexity
365 : Constant.
366 :
367 : @par Exception Safety
368 : No-throw guarantee.
369 :
370 : @param i The initial value.
371 :
372 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
373 : use. The container will acquire shared ownership of the memory
374 : resource.
375 : */
376 3 : value(
377 : signed char i,
378 : storage_ptr sp = {}) noexcept
379 3 : : sca_(static_cast<std::int64_t>(
380 3 : i), std::move(sp))
381 : {
382 3 : }
383 :
384 : /** Construct a `std::int64_t`.
385 :
386 : @par Complexity
387 : Constant.
388 :
389 : @par Exception Safety
390 : No-throw guarantee.
391 :
392 : @param i The initial value.
393 :
394 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
395 : use. The container will acquire shared ownership of the memory
396 : resource.
397 : */
398 4 : value(
399 : short i,
400 : storage_ptr sp = {}) noexcept
401 4 : : sca_(static_cast<std::int64_t>(
402 4 : i), std::move(sp))
403 : {
404 4 : }
405 :
406 : /** Construct a `std::int64_t`.
407 :
408 : @par Complexity
409 : Constant.
410 :
411 : @par Exception Safety
412 : No-throw guarantee.
413 :
414 : @param i The initial value.
415 :
416 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
417 : use. The container will acquire shared ownership of the memory
418 : resource.
419 : */
420 11277 : value(
421 : int i,
422 : storage_ptr sp = {}) noexcept
423 11277 : : sca_(static_cast<std::int64_t>(i),
424 11277 : std::move(sp))
425 : {
426 11277 : }
427 :
428 : /** Construct a `std::int64_t`.
429 :
430 : @par Complexity
431 : Constant.
432 :
433 : @par Exception Safety
434 : No-throw guarantee.
435 :
436 : @param i The initial value.
437 :
438 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
439 : use. The container will acquire shared ownership of the memory
440 : resource.
441 : */
442 5834 : value(
443 : long i,
444 : storage_ptr sp = {}) noexcept
445 5834 : : sca_(static_cast<std::int64_t>(i),
446 5834 : std::move(sp))
447 : {
448 5834 : }
449 :
450 : /** Construct a `std::int64_t`.
451 :
452 : @par Complexity
453 : Constant.
454 :
455 : @par Exception Safety
456 : No-throw guarantee.
457 :
458 : @param i The initial value.
459 :
460 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
461 : use. The container will acquire shared ownership of the memory
462 : resource.
463 : */
464 3 : value(
465 : long long i,
466 : storage_ptr sp = {}) noexcept
467 3 : : sca_(static_cast<std::int64_t>(i),
468 3 : std::move(sp))
469 : {
470 3 : }
471 :
472 : /** Construct a `std::uint64_t`.
473 :
474 : @par Complexity
475 : Constant.
476 :
477 : @par Exception Safety
478 : No-throw guarantee.
479 :
480 : @param u The initial value.
481 :
482 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
483 : use. The container will acquire shared ownership of the memory
484 : resource.
485 : */
486 23 : value(
487 : unsigned char u,
488 : storage_ptr sp = {}) noexcept
489 23 : : sca_(static_cast<std::uint64_t>(
490 23 : u), std::move(sp))
491 : {
492 23 : }
493 :
494 : /** Construct a `std::uint64_t`.
495 :
496 : @par Complexity
497 : Constant.
498 :
499 : @par Exception Safety
500 : No-throw guarantee.
501 :
502 : @param u The initial value.
503 :
504 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
505 : use. The container will acquire shared ownership of the memory
506 : resource.
507 : */
508 3 : value(
509 : unsigned short u,
510 : storage_ptr sp = {}) noexcept
511 3 : : sca_(static_cast<std::uint64_t>(u),
512 3 : std::move(sp))
513 : {
514 3 : }
515 :
516 : /** Construct a `std::uint64_t`.
517 :
518 : @par Complexity
519 : Constant.
520 :
521 : @par Exception Safety
522 : No-throw guarantee.
523 :
524 : @param u The initial value.
525 :
526 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
527 : use. The container will acquire shared ownership of the memory
528 : resource.
529 : */
530 52 : value(
531 : unsigned int u,
532 : storage_ptr sp = {}) noexcept
533 52 : : sca_(static_cast<std::uint64_t>(u),
534 52 : std::move(sp))
535 : {
536 52 : }
537 :
538 : /** Construct a `std::uint64_t`.
539 :
540 : @par Complexity
541 : Constant.
542 :
543 : @par Exception Safety
544 : No-throw guarantee.
545 :
546 : @param u The initial value.
547 :
548 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
549 : use. The container will acquire shared ownership of the memory
550 : resource.
551 : */
552 215 : value(
553 : unsigned long u,
554 : storage_ptr sp = {}) noexcept
555 215 : : sca_(static_cast<std::uint64_t>(u),
556 215 : std::move(sp))
557 : {
558 215 : }
559 :
560 : /** Construct a `std::uint64_t`.
561 :
562 : @par Complexity
563 : Constant.
564 :
565 : @par Exception Safety
566 : No-throw guarantee.
567 :
568 : @param u The initial value.
569 :
570 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
571 : use. The container will acquire shared ownership of the memory
572 : resource.
573 : */
574 2 : value(
575 : unsigned long long u,
576 : storage_ptr sp = {}) noexcept
577 2 : : sca_(static_cast<std::uint64_t>(u),
578 2 : std::move(sp))
579 : {
580 2 : }
581 :
582 : /** Construct a `double`.
583 :
584 : @par Complexity
585 : Constant.
586 :
587 : @par Exception Safety
588 : No-throw guarantee.
589 :
590 : @param d The initial value.
591 :
592 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
593 : use. The container will acquire shared ownership of the memory
594 : resource.
595 : */
596 2039949 : value(
597 : double d,
598 : storage_ptr sp = {}) noexcept
599 2039949 : : sca_(d, std::move(sp))
600 : {
601 2039949 : }
602 :
603 : /** Construct a @ref string.
604 :
605 : The string is constructed with a copy of the
606 : string view `s`, using the specified memory resource.
607 :
608 : @par Complexity
609 : Linear in `s.size()`.
610 :
611 : @par Exception Safety
612 : Strong guarantee.
613 : Calls to `memory_resource::allocate` may throw.
614 :
615 : @param s The string view to construct with.
616 :
617 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
618 : use. The container will acquire shared ownership of the memory
619 : resource.
620 : */
621 17178 : value(
622 : string_view s,
623 : storage_ptr sp = {})
624 17178 : : str_(s, std::move(sp))
625 : {
626 17170 : }
627 :
628 : /** Construct a @ref string.
629 :
630 : The string is constructed with a copy of the
631 : null-terminated string `s`, using the specified
632 : memory resource.
633 :
634 : @par Complexity
635 : Linear in `std::strlen(s)`.
636 :
637 : @par Exception Safety
638 : Strong guarantee.
639 : Calls to `memory_resource::allocate` may throw.
640 :
641 : @param s The null-terminated string to construct
642 : with.
643 :
644 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
645 : use. The container will acquire shared ownership of the memory
646 : resource.
647 : */
648 164 : value(
649 : char const* s,
650 : storage_ptr sp = {})
651 164 : : str_(s, std::move(sp))
652 : {
653 164 : }
654 :
655 : /** Construct a @ref string.
656 :
657 : The value is constructed from `other`, using the
658 : same memory resource. To transfer ownership, use `std::move`:
659 :
660 : @par Example
661 : @code
662 : string str = "The Boost C++ Library Collection";
663 :
664 : // transfer ownership
665 : value jv( std::move(str) );
666 :
667 : assert( str.empty() );
668 : assert( *str.storage() == *jv.storage() );
669 : @endcode
670 :
671 : @par Complexity
672 : Constant.
673 :
674 : @par Exception Safety
675 : No-throw guarantee.
676 :
677 : @param other The string to construct with.
678 : */
679 471 : value(
680 : string other) noexcept
681 471 : : str_(std::move(other))
682 : {
683 471 : }
684 :
685 : /** Construct a @ref string.
686 :
687 : The value is copy constructed from `other`,
688 : using the specified memory resource.
689 :
690 : @par Complexity
691 : Linear in `other.size()`.
692 :
693 : @par Exception Safety
694 : Strong guarantee.
695 : Calls to `memory_resource::allocate` may throw.
696 :
697 : @param other The string to construct with.
698 :
699 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
700 : use. The container will acquire shared ownership of the memory
701 : resource.
702 : */
703 12 : value(
704 : string const& other,
705 : storage_ptr sp)
706 12 : : str_(
707 : other,
708 12 : std::move(sp))
709 : {
710 12 : }
711 :
712 : /** Construct a @ref string.
713 :
714 : The value is move constructed from `other`,
715 : using the specified memory resource.
716 :
717 : @par Complexity
718 : Constant or linear in `other.size()`.
719 :
720 : @par Exception Safety
721 : Strong guarantee.
722 : Calls to `memory_resource::allocate` may throw.
723 :
724 : @param other The string to construct with.
725 :
726 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
727 : use. The container will acquire shared ownership of the memory
728 : resource.
729 : */
730 9 : value(
731 : string&& other,
732 : storage_ptr sp)
733 18 : : str_(
734 9 : std::move(other),
735 9 : std::move(sp))
736 : {
737 9 : }
738 :
739 : /** Construct a @ref string.
740 :
741 : This is the fastest way to construct
742 : an empty string, using the specified
743 : memory resource. The variable @ref string_kind
744 : may be passed as the first parameter
745 : to select this overload:
746 :
747 : @par Example
748 : @code
749 : // Construct an empty string
750 :
751 : value jv( string_kind );
752 : @endcode
753 :
754 : @par Complexity
755 : Constant.
756 :
757 : @par Exception Safety
758 : No-throw guarantee.
759 :
760 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
761 : use. The container will acquire shared ownership of the memory
762 : resource.
763 :
764 : @see @ref string_kind
765 : */
766 8977 : value(
767 : string_kind_t,
768 : storage_ptr sp = {}) noexcept
769 8977 : : str_(std::move(sp))
770 : {
771 8977 : }
772 :
773 : /** Construct an @ref array.
774 :
775 : The value is constructed from `other`, using the
776 : same memory resource. To transfer ownership, use `std::move`:
777 :
778 : @par Example
779 : @code
780 : array arr( {1, 2, 3, 4, 5} );
781 :
782 : // transfer ownership
783 : value jv( std::move(arr) );
784 :
785 : assert( arr.empty() );
786 : assert( *arr.storage() == *jv.storage() );
787 : @endcode
788 :
789 : @par Complexity
790 : Constant.
791 :
792 : @par Exception Safety
793 : No-throw guarantee.
794 :
795 : @param other The array to construct with.
796 : */
797 180 : value(array other) noexcept
798 180 : : arr_(std::move(other))
799 : {
800 180 : }
801 :
802 : /** Construct an @ref array.
803 :
804 : The value is copy constructed from `other`,
805 : using the specified memory resource.
806 :
807 : @par Complexity
808 : Linear in `other.size()`.
809 :
810 : @par Exception Safety
811 : Strong guarantee.
812 : Calls to `memory_resource::allocate` may throw.
813 :
814 : @param other The array to construct with.
815 :
816 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
817 : use. The container will acquire shared ownership of the memory
818 : resource.
819 : */
820 4 : value(
821 : array const& other,
822 : storage_ptr sp)
823 4 : : arr_(
824 : other,
825 4 : std::move(sp))
826 : {
827 4 : }
828 :
829 : /** Construct an @ref array.
830 :
831 : The value is move-constructed from `other`,
832 : using the specified memory resource.
833 :
834 : @par Complexity
835 : Constant or linear in `other.size()`.
836 :
837 : @par Exception Safety
838 : Strong guarantee.
839 : Calls to `memory_resource::allocate` may throw.
840 :
841 : @param other The array to construct with.
842 :
843 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
844 : use. The container will acquire shared ownership of the memory
845 : resource.
846 : */
847 23 : value(
848 : array&& other,
849 : storage_ptr sp)
850 46 : : arr_(
851 23 : std::move(other),
852 23 : std::move(sp))
853 : {
854 23 : }
855 :
856 : /** Construct an @ref array.
857 :
858 : This is the fastest way to construct
859 : an empty array, using the specified
860 : memory resource. The variable @ref array_kind
861 : may be passed as the first parameter
862 : to select this overload:
863 :
864 : @par Example
865 : @code
866 : // Construct an empty array
867 :
868 : value jv( array_kind );
869 : @endcode
870 :
871 : @par Complexity
872 : Constant.
873 :
874 : @par Exception Safety
875 : No-throw guarantee.
876 :
877 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
878 : use. The container will acquire shared ownership of the memory
879 : resource.
880 :
881 : @see @ref array_kind
882 : */
883 17 : value(
884 : array_kind_t,
885 : storage_ptr sp = {}) noexcept
886 17 : : arr_(std::move(sp))
887 : {
888 17 : }
889 :
890 : /** Construct an @ref object.
891 :
892 : The value is constructed from `other`, using the
893 : same memory resource. To transfer ownership, use `std::move`:
894 :
895 : @par Example
896 : @code
897 : object obj( {{"a",1}, {"b",2}, {"c"},3}} );
898 :
899 : // transfer ownership
900 : value jv( std::move(obj) );
901 :
902 : assert( obj.empty() );
903 : assert( *obj.storage() == *jv.storage() );
904 : @endcode
905 :
906 : @par Complexity
907 : Constant.
908 :
909 : @par Exception Safety
910 : No-throw guarantee.
911 :
912 : @param other The object to construct with.
913 : */
914 69 : value(object other) noexcept
915 69 : : obj_(std::move(other))
916 : {
917 69 : }
918 :
919 : /** Construct an @ref object.
920 :
921 : The value is copy constructed from `other`,
922 : using the specified memory resource.
923 :
924 : @par Complexity
925 : Linear in `other.size()`.
926 :
927 : @par Exception Safety
928 : Strong guarantee.
929 : Calls to `memory_resource::allocate` may throw.
930 :
931 : @param other The object to construct with.
932 :
933 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
934 : use. The container will acquire shared ownership of the memory
935 : resource.
936 : */
937 4 : value(
938 : object const& other,
939 : storage_ptr sp)
940 4 : : obj_(
941 : other,
942 4 : std::move(sp))
943 : {
944 4 : }
945 :
946 : /** Construct an @ref object.
947 :
948 : The value is move constructed from `other`,
949 : using the specified memory resource.
950 :
951 : @par Complexity
952 : Constant or linear in `other.size()`.
953 :
954 : @par Exception Safety
955 : Strong guarantee.
956 : Calls to `memory_resource::allocate` may throw.
957 :
958 : @param other The object to construct with.
959 :
960 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
961 : use. The container will acquire shared ownership of the memory
962 : resource.
963 : */
964 57 : value(
965 : object&& other,
966 : storage_ptr sp)
967 114 : : obj_(
968 57 : std::move(other),
969 57 : std::move(sp))
970 : {
971 57 : }
972 :
973 : /** Construct an @ref object.
974 :
975 : This is the fastest way to construct
976 : an empty object, using the specified
977 : memory resource. The variable @ref object_kind
978 : may be passed as the first parameter
979 : to select this overload:
980 :
981 : @par Example
982 : @code
983 : // Construct an empty object
984 :
985 : value jv( object_kind );
986 : @endcode
987 :
988 : @par Complexity
989 : Constant.
990 :
991 : @par Exception Safety
992 : No-throw guarantee.
993 :
994 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
995 : use. The container will acquire shared ownership of the memory
996 : resource.
997 :
998 : @see @ref object_kind
999 : */
1000 18 : value(
1001 : object_kind_t,
1002 : storage_ptr sp = {}) noexcept
1003 18 : : obj_(std::move(sp))
1004 : {
1005 18 : }
1006 :
1007 : /** Construct from an initializer-list
1008 :
1009 : @li If the initializer list consists of key/value
1010 : pairs, an @ref object is created; otherwise,
1011 :
1012 : @li if the size of the initializer list is exactly 1, the object is
1013 : constructed directly from that sole element; otherwise,
1014 :
1015 : @li an @ref array is created.
1016 :
1017 : The contents of the initializer list are copied to the newly
1018 : constructed value using the specified memory resource.
1019 :
1020 : @par Complexity
1021 : Linear in `init.size()`.
1022 :
1023 : @par Exception Safety
1024 : Strong guarantee.
1025 : Calls to `memory_resource::allocate` may throw.
1026 :
1027 : @param init The initializer list to construct from.
1028 :
1029 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
1030 : use. The container will acquire shared ownership of the memory
1031 : resource.
1032 : */
1033 : BOOST_JSON_DECL
1034 : value(
1035 : std::initializer_list<value_ref> init,
1036 : storage_ptr sp = {});
1037 :
1038 : //------------------------------------------------------
1039 : //
1040 : // Assignment
1041 : //
1042 : //------------------------------------------------------
1043 :
1044 : /** Copy assignment.
1045 :
1046 : The contents of the value are replaced with an
1047 : element-wise copy of the contents of `other`.
1048 :
1049 : @par Complexity
1050 : Linear in the size of `*this` plus `other`.
1051 :
1052 : @par Exception Safety
1053 : Strong guarantee.
1054 : Calls to `memory_resource::allocate` may throw.
1055 :
1056 : @param other The value to copy.
1057 : */
1058 : BOOST_JSON_DECL
1059 : value&
1060 : operator=(value const& other);
1061 :
1062 : /** Move assignment.
1063 :
1064 : The contents of the value are replaced with the
1065 : contents of `other` using move semantics:
1066 :
1067 : @li If `*other.storage() == *sp`, ownership of
1068 : the underlying memory is transferred in constant
1069 : time, with no possibility of exceptions.
1070 : After assignment, the moved-from value becomes
1071 : a null with its current storage pointer.
1072 :
1073 : @li If `*other.storage() != *sp`, an
1074 : element-wise copy is performed if
1075 : `other.is_structured() == true`, which may throw.
1076 : In this case, the moved-from value is not
1077 : changed.
1078 :
1079 : @par Complexity
1080 : Constant, or linear in
1081 : `this->size()` plus `other.size()`.
1082 :
1083 : @par Exception Safety
1084 : Strong guarantee.
1085 : Calls to `memory_resource::allocate` may throw.
1086 :
1087 : @param other The value to assign from.
1088 : */
1089 : BOOST_JSON_DECL
1090 : value&
1091 : operator=(value&& other);
1092 :
1093 : /** Assignment.
1094 :
1095 : Replace `*this` with the value formed by
1096 : constructing from `init` and `this->storage()`.
1097 : If the initializer list consists of key/value
1098 : pairs, the resulting @ref object is assigned.
1099 : Otherwise an @ref array is assigned. The contents
1100 : of the initializer list are moved to `*this`
1101 : using the existing memory resource.
1102 :
1103 : @par Complexity
1104 : Linear in `init.size()`.
1105 :
1106 : @par Exception Safety
1107 : Strong guarantee.
1108 : Calls to `memory_resource::allocate` may throw.
1109 :
1110 : @param init The initializer list to assign from.
1111 : */
1112 : BOOST_JSON_DECL
1113 : value&
1114 : operator=(
1115 : std::initializer_list<value_ref> init);
1116 :
1117 : /** Assignment.
1118 :
1119 : Replace `*this` with null.
1120 :
1121 : @par Exception Safety
1122 : No-throw guarantee.
1123 :
1124 : @par Complexity
1125 : Linear in the size of `*this`.
1126 : */
1127 : value&
1128 18 : operator=(std::nullptr_t) noexcept
1129 : {
1130 18 : if(is_scalar())
1131 : {
1132 12 : sca_.k = json::kind::null;
1133 : }
1134 : else
1135 : {
1136 18 : ::new(&sca_) scalar(
1137 6 : destroy());
1138 : }
1139 18 : return *this;
1140 : }
1141 :
1142 : /** Assignment.
1143 :
1144 : Replace `*this` with `b`.
1145 :
1146 : @par Exception Safety
1147 : No-throw guarantee.
1148 :
1149 : @par Complexity
1150 : Linear in the size of `*this`.
1151 :
1152 : @param b The new value.
1153 : */
1154 : #ifdef BOOST_JSON_DOCS
1155 : value& operator=(bool b) noexcept;
1156 : #else
1157 : template<class T
1158 : ,class = typename std::enable_if<
1159 : std::is_same<T, bool>::value>::type
1160 : >
1161 51 : value& operator=(T b) noexcept
1162 : {
1163 51 : if(is_scalar())
1164 : {
1165 50 : sca_.b = b;
1166 50 : sca_.k = json::kind::bool_;
1167 : }
1168 : else
1169 : {
1170 1 : ::new(&sca_) scalar(
1171 : b, destroy());
1172 : }
1173 51 : return *this;
1174 : }
1175 : #endif
1176 :
1177 : /** Assignment.
1178 :
1179 : Replace `*this` with `i`.
1180 :
1181 : @par Exception Safety
1182 : No-throw guarantee.
1183 :
1184 : @par Complexity
1185 : Linear in the size of `*this`.
1186 :
1187 : @param i The new value.
1188 : */
1189 : /** @{ */
1190 2 : value& operator=(signed char i) noexcept
1191 : {
1192 2 : return operator=(
1193 2 : static_cast<long long>(i));
1194 : }
1195 :
1196 8 : value& operator=(short i) noexcept
1197 : {
1198 8 : return operator=(
1199 8 : static_cast<long long>(i));
1200 : }
1201 :
1202 6421 : value& operator=(int i) noexcept
1203 : {
1204 6421 : return operator=(
1205 6421 : static_cast<long long>(i));
1206 : }
1207 :
1208 12 : value& operator=(long i) noexcept
1209 : {
1210 12 : return operator=(
1211 12 : static_cast<long long>(i));
1212 : }
1213 :
1214 6451 : value& operator=(long long i) noexcept
1215 : {
1216 6451 : if(is_scalar())
1217 : {
1218 6448 : sca_.i = i;
1219 6448 : sca_.k = json::kind::int64;
1220 : }
1221 : else
1222 : {
1223 9 : ::new(&sca_) scalar(static_cast<
1224 3 : std::int64_t>(i), destroy());
1225 : }
1226 6451 : return *this;
1227 : }
1228 : /** @} */
1229 :
1230 : /** Assignment.
1231 :
1232 : Replace `*this` with `i`.
1233 :
1234 : @par Exception Safety
1235 : No-throw guarantee.
1236 :
1237 : @par Complexity
1238 : Linear in the size of `*this`.
1239 :
1240 : @param u The new value.
1241 : */
1242 : /** @{ */
1243 6 : value& operator=(unsigned char u) noexcept
1244 : {
1245 6 : return operator=(static_cast<
1246 6 : unsigned long long>(u));
1247 : }
1248 :
1249 8 : value& operator=(unsigned short u) noexcept
1250 : {
1251 8 : return operator=(static_cast<
1252 8 : unsigned long long>(u));
1253 : }
1254 :
1255 8 : value& operator=(unsigned int u) noexcept
1256 : {
1257 8 : return operator=(static_cast<
1258 8 : unsigned long long>(u));
1259 : }
1260 :
1261 17 : value& operator=(unsigned long u) noexcept
1262 : {
1263 17 : return operator=(static_cast<
1264 17 : unsigned long long>(u));
1265 : }
1266 :
1267 47 : value& operator=(unsigned long long u) noexcept
1268 : {
1269 47 : if(is_scalar())
1270 : {
1271 46 : sca_.u = u;
1272 46 : sca_.k = json::kind::uint64;
1273 : }
1274 : else
1275 : {
1276 3 : ::new(&sca_) scalar(static_cast<
1277 1 : std::uint64_t>(u), destroy());
1278 : }
1279 47 : return *this;
1280 : }
1281 : /** @} */
1282 :
1283 : /** Assignment.
1284 :
1285 : Replace `*this` with `d`.
1286 :
1287 : @par Exception Safety
1288 : No-throw guarantee.
1289 :
1290 : @par Complexity
1291 : Linear in the size of `*this`.
1292 :
1293 : @param d The new value.
1294 : */
1295 32 : value& operator=(double d) noexcept
1296 : {
1297 32 : if(is_scalar())
1298 : {
1299 25 : sca_.d = d;
1300 25 : sca_.k = json::kind::double_;
1301 : }
1302 : else
1303 : {
1304 21 : ::new(&sca_) scalar(
1305 7 : d, destroy());
1306 : }
1307 32 : return *this;
1308 : }
1309 :
1310 : /** Assignment.
1311 :
1312 : Replace `*this` with a copy of the string `s`.
1313 :
1314 : @par Exception Safety
1315 : Strong guarantee.
1316 : Calls to `memory_resource::allocate` may throw.
1317 :
1318 : @par Complexity
1319 : Linear in the sum of sizes of `*this` and `s`
1320 :
1321 : @param s The new string.
1322 : */
1323 : /** @{ */
1324 : BOOST_JSON_DECL value& operator=(string_view s);
1325 : BOOST_JSON_DECL value& operator=(char const* s);
1326 : BOOST_JSON_DECL value& operator=(string const& s);
1327 : /** @} */
1328 :
1329 : /** Assignment.
1330 :
1331 : The contents of the value are replaced with the
1332 : contents of `s` using move semantics:
1333 :
1334 : @li If `*other.storage() == *this->storage()`,
1335 : ownership of the underlying memory is transferred
1336 : in constant time, with no possibility of exceptions.
1337 : After assignment, the moved-from string becomes
1338 : empty with its current storage pointer.
1339 :
1340 : @li If `*other.storage() != *this->storage()`, an
1341 : element-wise copy is performed, which may throw.
1342 : In this case, the moved-from string is not
1343 : changed.
1344 :
1345 : @par Complexity
1346 : Constant, or linear in the size of `*this` plus `s.size()`.
1347 :
1348 : @par Exception Safety
1349 : Strong guarantee.
1350 : Calls to `memory_resource::allocate` may throw.
1351 :
1352 : @param s The string to move-assign from.
1353 : */
1354 : BOOST_JSON_DECL value& operator=(string&& s);
1355 :
1356 : /** Assignment.
1357 :
1358 : Replace `*this` with a copy of the array `arr`.
1359 :
1360 : @par Exception Safety
1361 : Strong guarantee.
1362 : Calls to `memory_resource::allocate` may throw.
1363 :
1364 : @par Complexity
1365 : Linear in the sum of sizes of `*this` and `arr`
1366 :
1367 : @param arr The new array.
1368 : */
1369 : BOOST_JSON_DECL value& operator=(array const& arr);
1370 :
1371 : /** Assignment.
1372 :
1373 : The contents of the value are replaced with the
1374 : contents of `arr` using move semantics:
1375 :
1376 : @li If `*arr.storage() == *this->storage()`,
1377 : ownership of the underlying memory is transferred
1378 : in constant time, with no possibility of exceptions.
1379 : After assignment, the moved-from array becomes
1380 : empty with its current storage pointer.
1381 :
1382 : @li If `*arr.storage() != *this->storage()`, an
1383 : element-wise copy is performed, which may throw.
1384 : In this case, the moved-from array is not
1385 : changed.
1386 :
1387 : @par Complexity
1388 : Constant, or linear in the size of `*this` plus `arr.size()`.
1389 :
1390 : @par Exception Safety
1391 : Strong guarantee.
1392 : Calls to `memory_resource::allocate` may throw.
1393 :
1394 : @param arr The array to move-assign from.
1395 : */
1396 : BOOST_JSON_DECL value& operator=(array&& arr);
1397 :
1398 : /** Assignment.
1399 :
1400 : Replace `*this` with a copy of the obect `obj`.
1401 :
1402 : @par Exception Safety
1403 : Strong guarantee.
1404 : Calls to `memory_resource::allocate` may throw.
1405 :
1406 : @par Complexity
1407 : Linear in the sum of sizes of `*this` and `obj`
1408 :
1409 : @param obj The new object.
1410 : */
1411 : BOOST_JSON_DECL value& operator=(object const& obj);
1412 :
1413 : /** Assignment.
1414 :
1415 : The contents of the value are replaced with the
1416 : contents of `obj` using move semantics:
1417 :
1418 : @li If `*obj.storage() == *this->storage()`,
1419 : ownership of the underlying memory is transferred
1420 : in constant time, with no possibility of exceptions.
1421 : After assignment, the moved-from object becomes
1422 : empty with its current storage pointer.
1423 :
1424 : @li If `*obj.storage() != *this->storage()`, an
1425 : element-wise copy is performed, which may throw.
1426 : In this case, the moved-from object is not
1427 : changed.
1428 :
1429 : @par Complexity
1430 : Constant, or linear in the size of `*this` plus `obj.size()`.
1431 :
1432 : @par Exception Safety
1433 : Strong guarantee.
1434 : Calls to `memory_resource::allocate` may throw.
1435 :
1436 : @param obj The object to move-assign from.
1437 : */
1438 : BOOST_JSON_DECL value& operator=(object&& obj);
1439 :
1440 : //------------------------------------------------------
1441 : //
1442 : // Modifiers
1443 : //
1444 : //------------------------------------------------------
1445 :
1446 : /** Change the kind to null, discarding the previous contents.
1447 :
1448 : The value is replaced with a null,
1449 : destroying the previous contents.
1450 :
1451 : @par Complexity
1452 : Linear in the size of `*this`.
1453 :
1454 : @par Exception Safety
1455 : No-throw guarantee.
1456 : */
1457 : void
1458 8 : emplace_null() noexcept
1459 : {
1460 8 : *this = nullptr;
1461 8 : }
1462 :
1463 : /** Return a reference to a `bool`, changing the kind and replacing the contents.
1464 :
1465 : The value is replaced with a `bool`
1466 : initialized to `false`, destroying the
1467 : previous contents.
1468 :
1469 : @par Complexity
1470 : Linear in the size of `*this`.
1471 :
1472 : @par Exception Safety
1473 : No-throw guarantee.
1474 : */
1475 : bool&
1476 1 : emplace_bool() noexcept
1477 : {
1478 1 : *this = false;
1479 1 : return sca_.b;
1480 : }
1481 :
1482 : /** Return a reference to a `std::int64_t`, changing the kind and replacing the contents.
1483 :
1484 : The value is replaced with a `std::int64_t`
1485 : initialized to zero, destroying the
1486 : previous contents.
1487 :
1488 : @par Complexity
1489 : Linear in the size of `*this`.
1490 :
1491 : @par Exception Safety
1492 : No-throw guarantee.
1493 : */
1494 : std::int64_t&
1495 2 : emplace_int64() noexcept
1496 : {
1497 2 : *this = std::int64_t{};
1498 2 : return sca_.i;
1499 : }
1500 :
1501 : /** Return a reference to a `std::uint64_t`, changing the kind and replacing the contents.
1502 :
1503 : The value is replaced with a `std::uint64_t`
1504 : initialized to zero, destroying the
1505 : previous contents.
1506 :
1507 : @par Complexity
1508 : Linear in the size of `*this`.
1509 :
1510 : @par Exception Safety
1511 : No-throw guarantee.
1512 : */
1513 : std::uint64_t&
1514 1 : emplace_uint64() noexcept
1515 : {
1516 1 : *this = std::uint64_t{};
1517 1 : return sca_.u;
1518 : }
1519 :
1520 : /** Return a reference to a `double`, changing the kind and replacing the contents.
1521 :
1522 : The value is replaced with a `double`
1523 : initialized to zero, destroying the
1524 : previous contents.
1525 :
1526 : @par Complexity
1527 : Linear in the size of `*this`.
1528 :
1529 : @par Exception Safety
1530 : No-throw guarantee.
1531 : */
1532 : double&
1533 1 : emplace_double() noexcept
1534 : {
1535 1 : *this = double{};
1536 1 : return sca_.d;
1537 : }
1538 :
1539 : /** Return a reference to a @ref string, changing the kind and replacing the contents.
1540 :
1541 : The value is replaced with an empty @ref string
1542 : using the current memory resource, destroying the
1543 : previous contents.
1544 :
1545 : @par Complexity
1546 : Linear in the size of `*this`.
1547 :
1548 : @par Exception Safety
1549 : No-throw guarantee.
1550 : */
1551 : BOOST_JSON_DECL
1552 : string&
1553 : emplace_string() noexcept;
1554 :
1555 : /** Return a reference to an @ref array, changing the kind and replacing the contents.
1556 :
1557 : The value is replaced with an empty @ref array
1558 : using the current memory resource, destroying the
1559 : previous contents.
1560 :
1561 : @par Complexity
1562 : Linear in the size of `*this`.
1563 :
1564 : @par Exception Safety
1565 : No-throw guarantee.
1566 : */
1567 : BOOST_JSON_DECL
1568 : array&
1569 : emplace_array() noexcept;
1570 :
1571 : /** Return a reference to an @ref object, changing the kind and replacing the contents.
1572 :
1573 : The contents are replaced with an empty @ref object using the current
1574 : `boost::container::pmr::memory_resource`. All previously obtained
1575 : iterators and references obtained beforehand are invalidated.
1576 :
1577 : @par Complexity
1578 : Linear in the size of `*this`.
1579 :
1580 : @par Exception Safety
1581 : No-throw guarantee.
1582 : */
1583 : BOOST_JSON_DECL
1584 : object&
1585 : emplace_object() noexcept;
1586 :
1587 : /** Swap the given values.
1588 :
1589 : Exchanges the contents of this value with another value. Ownership of
1590 : the respective `boost::container::pmr::memory_resource` objects is not
1591 : transferred:
1592 :
1593 : @li If `*other.storage() == *this->storage()`,
1594 : ownership of the underlying memory is swapped in
1595 : constant time, with no possibility of exceptions.
1596 : All iterators and references remain valid.
1597 :
1598 : @li If `*other.storage() != *this->storage()`,
1599 : the contents are logically swapped by making copies,
1600 : which can throw. In this case all iterators and
1601 : references are invalidated.
1602 :
1603 : @par Complexity
1604 : Constant or linear in the sum of the sizes of
1605 : the values.
1606 :
1607 : @par Exception Safety
1608 : Strong guarantee.
1609 : Calls to `memory_resource::allocate` may throw.
1610 :
1611 : @param other The value to swap with.
1612 : If `this == &other`, this function call has no effect.
1613 : */
1614 : BOOST_JSON_DECL
1615 : void
1616 : swap(value& other);
1617 :
1618 : /** Swap the given values.
1619 :
1620 : Exchanges the contents of value `lhs` with another value `rhs`.
1621 : Ownership of the respective `boost::container::pmr::memory_resource`
1622 : objects is not transferred.
1623 :
1624 : @li If `*lhs.storage() == *rhs.storage()`,
1625 : ownership of the underlying memory is swapped in
1626 : constant time, with no possibility of exceptions.
1627 : All iterators and references remain valid.
1628 :
1629 : @li If `*lhs.storage() != *rhs.storage`,
1630 : the contents are logically swapped by a copy,
1631 : which can throw. In this case all iterators and
1632 : references are invalidated.
1633 :
1634 : @par Effects
1635 : @code
1636 : lhs.swap( rhs );
1637 : @endcode
1638 :
1639 : @par Complexity
1640 : Constant or linear in the sum of the sizes of
1641 : the values.
1642 :
1643 : @par Exception Safety
1644 : Strong guarantee.
1645 : Calls to `memory_resource::allocate` may throw.
1646 :
1647 : @param lhs The value to exchange.
1648 :
1649 : @param rhs The value to exchange.
1650 : If `&lhs == &rhs`, this function call has no effect.
1651 :
1652 : @see @ref value::swap
1653 : */
1654 : friend
1655 : void
1656 3 : swap(value& lhs, value& rhs)
1657 : {
1658 3 : lhs.swap(rhs);
1659 3 : }
1660 :
1661 : //------------------------------------------------------
1662 : //
1663 : // Observers
1664 : //
1665 : //------------------------------------------------------
1666 :
1667 : /** Returns the kind of this JSON value.
1668 :
1669 : This function returns the discriminating
1670 : enumeration constant of type @ref json::kind
1671 : corresponding to the underlying representation
1672 : stored in the container.
1673 :
1674 : @par Complexity
1675 : Constant.
1676 :
1677 : @par Exception Safety
1678 : No-throw guarantee.
1679 : */
1680 : json::kind
1681 4610508 : kind() const noexcept
1682 : {
1683 : return static_cast<json::kind>(
1684 : static_cast<unsigned char>(
1685 4610508 : sca_.k) & 0x3f);
1686 : }
1687 :
1688 : /** Return `true` if this is an array
1689 :
1690 : This function is used to determine if the underlying
1691 : representation is a certain kind.
1692 :
1693 : @par Effects
1694 : @code
1695 : return this->kind() == kind::array;
1696 : @endcode
1697 :
1698 : @par Complexity
1699 : Constant.
1700 :
1701 : @par Exception Safety
1702 : No-throw guarantee.
1703 : */
1704 : bool
1705 6039 : is_array() const noexcept
1706 : {
1707 6039 : return kind() == json::kind::array;
1708 : }
1709 :
1710 : /** Return `true` if this is an object
1711 :
1712 : This function is used to determine if the underlying
1713 : representation is a certain kind.
1714 :
1715 : @par Effects
1716 : @code
1717 : return this->kind() == kind::object;
1718 : @endcode
1719 :
1720 : @par Complexity
1721 : Constant.
1722 :
1723 : @par Exception Safety
1724 : No-throw guarantee.
1725 : */
1726 : bool
1727 53267 : is_object() const noexcept
1728 : {
1729 53267 : return kind() == json::kind::object;
1730 : }
1731 :
1732 : /** Return `true` if this is a string
1733 :
1734 : This function is used to determine if the underlying
1735 : representation is a certain kind.
1736 :
1737 : @par Effects
1738 : @code
1739 : return this->kind() == kind::string;
1740 : @endcode
1741 :
1742 : @par Complexity
1743 : Constant.
1744 :
1745 : @par Exception Safety
1746 : No-throw guarantee.
1747 : */
1748 : bool
1749 88387 : is_string() const noexcept
1750 : {
1751 88387 : return kind() == json::kind::string;
1752 : }
1753 :
1754 : /** Return `true` if this is a signed integer
1755 :
1756 : This function is used to determine if the underlying
1757 : representation is a certain kind.
1758 :
1759 : @par Effects
1760 : @code
1761 : return this->kind() == kind::int64;
1762 : @endcode
1763 :
1764 : @par Complexity
1765 : Constant.
1766 :
1767 : @par Exception Safety
1768 : No-throw guarantee.
1769 : */
1770 : bool
1771 14887 : is_int64() const noexcept
1772 : {
1773 14887 : return kind() == json::kind::int64;
1774 : }
1775 :
1776 : /** Return `true` if this is a unsigned integer
1777 :
1778 : This function is used to determine if the underlying
1779 : representation is a certain kind.
1780 :
1781 : @par Effects
1782 : @code
1783 : return this->kind() == kind::uint64;
1784 : @endcode
1785 :
1786 : @par Complexity
1787 : Constant.
1788 :
1789 : @par Exception Safety
1790 : No-throw guarantee.
1791 : */
1792 : bool
1793 340 : is_uint64() const noexcept
1794 : {
1795 340 : return kind() == json::kind::uint64;
1796 : }
1797 :
1798 : /** Return `true` if this is a double
1799 :
1800 : This function is used to determine if the underlying
1801 : representation is a certain kind.
1802 :
1803 : @par Effects
1804 : @code
1805 : return this->kind() == kind::double_;
1806 : @endcode
1807 :
1808 : @par Complexity
1809 : Constant.
1810 :
1811 : @par Exception Safety
1812 : No-throw guarantee.
1813 : */
1814 : bool
1815 2078681 : is_double() const noexcept
1816 : {
1817 2078681 : return kind() == json::kind::double_;
1818 : }
1819 :
1820 : /** Return `true` if this is a bool
1821 :
1822 : This function is used to determine if the underlying
1823 : representation is a certain kind.
1824 :
1825 : @par Effects
1826 : @code
1827 : return this->kind() == kind::bool_;
1828 : @endcode
1829 :
1830 : @par Complexity
1831 : Constant.
1832 :
1833 : @par Exception Safety
1834 : No-throw guarantee.
1835 : */
1836 : bool
1837 952 : is_bool() const noexcept
1838 : {
1839 952 : return kind() == json::kind::bool_;
1840 : }
1841 :
1842 : /** Returns true if this is a null.
1843 :
1844 : This function is used to determine if the underlying
1845 : representation is a certain kind.
1846 :
1847 : @par Effects
1848 : @code
1849 : return this->kind() == kind::null;
1850 : @endcode
1851 :
1852 : @par Complexity
1853 : Constant.
1854 :
1855 : @par Exception Safety
1856 : No-throw guarantee.
1857 : */
1858 : bool
1859 148 : is_null() const noexcept
1860 : {
1861 148 : return kind() == json::kind::null;
1862 : }
1863 :
1864 : /** Returns true if this is an array or object.
1865 :
1866 : This function returns `true` if
1867 : @ref kind() is either `kind::object` or
1868 : `kind::array`.
1869 :
1870 : @par Complexity
1871 : Constant.
1872 :
1873 : @par Exception Safety
1874 : No-throw guarantee.
1875 : */
1876 : bool
1877 8 : is_structured() const noexcept
1878 : {
1879 : // VFALCO Could use bit 0x20 for this
1880 : return
1881 15 : kind() == json::kind::object ||
1882 15 : kind() == json::kind::array;
1883 : }
1884 :
1885 : /** Returns true if this is not an array or object.
1886 :
1887 : This function returns `true` if
1888 : @ref kind() is neither `kind::object` nor
1889 : `kind::array`.
1890 :
1891 : @par Complexity
1892 : Constant.
1893 :
1894 : @par Exception Safety
1895 : No-throw guarantee.
1896 : */
1897 : bool
1898 8 : is_primitive() const noexcept
1899 : {
1900 : // VFALCO Could use bit 0x20 for this
1901 : return
1902 15 : sca_.k != json::kind::object &&
1903 15 : sca_.k != json::kind::array;
1904 : }
1905 :
1906 : /** Returns true if this is a number.
1907 :
1908 : This function returns `true` when
1909 : @ref kind() is one of the following values:
1910 : `kind::int64`, `kind::uint64`, or
1911 : `kind::double_`.
1912 :
1913 : @par Complexity
1914 : Constant.
1915 :
1916 : @par Exception Safety
1917 : No-throw guarantee.
1918 : */
1919 : bool
1920 83 : is_number() const noexcept
1921 : {
1922 : // VFALCO Could use bit 0x40 for this
1923 : return
1924 92 : kind() == json::kind::int64 ||
1925 92 : kind() == json::kind::uint64 ||
1926 91 : kind() == json::kind::double_;
1927 : }
1928 :
1929 : //------------------------------------------------------
1930 :
1931 : /** Return an @ref array pointer if this is an array, else return `nullptr`
1932 :
1933 : If `this->kind() == kind::array`, returns a pointer
1934 : to the underlying array. Otherwise, returns `nullptr`.
1935 :
1936 : @par Example
1937 : The return value is used in both a boolean context and
1938 : to assign a variable:
1939 : @code
1940 : if( auto p = jv.if_array() )
1941 : return *p;
1942 : @endcode
1943 :
1944 : @par Complexity
1945 : Constant.
1946 :
1947 : @par Exception Safety
1948 : No-throw guarantee.
1949 : */
1950 : array const*
1951 268 : if_array() const noexcept
1952 : {
1953 268 : if(kind() == json::kind::array)
1954 231 : return &arr_;
1955 37 : return nullptr;
1956 : }
1957 :
1958 : /** Return an @ref array pointer if this is an array, else return `nullptr`
1959 :
1960 : If `this->kind() == kind::array`, returns a pointer
1961 : to the underlying array. Otherwise, returns `nullptr`.
1962 :
1963 : @par Example
1964 : The return value is used in both a boolean context and
1965 : to assign a variable:
1966 : @code
1967 : if( auto p = jv.if_array() )
1968 : return *p;
1969 : @endcode
1970 :
1971 : @par Complexity
1972 : Constant.
1973 :
1974 : @par Exception Safety
1975 : No-throw guarantee.
1976 : */
1977 : array*
1978 9 : if_array() noexcept
1979 : {
1980 9 : if(kind() == json::kind::array)
1981 2 : return &arr_;
1982 7 : return nullptr;
1983 : }
1984 :
1985 : /** Return an @ref object pointer if this is an object, else return `nullptr`
1986 :
1987 : If `this->kind() == kind::object`, returns a pointer
1988 : to the underlying object. Otherwise, returns `nullptr`.
1989 :
1990 : @par Example
1991 : The return value is used in both a boolean context and
1992 : to assign a variable:
1993 : @code
1994 : if( auto p = jv.if_object() )
1995 : return *p;
1996 : @endcode
1997 :
1998 : @par Complexity
1999 : Constant.
2000 :
2001 : @par Exception Safety
2002 : No-throw guarantee.
2003 : */
2004 : object const*
2005 104 : if_object() const noexcept
2006 : {
2007 104 : if(kind() == json::kind::object)
2008 79 : return &obj_;
2009 25 : return nullptr;
2010 : }
2011 :
2012 : /** Return an @ref object pointer if this is an object, else return `nullptr`
2013 :
2014 : If `this->kind() == kind::object`, returns a pointer
2015 : to the underlying object. Otherwise, returns `nullptr`.
2016 :
2017 : @par Example
2018 : The return value is used in both a boolean context and
2019 : to assign a variable:
2020 : @code
2021 : if( auto p = jv.if_object() )
2022 : return *p;
2023 : @endcode
2024 :
2025 : @par Complexity
2026 : Constant.
2027 :
2028 : @par Exception Safety
2029 : No-throw guarantee.
2030 : */
2031 : object*
2032 10 : if_object() noexcept
2033 : {
2034 10 : if(kind() == json::kind::object)
2035 3 : return &obj_;
2036 7 : return nullptr;
2037 : }
2038 :
2039 : /** Return a @ref string pointer if this is a string, else return `nullptr`
2040 :
2041 : If `this->kind() == kind::string`, returns a pointer
2042 : to the underlying object. Otherwise, returns `nullptr`.
2043 :
2044 : @par Example
2045 : The return value is used in both a boolean context and
2046 : to assign a variable:
2047 : @code
2048 : if( auto p = jv.if_string() )
2049 : return *p;
2050 : @endcode
2051 :
2052 : @par Complexity
2053 : Constant.
2054 :
2055 : @par Exception Safety
2056 : No-throw guarantee.
2057 : */
2058 : string const*
2059 318 : if_string() const noexcept
2060 : {
2061 318 : if(kind() == json::kind::string)
2062 250 : return &str_;
2063 68 : return nullptr;
2064 : }
2065 :
2066 : /** Return a @ref string pointer if this is a string, else return `nullptr`
2067 :
2068 : If `this->kind() == kind::string`, returns a pointer
2069 : to the underlying object. Otherwise, returns `nullptr`.
2070 :
2071 : @par Example
2072 : The return value is used in both a boolean context and
2073 : to assign a variable:
2074 : @code
2075 : if( auto p = jv.if_string() )
2076 : return *p;
2077 : @endcode
2078 :
2079 : @par Complexity
2080 : Constant.
2081 :
2082 : @par Exception Safety
2083 : No-throw guarantee.
2084 : */
2085 : string*
2086 10 : if_string() noexcept
2087 : {
2088 10 : if(kind() == json::kind::string)
2089 3 : return &str_;
2090 7 : return nullptr;
2091 : }
2092 :
2093 : /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
2094 :
2095 : If `this->kind() == kind::int64`, returns a pointer
2096 : to the underlying integer. Otherwise, returns `nullptr`.
2097 :
2098 : @par Example
2099 : The return value is used in both a boolean context and
2100 : to assign a variable:
2101 : @code
2102 : if( auto p = jv.if_int64() )
2103 : return *p;
2104 : @endcode
2105 :
2106 : @par Complexity
2107 : Constant.
2108 :
2109 : @par Exception Safety
2110 : No-throw guarantee.
2111 : */
2112 : std::int64_t const*
2113 8 : if_int64() const noexcept
2114 : {
2115 8 : if(kind() == json::kind::int64)
2116 1 : return &sca_.i;
2117 7 : return nullptr;
2118 : }
2119 :
2120 : /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
2121 :
2122 : If `this->kind() == kind::int64`, returns a pointer
2123 : to the underlying integer. Otherwise, returns `nullptr`.
2124 :
2125 : @par Example
2126 : The return value is used in both a boolean context and
2127 : to assign a variable:
2128 : @code
2129 : if( auto p = jv.if_int64() )
2130 : return *p;
2131 : @endcode
2132 :
2133 : @par Complexity
2134 : Constant.
2135 :
2136 : @par Exception Safety
2137 : No-throw guarantee.
2138 : */
2139 : std::int64_t*
2140 10 : if_int64() noexcept
2141 : {
2142 10 : if(kind() == json::kind::int64)
2143 3 : return &sca_.i;
2144 7 : return nullptr;
2145 : }
2146 :
2147 : /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
2148 :
2149 : If `this->kind() == kind::uint64`, returns a pointer
2150 : to the underlying unsigned integer. Otherwise, returns
2151 : `nullptr`.
2152 :
2153 : @par Example
2154 : The return value is used in both a boolean context and
2155 : to assign a variable:
2156 : @code
2157 : if( auto p = jv.if_uint64() )
2158 : return *p;
2159 : @endcode
2160 :
2161 : @par Complexity
2162 : Constant.
2163 :
2164 : @par Exception Safety
2165 : No-throw guarantee.
2166 : */
2167 : std::uint64_t const*
2168 8 : if_uint64() const noexcept
2169 : {
2170 8 : if(kind() == json::kind::uint64)
2171 1 : return &sca_.u;
2172 7 : return nullptr;
2173 : }
2174 :
2175 : /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
2176 :
2177 : If `this->kind() == kind::uint64`, returns a pointer
2178 : to the underlying unsigned integer. Otherwise, returns
2179 : `nullptr`.
2180 :
2181 : @par Example
2182 : The return value is used in both a boolean context and
2183 : to assign a variable:
2184 : @code
2185 : if( auto p = jv.if_uint64() )
2186 : return *p;
2187 : @endcode
2188 :
2189 : @par Complexity
2190 : Constant.
2191 :
2192 : @par Exception Safety
2193 : No-throw guarantee.
2194 : */
2195 : std::uint64_t*
2196 8 : if_uint64() noexcept
2197 : {
2198 8 : if(kind() == json::kind::uint64)
2199 1 : return &sca_.u;
2200 7 : return nullptr;
2201 : }
2202 :
2203 : /** Return a `double` pointer if this is a double, else return `nullptr`
2204 :
2205 : If `this->kind() == kind::double_`, returns a pointer
2206 : to the underlying double. Otherwise, returns
2207 : `nullptr`.
2208 :
2209 : @par Example
2210 : The return value is used in both a boolean context and
2211 : to assign a variable:
2212 : @code
2213 : if( auto p = jv.if_double() )
2214 : return *p;
2215 : @endcode
2216 :
2217 : @par Complexity
2218 : Constant.
2219 :
2220 : @par Exception Safety
2221 : No-throw guarantee.
2222 : */
2223 : double const*
2224 8 : if_double() const noexcept
2225 : {
2226 8 : if(kind() == json::kind::double_)
2227 1 : return &sca_.d;
2228 7 : return nullptr;
2229 : }
2230 :
2231 : /** Return a `double` pointer if this is a double, else return `nullptr`
2232 :
2233 : If `this->kind() == kind::double_`, returns a pointer
2234 : to the underlying double. Otherwise, returns
2235 : `nullptr`.
2236 :
2237 : @par Example
2238 : The return value is used in both a boolean context and
2239 : to assign a variable:
2240 : @code
2241 : if( auto p = jv.if_double() )
2242 : return *p;
2243 : @endcode
2244 :
2245 : @par Complexity
2246 : Constant.
2247 :
2248 : @par Exception Safety
2249 : No-throw guarantee.
2250 : */
2251 : double*
2252 8 : if_double() noexcept
2253 : {
2254 8 : if(kind() == json::kind::double_)
2255 1 : return &sca_.d;
2256 7 : return nullptr;
2257 : }
2258 :
2259 : /** Return a `bool` pointer if this is a boolean, else return `nullptr`
2260 :
2261 : If `this->kind() == kind::bool_`, returns a pointer
2262 : to the underlying boolean. Otherwise, returns
2263 : `nullptr`.
2264 :
2265 : @par Example
2266 : The return value is used in both a boolean context and
2267 : to assign a variable:
2268 : @code
2269 : if( auto p = jv.if_bool() )
2270 : return *p;
2271 : @endcode
2272 :
2273 : @par Complexity
2274 : Constant.
2275 :
2276 : @par Exception Safety
2277 : No-throw guarantee.
2278 : */
2279 : bool const*
2280 57 : if_bool() const noexcept
2281 : {
2282 57 : if(kind() == json::kind::bool_)
2283 43 : return &sca_.b;
2284 14 : return nullptr;
2285 : }
2286 :
2287 : /** Return a `bool` pointer if this is a boolean, else return `nullptr`
2288 :
2289 : If `this->kind() == kind::bool_`, returns a pointer
2290 : to the underlying boolean. Otherwise, returns
2291 : `nullptr`.
2292 :
2293 : @par Example
2294 : The return value is used in both a boolean context and
2295 : to assign a variable:
2296 : @code
2297 : if( auto p = jv.if_bool() )
2298 : return *p;
2299 : @endcode
2300 :
2301 : @par Complexity
2302 : Constant.
2303 :
2304 : @par Exception Safety
2305 : No-throw guarantee.
2306 : */
2307 : bool*
2308 8 : if_bool() noexcept
2309 : {
2310 8 : if(kind() == json::kind::bool_)
2311 1 : return &sca_.b;
2312 7 : return nullptr;
2313 : }
2314 :
2315 : //------------------------------------------------------
2316 :
2317 : /** Return the stored number cast to an arithmetic type.
2318 :
2319 : This function attempts to return the stored value
2320 : converted to the arithmetic type `T` which may not
2321 : be `bool`:
2322 :
2323 : @li If `T` is an integral type and the stored
2324 : value is a number which can be losslessly converted,
2325 : the conversion is performed without error and the
2326 : converted number is returned.
2327 :
2328 : @li If `T` is an integral type and the stored value
2329 : is a number which cannot be losslessly converted,
2330 : then the operation fails with an error.
2331 :
2332 : @li If `T` is a floating point type and the stored
2333 : value is a number, the conversion is performed
2334 : without error. The converted number is returned,
2335 : with a possible loss of precision.
2336 :
2337 : @li Otherwise, if the stored value is not a number;
2338 : that is, if `this->is_number()` returns `false`, then
2339 : the operation fails with an error.
2340 :
2341 : @par Constraints
2342 : @code
2343 : std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
2344 : @endcode
2345 :
2346 : @par Complexity
2347 : Constant.
2348 :
2349 : @par Exception Safety
2350 : No-throw guarantee.
2351 :
2352 : @return The converted number.
2353 :
2354 : @param ec Set to the error, if any occurred.
2355 : */
2356 : /** @{ */
2357 : template<class T>
2358 : #ifdef BOOST_JSON_DOCS
2359 : T
2360 : #else
2361 : typename std::enable_if<
2362 : std::is_arithmetic<T>::value &&
2363 : ! std::is_same<T, bool>::value,
2364 : T>::type
2365 : #endif
2366 3613 : to_number(system::error_code& ec) const noexcept
2367 : {
2368 : error e;
2369 3613 : auto result = to_number<T>(e);
2370 3613 : BOOST_JSON_FAIL(ec, e);
2371 3613 : return result;
2372 : }
2373 :
2374 : template<class T>
2375 : #ifdef BOOST_JSON_DOCS
2376 : T
2377 : #else
2378 : typename std::enable_if<
2379 : std::is_arithmetic<T>::value &&
2380 : ! std::is_same<T, bool>::value,
2381 : T>::type
2382 : #endif
2383 1 : to_number(std::error_code& ec) const noexcept
2384 : {
2385 1 : system::error_code jec;
2386 1 : auto result = to_number<T>(jec);
2387 1 : ec = jec;
2388 1 : return result;
2389 : }
2390 : /** @} */
2391 :
2392 : /** Return the stored number as `boost::system::result<T>`.
2393 :
2394 : This function attempts to return the stored value converted to the
2395 : arithmetic type `T` which may not be `bool`:
2396 :
2397 : @li If `T` is an integral type and the stored value is a number which
2398 : can be losslessly converted, the conversion is performed without
2399 : error and `result<T>` containing the converted number is returned.
2400 :
2401 : @li If `T` is an integral type and the stored value is a number which
2402 : cannot be losslessly converted, then `result<T>` containing the
2403 : corresponding `error_code` is returned.
2404 :
2405 : @li If `T` is a floating point type and the stored value is a number,
2406 : the conversion is performed without error. `result<T>` containing
2407 : the converted number, with a possible loss of precision, is
2408 : returned.
2409 :
2410 : @li Otherwise, if the stored value is not a number; that is, if
2411 : `this->is_number()` returns `false`, then `result<T>` containing
2412 : the corresponding `error_code` is returned.
2413 :
2414 : @par Constraints
2415 : @code
2416 : std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
2417 : @endcode
2418 :
2419 : @par Complexity
2420 : Constant.
2421 :
2422 : @par Exception Safety
2423 : No-throw guarantee.
2424 :
2425 : @return `boost::system::result<T>` with either the converted number or
2426 : an `error_code`.
2427 : */
2428 : template<class T>
2429 : #ifdef BOOST_JSON_DOCS
2430 : system::result<T>
2431 : #else
2432 : typename std::enable_if<
2433 : std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
2434 : system::result<T>
2435 : >::type
2436 : #endif
2437 196 : try_to_number() const noexcept
2438 : {
2439 196 : system::error_code ec;
2440 196 : T result = to_number<T>(ec);
2441 196 : if( ec )
2442 78 : return {system::in_place_error, ec};
2443 :
2444 118 : return {system::in_place_value, result};
2445 : }
2446 :
2447 : /** Return the stored number cast to an arithmetic type.
2448 :
2449 : This function attempts to return the stored value
2450 : converted to the arithmetic type `T` which may not
2451 : be `bool`:
2452 :
2453 : @li If `T` is an integral type and the stored
2454 : value is a number which can be losslessly converted,
2455 : the conversion is performed without error and the
2456 : converted number is returned.
2457 :
2458 : @li If `T` is an integral type and the stored value
2459 : is a number which cannot be losslessly converted,
2460 : then the operation fails with an error.
2461 :
2462 : @li If `T` is a floating point type and the stored
2463 : value is a number, the conversion is performed
2464 : without error. The converted number is returned,
2465 : with a possible loss of precision.
2466 :
2467 : @li Otherwise, if the stored value is not a number;
2468 : that is, if `this->is_number()` returns `false`, then
2469 : the operation fails with an error.
2470 :
2471 : @par Constraints
2472 : @code
2473 : std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
2474 : @endcode
2475 :
2476 : @par Complexity
2477 : Constant.
2478 :
2479 : @return The converted number.
2480 :
2481 : @throw `boost::system::system_error` Thrown on error.
2482 : */
2483 : template<class T>
2484 : #ifdef BOOST_JSON_DOCS
2485 : T
2486 : #else
2487 : typename std::enable_if<
2488 : std::is_arithmetic<T>::value &&
2489 : ! std::is_same<T, bool>::value,
2490 : T>::type
2491 : #endif
2492 194 : to_number() const
2493 : {
2494 194 : return try_to_number<T>().value();
2495 : }
2496 :
2497 : //------------------------------------------------------
2498 : //
2499 : // Accessors
2500 : //
2501 : //------------------------------------------------------
2502 :
2503 : /** Return the associated memory resource.
2504 :
2505 : This function returns the `boost::container::pmr::memory_resource` used
2506 : by the container.
2507 :
2508 : @par Complexity
2509 : Constant.
2510 :
2511 : @par Exception Safety
2512 : No-throw guarantee.
2513 : */
2514 : storage_ptr const&
2515 75587 : storage() const noexcept
2516 : {
2517 75587 : return sp_;
2518 : }
2519 :
2520 : /** Return the associated allocator.
2521 :
2522 : This function returns an instance of @ref allocator_type constructed
2523 : from the associated `boost::container::pmr::memory_resource`.
2524 :
2525 : @par Complexity
2526 : Constant.
2527 :
2528 : @par Exception Safety
2529 : No-throw guarantee.
2530 : */
2531 : allocator_type
2532 1 : get_allocator() const noexcept
2533 : {
2534 1 : return sp_.get();
2535 : }
2536 :
2537 : //------------------------------------------------------
2538 :
2539 : /** Return `result` with a reference to the underlying @ref array
2540 :
2541 : If @ref is_array() is `true`, the result contains a reference to the
2542 : underlying @ref array, otherwise it contains an `error_code`.
2543 :
2544 : @par Example
2545 : The return value can be used in both a boolean context and
2546 : to assign a variable:
2547 : @code
2548 : if( auto r = jv.try_as_array() )
2549 : return *r;
2550 : @endcode
2551 :
2552 : But can also be used to throw an exception on error:
2553 : @code
2554 : return jv.try_as_array().value();
2555 : @endcode
2556 :
2557 : @par Complexity
2558 : Constant.
2559 :
2560 : @par Exception Safety
2561 : No-throw guarantee.
2562 : */
2563 : /** @{ */
2564 : BOOST_JSON_DECL
2565 : system::result<array&>
2566 : try_as_array() noexcept;
2567 :
2568 : BOOST_JSON_DECL
2569 : system::result<array const&>
2570 : try_as_array() const noexcept;
2571 : /** @} */
2572 :
2573 : /** Return `result` with a reference to the underlying @ref object
2574 :
2575 : If @ref is_object() is `true`, the result contains a reference to the
2576 : underlying @ref object, otherwise it contains an `error_code`.
2577 :
2578 : @par Example
2579 : The return value can be used in both a boolean context and
2580 : to assign a variable:
2581 : @code
2582 : if( auto r = jv.try_as_object() )
2583 : return *r;
2584 : @endcode
2585 :
2586 : But can also be used to throw an exception on error:
2587 : @code
2588 : return jv.try_as_object().value();
2589 : @endcode
2590 :
2591 : @par Complexity
2592 : Constant.
2593 :
2594 : @par Exception Safety
2595 : No-throw guarantee.
2596 : */
2597 : /** @{ */
2598 : BOOST_JSON_DECL
2599 : system::result<object&>
2600 : try_as_object() noexcept;
2601 :
2602 : BOOST_JSON_DECL
2603 : system::result<object const&>
2604 : try_as_object() const noexcept;
2605 : /** @} */
2606 :
2607 : /** Return `result` with a reference to the underlying @ref string
2608 :
2609 : If @ref is_string() is `true`, the result contains a reference to the
2610 : underlying @ref string, otherwise it contains an `error_code`.
2611 :
2612 : @par Example
2613 : The return value can be used in both a boolean context and
2614 : to assign a variable:
2615 : @code
2616 : if( auto r = jv.try_as_string() )
2617 : return *r;
2618 : @endcode
2619 :
2620 : But can also be used to throw an exception on error:
2621 : @code
2622 : return jv.try_as_string().value();
2623 : @endcode
2624 :
2625 : @par Complexity
2626 : Constant.
2627 :
2628 : @par Exception Safety
2629 : No-throw guarantee.
2630 : */
2631 : /** @{ */
2632 : BOOST_JSON_DECL
2633 : system::result<string&>
2634 : try_as_string() noexcept;
2635 :
2636 : BOOST_JSON_DECL
2637 : system::result<string const&>
2638 : try_as_string() const noexcept;
2639 : /** @} */
2640 :
2641 : /** Return `result` with a reference to the underlying `std::int64_t`
2642 :
2643 : If @ref is_int64() is `true`, the result contains a reference to the
2644 : underlying `std::int64_t`, otherwise it contains an `error_code`.
2645 :
2646 : @par Example
2647 : The return value can be used in both a boolean context and
2648 : to assign a variable:
2649 : @code
2650 : if( auto r = jv.try_as_int64() )
2651 : return *r;
2652 : @endcode
2653 :
2654 : But can also be used to throw an exception on error:
2655 : @code
2656 : return jv.try_as_int64().value();
2657 : @endcode
2658 :
2659 : @par Complexity
2660 : Constant.
2661 :
2662 : @par Exception Safety
2663 : No-throw guarantee.
2664 : */
2665 : BOOST_JSON_DECL
2666 : system::result<std::int64_t&>
2667 : try_as_int64() noexcept;
2668 :
2669 : /** Return `result` with the underlying `std::int64_t`
2670 :
2671 : If @ref is_int64() is `true`, the result contains a copy of the
2672 : underlying `std::int64_t`, otherwise it contains an `error_code`.
2673 :
2674 : @par Example
2675 : The return value can be used in both a boolean context and
2676 : to assign a variable:
2677 : @code
2678 : if( auto r = jv.try_as_int64() )
2679 : return *r;
2680 : @endcode
2681 :
2682 : But can also be used to throw an exception on error:
2683 : @code
2684 : return jv.try_as_int64().value();
2685 : @endcode
2686 :
2687 : @par Complexity
2688 : Constant.
2689 :
2690 : @par Exception Safety
2691 : No-throw guarantee.
2692 : */
2693 : BOOST_JSON_DECL
2694 : system::result<std::int64_t>
2695 : try_as_int64() const noexcept;
2696 :
2697 : /** Return `result` with a reference to the underlying `std::uint64_t`
2698 :
2699 : If @ref is_uint64() is `true`, the result contains a reference to the
2700 : underlying `std::uint64_t`, otherwise it contains an `error_code`.
2701 :
2702 : @par Example
2703 : The return value can be used in both a boolean context and
2704 : to assign a variable:
2705 : @code
2706 : if( auto r = jv.try_as_uint64() )
2707 : return *r;
2708 : @endcode
2709 :
2710 : But can also be used to throw an exception on error:
2711 : @code
2712 : return jv.try_as_uint64().value();
2713 : @endcode
2714 :
2715 : @par Complexity
2716 : Constant.
2717 :
2718 : @par Exception Safety
2719 : No-throw guarantee.
2720 : */
2721 : BOOST_JSON_DECL
2722 : system::result<std::uint64_t&>
2723 : try_as_uint64() noexcept;
2724 :
2725 : /** Return `result` with the underlying `std::uint64_t`
2726 :
2727 : If @ref is_uint64() is `true`, the result contains a copy of the
2728 : underlying `std::uint64_t`, otherwise it contains an `error_code`.
2729 :
2730 : @par Example
2731 : The return value can be used in both a boolean context and
2732 : to assign a variable:
2733 : @code
2734 : if( auto r = jv.try_as_uint64() )
2735 : return *r;
2736 : @endcode
2737 :
2738 : But can also be used to throw an exception on error:
2739 : @code
2740 : return jv.try_as_uint64().value();
2741 : @endcode
2742 :
2743 : @par Complexity
2744 : Constant.
2745 :
2746 : @par Exception Safety
2747 : No-throw guarantee.
2748 : */
2749 : BOOST_JSON_DECL
2750 : system::result<std::uint64_t>
2751 : try_as_uint64() const noexcept;
2752 :
2753 : /** Return `result` with a reference to the underlying `double`
2754 :
2755 : If @ref is_double() is `true`, the result contains a reference to the
2756 : underlying `double`, otherwise it contains an `error_code`.
2757 :
2758 : @par Example
2759 : The return value can be used in both a boolean context and
2760 : to assign a variable:
2761 : @code
2762 : if( auto r = jv.try_as_double() )
2763 : return *r;
2764 : @endcode
2765 :
2766 : But can also be used to throw an exception on error:
2767 : @code
2768 : return jv.try_as_double().value();
2769 : @endcode
2770 :
2771 : @par Complexity
2772 : Constant.
2773 :
2774 : @par Exception Safety
2775 : No-throw guarantee.
2776 : */
2777 : BOOST_JSON_DECL
2778 : system::result<double&>
2779 : try_as_double() noexcept;
2780 :
2781 : /** Return `result` with the underlying `double`
2782 :
2783 : If @ref is_double() is `true`, the result contains a copy of the
2784 : underlying `double`, otherwise it contains an `error_code`.
2785 :
2786 : @par Example
2787 : The return value can be used in both a boolean context and
2788 : to assign a variable:
2789 : @code
2790 : if( auto r = jv.try_as_double() )
2791 : return *r;
2792 : @endcode
2793 :
2794 : But can also be used to throw an exception on error:
2795 : @code
2796 : return jv.try_as_double().value();
2797 : @endcode
2798 :
2799 : @par Complexity
2800 : Constant.
2801 :
2802 : @par Exception Safety
2803 : No-throw guarantee.
2804 : */
2805 : BOOST_JSON_DECL
2806 : system::result<double>
2807 : try_as_double() const noexcept;
2808 :
2809 : /** Return `result` with a reference to the underlying `bool`
2810 :
2811 : If @ref is_bool() is `true`, the result contains a reference to the
2812 : underlying `bool`, otherwise it contains an `error_code`.
2813 :
2814 : @par Example
2815 : The return value can be used in both a boolean context and
2816 : to assign a variable:
2817 : @code
2818 : if( auto r = jv.try_as_bool() )
2819 : return *r;
2820 : @endcode
2821 :
2822 : But can also be used to throw an exception on error:
2823 : @code
2824 : return jv.try_as_bool().value();
2825 : @endcode
2826 :
2827 : @par Complexity
2828 : Constant.
2829 :
2830 : @par Exception Safety
2831 : No-throw guarantee.
2832 : */
2833 : BOOST_JSON_DECL
2834 : system::result<bool&>
2835 : try_as_bool() noexcept;
2836 :
2837 : /** Return `result` with the underlying `bool`
2838 :
2839 : If @ref is_bool() is `true`, the result contains a copy of the
2840 : underlying `bool`, otherwise it contains an `error_code`.
2841 :
2842 : @par Example
2843 : The return value can be used in both a boolean context and
2844 : to assign a variable:
2845 : @code
2846 : if( auto r = jv.try_as_bool() )
2847 : return *r;
2848 : @endcode
2849 :
2850 : But can also be used to throw an exception on error:
2851 : @code
2852 : return jv.try_as_bool().value();
2853 : @endcode
2854 :
2855 : @par Complexity
2856 : Constant.
2857 :
2858 : @par Exception Safety
2859 : No-throw guarantee.
2860 : */
2861 : BOOST_JSON_DECL
2862 : system::result<bool>
2863 : try_as_bool() const noexcept;
2864 :
2865 : /** Return engaged `result` if the `value` is null
2866 :
2867 : If @ref is_null() is `true`, the result is engaged, otherwise it
2868 : contains an `error_code`.
2869 :
2870 : @par Example
2871 : The return value can be used in both a boolean context and
2872 : to assign a variable:
2873 : @code
2874 : if( auto r = jv.try_as_null() )
2875 : return *r;
2876 : @endcode
2877 :
2878 : But can also be used to throw an exception on error:
2879 : @code
2880 : return jv.try_as_null().value();
2881 : @endcode
2882 :
2883 : @par Complexity
2884 : Constant.
2885 :
2886 : @par Exception Safety
2887 : No-throw guarantee.
2888 : */
2889 : BOOST_JSON_DECL
2890 : system::result<std::nullptr_t>
2891 : try_as_null() const noexcept;
2892 :
2893 : //------------------------------------------------------
2894 :
2895 : /** Return a reference to the underlying `object`, or throw an exception.
2896 :
2897 : If @ref is_object() is `true`, returns
2898 : a reference to the underlying @ref object,
2899 : otherwise throws an exception.
2900 :
2901 : @par Exception Safety
2902 : Strong guarantee.
2903 :
2904 : @throw `boost::system::system_error` `! this->is_object()`.
2905 :
2906 : @param loc `source_location` to use in thrown exception; the source
2907 : location of the call site by default.
2908 :
2909 : @par Complexity
2910 : Constant.
2911 : */
2912 : /** @{ */
2913 : object&
2914 165 : as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
2915 : {
2916 165 : auto& self = const_cast<value const&>(*this);
2917 165 : return const_cast<object&>( self.as_object(loc) );
2918 : }
2919 :
2920 : object&&
2921 97 : as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2922 : {
2923 97 : return std::move( as_object(loc) );
2924 : }
2925 :
2926 : BOOST_JSON_DECL
2927 : object const&
2928 : as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2929 : /** @} */
2930 :
2931 : /** Return a reference to the underlying @ref array, or throw an exception.
2932 :
2933 : If @ref is_array() is `true`, returns
2934 : a reference to the underlying @ref array,
2935 : otherwise throws an exception.
2936 :
2937 : @par Exception Safety
2938 : Strong guarantee.
2939 :
2940 : @throw `boost::system::system_error` `! this->is_array()`.
2941 :
2942 : @param loc `source_location` to use in thrown exception; the source
2943 : location of the call site by default.
2944 :
2945 : @par Complexity
2946 : Constant.
2947 : */
2948 : /** @{ */
2949 : array&
2950 92 : as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
2951 : {
2952 92 : auto& self = const_cast<value const&>(*this);
2953 92 : return const_cast<array&>( self.as_array(loc) );
2954 : }
2955 :
2956 : array&&
2957 10 : as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2958 : {
2959 10 : return std::move( as_array(loc) );
2960 : }
2961 :
2962 : BOOST_JSON_DECL
2963 : array const&
2964 : as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2965 : /** @} */
2966 :
2967 : /** Return a reference to the underlying `string`, or throw an exception.
2968 :
2969 : If @ref is_string() is `true`, returns
2970 : a reference to the underlying @ref string,
2971 : otherwise throws an exception.
2972 :
2973 : @par Exception Safety
2974 : Strong guarantee.
2975 :
2976 : @throw `boost::system::system_error` `! this->is_string()`.
2977 :
2978 : @param loc `source_location` to use in thrown exception; the source
2979 : location of the call site by default.
2980 :
2981 : @par Complexity
2982 : Constant.
2983 : */
2984 : string&
2985 34 : as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
2986 : {
2987 34 : auto& self = const_cast<value const&>(*this);
2988 34 : return const_cast<string&>( self.as_string(loc) );
2989 : }
2990 :
2991 : /** Return a reference to the underlying `string`, or throw an exception.
2992 :
2993 : If @ref is_string() is `true`, returns
2994 : a reference to the underlying @ref string,
2995 : otherwise throws an exception.
2996 :
2997 : @par Exception Safety
2998 : Strong guarantee.
2999 :
3000 : @throw `boost::system::system_error` `! this->is_string()`.
3001 :
3002 : @param loc `source_location` to use in thrown exception; the source
3003 : location of the call site by default.
3004 :
3005 : @par Complexity
3006 : Constant.
3007 : */
3008 : /** @{ */
3009 : string&&
3010 12 : as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
3011 : {
3012 12 : return std::move( as_string(loc) );
3013 : }
3014 :
3015 : BOOST_JSON_DECL
3016 : string const&
3017 : as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
3018 :
3019 : BOOST_JSON_DECL
3020 : std::int64_t&
3021 : as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
3022 : /** @} */
3023 :
3024 : /** Return the underlying `std::int64_t`, or throw an exception.
3025 :
3026 : If @ref is_int64() is `true`, returns
3027 : the underlying `std::int64_t`,
3028 : otherwise throws an exception.
3029 :
3030 : @par Exception Safety
3031 : Strong guarantee.
3032 :
3033 : @throw `boost::system::system_error` `! this->is_int64()`.
3034 :
3035 : @param loc `source_location` to use in thrown exception; the source
3036 : location of the call site by default.
3037 :
3038 : @par Complexity
3039 : Constant.
3040 :
3041 : @par Note
3042 : This function is the const-qualified overload of @ref as_int64, which
3043 : is intended for direct access to the underlying object, __if__ it has
3044 : the type `std::int64_t`. It does not convert the underlying object to
3045 : type `std::int64_t` even if a lossless conversion is possible. If you
3046 : are not sure which kind your `value` has, and you only care about
3047 : getting a `std::int64_t` number, consider using @ref to_number instead.
3048 : */
3049 : BOOST_JSON_DECL
3050 : std::int64_t
3051 : as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
3052 :
3053 : /** Return a reference to the underlying `std::uint64_t`, or throw an exception.
3054 :
3055 : If @ref is_uint64() is `true`, returns
3056 : a reference to the underlying `std::uint64_t`,
3057 : otherwise throws an exception.
3058 :
3059 : @par Exception Safety
3060 : Strong guarantee.
3061 :
3062 : @throw `boost::system::system_error` `! this->is_uint64()`.
3063 :
3064 : @param loc `source_location` to use in thrown exception; the source
3065 : location of the call site by default.
3066 :
3067 : @par Complexity
3068 : Constant.
3069 :
3070 : @par Note
3071 : This function is intended for direct access to the underlying object,
3072 : __if__ it has the type `std::uint64_t`. It does not convert the
3073 : underlying object to type `std::uint64_t` even if a lossless conversion
3074 : is possible. If you are not sure which kind your `value` has, and you
3075 : only care about getting a `std::uint64_t` number, consider using
3076 : @ref to_number instead.
3077 : */
3078 : BOOST_JSON_DECL
3079 : std::uint64_t&
3080 : as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
3081 :
3082 : /** Return the underlying `std::uint64_t`, or throw an exception.
3083 :
3084 : If @ref is_uint64() is `true`, returns
3085 : the underlying `std::uint64_t`,
3086 : otherwise throws an exception.
3087 :
3088 : @par Exception Safety
3089 : Strong guarantee.
3090 :
3091 : @throw `boost::system::system_error` `! this->is_uint64()`.
3092 :
3093 : @param loc `source_location` to use in thrown exception; the source
3094 : location of the call site by default.
3095 :
3096 : @par Complexity
3097 : Constant.
3098 :
3099 : @par Note
3100 : This function is the const-qualified overload of @ref as_uint64, which
3101 : is intended for direct access to the underlying object, __if__ it has
3102 : the type `std::uint64_t`. It does not convert the underlying object to
3103 : type `std::uint64_t` even if a lossless conversion is possible. If you
3104 : are not sure which kind your `value` has, and you only care about
3105 : getting a `std::uint64_t` number, consider using
3106 : @ref to_number instead.
3107 : */
3108 : BOOST_JSON_DECL
3109 : std::uint64_t
3110 : as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
3111 :
3112 : /** Return a reference to the underlying `double`, or throw an exception.
3113 :
3114 : If @ref is_double() is `true`, returns
3115 : a reference to the underlying `double`,
3116 : otherwise throws an exception.
3117 :
3118 : @par Exception Safety
3119 : Strong guarantee.
3120 :
3121 : @throw `boost::system::system_error` `! this->is_double()`.
3122 :
3123 : @param loc `source_location` to use in thrown exception; the source
3124 : location of the call site by default.
3125 :
3126 : @par Complexity
3127 : Constant.
3128 :
3129 : @par Note
3130 : This function is intended for direct access to the underlying object,
3131 : __if__ it has the type `double`. It does not convert the underlying
3132 : object to type `double` even if a lossless conversion is possible. If
3133 : you are not sure which kind your `value` has, and you only care about
3134 : getting a `double` number, consider using @ref to_number instead.
3135 : */
3136 : BOOST_JSON_DECL
3137 : double&
3138 : as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
3139 :
3140 : /** Return the underlying `double`, or throw an exception.
3141 :
3142 : If @ref is_double() is `true`, returns
3143 : the underlying `double`,
3144 : otherwise throws an exception.
3145 :
3146 : @par Exception Safety
3147 : Strong guarantee.
3148 :
3149 : @throw `boost::system::system_error` `! this->is_double()`.
3150 :
3151 : @param loc `source_location` to use in thrown exception; the source
3152 : location of the call site by default.
3153 :
3154 : @par Complexity
3155 : Constant.
3156 :
3157 : @par Note
3158 : This function is the const-qualified overload of @ref as_double, which
3159 : is intended for direct access to the underlying object, __if__ it has
3160 : the type `double`. It does not convert the underlying object to type
3161 : `double` even if a lossless conversion is possible. If you are not sure
3162 : which kind your `value` has, and you only care about getting a `double`
3163 : number, consider using @ref to_number instead.
3164 : */
3165 : BOOST_JSON_DECL
3166 : double
3167 : as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
3168 :
3169 : /** Return a reference to the underlying `bool`, or throw an exception.
3170 :
3171 : If @ref is_bool() is `true`, returns
3172 : a reference to the underlying `bool`,
3173 : otherwise throws an exception.
3174 :
3175 : @par Exception Safety
3176 : Strong guarantee.
3177 :
3178 : @throw `boost::system::system_error` `! this->is_bool()`.
3179 :
3180 : @param loc `source_location` to use in thrown exception; the source
3181 : location of the call site by default.
3182 :
3183 : @par Complexity
3184 : Constant.
3185 : */
3186 : BOOST_JSON_DECL
3187 : bool&
3188 : as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
3189 :
3190 : /** Return the underlying `bool`, or throw an exception.
3191 :
3192 : If @ref is_bool() is `true`, returns
3193 : the underlying `bool`,
3194 : otherwise throws an exception.
3195 :
3196 : @par Exception Safety
3197 : Strong guarantee.
3198 :
3199 : @throw `boost::system::system_error` `! this->is_bool()`.
3200 :
3201 : @param loc `source_location` to use in thrown exception; the source
3202 : location of the call site by default.
3203 :
3204 : @par Complexity
3205 : Constant.
3206 : */
3207 : BOOST_JSON_DECL
3208 : bool
3209 : as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
3210 :
3211 : //------------------------------------------------------
3212 :
3213 : /** Return a reference to the underlying `object`, without checking.
3214 :
3215 : This is the fastest way to access the underlying
3216 : representation when the kind is known in advance.
3217 :
3218 : @par Preconditions
3219 :
3220 : @code
3221 : this->is_object()
3222 : @endcode
3223 :
3224 : @par Complexity
3225 : Constant.
3226 :
3227 : @par Exception Safety
3228 : No-throw guarantee.
3229 : */
3230 : /** @{ */
3231 : object&
3232 38 : get_object() & noexcept
3233 : {
3234 38 : BOOST_ASSERT(is_object());
3235 38 : return obj_;
3236 : }
3237 :
3238 : object&&
3239 1 : get_object() && noexcept
3240 : {
3241 1 : BOOST_ASSERT(is_object());
3242 1 : return std::move(obj_);
3243 : }
3244 :
3245 : object const&
3246 52948 : get_object() const& noexcept
3247 : {
3248 52948 : BOOST_ASSERT(is_object());
3249 52948 : return obj_;
3250 : }
3251 : /** @} */
3252 :
3253 : /** Return a reference to the underlying `array`, without checking.
3254 :
3255 : This is the fastest way to access the underlying
3256 : representation when the kind is known in advance.
3257 :
3258 : @par Preconditions
3259 :
3260 : @code
3261 : this->is_array()
3262 : @endcode
3263 :
3264 : @par Complexity
3265 : Constant.
3266 :
3267 : @par Exception Safety
3268 : No-throw guarantee.
3269 : */
3270 : /** @{ */
3271 : array&
3272 25 : get_array() & noexcept
3273 : {
3274 25 : BOOST_ASSERT(is_array());
3275 25 : return arr_;
3276 : }
3277 :
3278 : array&&
3279 1 : get_array() && noexcept
3280 : {
3281 1 : BOOST_ASSERT(is_array());
3282 1 : return std::move(arr_);
3283 : }
3284 :
3285 : array const&
3286 5725 : get_array() const& noexcept
3287 : {
3288 5725 : BOOST_ASSERT(is_array());
3289 5725 : return arr_;
3290 : }
3291 : /** @} */
3292 :
3293 : /** Return a reference to the underlying `string`, without checking.
3294 :
3295 : This is the fastest way to access the underlying
3296 : representation when the kind is known in advance.
3297 :
3298 : @par Preconditions
3299 :
3300 : @code
3301 : this->is_string()
3302 : @endcode
3303 :
3304 : @par Complexity
3305 : Constant.
3306 :
3307 : @par Exception Safety
3308 : No-throw guarantee.
3309 : */
3310 : /** @{ */
3311 : string&
3312 8971 : get_string() & noexcept
3313 : {
3314 8971 : BOOST_ASSERT(is_string());
3315 8971 : return str_;
3316 : }
3317 :
3318 : string&&
3319 1 : get_string() && noexcept
3320 : {
3321 1 : BOOST_ASSERT(is_string());
3322 1 : return std::move(str_);
3323 : }
3324 :
3325 : string const&
3326 41039 : get_string() const& noexcept
3327 : {
3328 41039 : BOOST_ASSERT(is_string());
3329 41039 : return str_;
3330 : }
3331 : /** @} */
3332 :
3333 : /** Return a reference to the underlying `std::int64_t`, without checking.
3334 :
3335 : This is the fastest way to access the underlying
3336 : representation when the kind is known in advance.
3337 :
3338 : @par Preconditions
3339 :
3340 : @code
3341 : this->is_int64()
3342 : @endcode
3343 :
3344 : @par Complexity
3345 : Constant.
3346 :
3347 : @par Exception Safety
3348 : No-throw guarantee.
3349 : */
3350 : std::int64_t&
3351 4 : get_int64() noexcept
3352 : {
3353 4 : BOOST_ASSERT(is_int64());
3354 4 : return sca_.i;
3355 : }
3356 :
3357 : /** Return the underlying `std::int64_t`, without checking.
3358 :
3359 : This is the fastest way to access the underlying
3360 : representation when the kind is known in advance.
3361 :
3362 : @par Preconditions
3363 :
3364 : @code
3365 : this->is_int64()
3366 : @endcode
3367 :
3368 : @par Complexity
3369 : Constant.
3370 :
3371 : @par Exception Safety
3372 : No-throw guarantee.
3373 : */
3374 : std::int64_t
3375 14299 : get_int64() const noexcept
3376 : {
3377 14299 : BOOST_ASSERT(is_int64());
3378 14299 : return sca_.i;
3379 : }
3380 :
3381 : /** Return a reference to the underlying `std::uint64_t`, without checking.
3382 :
3383 : This is the fastest way to access the underlying
3384 : representation when the kind is known in advance.
3385 :
3386 : @par Preconditions
3387 :
3388 : @code
3389 : this->is_uint64()
3390 : @endcode
3391 :
3392 : @par Complexity
3393 : Constant.
3394 :
3395 : @par Exception Safety
3396 : No-throw guarantee.
3397 : */
3398 : std::uint64_t&
3399 4 : get_uint64() noexcept
3400 : {
3401 4 : BOOST_ASSERT(is_uint64());
3402 4 : return sca_.u;
3403 : }
3404 :
3405 : /** Return the underlying `std::uint64_t`, without checking.
3406 :
3407 : This is the fastest way to access the underlying
3408 : representation when the kind is known in advance.
3409 :
3410 : @par Preconditions
3411 :
3412 : @code
3413 : this->is_uint64()
3414 : @endcode
3415 :
3416 : @par Complexity
3417 : Constant.
3418 :
3419 : @par Exception Safety
3420 : No-throw guarantee.
3421 : */
3422 : std::uint64_t
3423 212 : get_uint64() const noexcept
3424 : {
3425 212 : BOOST_ASSERT(is_uint64());
3426 212 : return sca_.u;
3427 : }
3428 :
3429 : /** Return a reference to the underlying `double`, without checking.
3430 :
3431 : This is the fastest way to access the underlying
3432 : representation when the kind is known in advance.
3433 :
3434 : @par Preconditions
3435 :
3436 : @code
3437 : this->is_double()
3438 : @endcode
3439 :
3440 : @par Complexity
3441 : Constant.
3442 :
3443 : @par Exception Safety
3444 : No-throw guarantee.
3445 : */
3446 : double&
3447 4 : get_double() noexcept
3448 : {
3449 4 : BOOST_ASSERT(is_double());
3450 4 : return sca_.d;
3451 : }
3452 :
3453 : /** Return the underlying `double`, without checking.
3454 :
3455 : This is the fastest way to access the underlying
3456 : representation when the kind is known in advance.
3457 :
3458 : @par Preconditions
3459 :
3460 : @code
3461 : this->is_double()
3462 : @endcode
3463 :
3464 : @par Complexity
3465 : Constant.
3466 :
3467 : @par Exception Safety
3468 : No-throw guarantee.
3469 : */
3470 : double
3471 39178 : get_double() const noexcept
3472 : {
3473 39178 : BOOST_ASSERT(is_double());
3474 39178 : return sca_.d;
3475 : }
3476 :
3477 : /** Return a reference to the underlying `bool`, without checking.
3478 :
3479 : This is the fastest way to access the underlying
3480 : representation when the kind is known in advance.
3481 :
3482 : @par Preconditions
3483 :
3484 : @code
3485 : this->is_bool()
3486 : @endcode
3487 :
3488 : @par Complexity
3489 : Constant.
3490 :
3491 : @par Exception Safety
3492 : No-throw guarantee.
3493 : */
3494 : bool&
3495 4 : get_bool() noexcept
3496 : {
3497 4 : BOOST_ASSERT(is_bool());
3498 4 : return sca_.b;
3499 : }
3500 :
3501 : /** Return the underlying `bool`, without checking.
3502 :
3503 : This is the fastest way to access the underlying
3504 : representation when the kind is known in advance.
3505 :
3506 : @par Preconditions
3507 :
3508 : @code
3509 : this->is_bool()
3510 : @endcode
3511 :
3512 : @par Complexity
3513 : Constant.
3514 :
3515 : @par Exception Safety
3516 : No-throw guarantee.
3517 : */
3518 : bool
3519 804 : get_bool() const noexcept
3520 : {
3521 804 : BOOST_ASSERT(is_bool());
3522 804 : return sca_.b;
3523 : }
3524 :
3525 : //------------------------------------------------------
3526 :
3527 : /** Access an element, with bounds checking.
3528 :
3529 : Returns `boost::system::result` containing a reference to the element
3530 : of the underlying object, if `pos` is within its range. If `pos` is
3531 : outside of that range, or the underlying value is not an object the
3532 : result contains an `error_code`.
3533 :
3534 : @par Exception Safety
3535 : No-throw guarantee.
3536 :
3537 : @param key The key of the element to find.
3538 :
3539 : @par Complexity
3540 : Constant.
3541 : */
3542 : /** @{ */
3543 : BOOST_JSON_DECL
3544 : boost::system::result<value&>
3545 : try_at(string_view key) noexcept;
3546 :
3547 : BOOST_JSON_DECL
3548 : boost::system::result<value const&>
3549 : try_at(string_view key) const noexcept;
3550 : /** @} */
3551 :
3552 : /** Access an element, with bounds checking.
3553 :
3554 : This function is used to access elements of
3555 : the underlying object, or throw an exception
3556 : if the value is not an object.
3557 :
3558 : @par Complexity
3559 : Constant.
3560 :
3561 : @par Exception Safety
3562 : Strong guarantee.
3563 :
3564 : @param key The key of the element to find.
3565 :
3566 : @param loc `source_location` to use in thrown exception; the source
3567 : location of the call site by default.
3568 :
3569 : @return `this->as_object(loc).at( key, loc )`.
3570 : */
3571 : /** @{ */
3572 : value&
3573 12 : at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
3574 : {
3575 12 : return as_object(loc).at(key, loc);
3576 : }
3577 :
3578 : value&&
3579 1 : at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
3580 : {
3581 1 : return std::move( as_object(loc) ).at(key, loc);
3582 : }
3583 :
3584 : value const&
3585 18 : at(
3586 : string_view key,
3587 : source_location const& loc = BOOST_CURRENT_LOCATION) const&
3588 : {
3589 18 : return as_object(loc).at(key, loc);
3590 : }
3591 : /** @} */
3592 :
3593 : /** Access an element, with bounds checking.
3594 :
3595 : Returns `boost::system::result` containing a reference to the element
3596 : of the underlying array, if `pos` is within its range. If `pos` is
3597 : outside of that range, or the underlying value is not an array the
3598 : result contains an `error_code`.
3599 :
3600 : @par Exception Safety
3601 : No-throw guarantee.
3602 :
3603 : @param pos A zero-based array index.
3604 :
3605 : @par Complexity
3606 : Constant.
3607 : */
3608 : /** @{ */
3609 : BOOST_JSON_DECL
3610 : boost::system::result<value&>
3611 : try_at(std::size_t pos) noexcept;
3612 :
3613 : BOOST_JSON_DECL
3614 : boost::system::result<value const&>
3615 : try_at(std::size_t pos) const noexcept;
3616 : /** @} */
3617 :
3618 : /** Access an element, with bounds checking.
3619 :
3620 : This function is used to access elements of
3621 : the underlying array, or throw an exception
3622 : if the value is not an array.
3623 :
3624 : @par Complexity
3625 : Constant.
3626 :
3627 : @par Exception Safety
3628 : Strong guarantee.
3629 :
3630 : @param pos A zero-based array index.
3631 :
3632 : @param loc `source_location` to use in thrown exception; the source
3633 : location of the call site by default.
3634 :
3635 : @return `this->as_array(loc).at( pos, loc )`.
3636 : */
3637 : /** @{ */
3638 : value &
3639 12 : at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
3640 : {
3641 12 : return as_array(loc).at(pos, loc);
3642 : }
3643 :
3644 : value&&
3645 10 : at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
3646 : {
3647 10 : return std::move( as_array(loc) ).at(pos, loc);
3648 : }
3649 :
3650 : value const&
3651 56 : at(
3652 : std::size_t pos,
3653 : source_location const& loc = BOOST_CURRENT_LOCATION) const&
3654 : {
3655 56 : return as_array(loc).at(pos, loc);
3656 : }
3657 : /** @} */
3658 :
3659 : /** Access an element via JSON Pointer.
3660 :
3661 : This function is used to access a (potentially nested) element of the
3662 : value using a JSON Pointer string.
3663 :
3664 : @par Complexity
3665 : Linear in the sizes of `ptr` and underlying array, object, or string.
3666 :
3667 : @par Exception Safety
3668 : No-throw guarantee.
3669 :
3670 : @param ptr JSON Pointer string.
3671 :
3672 : @return `boost::system::result<value&>` containing either a reference
3673 : to the element identified by `ptr` or a corresponding `error_code`.
3674 :
3675 : @see
3676 : [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
3677 : */
3678 : BOOST_JSON_DECL
3679 : system::result<value const&>
3680 : try_at_pointer(string_view ptr) const noexcept;
3681 :
3682 : /** Access an element via JSON Pointer.
3683 :
3684 : This function is used to access a (potentially nested) element of the
3685 : value using a JSON Pointer string.
3686 :
3687 : @par Complexity
3688 : Linear in the sizes of `ptr` and underlying array, object, or string.
3689 :
3690 : @par Exception Safety
3691 : No-throw guarantee.
3692 :
3693 : @param ptr JSON Pointer string.
3694 :
3695 : @return `boost::system::result<value const&>` containing either a
3696 : reference to the element identified by `ptr` or a corresponding
3697 : `error_code`.
3698 :
3699 : @see
3700 : [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
3701 : */
3702 : BOOST_JSON_DECL
3703 : system::result<value&>
3704 : try_at_pointer(string_view ptr) noexcept;
3705 :
3706 : /** Access an element via JSON Pointer.
3707 :
3708 : This function is used to access a (potentially nested)
3709 : element of the value using a JSON Pointer string.
3710 :
3711 : @par Complexity
3712 : Linear in the sizes of `ptr` and underlying array, object, or string.
3713 :
3714 : @par Exception Safety
3715 : Strong guarantee.
3716 :
3717 : @param ptr JSON Pointer string.
3718 :
3719 : @param loc `source_location` to use in thrown exception; the source
3720 : location of the call site by default.
3721 :
3722 : @return reference to the element identified by `ptr`.
3723 :
3724 : @throw `boost::system::system_error` if an error occurs.
3725 :
3726 : @see
3727 : <a href="https://datatracker.ietf.org/doc/html/rfc6901">
3728 : RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>
3729 : */
3730 : /** @{ */
3731 : BOOST_JSON_DECL
3732 : value const&
3733 : at_pointer(
3734 : string_view ptr,
3735 : source_location const& loc = BOOST_CURRENT_LOCATION) const&;
3736 :
3737 : inline
3738 : value&&
3739 : at_pointer(
3740 : string_view ptr,
3741 : source_location const& loc = BOOST_CURRENT_LOCATION) &&;
3742 :
3743 : inline
3744 : value&
3745 : at_pointer(
3746 : string_view ptr,
3747 : source_location const& loc = BOOST_CURRENT_LOCATION) &;
3748 : /** @} */
3749 :
3750 : /** Access an element via JSON Pointer.
3751 :
3752 : This function is used to access a (potentially nested)
3753 : element of the value using a JSON Pointer string.
3754 :
3755 : @par Complexity
3756 : Linear in the sizes of `ptr` and underlying array, object, or string.
3757 :
3758 : @par Exception Safety
3759 : No-throw guarantee.
3760 :
3761 : @param ptr JSON Pointer string.
3762 :
3763 : @param ec Set to the error, if any occurred.
3764 :
3765 : @return pointer to the element identified by `ptr`.
3766 :
3767 : @see
3768 : <a href="https://datatracker.ietf.org/doc/html/rfc6901">
3769 : RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>
3770 : */
3771 : /** @{ */
3772 : BOOST_JSON_DECL
3773 : value const*
3774 : find_pointer(string_view ptr, system::error_code& ec) const noexcept;
3775 :
3776 : BOOST_JSON_DECL
3777 : value*
3778 : find_pointer(string_view ptr, system::error_code& ec) noexcept;
3779 :
3780 : BOOST_JSON_DECL
3781 : value const*
3782 : find_pointer(string_view ptr, std::error_code& ec) const noexcept;
3783 :
3784 : BOOST_JSON_DECL
3785 : value*
3786 : find_pointer(string_view ptr, std::error_code& ec) noexcept;
3787 : /** @} */
3788 :
3789 : //------------------------------------------------------
3790 :
3791 : /** Set an element via JSON Pointer.
3792 :
3793 : This function is used to insert or assign to a potentially nested
3794 : element of the value using a JSON Pointer string. The function may
3795 : create intermediate elements corresponding to pointer segments.
3796 : <br/>
3797 :
3798 : The particular conditions when and what kind of intermediate element
3799 : is created is governed by the `ptr` parameter.
3800 :
3801 : Each pointer token is considered in sequence. For each token
3802 :
3803 : - if the containing value is an @ref object, then a new `null`
3804 : element is created with key equal to unescaped token string;
3805 : otherwise
3806 :
3807 : - if the containing value is an @ref array, and the token represents a
3808 : past-the-end marker, then a `null` element is appended to the array;
3809 : otherwise
3810 :
3811 : - if the containing value is an @ref array, and the token represents a
3812 : number, then if the difference between the number and array's size
3813 : is smaller than `opts.max_created_elements`, then the size of the
3814 : array is increased, so that the number can reference an element in the
3815 : array; otherwise
3816 :
3817 : - if the containing value is of different @ref kind and
3818 : `opts.replace_any_scalar` is `true`, or the value is `null`, then
3819 :
3820 : - if `opts.create_arrays` is `true` and the token either represents
3821 : past-the-end marker or a number, then the value is replaced with
3822 : an empty array and the token is considered again; otherwise
3823 :
3824 : - if `opts.create_objects` is `true`, then the value is replaced
3825 : with an empty object and the token is considered again; otherwise
3826 :
3827 : - an error is produced.
3828 :
3829 : @par Complexity
3830 : Linear in the sum of size of `ptr`, size of underlying array, object,
3831 : or string and `opts.max_created_elements`.
3832 :
3833 : @par Exception Safety
3834 : Basic guarantee.
3835 : Calls to `memory_resource::allocate` may throw.
3836 :
3837 : @param sv JSON Pointer string.
3838 :
3839 : @param ref The value to assign to pointed element.
3840 :
3841 : @param opts The options for the algorithm.
3842 :
3843 : @return `boost::json::result<value&>` containing either a reference to
3844 : the element identified by `ptr` or a corresponding `error_code`.
3845 :
3846 : @see
3847 : @ref set_pointer_options,
3848 : [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
3849 : */
3850 : BOOST_JSON_DECL
3851 : system::result<value&>
3852 : try_set_at_pointer(
3853 : string_view sv,
3854 : value_ref ref,
3855 : set_pointer_options const& opts = {} );
3856 :
3857 : /** Set an element via JSON Pointer.
3858 :
3859 : This function is used to insert or assign to a potentially nested
3860 : element of the value using a JSON Pointer string. The function may
3861 : create intermediate elements corresponding to pointer segments.
3862 : <br/>
3863 :
3864 : The particular conditions when and what kind of intermediate element
3865 : is created is governed by the `ptr` parameter.
3866 :
3867 : Each pointer token is considered in sequence. For each token
3868 :
3869 : - if the containing value is an @ref object, then a new `null`
3870 : element is created with key equal to unescaped token string; otherwise
3871 :
3872 : - if the containing value is an @ref array, and the token represents a
3873 : past-the-end marker, then a `null` element is appended to the array;
3874 : otherwise
3875 :
3876 : - if the containing value is an @ref array, and the token represents a
3877 : number, then if the difference between the number and array's size
3878 : is smaller than `opts.max_created_elements`, then the size of the
3879 : array is increased, so that the number can reference an element in the
3880 : array; otherwise
3881 :
3882 : - if the containing value is of different @ref kind and
3883 : `opts.replace_any_scalar` is `true`, or the value is `null`, then
3884 :
3885 : - if `opts.create_arrays` is `true` and the token either represents
3886 : past-the-end marker or a number, then the value is replaced with
3887 : an empty array and the token is considered again; otherwise
3888 :
3889 : - if `opts.create_objects` is `true`, then the value is replaced
3890 : with an empty object and the token is considered again; otherwise
3891 :
3892 : - an error is produced.
3893 :
3894 : @par Complexity
3895 : Linear in the sum of size of `ptr`, size of underlying array, object,
3896 : or string and `opts.max_created_elements`.
3897 :
3898 : @par Exception Safety
3899 : Basic guarantee.
3900 : Calls to `memory_resource::allocate` may throw.
3901 :
3902 : @param sv JSON Pointer string.
3903 :
3904 : @param ref The value to assign to pointed element.
3905 :
3906 : @param opts The options for the algorithm.
3907 :
3908 : @return Reference to the element identified by `ptr`.
3909 :
3910 : @see @ref set_pointer_options,
3911 : <a href="https://datatracker.ietf.org/doc/html/rfc6901">
3912 : RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>.
3913 : */
3914 : BOOST_JSON_DECL
3915 : value&
3916 : set_at_pointer(
3917 : string_view sv,
3918 : value_ref ref,
3919 : set_pointer_options const& opts = {} );
3920 :
3921 : /** Set an element via JSON Pointer.
3922 :
3923 : This function is used to insert or assign to a potentially nested
3924 : element of the value using a JSON Pointer string. The function may
3925 : create intermediate elements corresponding to pointer segments.
3926 : <br/>
3927 :
3928 : The particular conditions when and what kind of intermediate element
3929 : is created is governed by the `ptr` parameter.
3930 :
3931 : Each pointer token is considered in sequence. For each token
3932 :
3933 : - if the containing value is an @ref object, then a new `null`
3934 : element is created with key equal to unescaped token string;
3935 : otherwise
3936 :
3937 : - if the containing value is an @ref array, and the token represents a
3938 : past-the-end marker, then a `null` element is appended to the array;
3939 : otherwise
3940 :
3941 : - if the containing value is an @ref array, and the token represents a
3942 : number, then if the difference between the number and array's size
3943 : is smaller than `opts.max_created_elements`, then the size of the
3944 : array is increased, so that the number can reference an element in the
3945 : array; otherwise
3946 :
3947 : - if the containing value is of different @ref kind and
3948 : `opts.replace_any_scalar` is `true`, or the value is `null`, then
3949 :
3950 : - if `opts.create_arrays` is `true` and the token either represents
3951 : past-the-end marker or a number, then the value is replaced with
3952 : an empty array and the token is considered again; otherwise
3953 :
3954 : - if `opts.create_objects` is `true`, then the value is replaced
3955 : with an empty object and the token is considered again; otherwise
3956 :
3957 : - an error is produced.
3958 :
3959 : @par Complexity
3960 : Linear in the sum of size of `ptr`, size of underlying array, object,
3961 : or string and `opts.max_created_elements`.
3962 :
3963 : @par Exception Safety
3964 : Basic guarantee.
3965 : Calls to `memory_resource::allocate` may throw.
3966 :
3967 : @param sv JSON Pointer string.
3968 :
3969 : @param ref The value to assign to pointed element.
3970 :
3971 : @param ec Set to the error, if any occurred.
3972 :
3973 : @param opts The options for the algorithm.
3974 :
3975 : @return Pointer to the element identified by `ptr`.
3976 :
3977 : @see @ref set_pointer_options,
3978 : <a href="https://datatracker.ietf.org/doc/html/rfc6901">
3979 : RFC 6901 - JavaScript Object Notation (JSON) Pointer</a>.
3980 : */
3981 : /** @{ */
3982 : BOOST_JSON_DECL
3983 : value*
3984 : set_at_pointer(
3985 : string_view sv,
3986 : value_ref ref,
3987 : system::error_code& ec,
3988 : set_pointer_options const& opts = {} );
3989 :
3990 : BOOST_JSON_DECL
3991 : value*
3992 : set_at_pointer(
3993 : string_view sv,
3994 : value_ref ref,
3995 : std::error_code& ec,
3996 : set_pointer_options const& opts = {} );
3997 : /** @} */
3998 :
3999 : //------------------------------------------------------
4000 :
4001 : /** Return `true` if two values are equal.
4002 :
4003 : Two values are equal when they are the
4004 : same kind and their referenced values
4005 : are equal, or when they are both integral
4006 : types and their integral representations
4007 : are equal.
4008 :
4009 : @par Complexity
4010 : Constant or linear in the size of
4011 : the array, object, or string.
4012 :
4013 : @par Exception Safety
4014 : No-throw guarantee.
4015 : */
4016 : // inline friend speeds up overload resolution
4017 : friend
4018 : bool
4019 4226 : operator==(
4020 : value const& lhs,
4021 : value const& rhs) noexcept
4022 : {
4023 4226 : return lhs.equal(rhs);
4024 : }
4025 :
4026 : /** Return `true` if two values are not equal.
4027 :
4028 : Two values are equal when they are the
4029 : same kind and their referenced values
4030 : are equal, or when they are both integral
4031 : types and their integral representations
4032 : are equal.
4033 :
4034 : @par Complexity
4035 : Constant or linear in the size of
4036 : the array, object, or string.
4037 :
4038 : @par Exception Safety
4039 : No-throw guarantee.
4040 : */
4041 : friend
4042 : bool
4043 4032 : operator!=(
4044 : value const& lhs,
4045 : value const& rhs) noexcept
4046 : {
4047 4032 : return ! (lhs == rhs);
4048 : }
4049 :
4050 : /** Serialize @ref value to an output stream.
4051 :
4052 : This function serializes a `value` as JSON into the output stream.
4053 :
4054 : @return Reference to `os`.
4055 :
4056 : @par Complexity
4057 : Constant or linear in the size of `jv`.
4058 :
4059 : @par Exception Safety
4060 : Strong guarantee.
4061 : Calls to `memory_resource::allocate` may throw.
4062 :
4063 : @param os The output stream to serialize to.
4064 :
4065 : @param jv The value to serialize.
4066 : */
4067 : BOOST_JSON_DECL
4068 : friend
4069 : std::ostream&
4070 : operator<<(
4071 : std::ostream& os,
4072 : value const& jv);
4073 :
4074 : /** Parse @ref value from an input stream.
4075 :
4076 : This function parses JSON from an input stream into a `value`. If
4077 : parsing fails, `std::ios_base::failbit` will be set for `is` and
4078 : `jv` will be left unchanged. Regardless of whether `skipws` flag is set
4079 : on `is`, consumes whitespace before and after JSON, because whitespace
4080 : is considered a part of JSON. Behaves as
4081 : [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
4082 :
4083 : Note: this operator cannot assume that the stream only contains a
4084 : single JSON document, which may result in **very underwhelming
4085 : performance**, if the stream isn't cooperative. If you know that your
4086 : input consists of a single JSON document, consider using @ref parse
4087 : function instead.
4088 :
4089 : @return Reference to `is`.
4090 :
4091 : @par Complexity
4092 : Linear in the size of JSON data.
4093 :
4094 : @par Exception Safety
4095 : Basic guarantee.
4096 : Calls to `memory_resource::allocate` may throw.
4097 : The stream may throw as configured by
4098 : [`std::ios::exceptions`](https://en.cppreference.com/w/cpp/io/basic_ios/exceptions).
4099 :
4100 : @param is The input stream to parse from.
4101 :
4102 : @param jv The value to parse into.
4103 :
4104 : @see @ref parse.
4105 : */
4106 : BOOST_JSON_DECL
4107 : friend
4108 : std::istream&
4109 : operator>>(
4110 : std::istream& is,
4111 : value& jv);
4112 :
4113 : /** Helper for `boost::hash` support
4114 :
4115 : Computes a hash value for `jv`. This function is used by
4116 : `boost::hash<value>`. Similar overloads for @ref array, @ref object,
4117 : and @ref string do not exist, because those types are supported by
4118 : `boost::hash` out of the box.
4119 :
4120 : @return hash value for `jv`.
4121 :
4122 : @param jv `value` for which a hash is to be computed.
4123 :
4124 : @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
4125 : */
4126 : #ifndef BOOST_JSON_DOCS
4127 : template<
4128 : class T,
4129 : typename std::enable_if<
4130 : std::is_same< detail::remove_cvref<T>, value >::value >::type*
4131 : = nullptr>
4132 : friend
4133 : std::size_t
4134 248 : hash_value( T const& jv ) noexcept
4135 : #else
4136 : friend
4137 : inline
4138 : std::size_t
4139 : hash_value( value const& jv ) noexcept
4140 : #endif
4141 : {
4142 248 : return detail::hash_value_impl(jv);
4143 : }
4144 :
4145 : private:
4146 : static
4147 : void
4148 2133577 : relocate(
4149 : value* dest,
4150 : value const& src) noexcept
4151 : {
4152 2133577 : std::memcpy(
4153 : static_cast<void*>(dest),
4154 : &src,
4155 : sizeof(src));
4156 2133577 : }
4157 :
4158 : BOOST_JSON_DECL
4159 : storage_ptr
4160 : destroy() noexcept;
4161 :
4162 : BOOST_JSON_DECL
4163 : bool
4164 : equal(value const& other) const noexcept;
4165 :
4166 : template<class T>
4167 : auto
4168 3427 : to_number(error& e) const noexcept ->
4169 : typename std::enable_if<
4170 : std::is_signed<T>::value &&
4171 : ! std::is_floating_point<T>::value,
4172 : T>::type
4173 : {
4174 3427 : if(sca_.k == json::kind::int64)
4175 : {
4176 3340 : auto const i = sca_.i;
4177 6674 : if( i >= (std::numeric_limits<T>::min)() &&
4178 3334 : i <= (std::numeric_limits<T>::max)())
4179 : {
4180 3328 : e = {};
4181 3328 : return static_cast<T>(i);
4182 : }
4183 12 : e = error::not_exact;
4184 : }
4185 87 : else if(sca_.k == json::kind::uint64)
4186 : {
4187 20 : auto const u = sca_.u;
4188 20 : if(u <= static_cast<std::uint64_t>((
4189 20 : std::numeric_limits<T>::max)()))
4190 : {
4191 10 : e = {};
4192 10 : return static_cast<T>(u);
4193 : }
4194 10 : e = error::not_exact;
4195 : }
4196 67 : else if(sca_.k == json::kind::double_)
4197 : {
4198 20 : auto const d = sca_.d;
4199 20 : if( d >= static_cast<double>(
4200 40 : (detail::to_number_limit<T>::min)()) &&
4201 : d <= static_cast<double>(
4202 40 : (detail::to_number_limit<T>::max)()) &&
4203 20 : static_cast<T>(d) == d)
4204 : {
4205 9 : e = {};
4206 9 : return static_cast<T>(d);
4207 : }
4208 11 : e = error::not_exact;
4209 : }
4210 : else
4211 : {
4212 47 : e = error::not_number;
4213 : }
4214 80 : return T{};
4215 : }
4216 :
4217 : template<class T>
4218 : auto
4219 119 : to_number(error& e) const noexcept ->
4220 : typename std::enable_if<
4221 : std::is_unsigned<T>::value &&
4222 : ! std::is_same<T, bool>::value,
4223 : T>::type
4224 : {
4225 119 : if(sca_.k == json::kind::int64)
4226 : {
4227 44 : auto const i = sca_.i;
4228 72 : if( i >= 0 && static_cast<std::uint64_t>(i) <=
4229 28 : (std::numeric_limits<T>::max)())
4230 : {
4231 22 : e = {};
4232 22 : return static_cast<T>(i);
4233 : }
4234 22 : e = error::not_exact;
4235 : }
4236 75 : else if(sca_.k == json::kind::uint64)
4237 : {
4238 58 : auto const u = sca_.u;
4239 58 : if(u <= (std::numeric_limits<T>::max)())
4240 : {
4241 52 : e = {};
4242 52 : return static_cast<T>(u);
4243 : }
4244 6 : e = error::not_exact;
4245 : }
4246 17 : else if(sca_.k == json::kind::double_)
4247 : {
4248 12 : auto const d = sca_.d;
4249 8 : if( d >= 0 &&
4250 20 : d <= (detail::to_number_limit<T>::max)() &&
4251 8 : static_cast<T>(d) == d)
4252 : {
4253 4 : e = {};
4254 4 : return static_cast<T>(d);
4255 : }
4256 8 : e = error::not_exact;
4257 : }
4258 : else
4259 : {
4260 5 : e = error::not_number;
4261 : }
4262 41 : return T{};
4263 : }
4264 :
4265 : template<class T>
4266 : auto
4267 67 : to_number(error& e) const noexcept ->
4268 : typename std::enable_if<
4269 : std::is_floating_point<
4270 : T>::value, T>::type
4271 : {
4272 67 : if(sca_.k == json::kind::int64)
4273 : {
4274 16 : e = {};
4275 16 : return static_cast<T>(sca_.i);
4276 : }
4277 51 : if(sca_.k == json::kind::uint64)
4278 : {
4279 10 : e = {};
4280 10 : return static_cast<T>(sca_.u);
4281 : }
4282 41 : if(sca_.k == json::kind::double_)
4283 : {
4284 27 : e = {};
4285 27 : return static_cast<T>(sca_.d);
4286 : }
4287 14 : e = error::not_number;
4288 14 : return {};
4289 : }
4290 : };
4291 :
4292 : // Make sure things are as big as we think they should be
4293 : #if BOOST_JSON_ARCH == 64
4294 : BOOST_STATIC_ASSERT(sizeof(value) == 24);
4295 : #elif BOOST_JSON_ARCH == 32
4296 : BOOST_STATIC_ASSERT(sizeof(value) == 16);
4297 : #else
4298 : # error Unknown architecture
4299 : #endif
4300 :
4301 : //----------------------------------------------------------
4302 :
4303 : /** A key/value pair.
4304 :
4305 : This is the type of element used by the @ref object
4306 : container.
4307 : */
4308 : class key_value_pair
4309 : {
4310 : #ifndef BOOST_JSON_DOCS
4311 : friend struct detail::access;
4312 : using access = detail::access;
4313 : #endif
4314 :
4315 : BOOST_JSON_DECL
4316 : static char const empty_[1];
4317 :
4318 : inline
4319 : key_value_pair(
4320 : pilfered<json::value> k,
4321 : pilfered<json::value> v) noexcept;
4322 :
4323 : public:
4324 : /// Copy assignment (deleted).
4325 : key_value_pair&
4326 : operator=(key_value_pair const&) = delete;
4327 :
4328 : /** Destructor.
4329 :
4330 : The value is destroyed and all internally
4331 : allocated memory is freed.
4332 : */
4333 58936 : ~key_value_pair() noexcept
4334 52260 : {
4335 58936 : auto const& sp = value_.storage();
4336 58936 : if(sp.is_not_shared_and_deallocate_is_trivial())
4337 0 : return;
4338 58936 : if(key_ == empty_)
4339 6676 : return;
4340 52260 : sp->deallocate(const_cast<char*>(key_),
4341 52260 : len_ + 1, alignof(char));
4342 58936 : }
4343 :
4344 : /** Copy constructor.
4345 :
4346 : This constructs a key/value pair with a
4347 : copy of another key/value pair, using
4348 : the same memory resource as `other`.
4349 :
4350 : @par Exception Safety
4351 : Strong guarantee.
4352 : Calls to `memory_resource::allocate` may throw.
4353 :
4354 : @param other The key/value pair to copy.
4355 : */
4356 776 : key_value_pair(
4357 : key_value_pair const& other)
4358 776 : : key_value_pair(other,
4359 776 : other.storage())
4360 : {
4361 776 : }
4362 :
4363 : /** Copy constructor.
4364 :
4365 : This constructs a key/value pair with a
4366 : copy of another key/value pair, using
4367 : the specified memory resource.
4368 :
4369 : @par Exception Safety
4370 : Strong guarantee.
4371 : Calls to `memory_resource::allocate` may throw.
4372 :
4373 : @param other The key/value pair to copy.
4374 :
4375 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
4376 : use. The element will acquire shared ownership of the memory resource.
4377 : */
4378 : BOOST_JSON_DECL
4379 : key_value_pair(
4380 : key_value_pair const& other,
4381 : storage_ptr sp);
4382 :
4383 : /** Move constructor.
4384 :
4385 : The pair is constructed by acquiring
4386 : ownership of the contents of `other` and
4387 : shared ownership of `other`'s memory resource.
4388 :
4389 : @note
4390 :
4391 : After construction, the moved-from pair holds an
4392 : empty key, and a null value with its current
4393 : storage pointer.
4394 :
4395 : @par Complexity
4396 : Constant.
4397 :
4398 : @par Exception Safety
4399 : No-throw guarantee.
4400 :
4401 : @param other The pair to move.
4402 : */
4403 1 : key_value_pair(
4404 : key_value_pair&& other) noexcept
4405 1 : : value_(std::move(other.value_))
4406 2 : , key_(detail::exchange(
4407 1 : other.key_, empty_))
4408 2 : , len_(detail::exchange(
4409 1 : other.len_, 0))
4410 : {
4411 1 : }
4412 :
4413 : /** Pilfer constructor.
4414 :
4415 : The pair is constructed by acquiring ownership
4416 : of the contents of `other` using pilfer semantics.
4417 : This is more efficient than move construction, when
4418 : it is known that the moved-from object will be
4419 : immediately destroyed afterwards.
4420 :
4421 : @par Complexity
4422 : Constant.
4423 :
4424 : @par Exception Safety
4425 : No-throw guarantee.
4426 :
4427 : @param other The value to pilfer. After pilfer
4428 : construction, `other` is not in a usable state
4429 : and may only be destroyed.
4430 :
4431 : @see @ref pilfer,
4432 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
4433 : Valueless Variants Considered Harmful</a>
4434 : */
4435 6675 : key_value_pair(
4436 : pilfered<key_value_pair> other) noexcept
4437 6675 : : value_(pilfer(other.get().value_))
4438 13350 : , key_(detail::exchange(
4439 6675 : other.get().key_, empty_))
4440 13350 : , len_(detail::exchange(
4441 6675 : other.get().len_, 0))
4442 : {
4443 6675 : }
4444 :
4445 : /** Constructor.
4446 :
4447 : This constructs a key/value pair.
4448 :
4449 : @par Exception Safety
4450 : Strong guarantee.
4451 : Calls to `memory_resource::allocate` may throw.
4452 :
4453 : @param key The key string to use.
4454 :
4455 : @param args Optional arguments forwarded to
4456 : the @ref value constructor.
4457 : */
4458 : template<class... Args>
4459 : explicit
4460 7826 : key_value_pair(
4461 : string_view key,
4462 : Args&&... args)
4463 7827 : : value_(std::forward<Args>(args)...)
4464 : {
4465 7825 : if(key.size() > string::max_size())
4466 : {
4467 : BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
4468 1 : detail::throw_system_error( error::key_too_large, &loc );
4469 : }
4470 : auto s = reinterpret_cast<
4471 7824 : char*>(value_.storage()->
4472 7824 : allocate(key.size() + 1, alignof(char)));
4473 7518 : std::memcpy(s, key.data(), key.size());
4474 7518 : s[key.size()] = 0;
4475 7518 : key_ = s;
4476 7518 : len_ = static_cast<
4477 7518 : std::uint32_t>(key.size());
4478 7825 : }
4479 :
4480 : /** Constructor.
4481 :
4482 : This constructs a key/value pair. A
4483 : copy of the specified value is made,
4484 : using the specified memory resource.
4485 :
4486 : @par Exception Safety
4487 : Strong guarantee.
4488 : Calls to `memory_resource::allocate` may throw.
4489 :
4490 : @param p A `std::pair` with the key
4491 : string and @ref value to construct with.
4492 :
4493 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
4494 : use. The element will acquire shared ownership of the memory resource.
4495 : */
4496 : explicit
4497 0 : key_value_pair(
4498 : std::pair<
4499 : string_view,
4500 : json::value> const& p,
4501 : storage_ptr sp = {})
4502 0 : : key_value_pair(
4503 : p.first,
4504 0 : p.second,
4505 0 : std::move(sp))
4506 : {
4507 0 : }
4508 :
4509 : /** Constructor.
4510 :
4511 : This constructs a key/value pair.
4512 : Ownership of the specified value is
4513 : transferred by move construction.
4514 :
4515 : @par Exception Safety
4516 : Strong guarantee.
4517 : Calls to `memory_resource::allocate` may throw.
4518 :
4519 : @param p A `std::pair` with the key
4520 : string and @ref value to construct with.
4521 :
4522 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
4523 : use. The element will acquire shared ownership of the memory resource.
4524 : */
4525 : explicit
4526 3125 : key_value_pair(
4527 : std::pair<
4528 : string_view,
4529 : json::value>&& p,
4530 : storage_ptr sp = {})
4531 3125 : : key_value_pair(
4532 : p.first,
4533 3125 : std::move(p).second,
4534 6250 : std::move(sp))
4535 : {
4536 2978 : }
4537 :
4538 : /** Return the associated memory resource.
4539 :
4540 : This returns a pointer to the memory
4541 : resource used to construct the value.
4542 :
4543 : @par Complexity
4544 : Constant.
4545 :
4546 : @par Exception Safety
4547 : No-throw guarantee.
4548 : */
4549 : storage_ptr const&
4550 776 : storage() const noexcept
4551 : {
4552 776 : return value_.storage();
4553 : }
4554 :
4555 : /** Return the key of this element.
4556 :
4557 : After construction, the key may
4558 : not be modified.
4559 :
4560 : @par Complexity
4561 : Constant.
4562 :
4563 : @par Exception Safety
4564 : No-throw guarantee.
4565 : */
4566 : string_view const
4567 141830 : key() const noexcept
4568 : {
4569 141830 : return { key_, len_ };
4570 : }
4571 :
4572 : /** Return the key of this element as a null-terminated string.
4573 :
4574 : @par Complexity
4575 : Constant.
4576 :
4577 : @par Exception Safety
4578 : No-throw guarantee.
4579 : */
4580 : char const*
4581 1 : key_c_str() const noexcept
4582 : {
4583 1 : return key_;
4584 : }
4585 :
4586 : /** Return the value of this element.
4587 :
4588 : @par Complexity
4589 : Constant.
4590 :
4591 : @par Exception Safety
4592 : No-throw guarantee.
4593 : */
4594 : /** @{ */
4595 : json::value const&
4596 65269 : value() const& noexcept
4597 : {
4598 65269 : return value_;
4599 : }
4600 :
4601 : json::value&&
4602 : value() && noexcept
4603 : {
4604 : return std::move( value() );
4605 : }
4606 :
4607 : json::value&
4608 962 : value() & noexcept
4609 : {
4610 962 : return value_;
4611 : }
4612 : /** @} */
4613 :
4614 : private:
4615 : json::value value_;
4616 : char const* key_;
4617 : std::uint32_t len_;
4618 : std::uint32_t next_;
4619 : };
4620 :
4621 : //----------------------------------------------------------
4622 :
4623 : #ifdef BOOST_JSON_DOCS
4624 :
4625 : /** Tuple-like element access.
4626 :
4627 : This overload permits the key and value
4628 : of a `key_value_pair` to be accessed
4629 : by index. For example:
4630 :
4631 : @code
4632 :
4633 : key_value_pair kvp("num", 42);
4634 :
4635 : string_view key = get<0>(kvp);
4636 : value& jv = get<1>(kvp);
4637 :
4638 : @endcode
4639 :
4640 : @par Structured Bindings
4641 :
4642 : When using C++17 or greater, objects of type
4643 : @ref key_value_pair may be used to initialize
4644 : structured bindings:
4645 :
4646 : @code
4647 :
4648 : key_value_pair kvp("num", 42);
4649 :
4650 : auto& [key, value] = kvp;
4651 :
4652 : @endcode
4653 :
4654 : Depending on the value of `I`, the return type will be:
4655 :
4656 : @li `string_view const` if `I == 0`, or
4657 :
4658 : @li `value&`, `value const&`, or `value&&` if `I == 1`.
4659 :
4660 : Any other value for `I` is ill-formed.
4661 :
4662 : @tparam I The element index to access.
4663 :
4664 : @par Constraints
4665 :
4666 : `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
4667 :
4668 : @return `kvp.key()` if `I == 0`, or `kvp.value()`
4669 : if `I == 1`.
4670 :
4671 : @param kvp The @ref key_value_pair object
4672 : to access.
4673 : */
4674 : template<
4675 : std::size_t I,
4676 : class T>
4677 : __see_below__
4678 : get(T&& kvp) noexcept;
4679 :
4680 : #else
4681 :
4682 : template<std::size_t I>
4683 : auto
4684 : get(key_value_pair const&) noexcept ->
4685 : typename std::conditional<I == 0,
4686 : string_view const,
4687 : value const&>::type
4688 : {
4689 : static_assert(I == 0,
4690 : "key_value_pair index out of range");
4691 : }
4692 :
4693 : template<std::size_t I>
4694 : auto
4695 : get(key_value_pair&) noexcept ->
4696 : typename std::conditional<I == 0,
4697 : string_view const,
4698 : value&>::type
4699 : {
4700 : static_assert(I == 0,
4701 : "key_value_pair index out of range");
4702 : }
4703 :
4704 : template<std::size_t I>
4705 : auto
4706 : get(key_value_pair&&) noexcept ->
4707 : typename std::conditional<I == 0,
4708 : string_view const,
4709 : value&&>::type
4710 : {
4711 : static_assert(I == 0,
4712 : "key_value_pair index out of range");
4713 : }
4714 :
4715 : /** Extracts a key_value_pair's key using tuple-like interface
4716 : */
4717 : template<>
4718 : inline
4719 : string_view const
4720 19615 : get<0>(key_value_pair const& kvp) noexcept
4721 : {
4722 19615 : return kvp.key();
4723 : }
4724 :
4725 : /** Extracts a key_value_pair's key using tuple-like interface
4726 : */
4727 : template<>
4728 : inline
4729 : string_view const
4730 7 : get<0>(key_value_pair& kvp) noexcept
4731 : {
4732 7 : return kvp.key();
4733 : }
4734 :
4735 : /** Extracts a key_value_pair's key using tuple-like interface
4736 : */
4737 : template<>
4738 : inline
4739 : string_view const
4740 : get<0>(key_value_pair&& kvp) noexcept
4741 : {
4742 : return kvp.key();
4743 : }
4744 :
4745 : /** Extracts a key_value_pair's value using tuple-like interface
4746 : */
4747 : template<>
4748 : inline
4749 : value const&
4750 28305 : get<1>(key_value_pair const& kvp) noexcept
4751 : {
4752 28305 : return kvp.value();
4753 : }
4754 :
4755 : /** Extracts a key_value_pair's value using tuple-like interface
4756 : */
4757 : template<>
4758 : inline
4759 : value&
4760 7 : get<1>(key_value_pair& kvp) noexcept
4761 : {
4762 7 : return kvp.value();
4763 : }
4764 :
4765 : /** Extracts a key_value_pair's value using tuple-like interface
4766 : */
4767 : template<>
4768 : inline
4769 : value&&
4770 : get<1>(key_value_pair&& kvp) noexcept
4771 : {
4772 : return std::move(kvp.value());
4773 : }
4774 :
4775 : #endif
4776 :
4777 : } // namespace json
4778 : } // namespace boost
4779 :
4780 : #ifdef __clang__
4781 : # pragma clang diagnostic push
4782 : # pragma clang diagnostic ignored "-Wmismatched-tags"
4783 : #endif
4784 :
4785 : #ifndef BOOST_JSON_DOCS
4786 :
4787 : namespace std {
4788 :
4789 : /** Tuple-like size access for key_value_pair
4790 : */
4791 : template<>
4792 : struct tuple_size< ::boost::json::key_value_pair >
4793 : : std::integral_constant<std::size_t, 2>
4794 : {
4795 : };
4796 :
4797 : /** Tuple-like access for the key type of key_value_pair
4798 : */
4799 : template<>
4800 : struct tuple_element<0, ::boost::json::key_value_pair>
4801 : {
4802 : using type = ::boost::json::string_view const;
4803 : };
4804 :
4805 : /** Tuple-like access for the value type of key_value_pair
4806 : */
4807 : template<>
4808 : struct tuple_element<1, ::boost::json::key_value_pair>
4809 : {
4810 : using type = ::boost::json::value&;
4811 : };
4812 :
4813 : /** Tuple-like access for the value type of key_value_pair
4814 : */
4815 : template<>
4816 : struct tuple_element<1, ::boost::json::key_value_pair const>
4817 : {
4818 : using type = ::boost::json::value const&;
4819 : };
4820 :
4821 : } // std
4822 :
4823 : #endif
4824 :
4825 : // std::hash specialization
4826 : #ifndef BOOST_JSON_DOCS
4827 : namespace std {
4828 : template <>
4829 : struct hash< ::boost::json::value > {
4830 : BOOST_JSON_DECL
4831 : std::size_t
4832 : operator()(::boost::json::value const& jv) const noexcept;
4833 : };
4834 : } // std
4835 : #endif
4836 :
4837 :
4838 : #ifdef __clang__
4839 : # pragma clang diagnostic pop
4840 : #endif
4841 :
4842 : // These are here because value, array,
4843 : // and object form cyclic references.
4844 :
4845 : #include <boost/json/detail/impl/array.hpp>
4846 : #include <boost/json/impl/array.hpp>
4847 : #include <boost/json/impl/object.hpp>
4848 : #include <boost/json/impl/value.hpp>
4849 :
4850 : // These must come after array and object
4851 : #include <boost/json/impl/value_ref.hpp>
4852 :
4853 : #endif
|