GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: value.hpp
Date: 2025-12-23 17:22:01
Exec Total Coverage
Lines: 519 525 98.9%
Functions: 190 196 96.9%
Branches: 142 164 86.6%

Line Branch Exec Source
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
1/1
✓ Branch 3 taken 30236 times.
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
1/1
✓ Branch 3 taken 8060 times.
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
1/1
✓ Branch 3 taken 19 times.
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
1/1
✓ Branch 3 taken 17170 times.
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
1/1
✓ Branch 3 taken 134 times.
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
1/1
✓ Branch 2 taken 12 times.
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
1/1
✓ Branch 2 taken 9 times.
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
1/1
✓ Branch 2 taken 4 times.
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
1/1
✓ Branch 2 taken 22 times.
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
1/1
✓ Branch 2 taken 4 times.
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
1/1
✓ Branch 2 taken 57 times.
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
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
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
2/2
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 1 times.
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
2/2
✓ Branch 1 taken 6429 times.
✓ Branch 2 taken 3 times.
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
2/2
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 1 times.
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
2/2
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 7 times.
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
4/4
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 6 times.
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
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
15 sca_.k != json::kind::object &&
1917
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
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
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 1 times.
92 kind() == json::kind::int64 ||
1939
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 74 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 6 times.
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
2/2
✓ Branch 1 taken 159 times.
✓ Branch 2 taken 37 times.
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
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 25 times.
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
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 68 times.
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
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
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
2/2
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 13 times.
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
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
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 6943 to_number(system::error_code& ec) const noexcept
2381 {
2382 error e;
2383 6943 auto result = to_number<T>(e);
2384 6943 BOOST_JSON_FAIL(ec, e);
2385 6943 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 373 try_to_number() const noexcept
2452 {
2453 373 system::error_code ec;
2454 373 T result = to_number<T>(ec);
2455
2/2
✓ Branch 1 taken 78 times.
✓ Branch 2 taken 118 times.
373 if( ec )
2456 156 return {system::in_place_error, ec};
2457
2458 217 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 369 to_number() const
2507 {
2508
1/1
✓ Branch 3 taken 117 times.
369 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
38 BOOST_ASSERT(is_object());
3249 38 return obj_;
3250 }
3251
3252 object&&
3253 1 get_object() && noexcept
3254 {
3255
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 BOOST_ASSERT(is_object());
3256 1 return std::move(obj_);
3257 }
3258
3259 object const&
3260 52907 get_object() const& noexcept
3261 {
3262
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 52907 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 BOOST_ASSERT(is_array());
3289 25 return arr_;
3290 }
3291
3292 array&&
3293 1 get_array() && noexcept
3294 {
3295
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 BOOST_ASSERT(is_array());
3296 1 return std::move(arr_);
3297 }
3298
3299 array const&
3300 5582 get_array() const& noexcept
3301 {
3302
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5582 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8971 times.
8971 BOOST_ASSERT(is_string());
3329 8971 return str_;
3330 }
3331
3332 string&&
3333 1 get_string() && noexcept
3334 {
3335
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 BOOST_ASSERT(is_string());
3336 1 return std::move(str_);
3337 }
3338
3339 string const&
3340 40831 get_string() const& noexcept
3341 {
3342
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40831 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14191 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 209 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39138 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 796 times.
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 6609 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
2/2
✓ Branch 0 taken 3232 times.
✓ Branch 1 taken 79 times.
6609 if(sca_.k == json::kind::int64)
4189 {
4190 6451 auto const i = sca_.i;
4191
5/6
✓ Branch 1 taken 3226 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3220 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
12890 if( i >= (std::numeric_limits<T>::min)() &&
4192
2/2
✓ Branch 1 taken 3200 times.
✓ Branch 2 taken 6 times.
6439 i <= (std::numeric_limits<T>::max)())
4193 {
4194 6427 e = {};
4195 6427 return static_cast<T>(i);
4196 }
4197 24 e = error::not_exact;
4198 }
4199
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 59 times.
158 else if(sca_.k == json::kind::uint64)
4200 {
4201 40 auto const u = sca_.u;
4202
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
40 if(u <= static_cast<std::uint64_t>((
4203 40 std::numeric_limits<T>::max)()))
4204 {
4205 20 e = {};
4206 20 return static_cast<T>(u);
4207 }
4208 20 e = error::not_exact;
4209 }
4210
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 41 times.
118 else if(sca_.k == json::kind::double_)
4211 {
4212 36 auto const d = sca_.d;
4213 36 if( d >= static_cast<double>(
4214
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
72 (detail::to_number_limit<T>::min)()) &&
4215 d <= static_cast<double>(
4216
3/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 10 times.
72 (detail::to_number_limit<T>::max)()) &&
4217
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 10 times.
36 static_cast<T>(d) == d)
4218 {
4219 16 e = {};
4220 16 return static_cast<T>(d);
4221 }
4222 20 e = error::not_exact;
4223 }
4224 else
4225 {
4226 82 e = error::not_number;
4227 }
4228 146 return T{};
4229 }
4230
4231 template<class T>
4232 auto
4233 202 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
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 65 times.
202 if(sca_.k == json::kind::int64)
4240 {
4241 76 auto const i = sca_.i;
4242
6/6
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
120 if( i >= 0 && static_cast<std::uint64_t>(i) <=
4243
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 6 times.
44 (std::numeric_limits<T>::max)())
4244 {
4245 32 e = {};
4246 32 return static_cast<T>(i);
4247 }
4248 44 e = error::not_exact;
4249 }
4250
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 17 times.
126 else if(sca_.k == json::kind::uint64)
4251 {
4252 92 auto const u = sca_.u;
4253
2/2
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 6 times.
92 if(u <= (std::numeric_limits<T>::max)())
4254 {
4255 80 e = {};
4256 80 return static_cast<T>(u);
4257 }
4258 12 e = error::not_exact;
4259 }
4260
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 5 times.
34 else if(sca_.k == json::kind::double_)
4261 {
4262 24 auto const d = sca_.d;
4263
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
16 if( d >= 0 &&
4264
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 8 times.
40 d <= (detail::to_number_limit<T>::max)() &&
4265
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
16 static_cast<T>(d) == d)
4266 {
4267 8 e = {};
4268 8 return static_cast<T>(d);
4269 }
4270 16 e = error::not_exact;
4271 }
4272 else
4273 {
4274 10 e = error::not_number;
4275 }
4276 82 return T{};
4277 }
4278
4279 template<class T>
4280 auto
4281 116 to_number(error& e) const noexcept ->
4282 typename std::enable_if<
4283 std::is_floating_point<
4284 T>::value, T>::type
4285 {
4286
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 42 times.
116 if(sca_.k == json::kind::int64)
4287 {
4288 32 e = {};
4289 32 return static_cast<T>(sca_.i);
4290 }
4291
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 32 times.
84 if(sca_.k == json::kind::uint64)
4292 {
4293 20 e = {};
4294 20 return static_cast<T>(sca_.u);
4295 }
4296
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 14 times.
64 if(sca_.k == json::kind::double_)
4297 {
4298 36 e = {};
4299 36 return static_cast<T>(sca_.d);
4300 }
4301 28 e = error::not_number;
4302 28 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 58814 times.
58814 if(sp.is_not_shared_and_deallocate_is_trivial())
4351 return;
4352
2/2
✓ Branch 0 taken 6633 times.
✓ Branch 1 taken 52181 times.
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
1/1
✓ Branch 3 taken 758 times.
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 15322 key_value_pair(
4475 string_view key,
4476 Args&&... args)
4477
2/2
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3719 times.
15324 : value_(std::forward<Args>(args)...)
4478 {
4479
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 7763 times.
15320 if(key.size() > string::max_size())
4480 {
4481 BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
4482 2 detail::throw_system_error( error::key_too_large, &loc );
4483 }
4484 auto s = reinterpret_cast<
4485 15318 char*>(value_.storage()->
4486
1/1
✓ Branch 3 taken 7457 times.
15318 allocate(key.size() + 1, alignof(char)));
4487 14706 std::memcpy(s, key.data(), key.size());
4488 14706 s[key.size()] = 0;
4489 14706 key_ = s;
4490 14706 len_ = static_cast<
4491 14706 std::uint32_t>(key.size());
4492 15320 }
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 key_value_pair(
4512 std::pair<
4513 string_view,
4514 json::value> const& p,
4515 storage_ptr sp = {})
4516 : key_value_pair(
4517 p.first,
4518 p.second,
4519 std::move(sp))
4520 {
4521 }
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
4868