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