2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
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)
8 // Official repository: https://github.com/boostorg/json
11 #ifndef BOOST_JSON_VALUE_HPP
12 #define BOOST_JSON_VALUE_HPP
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/storage_ptr.hpp>
20 #include <boost/json/string.hpp>
21 #include <boost/json/string_view.hpp>
22 #include <boost/json/value_ref.hpp>
23 #include <boost/json/detail/except.hpp>
24 #include <boost/json/detail/value.hpp>
27 #include <initializer_list>
31 #include <type_traits>
36 //----------------------------------------------------------
38 /** The type used to represent any JSON value
41 <a href="https://en.cppreference.com/w/cpp/concepts/regular"><em>Regular</em></a>.
44 a variant of the basic JSON data types: array,
45 object, string, number, boolean, and null.
49 Distinct instances may be accessed concurrently.
50 Non-const member functions of a shared instance
51 may not be called concurrently with any other
52 member functions of that instance.
56 #ifndef BOOST_JSON_DOCS
57 using scalar = detail::scalar;
61 storage_ptr sp_; // must come first
71 #ifndef BOOST_JSON_DOCS
72 // VFALCO doc toolchain incorrectly treats this as public
73 friend struct detail::access;
78 detail::unchecked_array&& ua)
85 detail::unchecked_object&& uo)
94 : str_(detail::key_t{}, s, std::move(sp))
103 : str_(detail::key_t{}, s1, s2, std::move(sp))
107 inline bool is_scalar() const noexcept
109 return sca_.k < json::kind::string;
113 /** The type of _Allocator_ returned by @ref get_allocator
115 This type is a @ref polymorphic_allocator.
117 #ifdef BOOST_JSON_DOCS
118 // VFALCO doc toolchain renders this incorrectly
119 using allocator_type = __see_below__;
121 using allocator_type = polymorphic_allocator<value>;
126 The value and all of its contents are destroyed.
127 Any dynamically allocated memory that was allocated
131 Constant, or linear in size for array or object.
133 @par Exception Safety
139 /** Default constructor.
141 The constructed value is null,
142 using the default memory resource.
147 @par Exception Safety
157 The constructed value is null,
158 using the specified @ref memory_resource.
163 @par Exception Safety
166 @param sp A pointer to the @ref memory_resource
167 to use. The container will acquire shared
168 ownership of the memory resource.
171 value(storage_ptr sp) noexcept
172 : sca_(std::move(sp))
176 /** Pilfer constructor.
178 The value is constructed by acquiring ownership
179 of the contents of `other` using pilfer semantics.
180 This is more efficient than move construction, when
181 it is known that the moved-from object will be
182 immediately destroyed afterwards.
187 @par Exception Safety
190 @param other The value to pilfer. After pilfer
191 construction, `other` is not in a usable state
192 and may only be destroyed.
195 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
196 Valueless Variants Considered Harmful</a>
198 value(pilfered<value> other) noexcept
200 relocate(this, other.get());
201 ::new(&other.get().sca_) scalar();
204 /** Copy constructor.
206 The value is constructed with a copy of the
207 contents of `other`, using the same
208 memory resource as `other`.
211 Linear in the size of `other`.
213 @par Exception Safety
215 Calls to `memory_resource::allocate` may throw.
217 @param other The value to copy.
219 value(value const& other)
220 : value(other, other.storage())
226 The value is constructed with a copy of the
227 contents of `other`, using the
228 specified memory resource.
231 Linear in the size of `other`.
233 @par Exception Safety
235 Calls to `memory_resource::allocate` may throw.
237 @param other The value to copy.
239 @param sp A pointer to the @ref memory_resource
240 to use. The container will acquire shared
241 ownership of the memory resource.
250 The value is constructed by acquiring ownership of
251 the contents of `other` and shared ownership of
252 `other`'s memory resource.
256 After construction, the moved-from value becomes a
257 null value with its current storage pointer.
262 @par Exception Safety
265 @param other The value to move.
268 value(value&& other) noexcept;
272 The value is constructed with the contents of
273 `other` by move semantics, using the specified
276 @li If `*other.storage() == *sp`, ownership of
277 the underlying memory is transferred in constant
278 time, with no possibility of exceptions.
279 After construction, the moved-from value becomes
280 a null value with its current storage pointer.
282 @li If `*other.storage() != *sp`, an
283 element-wise copy is performed if
284 `other.is_structured() == true`, which may throw.
285 In this case, the moved-from value is not
289 Constant or linear in the size of `other`.
291 @par Exception Safety
293 Calls to `memory_resource::allocate` may throw.
295 @param other The value to move.
297 @param sp A pointer to the @ref memory_resource
298 to use. The container will acquire shared
299 ownership of the memory resource.
306 //------------------------------------------------------
310 //------------------------------------------------------
312 /** Construct a null.
314 A null value is a monostate.
319 @par Exception Safety
322 @param sp A pointer to the @ref memory_resource
323 to use. The container will acquire shared
324 ownership of the memory resource.
328 storage_ptr sp = {}) noexcept
329 : sca_(std::move(sp))
333 /** Construct a bool.
335 This constructs a `bool` value using
336 the specified memory resource.
341 @par Exception Safety
344 @param b The initial value.
346 @param sp A pointer to the @ref memory_resource
347 to use. The container will acquire shared
348 ownership of the memory resource.
350 #ifdef BOOST_JSON_DOCS
353 storage_ptr sp = {}) noexcept;
356 ,class = typename std::enable_if<
357 std::is_same<Bool, bool>::value>::type
361 storage_ptr sp = {}) noexcept
362 : sca_(b, std::move(sp))
367 /** Construct a `std::int64_t`.
372 @par Exception Safety
375 @param i The initial value.
377 @param sp A pointer to the @ref memory_resource
378 to use. The container will acquire shared
379 ownership of the memory resource.
383 storage_ptr sp = {}) noexcept
384 : sca_(static_cast<std::int64_t>(
389 /** Construct a `std::int64_t`.
394 @par Exception Safety
397 @param i The initial value.
399 @param sp A pointer to the @ref memory_resource
400 to use. The container will acquire shared
401 ownership of the memory resource.
405 storage_ptr sp = {}) noexcept
406 : sca_(static_cast<std::int64_t>(
411 /** Construct a `std::int64_t`.
416 @par Exception Safety
419 @param i The initial value.
421 @param sp A pointer to the @ref memory_resource
422 to use. The container will acquire shared
423 ownership of the memory resource.
427 storage_ptr sp = {}) noexcept
428 : sca_(static_cast<std::int64_t>(i),
433 /** Construct a `std::int64_t`.
438 @par Exception Safety
441 @param i The initial value.
443 @param sp A pointer to the @ref memory_resource
444 to use. The container will acquire shared
445 ownership of the memory resource.
449 storage_ptr sp = {}) noexcept
450 : sca_(static_cast<std::int64_t>(i),
455 /** Construct a `std::int64_t`.
460 @par Exception Safety
463 @param i The initial value.
465 @param sp A pointer to the @ref memory_resource
466 to use. The container will acquire shared
467 ownership of the memory resource.
471 storage_ptr sp = {}) noexcept
472 : sca_(static_cast<std::int64_t>(i),
477 /** Construct a `std::uint64_t`.
482 @par Exception Safety
485 @param u The initial value.
487 @param sp A pointer to the @ref memory_resource
488 to use. The container will acquire shared
489 ownership of the memory resource.
493 storage_ptr sp = {}) noexcept
494 : sca_(static_cast<std::uint64_t>(
499 /** Construct a `std::uint64_t`.
504 @par Exception Safety
507 @param u The initial value.
509 @param sp A pointer to the @ref memory_resource
510 to use. The container will acquire shared
511 ownership of the memory resource.
515 storage_ptr sp = {}) noexcept
516 : sca_(static_cast<std::uint64_t>(u),
521 /** Construct a `std::uint64_t`.
526 @par Exception Safety
529 @param u The initial value.
531 @param sp A pointer to the @ref memory_resource
532 to use. The container will acquire shared
533 ownership of the memory resource.
537 storage_ptr sp = {}) noexcept
538 : sca_(static_cast<std::uint64_t>(u),
543 /** Construct a `std::uint64_t`.
548 @par Exception Safety
551 @param u The initial value.
553 @param sp A pointer to the @ref memory_resource
554 to use. The container will acquire shared
555 ownership of the memory resource.
559 storage_ptr sp = {}) noexcept
560 : sca_(static_cast<std::uint64_t>(u),
565 /** Construct a `std::uint64_t`.
570 @par Exception Safety
573 @param u The initial value.
575 @param sp A pointer to the @ref memory_resource
576 to use. The container will acquire shared
577 ownership of the memory resource.
580 unsigned long long u,
581 storage_ptr sp = {}) noexcept
582 : sca_(static_cast<std::uint64_t>(u),
587 /** Construct a `double`.
592 @par Exception Safety
595 @param d The initial value.
597 @param sp A pointer to the @ref memory_resource
598 to use. The container will acquire shared
599 ownership of the memory resource.
603 storage_ptr sp = {}) noexcept
604 : sca_(d, std::move(sp))
608 /** Construct a @ref string.
610 The string is constructed with a copy of the
611 string view `s`, using the specified memory resource.
614 Linear in `s.size()`.
616 @par Exception Safety
618 Calls to `memory_resource::allocate` may throw.
620 @param s The string view to construct with.
622 @param sp A pointer to the @ref memory_resource
623 to use. The container will acquire shared
624 ownership of the memory resource.
629 : str_(s, std::move(sp))
633 /** Construct a @ref string.
635 The string is constructed with a copy of the
636 null-terminated string `s`, using the specified
640 Linear in `std::strlen(s)`.
642 @par Exception Safety
644 Calls to `memory_resource::allocate` may throw.
646 @param s The null-terminated string to construct
649 @param sp A pointer to the @ref memory_resource
650 to use. The container will acquire shared
651 ownership of the memory resource.
656 : str_(s, std::move(sp))
660 /** Construct a @ref string.
662 The value is constructed from `other`, using the
663 same memory resource. To transfer ownership, use `std::move`:
667 string str = "The Boost C++ Library Collection";
669 // transfer ownership
670 value jv( std::move(str) );
672 assert( str.empty() );
673 assert( *str.storage() == *jv.storage() );
679 @par Exception Safety
682 @param other The string to construct with.
685 string other) noexcept
686 : str_(std::move(other))
690 /** Construct a @ref string.
692 The value is copy constructed from `other`,
693 using the specified memory resource.
696 Linear in `other.size()`.
698 @par Exception Safety
700 Calls to `memory_resource::allocate` may throw.
702 @param other The string to construct with.
704 @param sp A pointer to the @ref memory_resource
705 to use. The container will acquire shared
706 ownership of the memory resource.
717 /** Construct a @ref string.
719 The value is move constructed from `other`,
720 using the specified memory resource.
723 Constant or linear in `other.size()`.
725 @par Exception Safety
727 Calls to `memory_resource::allocate` may throw.
729 @param other The string to construct with.
731 @param sp A pointer to the @ref memory_resource
732 to use. The container will acquire shared
733 ownership of the memory resource.
744 /** Construct a @ref string.
746 This is the fastest way to construct
747 an empty string, using the specified
748 memory resource. The variable @ref string_kind
749 may be passed as the first parameter
750 to select this overload:
754 // Construct an empty string
756 value jv( string_kind );
762 @par Exception Safety
765 @param sp A pointer to the @ref memory_resource
766 to use. The container will acquire shared
767 ownership of the memory resource.
769 @see @ref string_kind
773 storage_ptr sp = {}) noexcept
774 : str_(std::move(sp))
778 /** Construct an @ref array.
780 The value is constructed from `other`, using the
781 same memory resource. To transfer ownership, use `std::move`:
785 array arr( {1, 2, 3, 4, 5} );
787 // transfer ownership
788 value jv( std::move(arr) );
790 assert( arr.empty() );
791 assert( *arr.storage() == *jv.storage() );
797 @par Exception Safety
800 @param other The array to construct with.
802 value(array other) noexcept
803 : arr_(std::move(other))
807 /** Construct an @ref array.
809 The value is copy constructed from `other`,
810 using the specified memory resource.
813 Linear in `other.size()`.
815 @par Exception Safety
817 Calls to `memory_resource::allocate` may throw.
819 @param other The array to construct with.
821 @param sp A pointer to the @ref memory_resource
822 to use. The container will acquire shared
823 ownership of the memory resource.
834 /** Construct an @ref array.
836 The value is move-constructed from `other`,
837 using the specified memory resource.
840 Constant or linear in `other.size()`.
842 @par Exception Safety
844 Calls to `memory_resource::allocate` may throw.
846 @param other The array to construct with.
848 @param sp A pointer to the @ref memory_resource
849 to use. The container will acquire shared
850 ownership of the memory resource.
861 /** Construct an @ref array.
863 This is the fastest way to construct
864 an empty array, using the specified
865 memory resource. The variable @ref array_kind
866 may be passed as the first parameter
867 to select this overload:
871 // Construct an empty array
873 value jv( array_kind );
879 @par Exception Safety
882 @param sp A pointer to the @ref memory_resource
883 to use. The container will acquire shared
884 ownership of the memory resource.
890 storage_ptr sp = {}) noexcept
891 : arr_(std::move(sp))
895 /** Construct an @ref object.
897 The value is constructed from `other`, using the
898 same memory resource. To transfer ownership, use `std::move`:
902 object obj( {{"a",1}, {"b",2}, {"c"},3}} );
904 // transfer ownership
905 value jv( std::move(obj) );
907 assert( obj.empty() );
908 assert( *obj.storage() == *jv.storage() );
914 @par Exception Safety
917 @param other The object to construct with.
919 value(object other) noexcept
920 : obj_(std::move(other))
924 /** Construct an @ref object.
926 The value is copy constructed from `other`,
927 using the specified memory resource.
930 Linear in `other.size()`.
932 @par Exception Safety
934 Calls to `memory_resource::allocate` may throw.
936 @param other The object to construct with.
938 @param sp A pointer to the @ref memory_resource
939 to use. The container will acquire shared
940 ownership of the memory resource.
951 /** Construct an @ref object.
953 The value is move constructed from `other`,
954 using the specified memory resource.
957 Constant or linear in `other.size()`.
959 @par Exception Safety
961 Calls to `memory_resource::allocate` may throw.
963 @param other The object to construct with.
965 @param sp A pointer to the @ref memory_resource
966 to use. The container will acquire shared
967 ownership of the memory resource.
978 /** Construct an @ref object.
980 This is the fastest way to construct
981 an empty object, using the specified
982 memory resource. The variable @ref object_kind
983 may be passed as the first parameter
984 to select this overload:
988 // Construct an empty object
990 value jv( object_kind );
996 @par Exception Safety
999 @param sp A pointer to the @ref memory_resource
1000 to use. The container will acquire shared
1001 ownership of the memory resource.
1003 @see @ref object_kind
1007 storage_ptr sp = {}) noexcept
1008 : obj_(std::move(sp))
1012 /** Construct from an initializer-list
1014 If the initializer list consists of key/value
1015 pairs, an @ref object is created. Otherwise
1016 an @ref array is created. The contents of the
1017 initializer list are copied to the newly constructed
1018 value using the specified memory resource.
1021 Linear in `init.size()`.
1023 @par Exception Safety
1025 Calls to `memory_resource::allocate` may throw.
1027 @param init The initializer list to construct from.
1029 @param sp A pointer to the @ref memory_resource
1030 to use. The container will acquire shared
1031 ownership of the memory resource.
1035 std::initializer_list<value_ref> init,
1036 storage_ptr sp = {});
1038 //------------------------------------------------------
1042 //------------------------------------------------------
1044 /** Copy assignment.
1046 The contents of the value are replaced with an
1047 element-wise copy of the contents of `other`.
1050 Linear in the size of `*this` plus `other`.
1052 @par Exception Safety
1054 Calls to `memory_resource::allocate` may throw.
1056 @param other The value to copy.
1060 operator=(value const& other);
1062 /** Move assignment.
1064 The contents of the value are replaced with the
1065 contents of `other` using move semantics:
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.
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
1080 Constant, or linear in
1081 `this->size()` plus `other.size()`.
1083 @par Exception Safety
1085 Calls to `memory_resource::allocate` may throw.
1087 @param other The value to assign from.
1091 operator=(value&& other);
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.
1104 Linear in `init.size()`.
1106 @par Exception Safety
1108 Calls to `memory_resource::allocate` may throw.
1110 @param init The initializer list to assign from.
1115 std::initializer_list<value_ref> init);
1119 Replace `*this` with null.
1121 @par Exception Safety
1125 Linear in the size of `*this`.
1128 operator=(std::nullptr_t) noexcept
1132 sca_.k = json::kind::null;
1136 ::new(&sca_) scalar(
1144 Replace `*this` with `b`.
1146 @par Exception Safety
1150 Linear in the size of `*this`.
1152 @param b The new value.
1154 #ifdef BOOST_JSON_DOCS
1155 value& operator=(bool b) noexcept;
1158 ,class = typename std::enable_if<
1159 std::is_same<Bool, bool>::value>::type
1161 value& operator=(Bool b) noexcept
1166 sca_.k = json::kind::bool_;
1170 ::new(&sca_) scalar(
1179 Replace `*this` with `i`.
1181 @par Exception Safety
1185 Linear in the size of `*this`.
1187 @param i The new value.
1190 value& operator=(signed char i) noexcept
1193 static_cast<long long>(i));
1196 value& operator=(short i) noexcept
1199 static_cast<long long>(i));
1202 value& operator=(int i) noexcept
1205 static_cast<long long>(i));
1208 value& operator=(long i) noexcept
1211 static_cast<long long>(i));
1214 value& operator=(long long i) noexcept
1219 sca_.k = json::kind::int64;
1223 ::new(&sca_) scalar(static_cast<
1224 std::int64_t>(i), destroy());
1232 Replace `*this` with `i`.
1234 @par Exception Safety
1238 Linear in the size of `*this`.
1240 @param u The new value.
1243 value& operator=(unsigned char u) noexcept
1245 return operator=(static_cast<
1246 unsigned long long>(u));
1249 value& operator=(unsigned short u) noexcept
1251 return operator=(static_cast<
1252 unsigned long long>(u));
1255 value& operator=(unsigned int u) noexcept
1257 return operator=(static_cast<
1258 unsigned long long>(u));
1261 value& operator=(unsigned long u) noexcept
1263 return operator=(static_cast<
1264 unsigned long long>(u));
1267 value& operator=(unsigned long long u) noexcept
1272 sca_.k = json::kind::uint64;
1276 ::new(&sca_) scalar(static_cast<
1277 std::uint64_t>(u), destroy());
1285 Replace `*this` with `d`.
1287 @par Exception Safety
1291 Linear in the size of `*this`.
1293 @param d The new value.
1295 value& operator=(double d) noexcept
1300 sca_.k = json::kind::double_;
1304 ::new(&sca_) scalar(
1312 Replace `*this` with a copy of the string `s`.
1314 @par Exception Safety
1316 Calls to `memory_resource::allocate` may throw.
1319 Linear in the sum of sizes of `*this` and `s`
1321 @param s The new string.
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);
1331 The contents of the value are replaced with the
1332 contents of `s` using move semantics:
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.
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
1346 Constant, or linear in the size of `*this` plus `s.size()`.
1348 @par Exception Safety
1350 Calls to `memory_resource::allocate` may throw.
1352 @param s The string to move-assign from.
1354 BOOST_JSON_DECL value& operator=(string&& s);
1358 Replace `*this` with a copy of the array `arr`.
1360 @par Exception Safety
1362 Calls to `memory_resource::allocate` may throw.
1365 Linear in the sum of sizes of `*this` and `arr`
1367 @param arr The new array.
1369 BOOST_JSON_DECL value& operator=(array const& arr);
1373 The contents of the value are replaced with the
1374 contents of `arr` using move semantics:
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.
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
1388 Constant, or linear in the size of `*this` plus `arr.size()`.
1390 @par Exception Safety
1392 Calls to `memory_resource::allocate` may throw.
1394 @param arr The array to move-assign from.
1396 BOOST_JSON_DECL value& operator=(array&& arr);
1400 Replace `*this` with a copy of the obect `obj`.
1402 @par Exception Safety
1404 Calls to `memory_resource::allocate` may throw.
1407 Linear in the sum of sizes of `*this` and `obj`
1409 @param obj The new object.
1411 BOOST_JSON_DECL value& operator=(object const& obj);
1415 The contents of the value are replaced with the
1416 contents of `obj` using move semantics:
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.
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
1430 Constant, or linear in the size of `*this` plus `obj.size()`.
1432 @par Exception Safety
1434 Calls to `memory_resource::allocate` may throw.
1436 @param obj The object to move-assign from.
1438 BOOST_JSON_DECL value& operator=(object&& obj);
1440 //------------------------------------------------------
1444 //------------------------------------------------------
1446 /** Change the kind to null, discarding the previous contents.
1448 The value is replaced with a null,
1449 destroying the previous contents.
1452 Linear in the size of `*this`.
1454 @par Exception Safety
1458 emplace_null() noexcept
1463 /** Return a reference to a `bool`, changing the kind and replacing the contents.
1465 The value is replaced with a `bool`
1466 initialized to `false`, destroying the
1470 Linear in the size of `*this`.
1472 @par Exception Safety
1476 emplace_bool() noexcept
1482 /** Return a reference to a `std::int64_t`, changing the kind and replacing the contents.
1484 The value is replaced with a `std::int64_t`
1485 initialized to zero, destroying the
1489 Linear in the size of `*this`.
1491 @par Exception Safety
1495 emplace_int64() noexcept
1497 *this = std::int64_t{};
1501 /** Return a reference to a `std::uint64_t`, changing the kind and replacing the contents.
1503 The value is replaced with a `std::uint64_t`
1504 initialized to zero, destroying the
1508 Linear in the size of `*this`.
1510 @par Exception Safety
1514 emplace_uint64() noexcept
1516 *this = std::uint64_t{};
1520 /** Return a reference to a `double`, changing the kind and replacing the contents.
1522 The value is replaced with a `double`
1523 initialized to zero, destroying the
1527 Linear in the size of `*this`.
1529 @par Exception Safety
1533 emplace_double() noexcept
1539 /** Return a reference to a @ref string, changing the kind and replacing the contents.
1541 The value is replaced with an empty @ref string
1542 using the current memory resource, destroying the
1546 Linear in the size of `*this`.
1548 @par Exception Safety
1553 emplace_string() noexcept;
1555 /** Return a reference to an @ref array, changing the kind and replacing the contents.
1557 The value is replaced with an empty @ref array
1558 using the current memory resource, destroying the
1562 Linear in the size of `*this`.
1564 @par Exception Safety
1569 emplace_array() noexcept;
1571 /** Return a reference to an @ref object, changing the kind and replacing the contents.
1573 The contents are replaced with an empty @ref object
1574 using the current @ref memory_resource. All
1575 previously obtained iterators and references
1576 obtained beforehand are invalidated.
1579 Linear in the size of `*this`.
1581 @par Exception Safety
1586 emplace_object() noexcept;
1588 /** Swap the given values.
1590 Exchanges the contents of this value with another
1591 value. Ownership of the respective @ref memory_resource
1592 objects is not transferred:
1594 @li If `*other.storage() == *this->storage()`,
1595 ownership of the underlying memory is swapped in
1596 constant time, with no possibility of exceptions.
1597 All iterators and references remain valid.
1599 @li If `*other.storage() != *this->storage()`,
1600 the contents are logically swapped by making copies,
1601 which can throw. In this case all iterators and
1602 references are invalidated.
1605 Constant or linear in the sum of the sizes of
1608 @par Exception Safety
1610 Calls to `memory_resource::allocate` may throw.
1612 @param other The value to swap with.
1613 If `this == &other`, this function call has no effect.
1619 /** Swap the given values.
1621 Exchanges the contents of value `lhs` with
1622 another value `rhs`. Ownership of the respective
1623 @ref memory_resource objects is not transferred.
1625 @li If `*lhs.storage() == *rhs.storage()`,
1626 ownership of the underlying memory is swapped in
1627 constant time, with no possibility of exceptions.
1628 All iterators and references remain valid.
1630 @li If `*lhs.storage() != *rhs.storage`,
1631 the contents are logically swapped by a copy,
1632 which can throw. In this case all iterators and
1633 references are invalidated.
1641 Constant or linear in the sum of the sizes of
1644 @par Exception Safety
1646 Calls to `memory_resource::allocate` may throw.
1648 @param lhs The value to exchange.
1650 @param rhs The value to exchange.
1651 If `&lhs == &rhs`, this function call has no effect.
1653 @see @ref value::swap
1657 swap(value& lhs, value& rhs)
1662 //------------------------------------------------------
1666 //------------------------------------------------------
1668 /** Returns the kind of this JSON value.
1670 This function returns the discriminating
1671 enumeration constant of type @ref json::kind
1672 corresponding to the underlying representation
1673 stored in the container.
1678 @par Exception Safety
1682 kind() const noexcept
1684 return static_cast<json::kind>(
1685 static_cast<unsigned char>(
1689 /** Return `true` if this is an array
1691 This function is used to determine if the underlying
1692 representation is a certain kind.
1696 return this->kind() == kind::array;
1702 @par Exception Safety
1706 is_array() const noexcept
1708 return kind() == json::kind::array;
1711 /** Return `true` if this is an object
1713 This function is used to determine if the underlying
1714 representation is a certain kind.
1718 return this->kind() == kind::object;
1724 @par Exception Safety
1728 is_object() const noexcept
1730 return kind() == json::kind::object;
1733 /** Return `true` if this is a string
1735 This function is used to determine if the underlying
1736 representation is a certain kind.
1740 return this->kind() == kind::string;
1746 @par Exception Safety
1750 is_string() const noexcept
1752 return kind() == json::kind::string;
1755 /** Return `true` if this is a signed integer
1757 This function is used to determine if the underlying
1758 representation is a certain kind.
1762 return this->kind() == kind::int64;
1768 @par Exception Safety
1772 is_int64() const noexcept
1774 return kind() == json::kind::int64;
1777 /** Return `true` if this is a unsigned integer
1779 This function is used to determine if the underlying
1780 representation is a certain kind.
1784 return this->kind() == kind::uint64;
1790 @par Exception Safety
1794 is_uint64() const noexcept
1796 return kind() == json::kind::uint64;
1799 /** Return `true` if this is a double
1801 This function is used to determine if the underlying
1802 representation is a certain kind.
1806 return this->kind() == kind::double_;
1812 @par Exception Safety
1816 is_double() const noexcept
1818 return kind() == json::kind::double_;
1821 /** Return `true` if this is a bool
1823 This function is used to determine if the underlying
1824 representation is a certain kind.
1828 return this->kind() == kind::bool_;
1834 @par Exception Safety
1838 is_bool() const noexcept
1840 return kind() == json::kind::bool_;
1843 /** Returns true if this is a null.
1845 This function is used to determine if the underlying
1846 representation is a certain kind.
1850 return this->kind() == kind::null;
1856 @par Exception Safety
1860 is_null() const noexcept
1862 return kind() == json::kind::null;
1865 /** Returns true if this is an array or object.
1867 This function returns `true` if
1868 @ref kind() is either `kind::object` or
1874 @par Exception Safety
1878 is_structured() const noexcept
1880 // VFALCO Could use bit 0x20 for this
1882 kind() == json::kind::object ||
1883 kind() == json::kind::array;
1886 /** Returns true if this is not an array or object.
1888 This function returns `true` if
1889 @ref kind() is neither `kind::object` nor
1895 @par Exception Safety
1899 is_primitive() const noexcept
1901 // VFALCO Could use bit 0x20 for this
1903 sca_.k != json::kind::object &&
1904 sca_.k != json::kind::array;
1907 /** Returns true if this is a number.
1909 This function returns `true` when
1910 @ref kind() is one of the following values:
1911 `kind::int64`, `kind::uint64`, or
1917 @par Exception Safety
1921 is_number() const noexcept
1923 // VFALCO Could use bit 0x40 for this
1925 kind() == json::kind::int64 ||
1926 kind() == json::kind::uint64 ||
1927 kind() == json::kind::double_;
1930 //------------------------------------------------------
1932 /** Return an @ref array pointer if this is an array, else return `nullptr`
1934 If `this->kind() == kind::array`, returns a pointer
1935 to the underlying array. Otherwise, returns `nullptr`.
1938 The return value is used in both a boolean context and
1939 to assign a variable:
1941 if( auto p = jv.if_array() )
1948 @par Exception Safety
1952 if_array() const noexcept
1954 if(kind() == json::kind::array)
1959 /** Return an @ref array pointer if this is an array, else return `nullptr`
1961 If `this->kind() == kind::array`, returns a pointer
1962 to the underlying array. Otherwise, returns `nullptr`.
1965 The return value is used in both a boolean context and
1966 to assign a variable:
1968 if( auto p = jv.if_array() )
1975 @par Exception Safety
1981 if(kind() == json::kind::array)
1986 /** Return an @ref object pointer if this is an object, else return `nullptr`
1988 If `this->kind() == kind::object`, returns a pointer
1989 to the underlying object. Otherwise, returns `nullptr`.
1992 The return value is used in both a boolean context and
1993 to assign a variable:
1995 if( auto p = jv.if_object() )
2002 @par Exception Safety
2006 if_object() const noexcept
2008 if(kind() == json::kind::object)
2013 /** Return an @ref object pointer if this is an object, else return `nullptr`
2015 If `this->kind() == kind::object`, returns a pointer
2016 to the underlying object. Otherwise, returns `nullptr`.
2019 The return value is used in both a boolean context and
2020 to assign a variable:
2022 if( auto p = jv.if_object() )
2029 @par Exception Safety
2033 if_object() noexcept
2035 if(kind() == json::kind::object)
2040 /** Return a @ref string pointer if this is a string, else return `nullptr`
2042 If `this->kind() == kind::string`, returns a pointer
2043 to the underlying object. Otherwise, returns `nullptr`.
2046 The return value is used in both a boolean context and
2047 to assign a variable:
2049 if( auto p = jv.if_string() )
2056 @par Exception Safety
2060 if_string() const noexcept
2062 if(kind() == json::kind::string)
2067 /** Return a @ref string pointer if this is a string, else return `nullptr`
2069 If `this->kind() == kind::string`, returns a pointer
2070 to the underlying object. Otherwise, returns `nullptr`.
2073 The return value is used in both a boolean context and
2074 to assign a variable:
2076 if( auto p = jv.if_string() )
2083 @par Exception Safety
2087 if_string() noexcept
2089 if(kind() == json::kind::string)
2094 /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
2096 If `this->kind() == kind::int64`, returns a pointer
2097 to the underlying integer. Otherwise, returns `nullptr`.
2100 The return value is used in both a boolean context and
2101 to assign a variable:
2103 if( auto p = jv.if_int64() )
2110 @par Exception Safety
2114 if_int64() const noexcept
2116 if(kind() == json::kind::int64)
2121 /** Return an `int64_t` pointer if this is a signed integer, else return `nullptr`
2123 If `this->kind() == kind::int64`, returns a pointer
2124 to the underlying integer. Otherwise, returns `nullptr`.
2127 The return value is used in both a boolean context and
2128 to assign a variable:
2130 if( auto p = jv.if_int64() )
2137 @par Exception Safety
2143 if(kind() == json::kind::int64)
2148 /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
2150 If `this->kind() == kind::uint64`, returns a pointer
2151 to the underlying unsigned integer. Otherwise, returns
2155 The return value is used in both a boolean context and
2156 to assign a variable:
2158 if( auto p = jv.if_uint64() )
2165 @par Exception Safety
2168 std::uint64_t const*
2169 if_uint64() const noexcept
2171 if(kind() == json::kind::uint64)
2176 /** Return a `uint64_t` pointer if this is an unsigned integer, else return `nullptr`
2178 If `this->kind() == kind::uint64`, returns a pointer
2179 to the underlying unsigned integer. Otherwise, returns
2183 The return value is used in both a boolean context and
2184 to assign a variable:
2186 if( auto p = jv.if_uint64() )
2193 @par Exception Safety
2197 if_uint64() noexcept
2199 if(kind() == json::kind::uint64)
2204 /** Return a `double` pointer if this is a double, else return `nullptr`
2206 If `this->kind() == kind::double_`, returns a pointer
2207 to the underlying double. Otherwise, returns
2211 The return value is used in both a boolean context and
2212 to assign a variable:
2214 if( auto p = jv.if_double() )
2221 @par Exception Safety
2225 if_double() const noexcept
2227 if(kind() == json::kind::double_)
2232 /** Return a `double` pointer if this is a double, else return `nullptr`
2234 If `this->kind() == kind::double_`, returns a pointer
2235 to the underlying double. Otherwise, returns
2239 The return value is used in both a boolean context and
2240 to assign a variable:
2242 if( auto p = jv.if_double() )
2249 @par Exception Safety
2253 if_double() noexcept
2255 if(kind() == json::kind::double_)
2260 /** Return a `bool` pointer if this is a boolean, else return `nullptr`
2262 If `this->kind() == kind::bool_`, returns a pointer
2263 to the underlying boolean. Otherwise, returns
2267 The return value is used in both a boolean context and
2268 to assign a variable:
2270 if( auto p = jv.if_bool() )
2277 @par Exception Safety
2281 if_bool() const noexcept
2283 if(kind() == json::kind::bool_)
2288 /** Return a `bool` pointer if this is a boolean, else return `nullptr`
2290 If `this->kind() == kind::bool_`, returns a pointer
2291 to the underlying boolean. Otherwise, returns
2295 The return value is used in both a boolean context and
2296 to assign a variable:
2298 if( auto p = jv.if_bool() )
2305 @par Exception Safety
2311 if(kind() == json::kind::bool_)
2316 //------------------------------------------------------
2318 /** Return the stored number cast to an arithmetic type.
2320 This function attempts to return the stored value
2321 converted to the arithmetic type `T` which may not
2324 @li If `T` is an integral type and the stored
2325 value is a number which can be losslessly converted,
2326 the conversion is performed without error and the
2327 converted number is returned.
2329 @li If `T` is an integral type and the stored value
2330 is a number which cannot be losslessly converted,
2331 then the operation fails with an error.
2333 @li If `T` is a floating point type and the stored
2334 value is a number, the conversion is performed
2335 without error. The converted number is returned,
2336 with a possible loss of precision.
2338 @li Otherwise, if the stored value is not a number;
2339 that is, if `this->is_number()` returns `false`, then
2340 the operation fails with an error.
2344 std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
2350 @par Exception Safety
2353 @return The converted number.
2355 @param ec Set to the error, if any occurred.
2357 #ifdef BOOST_JSON_DOCS
2359 T to_number(error_code& ec) const noexcept;
2362 /** Return the stored number cast to an arithmetic type.
2364 This function attempts to return the stored value
2365 converted to the arithmetic type `T` which may not
2368 @li If `T` is an integral type and the stored
2369 value is a number which can be losslessly converted,
2370 the conversion is performed without error and the
2371 converted number is returned.
2373 @li If `T` is an integral type and the stored value
2374 is a number which cannot be losslessly converted,
2375 then the operation fails with an error.
2377 @li If `T` is a floating point type and the stored
2378 value is a number, the conversion is performed
2379 without error. The converted number is returned,
2380 with a possible loss of precision.
2382 @li Otherwise, if the stored value is not a number;
2383 that is, if `this->is_number()` returns `false`, then
2384 the operation fails with an error.
2388 std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
2394 @return The converted number.
2396 @throw system_error on error.
2399 #ifdef BOOST_JSON_DOCS
2402 typename std::enable_if<
2403 std::is_arithmetic<T>::value &&
2404 ! std::is_same<T, bool>::value,
2410 auto result = to_number<T>(ec);
2412 detail::throw_system_error(ec,
2413 BOOST_CURRENT_LOCATION);
2417 #ifndef BOOST_JSON_DOCS
2420 to_number(error_code& ec) const noexcept ->
2421 typename std::enable_if<
2422 std::is_signed<T>::value &&
2423 ! std::is_floating_point<T>::value,
2426 if(sca_.k == json::kind::int64)
2428 auto const i = sca_.i;
2429 if( i >= (std::numeric_limits<T>::min)() &&
2430 i <= (std::numeric_limits<T>::max)())
2433 return static_cast<T>(i);
2435 ec = error::not_exact;
2437 else if(sca_.k == json::kind::uint64)
2439 auto const u = sca_.u;
2440 if(u <= static_cast<std::uint64_t>((
2441 std::numeric_limits<T>::max)()))
2444 return static_cast<T>(u);
2446 ec = error::not_exact;
2448 else if(sca_.k == json::kind::double_)
2450 auto const d = sca_.d;
2451 if( d >= static_cast<double>(
2452 (detail::to_number_limit<T>::min)()) &&
2453 d <= static_cast<double>(
2454 (detail::to_number_limit<T>::max)()) &&
2455 static_cast<T>(d) == d)
2458 return static_cast<T>(d);
2460 ec = error::not_exact;
2464 ec = error::not_number;
2471 to_number(error_code& ec) const noexcept ->
2472 typename std::enable_if<
2473 std::is_unsigned<T>::value &&
2474 ! std::is_same<T, bool>::value,
2477 if(sca_.k == json::kind::int64)
2479 auto const i = sca_.i;
2480 if( i >= 0 && static_cast<std::uint64_t>(i) <=
2481 (std::numeric_limits<T>::max)())
2484 return static_cast<T>(i);
2486 ec = error::not_exact;
2488 else if(sca_.k == json::kind::uint64)
2490 auto const u = sca_.u;
2491 if(u <= (std::numeric_limits<T>::max)())
2494 return static_cast<T>(u);
2496 ec = error::not_exact;
2498 else if(sca_.k == json::kind::double_)
2500 auto const d = sca_.d;
2502 d <= (detail::to_number_limit<T>::max)() &&
2503 static_cast<T>(d) == d)
2506 return static_cast<T>(d);
2508 ec = error::not_exact;
2512 ec = error::not_number;
2519 to_number(error_code& ec) const noexcept ->
2520 typename std::enable_if<
2521 std::is_floating_point<
2524 if(sca_.k == json::kind::int64)
2527 return static_cast<T>(sca_.i);
2529 if(sca_.k == json::kind::uint64)
2532 return static_cast<T>(sca_.u);
2534 if(sca_.k == json::kind::double_)
2537 return static_cast<T>(sca_.d);
2539 ec = error::not_number;
2544 //------------------------------------------------------
2548 //------------------------------------------------------
2550 /** Return the memory resource associated with the value.
2552 This returns a pointer to the memory resource
2553 that was used to construct the value.
2558 @par Exception Safety
2562 storage() const noexcept
2567 /** Return the associated @ref memory_resource
2569 This function returns an instance of
2570 @ref polymorphic_allocator constructed from the
2571 associated @ref memory_resource.
2576 @par Exception Safety
2580 get_allocator() const noexcept
2585 //------------------------------------------------------
2587 /** Return a reference to the underlying `object`, or throw an exception.
2589 If @ref is_object() is `true`, returns
2590 a reference to the underlying @ref object,
2591 otherwise throws an exception.
2596 @par Exception Safety
2599 @throw std::invalid_argument `! this->is_object()`
2605 detail::throw_invalid_argument(
2607 BOOST_CURRENT_LOCATION);
2611 /** Return a reference to the underlying `object`, or throw an exception.
2613 If @ref is_object() is `true`, returns
2614 a reference to the underlying @ref object,
2615 otherwise throws an exception.
2620 @par Exception Safety
2623 @throw std::invalid_argument `! this->is_object()`
2629 detail::throw_invalid_argument(
2631 BOOST_CURRENT_LOCATION);
2635 /** Return a reference to the underlying @ref array, or throw an exception.
2637 If @ref is_array() is `true`, returns
2638 a reference to the underlying @ref array,
2639 otherwise throws an exception.
2644 @par Exception Safety
2647 @throw std::invalid_argument `! this->is_array()`
2653 detail::throw_invalid_argument(
2655 BOOST_CURRENT_LOCATION);
2659 /** Return a reference to the underlying `array`, or throw an exception.
2661 If @ref is_array() is `true`, returns
2662 a reference to the underlying @ref array,
2663 otherwise throws an exception.
2668 @par Exception Safety
2671 @throw std::invalid_argument `! this->is_array()`
2677 detail::throw_invalid_argument(
2679 BOOST_CURRENT_LOCATION);
2683 /** Return a reference to the underlying `string`, or throw an exception.
2685 If @ref is_string() is `true`, returns
2686 a reference to the underlying @ref string,
2687 otherwise throws an exception.
2692 @par Exception Safety
2695 @throw std::invalid_argument `! this->is_string()`
2701 detail::throw_invalid_argument(
2703 BOOST_CURRENT_LOCATION);
2707 /** Return a reference to the underlying `string`, or throw an exception.
2709 If @ref is_string() is `true`, returns
2710 a reference to the underlying @ref string,
2711 otherwise throws an exception.
2716 @par Exception Safety
2719 @throw std::invalid_argument `! this->is_string()`
2725 detail::throw_invalid_argument(
2727 BOOST_CURRENT_LOCATION);
2731 /** Return a reference to the underlying `std::int64_t`, or throw an exception.
2733 If @ref is_int64() is `true`, returns
2734 a reference to the underlying `std::int64_t`,
2735 otherwise throws an exception.
2740 @par Exception Safety
2743 @throw std::invalid_argument `! this->is_int64()`
2749 detail::throw_invalid_argument(
2751 BOOST_CURRENT_LOCATION);
2755 /** Return the underlying `std::int64_t`, or throw an exception.
2757 If @ref is_int64() is `true`, returns
2758 the underlying `std::int64_t`,
2759 otherwise throws an exception.
2764 @par Exception Safety
2767 @throw std::invalid_argument `! this->is_int64()`
2773 detail::throw_invalid_argument(
2775 BOOST_CURRENT_LOCATION);
2779 /** Return a reference to the underlying `std::uint64_t`, or throw an exception.
2781 If @ref is_uint64() is `true`, returns
2782 a reference to the underlying `std::uint64_t`,
2783 otherwise throws an exception.
2788 @par Exception Safety
2791 @throw std::invalid_argument `! this->is_uint64()`
2797 detail::throw_invalid_argument(
2799 BOOST_CURRENT_LOCATION);
2803 /** Return the underlying `std::uint64_t`, or throw an exception.
2805 If @ref is_int64() is `true`, returns
2806 the underlying `std::uint64_t`,
2807 otherwise throws an exception.
2812 @par Exception Safety
2815 @throw std::length_error `! this->is_uint64()`
2821 detail::throw_invalid_argument(
2823 BOOST_CURRENT_LOCATION);
2827 /** Return a reference to the underlying `double`, or throw an exception.
2829 If @ref is_double() is `true`, returns
2830 a reference to the underlying `double`,
2831 otherwise throws an exception.
2836 @par Exception Safety
2839 @throw std::invalid_argument `! this->is_double()`
2845 detail::throw_invalid_argument(
2847 BOOST_CURRENT_LOCATION);
2851 /** Return the underlying `double`, or throw an exception.
2853 If @ref is_int64() is `true`, returns
2854 the underlying `double`,
2855 otherwise throws an exception.
2860 @par Exception Safety
2863 @throw std::invalid_argument `! this->is_double()`
2869 detail::throw_invalid_argument(
2871 BOOST_CURRENT_LOCATION);
2875 /** Return a reference to the underlying `bool`, or throw an exception.
2877 If @ref is_bool() is `true`, returns
2878 a reference to the underlying `bool`,
2879 otherwise throws an exception.
2884 @par Exception Safety
2887 @throw std::invalid_argument `! this->is_bool()`
2893 detail::throw_invalid_argument(
2895 BOOST_CURRENT_LOCATION);
2899 /** Return the underlying `bool`, or throw an exception.
2901 If @ref is_bool() is `true`, returns
2902 the underlying `bool`,
2903 otherwise throws an exception.
2908 @par Exception Safety
2911 @throw std::invalid_argument `! this->is_bool()`
2917 detail::throw_invalid_argument(
2919 BOOST_CURRENT_LOCATION);
2923 //------------------------------------------------------
2925 /** Return a reference to the underlying `object`, without checking.
2927 This is the fastest way to access the underlying
2928 representation when the kind is known in advance.
2939 @par Exception Safety
2943 get_object() noexcept
2945 BOOST_ASSERT(is_object());
2949 /** Return a reference to the underlying `object`, without checking.
2951 This is the fastest way to access the underlying
2952 representation when the kind is known in advance.
2963 @par Exception Safety
2967 get_object() const noexcept
2969 BOOST_ASSERT(is_object());
2973 /** Return a reference to the underlying `array`, without checking.
2975 This is the fastest way to access the underlying
2976 representation when the kind is known in advance.
2987 @par Exception Safety
2991 get_array() noexcept
2993 BOOST_ASSERT(is_array());
2997 /** Return a reference to the underlying `array`, without checking.
2999 This is the fastest way to access the underlying
3000 representation when the kind is known in advance.
3011 @par Exception Safety
3015 get_array() const noexcept
3017 BOOST_ASSERT(is_array());
3021 /** Return a reference to the underlying `string`, without checking.
3023 This is the fastest way to access the underlying
3024 representation when the kind is known in advance.
3035 @par Exception Safety
3039 get_string() noexcept
3041 BOOST_ASSERT(is_string());
3045 /** Return a reference to the underlying `string`, without checking.
3047 This is the fastest way to access the underlying
3048 representation when the kind is known in advance.
3059 @par Exception Safety
3063 get_string() const noexcept
3065 BOOST_ASSERT(is_string());
3069 /** Return a reference to the underlying `std::int64_t`, without checking.
3071 This is the fastest way to access the underlying
3072 representation when the kind is known in advance.
3083 @par Exception Safety
3087 get_int64() noexcept
3089 BOOST_ASSERT(is_int64());
3093 /** Return the underlying `std::int64_t`, without checking.
3095 This is the fastest way to access the underlying
3096 representation when the kind is known in advance.
3107 @par Exception Safety
3111 get_int64() const noexcept
3113 BOOST_ASSERT(is_int64());
3117 /** Return a reference to the underlying `std::uint64_t`, without checking.
3119 This is the fastest way to access the underlying
3120 representation when the kind is known in advance.
3131 @par Exception Safety
3135 get_uint64() noexcept
3137 BOOST_ASSERT(is_uint64());
3141 /** Return the underlying `std::uint64_t`, without checking.
3143 This is the fastest way to access the underlying
3144 representation when the kind is known in advance.
3155 @par Exception Safety
3159 get_uint64() const noexcept
3161 BOOST_ASSERT(is_uint64());
3165 /** Return a reference to the underlying `double`, without checking.
3167 This is the fastest way to access the underlying
3168 representation when the kind is known in advance.
3179 @par Exception Safety
3183 get_double() noexcept
3185 BOOST_ASSERT(is_double());
3189 /** Return the underlying `double`, without checking.
3191 This is the fastest way to access the underlying
3192 representation when the kind is known in advance.
3203 @par Exception Safety
3207 get_double() const noexcept
3209 BOOST_ASSERT(is_double());
3213 /** Return a reference to the underlying `bool`, without checking.
3215 This is the fastest way to access the underlying
3216 representation when the kind is known in advance.
3227 @par Exception Safety
3233 BOOST_ASSERT(is_bool());
3237 /** Return the underlying `bool`, without checking.
3239 This is the fastest way to access the underlying
3240 representation when the kind is known in advance.
3251 @par Exception Safety
3255 get_bool() const noexcept
3257 BOOST_ASSERT(is_bool());
3261 //------------------------------------------------------
3263 /** Access an element, with bounds checking.
3265 This function is used to access elements of
3266 the underlying object, or throw an exception
3267 if the value is not an object.
3272 @par Exception Safety
3275 @param key The key of the element to find.
3277 @return `this->as_object().at( key )`.
3280 at(string_view key) const
3282 return as_object().at(key);
3285 /** Access an element, with bounds checking.
3287 This function is used to access elements of
3288 the underlying array, or throw an exception
3289 if the value is not an array.
3294 @par Exception Safety
3297 @param pos A zero-based array index.
3299 @return `this->as_array().at( pos )`.
3302 at(std::size_t pos) const
3304 return as_array().at(pos);
3307 /** Return `true` if two values are equal.
3309 Two values are equal when they are the
3310 same kind and their referenced values
3311 are equal, or when they are both integral
3312 types and their integral representations
3316 Constant or linear in the size of
3317 the array, object, or string.
3319 @par Exception Safety
3322 // inline friend speeds up overload resolution
3327 value const& rhs) noexcept
3329 return lhs.equal(rhs);
3332 /** Return `true` if two values are not equal.
3334 Two values are equal when they are the
3335 same kind and their referenced values
3336 are equal, or when they are both integral
3337 types and their integral representations
3341 Constant or linear in the size of
3342 the array, object, or string.
3344 @par Exception Safety
3351 value const& rhs) noexcept
3353 return ! (lhs == rhs);
3361 value const& src) noexcept
3364 static_cast<void*>(dest),
3375 equal(value const& other) const noexcept;
3378 // Make sure things are as big as we think they should be
3379 #if BOOST_JSON_ARCH == 64
3380 BOOST_STATIC_ASSERT(sizeof(value) == 24);
3381 #elif BOOST_JSON_ARCH == 32
3382 BOOST_STATIC_ASSERT(sizeof(value) == 16);
3384 # error Unknown architecture
3387 //----------------------------------------------------------
3389 /** A key/value pair.
3391 This is the type of element used by the @ref object
3394 class key_value_pair
3396 #ifndef BOOST_JSON_DOCS
3397 friend struct detail::access;
3398 using access = detail::access;
3402 static char const empty_[1];
3406 pilfered<json::value> k,
3407 pilfered<json::value> v) noexcept;
3410 /// Copy assignment (deleted).
3412 operator=(key_value_pair const&) = delete;
3416 The value is destroyed and all internally
3417 allocated memory is freed.
3421 auto const& sp = value_.storage();
3422 if(sp.is_not_shared_and_deallocate_is_trivial())
3426 sp->deallocate(const_cast<char*>(key_),
3427 len_ + 1, alignof(char));
3430 /** Copy constructor.
3432 This constructs a key/value pair with a
3433 copy of another key/value pair, using
3434 the same memory resource as `other`.
3436 @par Exception Safety
3438 Calls to `memory_resource::allocate` may throw.
3440 @param other The key/value pair to copy.
3443 key_value_pair const& other)
3444 : key_value_pair(other,
3449 /** Copy constructor.
3451 This constructs a key/value pair with a
3452 copy of another key/value pair, using
3453 the specified memory resource.
3455 @par Exception Safety
3457 Calls to `memory_resource::allocate` may throw.
3459 @param other The key/value pair to copy.
3461 @param sp A pointer to the @ref memory_resource
3462 to use. The element will acquire shared
3463 ownership of the memory resource.
3467 key_value_pair const& other,
3470 /** Move constructor.
3472 The pair is constructed by acquiring
3473 ownership of the contents of `other` and
3474 shared ownership of `other`'s memory resource.
3478 After construction, the moved-from pair holds an
3479 empty key, and a null value with its current
3485 @par Exception Safety
3488 @param other The pair to move.
3491 key_value_pair&& other) noexcept
3492 : value_(std::move(other.value_))
3493 , key_(detail::exchange(
3494 other.key_, empty_))
3495 , len_(detail::exchange(
3500 /** Pilfer constructor.
3502 The pair is constructed by acquiring ownership
3503 of the contents of `other` using pilfer semantics.
3504 This is more efficient than move construction, when
3505 it is known that the moved-from object will be
3506 immediately destroyed afterwards.
3511 @par Exception Safety
3514 @param other The value to pilfer. After pilfer
3515 construction, `other` is not in a usable state
3516 and may only be destroyed.
3519 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
3520 Valueless Variants Considered Harmful</a>
3523 pilfered<key_value_pair> other) noexcept
3524 : value_(pilfer(other.get().value_))
3525 , key_(detail::exchange(
3526 other.get().key_, empty_))
3527 , len_(detail::exchange(
3528 other.get().len_, 0))
3534 This constructs a key/value pair.
3536 @par Exception Safety
3538 Calls to `memory_resource::allocate` may throw.
3540 @param key The key string to use.
3542 @param args Optional arguments forwarded to
3543 the @ref value constructor.
3545 template<class... Args>
3550 : value_(std::forward<Args>(args)...)
3552 if(key.size() > string::max_size())
3553 detail::throw_length_error(
3555 BOOST_CURRENT_LOCATION);
3556 auto s = reinterpret_cast<
3557 char*>(value_.storage()->
3558 allocate(key.size() + 1));
3559 std::memcpy(s, key.data(), key.size());
3563 std::uint32_t>(key.size());
3568 This constructs a key/value pair. A
3569 copy of the specified value is made,
3570 using the specified memory resource.
3572 @par Exception Safety
3574 Calls to `memory_resource::allocate` may throw.
3576 @param p A `std::pair` with the key
3577 string and @ref value to construct with.
3579 @param sp A pointer to the @ref memory_resource
3580 to use. The element will acquire shared
3581 ownership of the memory resource.
3587 json::value> const& p,
3588 storage_ptr sp = {})
3598 This constructs a key/value pair.
3599 Ownership of the specified value is
3600 transferred by move construction.
3602 @par Exception Safety
3604 Calls to `memory_resource::allocate` may throw.
3606 @param p A `std::pair` with the key
3607 string and @ref value to construct with.
3609 @param sp A pointer to the @ref memory_resource
3610 to use. The element will acquire shared
3611 ownership of the memory resource.
3618 storage_ptr sp = {})
3621 std::move(p).second,
3626 /** Return the associated memory resource.
3628 This returns a pointer to the memory
3629 resource used to construct the value.
3634 @par Exception Safety
3638 storage() const noexcept
3640 return value_.storage();
3643 /** Return the key of this element.
3645 After construction, the key may
3651 @par Exception Safety
3655 key() const noexcept
3657 return { key_, len_ };
3660 /** Return the key of this element as a null-terminated string.
3665 @par Exception Safety
3669 key_c_str() const noexcept
3674 /** Return the value of this element.
3679 @par Exception Safety
3683 value() const noexcept
3688 /** Return the value of this element.
3693 @par Exception Safety
3706 std::uint32_t next_;
3709 //----------------------------------------------------------
3711 #ifdef BOOST_JSON_DOCS
3713 /** Tuple-like element access.
3715 This overload permits the key and value
3716 of a `key_value_pair` to be accessed
3717 by index. For example:
3721 key_value_pair kvp("num", 42);
3723 string_view key = get<0>(kvp);
3724 value& jv = get<1>(kvp);
3728 @par Structured Bindings
3730 When using C++17 or greater, objects of type
3731 @ref key_value_pair may be used to initialize
3732 structured bindings:
3736 key_value_pair kvp("num", 42);
3738 auto& [key, value] = kvp;
3742 Depending on the value of `I`, the return type will be:
3744 @li `string_view const` if `I == 0`, or
3746 @li `value&`, `value const&`, or `value&&` if `I == 1`.
3748 Any other value for `I` is ill-formed.
3750 @tparam I The element index to access.
3754 `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
3756 @return `kvp.key()` if `I == 0`, or `kvp.value()`
3759 @param kvp The @ref key_value_pair object
3766 get(T&& kvp) noexcept;
3770 template<std::size_t I>
3772 get(key_value_pair const&) noexcept ->
3773 typename std::conditional<I == 0,
3777 static_assert(I == 0,
3778 "key_value_pair index out of range");
3781 template<std::size_t I>
3783 get(key_value_pair&) noexcept ->
3784 typename std::conditional<I == 0,
3788 static_assert(I == 0,
3789 "key_value_pair index out of range");
3792 template<std::size_t I>
3794 get(key_value_pair&&) noexcept ->
3795 typename std::conditional<I == 0,
3799 static_assert(I == 0,
3800 "key_value_pair index out of range");
3803 /** Extracts a key_value_pair's key using tuple-like interface
3808 get<0>(key_value_pair const& kvp) noexcept
3813 /** Extracts a key_value_pair's key using tuple-like interface
3818 get<0>(key_value_pair& kvp) noexcept
3823 /** Extracts a key_value_pair's key using tuple-like interface
3828 get<0>(key_value_pair&& kvp) noexcept
3833 /** Extracts a key_value_pair's value using tuple-like interface
3838 get<1>(key_value_pair const& kvp) noexcept
3843 /** Extracts a key_value_pair's value using tuple-like interface
3848 get<1>(key_value_pair& kvp) noexcept
3853 /** Extracts a key_value_pair's value using tuple-like interface
3858 get<1>(key_value_pair&& kvp) noexcept
3860 return std::move(kvp.value());
3868 # pragma clang diagnostic push
3869 # pragma clang diagnostic ignored "-Wmismatched-tags"
3872 #ifndef BOOST_JSON_DOCS
3876 /** Tuple-like size access for key_value_pair
3879 struct tuple_size< ::boost::json::key_value_pair >
3880 : std::integral_constant<std::size_t, 2>
3884 /** Tuple-like access for the key type of key_value_pair
3887 struct tuple_element<0, ::boost::json::key_value_pair>
3889 using type = ::boost::json::string_view const;
3892 /** Tuple-like access for the value type of key_value_pair
3895 struct tuple_element<1, ::boost::json::key_value_pair>
3897 using type = ::boost::json::value&;
3900 /** Tuple-like access for the value type of key_value_pair
3903 struct tuple_element<1, ::boost::json::key_value_pair const>
3905 using type = ::boost::json::value const&;
3913 # pragma clang diagnostic pop
3916 // These are here because value, array,
3917 // and object form cyclic references.
3919 #include <boost/json/detail/impl/array.hpp>
3920 #include <boost/json/impl/array.hpp>
3921 #include <boost/json/impl/object.hpp>
3923 // These must come after array and object
3924 #include <boost/json/impl/value_ref.hpp>