GCC Code Coverage Report


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