value.hpp

98.9% Lines (516/522) 98.0% List of functions (192/196)
value.hpp
f(x) Functions (196)
Function Calls Lines Blocks
boost::json::value::value(boost::json::detail::unchecked_array&&) :75 2120x 100.0% 100.0% boost::json::value::value(boost::json::detail::unchecked_object&&) :82 34879x 100.0% 100.0% boost::json::value::value(boost::json::detail::key_t const&, boost::core::basic_string_view<char>, boost::json::storage_ptr) :88 30296x 100.0% 100.0% boost::json::value::value(boost::json::detail::key_t const&, boost::core::basic_string_view<char>, boost::core::basic_string_view<char>, boost::json::storage_ptr) :96 8060x 100.0% 67.0% boost::json::value::is_scalar() const :105 6707x 100.0% 100.0% boost::json::value::value() :227 211x 100.0% 100.0% boost::json::value::value(boost::json::storage_ptr) :238 7138x 100.0% 100.0% boost::json::value::value(decltype(nullptr), boost::json::storage_ptr) :244 9679x 100.0% 100.0% boost::json::value::value<bool, void>(bool, boost::json::storage_ptr) :265 776x 100.0% 100.0% boost::json::value::value(signed char, boost::json::storage_ptr) :278 3x 100.0% 100.0% boost::json::value::value(short, boost::json::storage_ptr) :287 4x 100.0% 100.0% boost::json::value::value(int, boost::json::storage_ptr) :296 11288x 100.0% 100.0% boost::json::value::value(long, boost::json::storage_ptr) :305 5834x 100.0% 100.0% boost::json::value::value(long long, boost::json::storage_ptr) :314 3x 100.0% 100.0% boost::json::value::value(unsigned char, boost::json::storage_ptr) :327 23x 100.0% 100.0% boost::json::value::value(unsigned short, boost::json::storage_ptr) :336 3x 100.0% 100.0% boost::json::value::value(unsigned int, boost::json::storage_ptr) :345 52x 100.0% 100.0% boost::json::value::value(unsigned long, boost::json::storage_ptr) :354 215x 100.0% 100.0% boost::json::value::value(unsigned long long, boost::json::storage_ptr) :363 2x 100.0% 100.0% boost::json::value::value(double, boost::json::storage_ptr) :376 2039949x 100.0% 100.0% boost::json::value::value(boost::core::basic_string_view<char>, boost::json::storage_ptr) :388 17178x 100.0% 100.0% boost::json::value::value(char const*, boost::json::storage_ptr) :396 136x 100.0% 75.0% boost::json::value::value(boost::json::string) :404 401x 100.0% 100.0% boost::json::value::value(boost::json::string const&, boost::json::storage_ptr) :411 12x 100.0% 75.0% boost::json::value::value(boost::json::string&&, boost::json::storage_ptr) :421 9x 100.0% 78.0% boost::json::value::value(boost::json::string_kind_t, boost::json::storage_ptr) :431 8977x 100.0% 100.0% boost::json::value::value(boost::json::array) :442 181x 100.0% 100.0% boost::json::value::value(boost::json::array const&, boost::json::storage_ptr) :448 4x 100.0% 75.0% boost::json::value::value(boost::json::array&&, boost::json::storage_ptr) :458 23x 100.0% 78.0% boost::json::value::value(boost::json::array_kind_t, boost::json::storage_ptr) :468 17x 100.0% 100.0% boost::json::value::value(boost::json::object) :479 61x 100.0% 100.0% boost::json::value::value(boost::json::object const&, boost::json::storage_ptr) :485 4x 100.0% 75.0% boost::json::value::value(boost::json::object&&, boost::json::storage_ptr) :493 57x 100.0% 78.0% boost::json::value::value(boost::json::object_kind_t, boost::json::storage_ptr) :501 18x 100.0% 100.0% boost::json::value::value(boost::json::value const&) :522 19x 100.0% 75.0% boost::json::value::value(boost::json::pilfered<boost::json::value>) :544 2129161x 100.0% 100.0% boost::json::value::operator=(decltype(nullptr)) :655 18x 100.0% 100.0% boost::json::value& boost::json::value::operator=<bool, void>(bool) :680 51x 100.0% 100.0% boost::json::value::operator=(signed char) :700 2x 100.0% 100.0% boost::json::value::operator=(short) :707 8x 100.0% 100.0% boost::json::value::operator=(int) :714 6529x 100.0% 100.0% boost::json::value::operator=(long) :721 12x 100.0% 100.0% boost::json::value::operator=(long long) :728 6559x 100.0% 100.0% boost::json::value::operator=(unsigned char) :747 6x 100.0% 100.0% boost::json::value::operator=(unsigned short) :754 8x 100.0% 100.0% boost::json::value::operator=(unsigned int) :761 8x 100.0% 100.0% boost::json::value::operator=(unsigned long) :768 17x 100.0% 100.0% boost::json::value::operator=(unsigned long long) :775 47x 100.0% 100.0% boost::json::value::operator=(double) :794 32x 100.0% 100.0% boost::json::value::emplace_null() :952 8x 100.0% 100.0% boost::json::value::emplace_bool() :971 1x 100.0% 100.0% boost::json::value::emplace_int64() :991 2x 100.0% 100.0% boost::json::value::emplace_uint64() :1011 1x 100.0% 100.0% boost::json::value::emplace_double() :1031 1x 100.0% 100.0% boost::json::swap(boost::json::value&, boost::json::value&) :1144 3x 100.0% 100.0% boost::json::value::kind() const :1168 4609688x 100.0% 100.0% boost::json::value::is_array() const :1188 6021x 100.0% 100.0% boost::json::value::is_object() const :1206 53270x 100.0% 100.0% boost::json::value::is_string() const :1224 88287x 100.0% 100.0% boost::json::value::is_int64() const :1242 14814x 100.0% 100.0% boost::json::value::is_uint64() const :1260 322x 100.0% 100.0% boost::json::value::is_double() const :1278 2078671x 100.0% 100.0% boost::json::value::is_bool() const :1296 924x 100.0% 100.0% boost::json::value::is_null() const :1314 148x 100.0% 100.0% boost::json::value::is_structured() const :1331 8x 100.0% 100.0% boost::json::value::is_primitive() const :1351 8x 100.0% 100.0% boost::json::value::is_number() const :1371 83x 100.0% 100.0% boost::json::value::if_array() const :1404 260x 100.0% 100.0% boost::json::value::if_array() :1412 12x 100.0% 100.0% boost::json::value::if_object() const :1442 94x 100.0% 100.0% boost::json::value::if_object() :1450 13x 100.0% 100.0% boost::json::value::if_string() const :1480 252x 100.0% 100.0% boost::json::value::if_string() :1488 13x 100.0% 100.0% boost::json::value::if_int64() const :1518 8x 100.0% 100.0% boost::json::value::if_int64() :1526 13x 100.0% 100.0% boost::json::value::if_uint64() const :1556 8x 100.0% 100.0% boost::json::value::if_uint64() :1564 11x 100.0% 100.0% boost::json::value::if_double() const :1594 8x 100.0% 100.0% boost::json::value::if_double() :1602 11x 100.0% 100.0% boost::json::value::if_bool() const :1632 57x 100.0% 100.0% boost::json::value::if_bool() :1640 11x 100.0% 100.0% std::enable_if<std::is_arithmetic<char>::value&&(!std::is_same<char, bool>::value), char>::type boost::json::value::to_number<char>(boost::system::error_code&) const :1697 1x 100.0% 100.0% std::enable_if<std::is_arithmetic<double>::value&&(!std::is_same<double, bool>::value), double>::type boost::json::value::to_number<double>(boost::system::error_code&) const :1697 39x 100.0% 100.0% std::enable_if<std::is_arithmetic<float>::value&&(!std::is_same<float, bool>::value), float>::type boost::json::value::to_number<float>(boost::system::error_code&) const :1697 28x 100.0% 100.0% std::enable_if<std::is_arithmetic<int>::value&&(!std::is_same<int, bool>::value), int>::type boost::json::value::to_number<int>(boost::system::error_code&) const :1697 3337x 100.0% 100.0% std::enable_if<std::is_arithmetic<long long>::value&&(!std::is_same<long long, bool>::value), long long>::type boost::json::value::to_number<long long>(boost::system::error_code&) const :1697 7x 100.0% 100.0% std::enable_if<std::is_arithmetic<long>::value&&(!std::is_same<long, bool>::value), long>::type boost::json::value::to_number<long>(boost::system::error_code&) const :1697 23x 100.0% 100.0% std::enable_if<std::is_arithmetic<short>::value&&(!std::is_same<short, bool>::value), short>::type boost::json::value::to_number<short>(boost::system::error_code&) const :1697 23x 100.0% 100.0% std::enable_if<std::is_arithmetic<signed char>::value&&(!std::is_same<signed char, bool>::value), signed char>::type boost::json::value::to_number<signed char>(boost::system::error_code&) const :1697 17x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned char>::value&&(!std::is_same<unsigned char, bool>::value), unsigned char>::type boost::json::value::to_number<unsigned char>(boost::system::error_code&) const :1697 33x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned int>::value&&(!std::is_same<unsigned int, bool>::value), unsigned int>::type boost::json::value::to_number<unsigned int>(boost::system::error_code&) const :1697 28x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned long long>::value&&(!std::is_same<unsigned long long, bool>::value), unsigned long long>::type boost::json::value::to_number<unsigned long long>(boost::system::error_code&) const :1697 7x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned long>::value&&(!std::is_same<unsigned long, bool>::value), unsigned long>::type boost::json::value::to_number<unsigned long>(boost::system::error_code&) const :1697 28x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned short>::value&&(!std::is_same<unsigned short, bool>::value), unsigned short>::type boost::json::value::to_number<unsigned short>(boost::system::error_code&) const :1697 23x 100.0% 100.0% std::enable_if<std::is_arithmetic<double>::value&&(!std::is_same<double, bool>::value), double>::type boost::json::value::to_number<double>(std::error_code&) const :1714 1x 100.0% 100.0% std::enable_if<std::is_arithmetic<char>::value&&(!std::is_same<char, bool>::value), char>::type boost::json::value::to_number<char>(boost::source_location const&) const :1739 0 0.0% 0.0% std::enable_if<std::is_arithmetic<double>::value&&(!std::is_same<double, bool>::value), double>::type boost::json::value::to_number<double>(boost::source_location const&) const :1739 21x 100.0% 100.0% std::enable_if<std::is_arithmetic<float>::value&&(!std::is_same<float, bool>::value), float>::type boost::json::value::to_number<float>(boost::source_location const&) const :1739 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<int>::value&&(!std::is_same<int, bool>::value), int>::type boost::json::value::to_number<int>(boost::source_location const&) const :1739 36x 100.0% 100.0% std::enable_if<std::is_arithmetic<long>::value&&(!std::is_same<long, bool>::value), long>::type boost::json::value::to_number<long>(boost::source_location const&) const :1739 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<short>::value&&(!std::is_same<short, bool>::value), short>::type boost::json::value::to_number<short>(boost::source_location const&) const :1739 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<signed char>::value&&(!std::is_same<signed char, bool>::value), signed char>::type boost::json::value::to_number<signed char>(boost::source_location const&) const :1739 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned char>::value&&(!std::is_same<unsigned char, bool>::value), unsigned char>::type boost::json::value::to_number<unsigned char>(boost::source_location const&) const :1739 20x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned int>::value&&(!std::is_same<unsigned int, bool>::value), unsigned int>::type boost::json::value::to_number<unsigned int>(boost::source_location const&) const :1739 21x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned long>::value&&(!std::is_same<unsigned long, bool>::value), unsigned long>::type boost::json::value::to_number<unsigned long>(boost::source_location const&) const :1739 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned short>::value&&(!std::is_same<unsigned short, bool>::value), unsigned short>::type boost::json::value::to_number<unsigned short>(boost::source_location const&) const :1739 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<char>::value&&(!std::is_same<char, bool>::value), boost::system::result<char, boost::system::error_code> >::type boost::json::value::try_to_number<char>() const :1787 0 0.0% 0.0% std::enable_if<std::is_arithmetic<double>::value&&(!std::is_same<double, bool>::value), boost::system::result<double, boost::system::error_code> >::type boost::json::value::try_to_number<double>() const :1787 22x 100.0% 100.0% std::enable_if<std::is_arithmetic<float>::value&&(!std::is_same<float, bool>::value), boost::system::result<float, boost::system::error_code> >::type boost::json::value::try_to_number<float>() const :1787 16x 83.3% 86.0% std::enable_if<std::is_arithmetic<int>::value&&(!std::is_same<int, bool>::value), boost::system::result<int, boost::system::error_code> >::type boost::json::value::try_to_number<int>() const :1787 37x 100.0% 100.0% std::enable_if<std::is_arithmetic<long>::value&&(!std::is_same<long, bool>::value), boost::system::result<long, boost::system::error_code> >::type boost::json::value::try_to_number<long>() const :1787 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<short>::value&&(!std::is_same<short, bool>::value), boost::system::result<short, boost::system::error_code> >::type boost::json::value::try_to_number<short>() const :1787 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<signed char>::value&&(!std::is_same<signed char, bool>::value), boost::system::result<signed char, boost::system::error_code> >::type boost::json::value::try_to_number<signed char>() const :1787 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned char>::value&&(!std::is_same<unsigned char, bool>::value), boost::system::result<unsigned char, boost::system::error_code> >::type boost::json::value::try_to_number<unsigned char>() const :1787 20x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned int>::value&&(!std::is_same<unsigned int, bool>::value), boost::system::result<unsigned int, boost::system::error_code> >::type boost::json::value::try_to_number<unsigned int>() const :1787 21x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned long>::value&&(!std::is_same<unsigned long, bool>::value), boost::system::result<unsigned long, boost::system::error_code> >::type boost::json::value::try_to_number<unsigned long>() const :1787 16x 100.0% 100.0% std::enable_if<std::is_arithmetic<unsigned short>::value&&(!std::is_same<unsigned short, bool>::value), boost::system::result<unsigned short, boost::system::error_code> >::type boost::json::value::try_to_number<unsigned short>() const :1787 16x 100.0% 100.0% boost::json::value::storage() const :1815 75892x 100.0% 100.0% boost::json::value::get_allocator() const :1832 1x 100.0% 100.0% boost::json::value::as_object(boost::source_location const&) & :2137 167x 100.0% 100.0% boost::json::value::as_object(boost::source_location const&) && :2145 97x 100.0% 100.0% boost::json::value::as_array(boost::source_location const&) & :2175 95x 100.0% 100.0% boost::json::value::as_array(boost::source_location const&) && :2183 10x 100.0% 100.0% boost::json::value::as_string(boost::source_location const&) & :2213 34x 100.0% 100.0% boost::json::value::as_string(boost::source_location const&) && :2221 12x 100.0% 100.0% boost::json::value::get_object() & :2389 40x 100.0% 80.0% boost::json::value::get_object() && :2396 1x 100.0% 80.0% boost::json::value::get_object() const & :2403 52947x 100.0% 80.0% boost::json::value::get_array() & :2430 27x 100.0% 80.0% boost::json::value::get_array() && :2437 1x 100.0% 80.0% boost::json::value::get_array() const & :2444 5702x 100.0% 80.0% boost::json::value::get_string() & :2471 8973x 100.0% 80.0% boost::json::value::get_string() && :2478 1x 100.0% 80.0% boost::json::value::get_string() const & :2485 40936x 100.0% 80.0% boost::json::value::get_int64() :2512 3x 100.0% 80.0% boost::json::value::get_int64() const :2519 14227x 100.0% 80.0% boost::json::value::get_uint64() :2546 3x 20.0% 80.0% boost::json::value::get_uint64() const :2553 195x 100.0% 80.0% boost::json::value::get_double() :2580 3x 100.0% 80.0% boost::json::value::get_double() const :2587 39169x 100.0% 80.0% boost::json::value::get_bool() :2614 3x 100.0% 80.0% boost::json::value::get_bool() const :2621 777x 100.0% 80.0% boost::json::value::at(boost::core::basic_string_view<char>, boost::source_location const&) & :2722 13x 100.0% 100.0% boost::json::value::at(boost::core::basic_string_view<char>, boost::source_location const&) && :2729 1x 100.0% 100.0% boost::json::value::at(boost::core::basic_string_view<char>, boost::source_location const&) const & :2736 18x 100.0% 100.0% boost::json::value::at(unsigned long, boost::source_location const&) & :2749 12x 100.0% 100.0% boost::json::value::at(unsigned long, boost::source_location const&) && :2756 10x 100.0% 100.0% boost::json::value::at(unsigned long, boost::source_location const&) const & :2763 56x 100.0% 100.0% boost::json::operator==(boost::json::value const&, boost::json::value const&) :3061 4172x 100.0% 100.0% boost::json::operator!=(boost::json::value const&, boost::json::value const&) :3083 3989x 100.0% 100.0% unsigned long boost::json::hash_value<boost::json::value, (void*)0>(boost::json::value const&) :3174 248x 100.0% 100.0% boost::json::value::relocate(boost::json::value*, boost::json::value const&) :3188 2133719x 100.0% 100.0% std::enable_if<std::is_signed<char>::value&&(!std::is_floating_point<char>::value), char>::type boost::json::value::to_number<char>(boost::json::error&) const :3208 1x 26.9% 31.0% std::enable_if<std::is_signed<int>::value&&(!std::is_floating_point<int>::value), int>::type boost::json::value::to_number<int>(boost::json::error&) const :3208 3337x 100.0% 100.0% std::enable_if<std::is_signed<long long>::value&&(!std::is_floating_point<long long>::value), long long>::type boost::json::value::to_number<long long>(boost::json::error&) const :3208 7x 26.9% 31.0% std::enable_if<std::is_signed<long>::value&&(!std::is_floating_point<long>::value), long>::type boost::json::value::to_number<long>(boost::json::error&) const :3208 23x 92.3% 90.0% std::enable_if<std::is_signed<short>::value&&(!std::is_floating_point<short>::value), short>::type boost::json::value::to_number<short>(boost::json::error&) const :3208 23x 96.2% 97.0% std::enable_if<std::is_signed<signed char>::value&&(!std::is_floating_point<signed char>::value), signed char>::type boost::json::value::to_number<signed char>(boost::json::error&) const :3208 17x 96.2% 97.0% std::enable_if<std::is_unsigned<unsigned char>::value&&(!std::is_same<unsigned char, bool>::value), unsigned char>::type boost::json::value::to_number<unsigned char>(boost::json::error&) const :3259 33x 95.8% 96.0% std::enable_if<std::is_unsigned<unsigned int>::value&&(!std::is_same<unsigned int, bool>::value), unsigned int>::type boost::json::value::to_number<unsigned int>(boost::json::error&) const :3259 28x 100.0% 100.0% std::enable_if<std::is_unsigned<unsigned long long>::value&&(!std::is_same<unsigned long long, bool>::value), unsigned long long>::type boost::json::value::to_number<unsigned long long>(boost::json::error&) const :3259 7x 29.2% 22.0% std::enable_if<std::is_unsigned<unsigned long>::value&&(!std::is_same<unsigned long, bool>::value), unsigned long>::type boost::json::value::to_number<unsigned long>(boost::json::error&) const :3259 28x 91.7% 93.0% std::enable_if<std::is_unsigned<unsigned short>::value&&(!std::is_same<unsigned short, bool>::value), unsigned short>::type boost::json::value::to_number<unsigned short>(boost::json::error&) const :3259 23x 95.8% 96.0% std::enable_if<std::is_floating_point<double>::value, double>::type boost::json::value::to_number<double>(boost::json::error&) const :3307 39x 100.0% 100.0% std::enable_if<std::is_floating_point<float>::value, float>::type boost::json::value::to_number<float>(boost::json::error&) const :3307 28x 83.3% 88.0% boost::json::key_value_pair::~key_value_pair() :3375 59054x 90.0% 93.0% boost::json::key_value_pair::key_value_pair<bool, boost::json::storage_ptr&>(boost::core::basic_string_view<char>, bool&&, boost::json::storage_ptr&) :3435 11x 91.7% 95.0% boost::json::key_value_pair::key_value_pair<boost::core::basic_string_view<char> const&, boost::json::storage_ptr&>(boost::core::basic_string_view<char>, boost::core::basic_string_view<char> const&, boost::json::storage_ptr&) :3435 4x 91.7% 96.0% boost::json::key_value_pair::key_value_pair<boost::json::value const&, boost::json::storage_ptr>(boost::core::basic_string_view<char>, boost::json::value const&, boost::json::storage_ptr&&) :3435 0 0.0% 0.0% boost::json::key_value_pair::key_value_pair<boost::json::value&, boost::json::storage_ptr&>(boost::core::basic_string_view<char>, boost::json::value&, boost::json::storage_ptr&) :3435 11x 91.7% 78.0% boost::json::key_value_pair::key_value_pair<boost::json::value, boost::json::storage_ptr&>(boost::core::basic_string_view<char>, boost::json::value&&, boost::json::storage_ptr&) :3435 576x 91.7% 78.0% boost::json::key_value_pair::key_value_pair<boost::json::value, boost::json::storage_ptr>(boost::core::basic_string_view<char>, boost::json::value&&, boost::json::storage_ptr&&) :3435 3125x 91.7% 83.0% boost::json::key_value_pair::key_value_pair<boost::json::value>(boost::core::basic_string_view<char>, boost::json::value&&) :3435 3762x 100.0% 94.0% boost::json::key_value_pair::key_value_pair<char const (&) [6], boost::json::storage_ptr&>(boost::core::basic_string_view<char>, char const (&) [6], boost::json::storage_ptr&) :3435 7x 91.7% 83.0% boost::json::key_value_pair::key_value_pair<char const (&) [6]>(boost::core::basic_string_view<char>, char const (&) [6]) :3435 1x 91.7% 77.0% boost::json::key_value_pair::key_value_pair<char const (&) [7], boost::json::storage_ptr&>(boost::core::basic_string_view<char>, char const (&) [7], boost::json::storage_ptr&) :3435 1x 91.7% 78.0% boost::json::key_value_pair::key_value_pair<decltype(nullptr), boost::json::storage_ptr&>(boost::core::basic_string_view<char>, decltype(nullptr)&&, boost::json::storage_ptr&) :3435 150x 91.7% 90.0% boost::json::key_value_pair::key_value_pair<decltype(nullptr)>(boost::core::basic_string_view<char>, decltype(nullptr)&&) :3435 1x 91.7% 89.0% boost::json::key_value_pair::key_value_pair<int&, boost::json::storage_ptr&>(boost::core::basic_string_view<char>, int&, boost::json::storage_ptr&) :3435 100x 91.7% 90.0% boost::json::key_value_pair::key_value_pair<int, boost::json::storage_ptr&>(boost::core::basic_string_view<char>, int&&, boost::json::storage_ptr&) :3435 20x 91.7% 95.0% boost::json::key_value_pair::key_value_pair<int>(boost::core::basic_string_view<char>, int&&) :3435 6x 91.7% 89.0% boost::json::key_value_pair::key_value_pair<unsigned long&, boost::json::storage_ptr&>(boost::core::basic_string_view<char>, unsigned long&, boost::json::storage_ptr&) :3435 110x 91.7% 90.0% boost::json::key_value_pair::key_value_pair(std::pair<boost::core::basic_string_view<char>, boost::json::value> const&, boost::json::storage_ptr) :3463 0 0.0% 0.0% boost::json::key_value_pair::key_value_pair(std::pair<boost::core::basic_string_view<char>, boost::json::value>&&, boost::json::storage_ptr) :3477 3125x 100.0% 100.0% boost::json::key_value_pair::key_value_pair(boost::json::key_value_pair const&) :3500 758x 100.0% 75.0% boost::json::key_value_pair::key_value_pair(boost::json::key_value_pair&&) :3508 1x 100.0% 100.0% boost::json::key_value_pair::key_value_pair(boost::json::pilfered<boost::json::key_value_pair>) :3519 6752x 100.0% 100.0% boost::json::key_value_pair::storage() const :3541 758x 100.0% 100.0% boost::json::key_value_pair::key() const :3557 143689x 100.0% 100.0% boost::json::key_value_pair::key_c_str() const :3571 1x 100.0% 100.0% boost::json::key_value_pair::value() const & :3587 65222x 100.0% 100.0% boost::json::key_value_pair::value() & :3599 1078x 100.0% 100.0% std::conditional<(0ul)==(0), boost::core::basic_string_view<char> const, boost::json::value const&>::type boost::json::get<0ul>(boost::json::key_value_pair const&) :3698 19609x 100.0% 100.0% std::conditional<(0ul)==(0), boost::core::basic_string_view<char> const, boost::json::value&>::type boost::json::get<0ul>(boost::json::key_value_pair&) :3708 7x 100.0% 100.0% std::conditional<(1ul)==(0), boost::core::basic_string_view<char> const, boost::json::value const&>::type boost::json::get<1ul>(boost::json::key_value_pair const&) :3728 28299x 100.0% 100.0% std::conditional<(1ul)==(0), boost::core::basic_string_view<char> const, boost::json::value&>::type boost::json::get<1ul>(boost::json::key_value_pair&) :3738 7x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/boostorg/json
9 //
10
11 #ifndef BOOST_JSON_VALUE_HPP
12 #define BOOST_JSON_VALUE_HPP
13
14 #include <boost/core/detail/static_assert.hpp>
15 #include <boost/json/detail/config.hpp>
16 #include <boost/json/array.hpp>
17 #include <boost/json/kind.hpp>
18 #include <boost/json/object.hpp>
19 #include <boost/json/pilfer.hpp>
20 #include <boost/json/set_pointer_options.hpp>
21 #include <boost/json/storage_ptr.hpp>
22 #include <boost/json/string.hpp>
23 #include <boost/json/string_view.hpp>
24 #include <boost/json/value_ref.hpp>
25 #include <boost/json/detail/except.hpp>
26 #include <boost/json/detail/value.hpp>
27 #include <cstdlib>
28 #include <cstring>
29 #include <initializer_list>
30 #include <iosfwd>
31 #include <limits>
32 #include <new>
33 #include <type_traits>
34 #include <utility>
35
36 namespace boost {
37 namespace json {
38
39 //----------------------------------------------------------
40
41 /** The type used to represent any JSON value
42
43 This is a [Regular](https://en.cppreference.com/w/cpp/concepts/regular)
44 type which works like a variant of the basic JSON data types: array,
45 object, string, number, boolean, and null.
46
47 @par Thread Safety
48 Distinct instances may be accessed concurrently. Non-const member
49 functions of a shared instance may not be called concurrently with any
50 other member functions of that instance.
51 */
52 class value
53 {
54 #ifndef BOOST_JSON_DOCS
55 using scalar = detail::scalar;
56
57 union
58 {
59 storage_ptr sp_; // must come first
60 array arr_;
61 object obj_;
62 string str_;
63 scalar sca_;
64 };
65 #endif
66
67 struct init_iter;
68
69 #ifndef BOOST_JSON_DOCS
70 // VFALCO doc toolchain incorrectly treats this as public
71 friend struct detail::access;
72 #endif
73
74 explicit
75 2120x value(
76 detail::unchecked_array&& ua)
77 2120x : arr_(std::move(ua))
78 {
79 2082x }
80
81 explicit
82 34879x value(
83 detail::unchecked_object&& uo)
84 34879x : obj_(std::move(uo))
85 {
86 34840x }
87
88 30296x value(
89 detail::key_t const&,
90 string_view s,
91 storage_ptr sp)
92 30296x : str_(detail::key_t{}, s, std::move(sp))
93 {
94 30236x }
95
96 8060x value(
97 detail::key_t const&,
98 string_view s1,
99 string_view s2,
100 storage_ptr sp)
101 8060x : str_(detail::key_t{}, s1, s2, std::move(sp))
102 {
103 8060x }
104
105 6707x inline bool is_scalar() const noexcept
106 {
107 6707x return sca_.k < json::kind::string;
108 }
109
110 public:
111 /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
112 using allocator_type = container::pmr::polymorphic_allocator<value>;
113
114 /** Destructor.
115
116 The value and all of its contents are destroyed. Any dynamically
117 allocated memory that was allocated internally is freed.
118
119 @par Complexity
120 Constant, or linear in size for array or object.
121
122 @par Exception Safety
123 No-throw guarantee.
124 */
125 BOOST_JSON_DECL
126 ~value() noexcept;
127
128 /** Constructors.
129
130 Construct a new `value`.
131
132 @li **(1)**--**(3)** the constructed value is null.
133 @li **(4)** the constructed value contains a copy of `b`.
134 @li **(5)**--**(9)** the constructed value contains a copy of `i`.
135 @li **(10)**--**(14)** the constructed value contains a copy of `u`.
136 @li **(15)** the constructed value contains a copy of `d`.
137 @li **(16)**, **(19)** the constructed value contains a copy of the
138 string `s`.
139 @li **(17)** the constructed value contains a copy of the
140 null-terminated string `s`.
141 @li **(18)** the constructed value takes ownership of `s`'s storage.
142 @li **(20)** if `*s.storage() == *sp` equivalent to **(18)**, otherwise
143 equivalent to **(19)**.
144 @li **(21)** the constructed value contains an empty string.
145 @li **(22)** the constructed value takes ownership of `arr`'s storage.
146 @li **(23)** the constructed value contains an element-wise copy of the
147 array `arr`.
148 @li **(24)** if `*arr.storage() == *sp` equivalent to **(22)**,
149 otherwise equivalent to **(23)**.
150 @li **(25)** the constructed value contains an empty array.
151 @li **(26)** the constructed value takes ownership of `obj`'s storage.
152 @li **(27)** the constructed value contains an element-wise copy of the
153 object `obj`.
154 @li **(28)** if `*obj.storage() == *sp` equivalent to **(26)**,
155 otherwise equivalent to **(27)**.
156 @li **(29)** the constructed value contains an empty object.
157 @li **(30)** the constructed value's contents are formed by
158 constructing from `init` and `sp` (see \<\<initializer_lists\>\>).
159 @li **(31)**, **(32)** the constructed value contains a copy of the
160 contents of `other`.
161 @li **(33)** the constructed value acquires ownership of the contents
162 of `other`.
163 @li **(34)** equivalent to **(33)** if `*sp == *other.storage()`;
164 otherwise equivalent to **(32)**.
165 @li **(35)** the constructed value acquires ownership of the contents
166 of `other` using pilfer semantics. This is more efficient than move
167 construction, when it is known that the moved-from object will be
168 immediately destroyed afterwards.
169
170 With **(2)**--**(17)**, **(19)**--**(21)**, **(23)**--**(25)**,
171 {sp} **(27)**--**(30)**, **(32)**, and **(34)** the constructed value
172 uses memory resource of `sp`. With **(18)**, **(22)**, **(26)**,
173 {sp} **(31)**, **(33)**, and **(35)** it uses the memory resource of
174 the argument (`s`, `arr`, obj`, or `value`). In either case the value
175 will share the ownership of the memory resource. With **(1)**
176 it uses the \<\<default_memory_resource, default memory resource\>\>.
177
178 After **(18)**, **(22)**, **(26)**, and **(33)** the argument behaves
179 as if newly constructed with its current storage pointer (i.e. becomes
180 an empty string, array, object, or null value).
181
182 After **(35)** `other` is not in a usable state and may only be
183 destroyed.
184
185 @par Complexity
186 @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
187 {sp} **(26)**, **(29)**, **(33)**, **(35)** constant.
188 @li **(16)**, **(19)** linear in `s.size()`.
189 @li **(17)** linear in `std::strlen(s)`.
190 @li **(20)** if `*s.storage() == *sp` constant, otherwise linear
191 in `s.size()`.
192 @li **(23)** linear in `arr.size()`.
193 @li **(24)** if `*arr.storage() == *sp` constant, otherwise linear
194 in `arr.size()`.
195 @li **(27)** linear in `obj.size()`.
196 @li **(28)** if `*obj.storage() == *sp` constant, otherwise linear
197 in `obj.size()`.
198 @li **(30)** linear in `init.size()`.
199 @li **(31)**, **(32)** linear in the size of `other`.
200 @li **(34)** constant if `*sp == *other.storage()`; otherwise linear in
201 the size of `other`.
202
203 The size of `other` is either the size of the underlying container
204 (if there is one), or can be considered to be 1.
205
206 @par Exception Safety
207 @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
208 **(26)**, **(29)**, **(33)**, **(35)** no-throw guarantee.
209 @li **(16)**, **(17)**, **(19)**, **(23)**, **(27)**,
210 **(30)**--**(32)** strong guarantee.
211 @li **(20)** if `*s.storage() == *sp` no-throw guarantee, otherwise
212 strong guarantee.
213 @li **(24)** if `*arr.storage() == *sp` no-throw guarantee, otherwise
214 strong guarantee.
215 @li **(28)** if `*obj.storage() == *sp` no-throw guarantee, otherwise
216 strong guarantee.
217 @li **(33)** if `*other.storage() == *sp` no-throw guarantee, otherwise
218 strong guarantee.
219
220 Calls to `memory_resource::allocate` may throw.
221
222 @see @ref pilfer,
223 [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
224 //
225 @{
226 */
227 211x value() noexcept
228 211x : sca_()
229 {
230 211x }
231
232 /** Overload
233
234 @param sp A pointer to the @ref boost::container::pmr::memory_resource
235 to use.
236 */
237 explicit
238 7138x value(storage_ptr sp) noexcept
239 7138x : sca_(std::move(sp))
240 {
241 7138x }
242
243 /// Overload
244 9679x value(
245 std::nullptr_t,
246 storage_ptr sp = {}) noexcept
247 9679x : sca_(std::move(sp))
248 {
249 9679x }
250
251 /** Overload
252
253 @param b The boolean to construct with.
254 @param sp
255 */
256 #ifdef BOOST_JSON_DOCS
257 value(
258 bool b,
259 storage_ptr sp = {}) noexcept;
260 #else
261 template<class T
262 ,class = typename std::enable_if<
263 std::is_same<T, bool>::value>::type
264 >
265 776x value(
266 T b,
267 storage_ptr sp = {}) noexcept
268 776x : sca_(b, std::move(sp))
269 {
270 776x }
271 #endif
272
273 /** Overload
274
275 @param i The number to construct with.
276 @param sp
277 */
278 3x value(
279 signed char i,
280 storage_ptr sp = {}) noexcept
281 3x : sca_(static_cast<std::int64_t>(
282 3x i), std::move(sp))
283 {
284 3x }
285
286 /// Overload
287 4x value(
288 short i,
289 storage_ptr sp = {}) noexcept
290 4x : sca_(static_cast<std::int64_t>(
291 4x i), std::move(sp))
292 {
293 4x }
294
295 /// Overload
296 11288x value(
297 int i,
298 storage_ptr sp = {}) noexcept
299 11288x : sca_(static_cast<std::int64_t>(i),
300 11288x std::move(sp))
301 {
302 11288x }
303
304 /// Overload
305 5834x value(
306 long i,
307 storage_ptr sp = {}) noexcept
308 5834x : sca_(static_cast<std::int64_t>(i),
309 5834x std::move(sp))
310 {
311 5834x }
312
313 /// Overload
314 3x value(
315 long long i,
316 storage_ptr sp = {}) noexcept
317 3x : sca_(static_cast<std::int64_t>(i),
318 3x std::move(sp))
319 {
320 3x }
321
322 /** Overload
323
324 @param u The number to construct with.
325 @param sp
326 */
327 23x value(
328 unsigned char u,
329 storage_ptr sp = {}) noexcept
330 23x : sca_(static_cast<std::uint64_t>(
331 23x u), std::move(sp))
332 {
333 23x }
334
335 /// Overload
336 3x value(
337 unsigned short u,
338 storage_ptr sp = {}) noexcept
339 3x : sca_(static_cast<std::uint64_t>(u),
340 3x std::move(sp))
341 {
342 3x }
343
344 /// Overload
345 52x value(
346 unsigned int u,
347 storage_ptr sp = {}) noexcept
348 52x : sca_(static_cast<std::uint64_t>(u),
349 52x std::move(sp))
350 {
351 52x }
352
353 /// Overload
354 215x value(
355 unsigned long u,
356 storage_ptr sp = {}) noexcept
357 215x : sca_(static_cast<std::uint64_t>(u),
358 215x std::move(sp))
359 {
360 215x }
361
362 /// Overload
363 2x value(
364 unsigned long long u,
365 storage_ptr sp = {}) noexcept
366 2x : sca_(static_cast<std::uint64_t>(u),
367 2x std::move(sp))
368 {
369 2x }
370
371 /** Overload
372
373 @param d The number to construct with.
374 @param sp
375 */
376 2039949x value(
377 double d,
378 storage_ptr sp = {}) noexcept
379 2039949x : sca_(d, std::move(sp))
380 {
381 2039949x }
382
383 /** Overload
384
385 @param s The string to construct with.
386 @param sp
387 */
388 17178x value(
389 string_view s,
390 storage_ptr sp = {})
391 17178x : str_(s, std::move(sp))
392 {
393 17170x }
394
395 /// Overload
396 136x value(
397 char const* s,
398 storage_ptr sp = {})
399 136x : str_(s, std::move(sp))
400 {
401 136x }
402
403 /// Overload
404 401x value(
405 string s) noexcept
406 401x : str_(std::move(s))
407 {
408 401x }
409
410 /// Overload
411 12x value(
412 string const& s,
413 storage_ptr sp)
414 12x : str_(
415 s,
416 12x std::move(sp))
417 {
418 12x }
419
420 /// Overload
421 9x value(
422 string&& s,
423 storage_ptr sp)
424 18x : str_(
425 9x std::move(s),
426 9x std::move(sp))
427 {
428 9x }
429
430 /// Overload
431 8977x value(
432 string_kind_t,
433 storage_ptr sp = {}) noexcept
434 8977x : str_(std::move(sp))
435 {
436 8977x }
437
438 /** Overload
439
440 @param arr The array to construct with.
441 */
442 181x value(array arr) noexcept
443 181x : arr_(std::move(arr))
444 {
445 181x }
446
447 /// Overload
448 4x value(
449 array const& arr,
450 storage_ptr sp)
451 4x : arr_(
452 arr,
453 4x std::move(sp))
454 {
455 4x }
456
457 /// Overload
458 23x value(
459 array&& arr,
460 storage_ptr sp)
461 46x : arr_(
462 23x std::move(arr),
463 23x std::move(sp))
464 {
465 23x }
466
467 /// Overload
468 17x value(
469 array_kind_t,
470 storage_ptr sp = {}) noexcept
471 17x : arr_(std::move(sp))
472 {
473 17x }
474
475 /** Overload
476
477 @param obj The object to construct with.
478 */
479 61x value(object obj) noexcept
480 61x : obj_(std::move(obj))
481 {
482 61x }
483
484 /// Overload
485 4x value(
486 object const& obj,
487 storage_ptr sp)
488 4x : obj_( obj, std::move(sp) )
489 {
490 4x }
491
492 /// Overload
493 57x value(
494 object&& obj,
495 storage_ptr sp)
496 57x : obj_( std::move(obj), std::move(sp) )
497 {
498 57x }
499
500 /// Overload
501 18x value(
502 object_kind_t,
503 storage_ptr sp = {}) noexcept
504 18x : obj_(std::move(sp))
505 {
506 18x }
507
508 /** Overload
509
510 @param init The initializer list to construct from.
511 @param sp
512 */
513 BOOST_JSON_DECL
514 value(
515 std::initializer_list<value_ref> init,
516 storage_ptr sp = {});
517
518 /** Overload
519
520 @param other Another `value`.
521 */
522 19x value(value const& other)
523 19x : value(other, other.storage())
524 {
525 19x }
526
527 /// Overload
528 BOOST_JSON_DECL
529 value(
530 value const& other,
531 storage_ptr sp);
532
533 /// Overload
534 BOOST_JSON_DECL
535 value(value&& other) noexcept;
536
537 /// Overload
538 BOOST_JSON_DECL
539 value(
540 value&& other,
541 storage_ptr sp);
542
543 /// Overload
544 2129161x value(pilfered<value> other) noexcept
545 2129161x {
546 2129161x relocate(this, other.get());
547 2129161x ::new(&other.get().sca_) scalar();
548 2129161x }
549 /// @}
550
551 //------------------------------------------------------
552 //
553 // Assignment
554 //
555 //------------------------------------------------------
556
557 /** Assignment.
558
559 Replaces the contents of this value.
560
561 @li **(1)** replaces with an element-wise copy of the contents of
562 `other`.
563 @li **(2)** replaces with the contents `other` using move semantics
564 (see below).
565 @li **(3)** replaces with the value formed by constructing from `init`
566 and `this->storage()` (see \<\<initializer_lists\>\>).
567 @li **(4)** replaces with null.
568 @li **(5)** replaces with the boolean value `b`.
569 @li **(6)**--**(10)** replaces with the signed integer `i`.
570 @li **(11)**--**(15)** replaces with the unsigned integer `u`.
571 @li **(16)** replaces with the number `d`.
572 @li **(17)**, **(19)** replaces with a copy of the string `s`.
573 @li **(18)**, equivalent to `*this = string_view(s)`.
574 @li **(20)** replaces with the string `s` using move semantics
575 see below.
576 @li **(21)** replaces with a copy of the array `arr`.
577 @li **(22)** replaces with the array `arr` using move semantics
578 (see below).
579 @li **(23)** replaces with a copy of the object `obj`.
580 @li **(24)** replaces with the object `obj` using move semantics
581 (see below).
582
583 Move assignment for `value` never changes the associated memory
584 resource. Because of this if the memory resource of the assigned value
585 differs from that of `*this`, the operation is equivalent to a copy.
586 Otherwise, it replaces the underlying storage in constant time without
587 the possibility of exceptions.
588
589 @par Complexity
590 @li **(1)** linear in the sizes of `*this` and `other`.
591 @li **(2)** constant if `*this->storage() == *other.storage()`,
592 otherwise linear in the sizes of `*this` and `other`.
593 @li **(3)** linear in the sizes of `*this` and `init`.
594 @li **(4)**--**(16)** linear in the size of `*this`.
595 @li **(17)**, **(19)** linear in the size of `*this` and `s.size()`.
596 @li **(18)** linear in the size of `*this` and `std::strlen(s)`.
597 @li **(22)** constant if `*this->storage() == *s.storage()`,
598 otherwise linear in the size of `*this` and `s.size()`.
599 @li **(21)** linear in the size of `*this` and `arr.size()`.
600 @li **(22)** constant if `*this->storage() == *arr.storage()`,
601 otherwise linear in the size of `*this` and `arr.size()`.
602 @li **(23)** linear in the size of `*this` and `obj.size()`.
603 @li **(24)** constant if `*this->storage() == *obj.storage()`,
604 otherwise linear in the size of `*this` and `obj.size()`.
605
606 The size of `*this` is either the size of the underlying container
607 (if there is one), or can be considered to be 1.
608
609 @par Exception Safety
610 @li **(1)**--**(3)**, **(17)**--**(24)** strong guarantee.
611 @li **(4)**--**(16)** no-throw guarantee.
612
613 Calls to `memory_resource::allocate` may throw.
614
615 @param other The source value.
616
617 @{
618 */
619 BOOST_JSON_DECL
620 value&
621 operator=(value const& other);
622
623 /** Overload
624
625 The contents of the value are replaced with the
626 contents of `other` using move semantics:
627
628 @li If `*other.storage() == *sp`, ownership of
629 the underlying memory is transferred in constant
630 time, with no possibility of exceptions.
631 After assignment, the moved-from value becomes
632 a null with its current storage pointer.
633
634 @li If `*other.storage() != *sp`, an
635 element-wise copy is performed if
636 `other.is_structured() == true`, which may throw.
637 In this case, the moved-from value is not
638 changed.
639 */
640 BOOST_JSON_DECL
641 value&
642 operator=(value&& other);
643
644 /** Overload
645
646 @param init The initializer list to assign from.
647 */
648 BOOST_JSON_DECL
649 value&
650 operator=(
651 std::initializer_list<value_ref> init);
652
653 /// Overload
654 value&
655 18x operator=(std::nullptr_t) noexcept
656 {
657 18x if(is_scalar())
658 {
659 12x sca_.k = json::kind::null;
660 }
661 else
662 {
663 18x ::new(&sca_) scalar(
664 6x destroy());
665 }
666 18x return *this;
667 }
668
669 /** Overload
670
671 @param b The new value.
672 */
673 #ifdef BOOST_JSON_DOCS
674 value& operator=(bool b) noexcept;
675 #else
676 template<class T
677 ,class = typename std::enable_if<
678 std::is_same<T, bool>::value>::type
679 >
680 51x value& operator=(T b) noexcept
681 {
682 51x if(is_scalar())
683 {
684 50x sca_.b = b;
685 50x sca_.k = json::kind::bool_;
686 }
687 else
688 {
689 1x ::new(&sca_) scalar(
690 b, destroy());
691 }
692 51x return *this;
693 }
694 #endif
695
696 /** Overload
697
698 @param i The new value.
699 */
700 2x value& operator=(signed char i) noexcept
701 {
702 2x return operator=(
703 2x static_cast<long long>(i));
704 }
705
706 /// Overload
707 8x value& operator=(short i) noexcept
708 {
709 8x return operator=(
710 8x static_cast<long long>(i));
711 }
712
713 /// Overload
714 6529x value& operator=(int i) noexcept
715 {
716 6529x return operator=(
717 6529x static_cast<long long>(i));
718 }
719
720 /// Overload
721 12x value& operator=(long i) noexcept
722 {
723 12x return operator=(
724 12x static_cast<long long>(i));
725 }
726
727 /// Overload
728 6559x value& operator=(long long i) noexcept
729 {
730 6559x if(is_scalar())
731 {
732 6556x sca_.i = i;
733 6556x sca_.k = json::kind::int64;
734 }
735 else
736 {
737 9x ::new(&sca_) scalar(static_cast<
738 3x std::int64_t>(i), destroy());
739 }
740 6559x return *this;
741 }
742
743 /** Overload
744
745 @param u The new value.
746 */
747 6x value& operator=(unsigned char u) noexcept
748 {
749 6x return operator=(static_cast<
750 6x unsigned long long>(u));
751 }
752
753 /// Overload
754 8x value& operator=(unsigned short u) noexcept
755 {
756 8x return operator=(static_cast<
757 8x unsigned long long>(u));
758 }
759
760 /// Overload
761 8x value& operator=(unsigned int u) noexcept
762 {
763 8x return operator=(static_cast<
764 8x unsigned long long>(u));
765 }
766
767 /// Overload
768 17x value& operator=(unsigned long u) noexcept
769 {
770 17x return operator=(static_cast<
771 17x unsigned long long>(u));
772 }
773
774 /// Overload
775 47x value& operator=(unsigned long long u) noexcept
776 {
777 47x if(is_scalar())
778 {
779 46x sca_.u = u;
780 46x sca_.k = json::kind::uint64;
781 }
782 else
783 {
784 3x ::new(&sca_) scalar(static_cast<
785 1x std::uint64_t>(u), destroy());
786 }
787 47x return *this;
788 }
789
790 /** Overload
791
792 @param d The new value.
793 */
794 32x value& operator=(double d) noexcept
795 {
796 32x if(is_scalar())
797 {
798 25x sca_.d = d;
799 25x sca_.k = json::kind::double_;
800 }
801 else
802 {
803 21x ::new(&sca_) scalar(
804 7x d, destroy());
805 }
806 32x return *this;
807 }
808
809 /** Overload
810
811 @param s The new string.
812 */
813 BOOST_JSON_DECL
814 value& operator=(string_view s);
815
816 /// Overload
817 BOOST_JSON_DECL
818 value& operator=(char const* s);
819
820 /// Overload
821 BOOST_JSON_DECL
822 value& operator=(string const& s);
823
824 /** Overload
825
826 The contents of the value are replaced with the
827 contents of `s` using move semantics:
828
829 @li If `*other.storage() == *this->storage()`,
830 ownership of the underlying memory is transferred
831 in constant time, with no possibility of exceptions.
832 After assignment, the moved-from string becomes
833 empty with its current storage pointer.
834
835 @li If `*other.storage() != *this->storage()`, an
836 element-wise copy is performed, which may throw.
837 In this case, the moved-from string is not
838 changed.
839
840 @param s The string to move-assign from.
841 */
842 BOOST_JSON_DECL
843 value& operator=(string&& s);
844
845 /** Overload
846
847 Replace `*this` with a copy of the array `arr`.
848
849 @par Exception Safety
850 Strong guarantee.
851 Calls to `memory_resource::allocate` may throw.
852
853 @par Complexity
854 Linear in the sum of sizes of `*this` and `arr`
855
856 @param arr The new array.
857 */
858 BOOST_JSON_DECL
859 value& operator=(array const& arr);
860
861 /** Overload
862
863 The contents of the value are replaced with the
864 contents of `arr` using move semantics:
865
866 @li If `*arr.storage() == *this->storage()`,
867 ownership of the underlying memory is transferred
868 in constant time, with no possibility of exceptions.
869 After assignment, the moved-from array becomes
870 empty with its current storage pointer.
871
872 @li If `*arr.storage() != *this->storage()`, an
873 element-wise copy is performed, which may throw.
874 In this case, the moved-from array is not
875 changed.
876
877 @par Complexity
878 Constant, or linear in the size of `*this` plus `arr.size()`.
879
880 @par Exception Safety
881 Strong guarantee.
882 Calls to `memory_resource::allocate` may throw.
883
884 @param arr The array to move-assign from.
885 */
886 BOOST_JSON_DECL
887 value& operator=(array&& arr);
888
889 /** Overload
890
891 Replace `*this` with a copy of the obect `obj`.
892
893 @par Exception Safety
894 Strong guarantee.
895 Calls to `memory_resource::allocate` may throw.
896
897 @par Complexity
898 Linear in the sum of sizes of `*this` and `obj`
899
900 @param obj The new object.
901 */
902 BOOST_JSON_DECL
903 value& operator=(object const& obj);
904
905 /** Overload
906
907 The contents of the value are replaced with the
908 contents of `obj` using move semantics:
909
910 @li If `*obj.storage() == *this->storage()`,
911 ownership of the underlying memory is transferred
912 in constant time, with no possibility of exceptions.
913 After assignment, the moved-from object becomes
914 empty with its current storage pointer.
915
916 @li If `*obj.storage() != *this->storage()`, an
917 element-wise copy is performed, which may throw.
918 In this case, the moved-from object is not
919 changed.
920
921 @par Complexity
922 Constant, or linear in the size of `*this` plus `obj.size()`.
923
924 @par Exception Safety
925 Strong guarantee.
926 Calls to `memory_resource::allocate` may throw.
927
928 @param obj The object to move-assign from.
929 */
930 BOOST_JSON_DECL
931 value& operator=(object&& obj);
932 /// @}
933
934 //------------------------------------------------------
935 //
936 // Modifiers
937 //
938 //------------------------------------------------------
939
940 /** Replace with a null value.
941
942 The current value is destroyed and the kind is changed to kind::null.
943 The associated memeory resource is kept unchanged.
944
945 @par Complexity
946 Linear in the size of `*this`.
947
948 @par Exception Safety
949 No-throw guarantee.
950 */
951 void
952 8x emplace_null() noexcept
953 {
954 8x *this = nullptr;
955 8x }
956
957 /** Replace with a `bool` value.
958
959 The value is replaced with a `bool` initialized to `false`, destroying
960 the previous contents, but keeping the memeory resource.
961
962 @par Complexity
963 Linear in the size of `*this`.
964
965 @par Exception Safety
966 No-throw guarantee.
967
968 @return `this->get_bool()`.
969 */
970 bool&
971 1x emplace_bool() noexcept
972 {
973 1x *this = false;
974 1x return sca_.b;
975 }
976
977 /** Replace with a `std::int64_t` value.
978
979 The value is replaced with a `std::int64_t` initialized to zero,
980 destroying the previous contents, but keeping the memeory resource.
981
982 @par Complexity
983 Linear in the size of `*this`.
984
985 @par Exception Safety
986 No-throw guarantee.
987
988 @return `this->get_int64()`.
989 */
990 std::int64_t&
991 2x emplace_int64() noexcept
992 {
993 2x *this = std::int64_t{};
994 2x return sca_.i;
995 }
996
997 /** Replace with a `std::uint64_t` value.
998
999 The value is replaced with a `std::uint64_t` initialized to zero,
1000 destroying the the previous contents, but keeping the memeory resource.
1001
1002 @par Complexity
1003 Linear in the size of `*this`.
1004
1005 @par Exception Safety
1006 No-throw guarantee.
1007
1008 @return `this->get_uint64()`.
1009 */
1010 std::uint64_t&
1011 1x emplace_uint64() noexcept
1012 {
1013 1x *this = std::uint64_t{};
1014 1x return sca_.u;
1015 }
1016
1017 /** Replace with a `double` value.
1018
1019 The value is replaced with a `double` initialized to zero, destroying
1020 the previous contents, but keeping the memeory resource.
1021
1022 @par Complexity
1023 Linear in the size of `*this`.
1024
1025 @par Exception Safety
1026 No-throw guarantee.
1027
1028 @return `this->get_double()`.
1029 */
1030 double&
1031 1x emplace_double() noexcept
1032 {
1033 1x *this = double{};
1034 1x return sca_.d;
1035 }
1036
1037 /** Replace with an empty @ref string.
1038
1039 The value is replaced with an empty @ref string using the current
1040 memory resource, destroying the previous contents. All previously
1041 obtained iterators and references obtained beforehand are invalidated.
1042
1043 @par Complexity
1044 Linear in the size of `*this`.
1045
1046 @par Exception Safety
1047 No-throw guarantee.
1048
1049 @return `this->get_string()`.
1050 */
1051 BOOST_JSON_DECL
1052 string&
1053 emplace_string() noexcept;
1054
1055 /** Replace with an empty array.
1056
1057 The value is replaced with an empty @ref array using the current memory
1058 resource, destroying the previous contents. All previously obtained
1059 iterators and references obtained beforehand are invalidated.
1060
1061 @par Complexity
1062 Linear in the size of `*this`.
1063
1064 @par Exception Safety
1065 No-throw guarantee.
1066
1067 @return `this->get_array()`.
1068 */
1069 BOOST_JSON_DECL
1070 array&
1071 emplace_array() noexcept;
1072
1073 /** Replace with an empty @ref object.
1074
1075 The value is replaced with an empty @ref array using the current memory
1076 resource, destroying the previous contents. All previously obtained
1077 iterators and references obtained beforehand are invalidated.
1078
1079 @par Complexity
1080 Linear in the size of `*this`.
1081
1082 @par Exception Safety
1083 No-throw guarantee.
1084
1085 @return `this->get_object()`.
1086 */
1087 BOOST_JSON_DECL
1088 object&
1089 emplace_object() noexcept;
1090
1091 /** Swap the given values.
1092
1093 Exchanges the contents of this value with another value. Ownership of
1094 the respective @ref boost::container::pmr::memory_resource objects is
1095 not transferred:
1096
1097 @li If `this == &other`, this function has no effect.
1098 @li If `*other.storage() == *this->storage()`, ownership of the
1099 underlying memory is swapped in constant time, with no possibility
1100 of exceptions. All iterators and references remain valid.
1101 @li If `*other.storage() != *this->storage()`, the contents are
1102 logically swapped by making copies, which can throw. In this case
1103 all iterators and references are invalidated.
1104
1105 @par Complexity
1106 Constant or linear in the sum of the sizes of the values.
1107
1108 @par Exception Safety
1109 Strong guarantee. Calls to `memory_resource::allocate` may throw.
1110
1111 @param other The value to swap with.
1112 */
1113 BOOST_JSON_DECL
1114 void
1115 swap(value& other);
1116
1117 /** Swap the given values.
1118
1119 Exchanges the contents of value `lhs` with another value `rhs`.
1120 Ownership of the respective @ref boost::container::pmr::memory_resource
1121 objects is not transferred.
1122
1123 @li If `&lhs == &rhs`, this function call has no effect.
1124 @li If `*lhs.storage() == *rhs.storage()`, ownership of the underlying
1125 memory is swapped in constant time, with no possibility of
1126 exceptions. All iterators and references remain valid.
1127 @li If `*lhs.storage() != *rhs.storage`, the contents are logically
1128 swapped by a copy, which can throw. In this case all iterators and
1129 references are invalidated.
1130
1131 @par Complexity
1132 Constant or linear in the sum of the sizes of the values.
1133
1134 @par Exception Safety
1135 Strong guarantee. Calls to `memory_resource::allocate` may throw.
1136
1137 @param lhs The value to exchange.
1138 @param rhs The value to exchange.
1139
1140 @see @ref value::swap
1141 */
1142 friend
1143 void
1144 3x swap(value& lhs, value& rhs)
1145 {
1146 3x lhs.swap(rhs);
1147 3x }
1148
1149 //------------------------------------------------------
1150 //
1151 // Observers
1152 //
1153 //------------------------------------------------------
1154
1155 /** Returns the kind of this JSON value.
1156
1157 This function returns the discriminating enumeration constant of type
1158 @ref json::kind corresponding to the underlying representation stored
1159 in the container.
1160
1161 @par Complexity
1162 Constant.
1163
1164 @par Exception Safety
1165 No-throw guarantee.
1166 */
1167 json::kind
1168 4609688x kind() const noexcept
1169 {
1170 return static_cast<json::kind>(
1171 static_cast<unsigned char>(
1172 4609688x sca_.k) & 0x3f);
1173 }
1174
1175 /** Check if this is an @ref array.
1176
1177 Returns `true` if the value's @ref kind() is `kind::array`.
1178
1179 @returns `this->kind() == kind::array`.
1180
1181 @par Complexity
1182 Constant.
1183
1184 @par Exception Safety
1185 No-throw guarantee.
1186 */
1187 bool
1188 6021x is_array() const noexcept
1189 {
1190 6021x return kind() == json::kind::array;
1191 }
1192
1193 /** Check if this is an @ref object.
1194
1195 Returns `true` if the value's @ref kind() is `kind::object`.
1196
1197 @returns `this->kind() == kind::object`.
1198
1199 @par Complexity
1200 Constant.
1201
1202 @par Exception Safety
1203 No-throw guarantee.
1204 */
1205 bool
1206 53270x is_object() const noexcept
1207 {
1208 53270x return kind() == json::kind::object;
1209 }
1210
1211 /** Check if this is a @ref string.
1212
1213 Returns `true` if the value's @ref kind() is `kind::string`.
1214
1215 @returns `this->kind() == kind::string`.
1216
1217 @par Complexity
1218 Constant.
1219
1220 @par Exception Safety
1221 No-throw guarantee.
1222 */
1223 bool
1224 88287x is_string() const noexcept
1225 {
1226 88287x return kind() == json::kind::string;
1227 }
1228
1229 /** Check if this is a `std::int64_t`.
1230
1231 Returns `true` if the value's @ref kind() is `kind::int64`.
1232
1233 @returns `this->kind() == kind::int64`.
1234
1235 @par Complexity
1236 Constant.
1237
1238 @par Exception Safety
1239 No-throw guarantee.
1240 */
1241 bool
1242 14814x is_int64() const noexcept
1243 {
1244 14814x return kind() == json::kind::int64;
1245 }
1246
1247 /** Checks if this is a `std::uint64_t`.
1248
1249 Returns `true` if the value's @ref kind() is `kind::uint64`.
1250
1251 @returns `this->kind() == kind::uint64`.
1252
1253 @par Complexity
1254 Constant.
1255
1256 @par Exception Safety
1257 No-throw guarantee.
1258 */
1259 bool
1260 322x is_uint64() const noexcept
1261 {
1262 322x return kind() == json::kind::uint64;
1263 }
1264
1265 /** Check if this is a `double`.
1266
1267 Returns `true` if the value's @ref kind() is `kind::double_`.
1268
1269 @returns `this->kind() == kind::double_`.
1270
1271 @par Complexity
1272 Constant.
1273
1274 @par Exception Safety
1275 No-throw guarantee.
1276 */
1277 bool
1278 2078671x is_double() const noexcept
1279 {
1280 2078671x return kind() == json::kind::double_;
1281 }
1282
1283 /** Check if this is a `bool`.
1284
1285 Returns `true` if the value's @ref kind() is `kind::bool_`.
1286
1287 @returns `this->kind() == kind::bool_`.
1288
1289 @par Complexity
1290 Constant.
1291
1292 @par Exception Safety
1293 No-throw guarantee.
1294 */
1295 bool
1296 924x is_bool() const noexcept
1297 {
1298 924x return kind() == json::kind::bool_;
1299 }
1300
1301 /** Check if this is a null value.
1302
1303 Returns `true` if the value's @ref kind() is `kind::null`.
1304
1305 @returns `this->kind() == kind::null`.
1306
1307 @par Complexity
1308 Constant.
1309
1310 @par Exception Safety
1311 No-throw guarantee.
1312 */
1313 bool
1314 148x is_null() const noexcept
1315 {
1316 148x return kind() == json::kind::null;
1317 }
1318
1319 /** Checks if this is an @ref array or an @ref object.
1320
1321 This function returns `true` if @ref kind() is either `kind::object` or
1322 `kind::array`.
1323
1324 @par Complexity
1325 Constant.
1326
1327 @par Exception Safety
1328 No-throw guarantee.
1329 */
1330 bool
1331 8x is_structured() const noexcept
1332 {
1333 // VFALCO Could use bit 0x20 for this
1334 return
1335 15x kind() == json::kind::object ||
1336 15x kind() == json::kind::array;
1337 }
1338
1339 /** Check if this is not an @ref array or @ref object.
1340
1341 This function returns `true` if @ref kind() is neither `kind::object`
1342 nor `kind::array`.
1343
1344 @par Complexity
1345 Constant.
1346
1347 @par Exception Safety
1348 No-throw guarantee.
1349 */
1350 bool
1351 8x is_primitive() const noexcept
1352 {
1353 // VFALCO Could use bit 0x20 for this
1354 return
1355 15x sca_.k != json::kind::object &&
1356 15x sca_.k != json::kind::array;
1357 }
1358
1359 /** Check if this is a number.
1360
1361 This function returns `true` when @ref kind() is one of `kind::int64`,
1362 `kind::uint64`, or `kind::double_`.
1363
1364 @par Complexity
1365 Constant.
1366
1367 @par Exception Safety
1368 No-throw guarantee.
1369 */
1370 bool
1371 83x is_number() const noexcept
1372 {
1373 // VFALCO Could use bit 0x40 for this
1374 return
1375 92x kind() == json::kind::int64 ||
1376 92x kind() == json::kind::uint64 ||
1377 91x kind() == json::kind::double_;
1378 }
1379
1380 //------------------------------------------------------
1381
1382 /** Return a pointer to the underlying @ref array.
1383
1384 If `this->kind() == kind::array`, returns a pointer to the underlying
1385 array. Otherwise, returns `nullptr`.
1386
1387 @par Example
1388 The return value is used in both a boolean context and
1389 to assign a variable:
1390 @code
1391 if( auto p = jv.if_array() )
1392 return *p;
1393 @endcode
1394
1395 @par Complexity
1396 Constant.
1397
1398 @par Exception Safety
1399 No-throw guarantee.
1400
1401 @{
1402 */
1403 array const*
1404 260x if_array() const noexcept
1405 {
1406 260x if(kind() == json::kind::array)
1407 223x return &arr_;
1408 37x return nullptr;
1409 }
1410
1411 array*
1412 12x if_array() noexcept
1413 {
1414 12x if(kind() == json::kind::array)
1415 5x return &arr_;
1416 7x return nullptr;
1417 }
1418 /// @}
1419
1420 /** Return a pointer to the underlying @ref object.
1421
1422 If `this->kind() == kind::object`, returns a pointer to the underlying
1423 object. Otherwise, returns `nullptr`.
1424
1425 @par Example
1426 The return value is used in both a boolean context and
1427 to assign a variable:
1428 @code
1429 if( auto p = jv.if_object() )
1430 return *p;
1431 @endcode
1432
1433 @par Complexity
1434 Constant.
1435
1436 @par Exception Safety
1437 No-throw guarantee.
1438
1439 @{
1440 */
1441 object const*
1442 94x if_object() const noexcept
1443 {
1444 94x if(kind() == json::kind::object)
1445 69x return &obj_;
1446 25x return nullptr;
1447 }
1448
1449 object*
1450 13x if_object() noexcept
1451 {
1452 13x if(kind() == json::kind::object)
1453 6x return &obj_;
1454 7x return nullptr;
1455 }
1456 /// @}
1457
1458 /** Return a pointer to the underlying @ref string.
1459
1460 If `this->kind() == kind::string`, returns a pointer to the underlying
1461 object. Otherwise, returns `nullptr`.
1462
1463 @par Example
1464 The return value is used in both a boolean context and
1465 to assign a variable:
1466 @code
1467 if( auto p = jv.if_string() )
1468 return *p;
1469 @endcode
1470
1471 @par Complexity
1472 Constant.
1473
1474 @par Exception Safety
1475 No-throw guarantee.
1476
1477 @{
1478 */
1479 string const*
1480 252x if_string() const noexcept
1481 {
1482 252x if(kind() == json::kind::string)
1483 184x return &str_;
1484 68x return nullptr;
1485 }
1486
1487 string*
1488 13x if_string() noexcept
1489 {
1490 13x if(kind() == json::kind::string)
1491 6x return &str_;
1492 7x return nullptr;
1493 }
1494 /// @}
1495
1496 /** Return a pointer to the underlying `std::int64_t`.
1497
1498 If `this->kind() == kind::int64`, returns a pointer to the underlying
1499 integer. Otherwise, returns `nullptr`.
1500
1501 @par Example
1502 The return value is used in both a boolean context and
1503 to assign a variable:
1504 @code
1505 if( auto p = jv.if_int64() )
1506 return *p;
1507 @endcode
1508
1509 @par Complexity
1510 Constant.
1511
1512 @par Exception Safety
1513 No-throw guarantee.
1514
1515 @{
1516 */
1517 std::int64_t const*
1518 8x if_int64() const noexcept
1519 {
1520 8x if(kind() == json::kind::int64)
1521 1x return &sca_.i;
1522 7x return nullptr;
1523 }
1524
1525 std::int64_t*
1526 13x if_int64() noexcept
1527 {
1528 13x if(kind() == json::kind::int64)
1529 6x return &sca_.i;
1530 7x return nullptr;
1531 }
1532 /// @}
1533
1534 /** Return a pointer to the underlying `std::uint64_t`.
1535
1536 If `this->kind() == kind::uint64`, returns a pointer to the underlying
1537 unsigned integer. Otherwise, returns `nullptr`.
1538
1539 @par Example
1540 The return value is used in both a boolean context and
1541 to assign a variable:
1542 @code
1543 if( auto p = jv.if_uint64() )
1544 return *p;
1545 @endcode
1546
1547 @par Complexity
1548 Constant.
1549
1550 @par Exception Safety
1551 No-throw guarantee.
1552
1553 @{
1554 */
1555 std::uint64_t const*
1556 8x if_uint64() const noexcept
1557 {
1558 8x if(kind() == json::kind::uint64)
1559 1x return &sca_.u;
1560 7x return nullptr;
1561 }
1562
1563 std::uint64_t*
1564 11x if_uint64() noexcept
1565 {
1566 11x if(kind() == json::kind::uint64)
1567 4x return &sca_.u;
1568 7x return nullptr;
1569 }
1570 /// @}
1571
1572 /** Return a pointer to the underlying `double`.
1573
1574 If `this->kind() == kind::double_`, returns a pointer to the underlying
1575 double. Otherwise, returns `nullptr`.
1576
1577 @par Example
1578 The return value is used in both a boolean context and
1579 to assign a variable:
1580 @code
1581 if( auto p = jv.if_double() )
1582 return *p;
1583 @endcode
1584
1585 @par Complexity
1586 Constant.
1587
1588 @par Exception Safety
1589 No-throw guarantee.
1590
1591 @{
1592 */
1593 double const*
1594 8x if_double() const noexcept
1595 {
1596 8x if(kind() == json::kind::double_)
1597 1x return &sca_.d;
1598 7x return nullptr;
1599 }
1600
1601 double*
1602 11x if_double() noexcept
1603 {
1604 11x if(kind() == json::kind::double_)
1605 4x return &sca_.d;
1606 7x return nullptr;
1607 }
1608 /// @}
1609
1610 /** Return a pointer to the underlying `bool` .
1611
1612 If `this->kind() == kind::bool_`, returns a pointer to the underlying
1613 boolean. Otherwise, returns `nullptr`.
1614
1615 @par Example
1616 The return value is used in both a boolean context and
1617 to assign a variable:
1618 @code
1619 if( auto p = jv.if_bool() )
1620 return *p;
1621 @endcode
1622
1623 @par Complexity
1624 Constant.
1625
1626 @par Exception Safety
1627 No-throw guarantee.
1628
1629 @{
1630 */
1631 bool const*
1632 57x if_bool() const noexcept
1633 {
1634 57x if(kind() == json::kind::bool_)
1635 43x return &sca_.b;
1636 14x return nullptr;
1637 }
1638
1639 bool*
1640 11x if_bool() noexcept
1641 {
1642 11x if(kind() == json::kind::bool_)
1643 4x return &sca_.b;
1644 7x return nullptr;
1645 }
1646 /// @}
1647
1648 //------------------------------------------------------
1649
1650 /** Return the stored number cast to an arithmetic type.
1651
1652 This function attempts to return the stored value converted to the
1653 arithmetic type `T` which may not be `bool`:
1654
1655 @li If `T` is an integral type and the stored value is a number which
1656 can be losslessly converted, the conversion is performed without
1657 error and the converted number is returned.
1658 @li If `T` is an integral type and the stored value is a number which
1659 cannot be losslessly converted, then the operation fails with
1660 an error.
1661 @li If `T` is a floating point type and the stored value is a number,
1662 the conversion is performed without error. The converted number is
1663 returned, with a possible loss of precision.
1664 @li Otherwise, if the stored value is not a number; that is, if
1665 @ref is_number() returns `false`, then the operation fails with
1666 an error.
1667
1668 @par Constraints
1669 @code
1670 std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1671 @endcode
1672
1673 @par Complexity
1674 Constant.
1675
1676 @par Exception Safety
1677 @li **(1)**, **(2)** no-throw guarantee.
1678 @li **(3)** strong guarantee.
1679
1680 @return The converted number.
1681
1682 @param ec Set to the error, if any occurred.
1683
1684 @return The converted number.
1685
1686 @{
1687 */
1688 template<class T>
1689 #ifdef BOOST_JSON_DOCS
1690 T
1691 #else
1692 typename std::enable_if<
1693 std::is_arithmetic<T>::value &&
1694 ! std::is_same<T, bool>::value,
1695 T>::type
1696 #endif
1697 3594x to_number(system::error_code& ec) const noexcept
1698 {
1699 error e;
1700 3594x auto result = to_number<T>(e);
1701 3594x BOOST_JSON_FAIL(ec, e);
1702 3594x return result;
1703 }
1704
1705 template<class T>
1706 #ifdef BOOST_JSON_DOCS
1707 T
1708 #else
1709 typename std::enable_if<
1710 std::is_arithmetic<T>::value &&
1711 ! std::is_same<T, bool>::value,
1712 T>::type
1713 #endif
1714 1x to_number(std::error_code& ec) const noexcept
1715 {
1716 1x system::error_code jec;
1717 1x auto result = to_number<T>(jec);
1718 1x ec = jec;
1719 1x return result;
1720 }
1721
1722 /** Overload
1723
1724 @param loc @ref boost::source_location to use in thrown exception; the
1725 source location of the call site by default.
1726
1727 @throws boost::system::system_error Overload **(3)** reports errors by
1728 throwing an exception.
1729 */
1730 template<class T>
1731 #ifdef BOOST_JSON_DOCS
1732 T
1733 #else
1734 typename std::enable_if<
1735 std::is_arithmetic<T>::value &&
1736 ! std::is_same<T, bool>::value,
1737 T>::type
1738 #endif
1739 194x to_number(source_location const& loc = BOOST_CURRENT_LOCATION) const
1740 {
1741 194x return try_to_number<T>().value(loc);
1742 }
1743 /// @}
1744
1745 /** Return the stored number as @ref boost::system::result.
1746
1747 This function attempts to return the stored value converted to the
1748 arithmetic type `T` which may not be `bool`:
1749
1750 @li If `T` is an integral type and the stored value is a number which
1751 can be losslessly converted, the conversion is performed without
1752 error and `result<T>` containing the converted number is returned.
1753 @li If `T` is an integral type and the stored value is a number which
1754 cannot be losslessly converted, then `result<T>` containing the
1755 corresponding `error_code` is returned.
1756 @li If `T` is a floating point type and the stored value is a number,
1757 the conversion is performed without error. `result<T>` containing
1758 the converted number, with a possible loss of precision, is
1759 returned.
1760 @li Otherwise, if the stored value is not a number; that is, if
1761 `this->is_number()` returns `false`, then `result<T>` containing
1762 the corresponding `error_code` is returned.
1763
1764 @par Constraints
1765 @code
1766 std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
1767 @endcode
1768
1769 @par Complexity
1770 Constant.
1771
1772 @par Exception Safety
1773 No-throw guarantee.
1774
1775 @return `boost::system::result<T>` with either the converted number or
1776 an `error_code`.
1777 */
1778 template<class T>
1779 #ifdef BOOST_JSON_DOCS
1780 system::result<T>
1781 #else
1782 typename std::enable_if<
1783 std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
1784 system::result<T>
1785 >::type
1786 #endif
1787 196x try_to_number() const noexcept
1788 {
1789 196x system::error_code ec;
1790 196x T result = to_number<T>(ec);
1791 196x if( ec )
1792 78x return {system::in_place_error, ec};
1793
1794 118x return {system::in_place_value, result};
1795 }
1796
1797 //------------------------------------------------------
1798 //
1799 // Accessors
1800 //
1801 //------------------------------------------------------
1802
1803 /** Return the associated memory resource.
1804
1805 This function returns a smart pointer to the
1806 @ref boost::container::pmr::memory_resource used by the container.
1807
1808 @par Complexity
1809 Constant.
1810
1811 @par Exception Safety
1812 No-throw guarantee.
1813 */
1814 storage_ptr const&
1815 75892x storage() const noexcept
1816 {
1817 75892x return sp_;
1818 }
1819
1820 /** Return the associated allocator.
1821
1822 This function returns an instance of @ref allocator_type constructed
1823 from the associated @ref boost::container::pmr::memory_resource.
1824
1825 @par Complexity
1826 Constant.
1827
1828 @par Exception Safety
1829 No-throw guarantee.
1830 */
1831 allocator_type
1832 1x get_allocator() const noexcept
1833 {
1834 1x return sp_.get();
1835 }
1836
1837 //------------------------------------------------------
1838
1839 /** Return `result` with a reference to the underlying @ref array
1840
1841 If @ref is_array() is `true`, the result contains a reference to the
1842 underlying @ref array, otherwise it contains an `error_code`.
1843
1844 @par Example
1845 The return value can be used in both a boolean context and
1846 to assign a variable:
1847 @code
1848 if( auto r = jv.try_as_array() )
1849 return *r;
1850 @endcode
1851
1852 But can also be used to throw an exception on error:
1853 @code
1854 return jv.try_as_array().value();
1855 @endcode
1856
1857 @par Complexity
1858 Constant.
1859
1860 @par Exception Safety
1861 No-throw guarantee.
1862
1863 @{
1864 */
1865 BOOST_JSON_DECL
1866 system::result<array&>
1867 try_as_array() noexcept;
1868
1869 BOOST_JSON_DECL
1870 system::result<array const&>
1871 try_as_array() const noexcept;
1872 /// @}
1873
1874 /** Return `result` with a reference to the underlying @ref object.
1875
1876 If @ref is_object() is `true`, the result contains a reference to the
1877 underlying @ref object, otherwise it contains an `error_code`.
1878
1879 @par Example
1880 The return value can be used in both a boolean context and
1881 to assign a variable:
1882 @code
1883 if( auto r = jv.try_as_object() )
1884 return *r;
1885 @endcode
1886
1887 But can also be used to throw an exception on error:
1888 @code
1889 return jv.try_as_object().value();
1890 @endcode
1891
1892 @par Complexity
1893 Constant.
1894
1895 @par Exception Safety
1896 No-throw guarantee.
1897
1898 @{
1899 */
1900 BOOST_JSON_DECL
1901 system::result<object&>
1902 try_as_object() noexcept;
1903
1904 BOOST_JSON_DECL
1905 system::result<object const&>
1906 try_as_object() const noexcept;
1907 /// @}
1908
1909 /** Return `result` with a reference to the underlying @ref string.
1910
1911 If @ref is_string() is `true`, the result contains a reference to the
1912 underlying @ref string, otherwise it contains an `error_code`.
1913
1914 @par Example
1915 The return value can be used in both a boolean context and
1916 to assign a variable:
1917 @code
1918 if( auto r = jv.try_as_string() )
1919 return *r;
1920 @endcode
1921
1922 But can also be used to throw an exception on error:
1923 @code
1924 return jv.try_as_string().value();
1925 @endcode
1926
1927 @par Complexity
1928 Constant.
1929
1930 @par Exception Safety
1931 No-throw guarantee.
1932
1933 @{
1934 */
1935 BOOST_JSON_DECL
1936 system::result<string&>
1937 try_as_string() noexcept;
1938
1939 BOOST_JSON_DECL
1940 system::result<string const&>
1941 try_as_string() const noexcept;
1942 /// @}
1943
1944 /** Return `result` with the underlying `std::int64_t`
1945
1946 If @ref is_int64() is `true`, the result contains a reference to **(1)**
1947 or a copy of **(2)** the underlying `std::int64_t`, otherwise it
1948 contains an `error_code`.
1949
1950 @par Example
1951 The return value can be used in both a boolean context and
1952 to assign a variable:
1953 @code
1954 if( auto r = jv.try_as_int64() )
1955 return *r;
1956 @endcode
1957
1958 But can also be used to throw an exception on error:
1959 @code
1960 return jv.try_as_int64().value();
1961 @endcode
1962
1963 @par Complexity
1964 Constant.
1965
1966 @par Exception Safety
1967 No-throw guarantee.
1968
1969 @{
1970 */
1971 BOOST_JSON_DECL
1972 system::result<std::int64_t&>
1973 try_as_int64() noexcept;
1974
1975 BOOST_JSON_DECL
1976 system::result<std::int64_t>
1977 try_as_int64() const noexcept;
1978 /// @}
1979
1980 /** Return `result` with the underlying `std::uint64_t`.
1981
1982 If @ref is_uint64() is `true`, the result contains a reference to **(1)**
1983 or a copy of **(2)** the underlying `std::uint64_t`, otherwise it
1984 contains an `error_code`.
1985
1986 @par Example
1987 The return value can be used in both a boolean context and
1988 to assign a variable:
1989 @code
1990 if( auto r = jv.try_as_uint64() )
1991 return *r;
1992 @endcode
1993
1994 But can also be used to throw an exception on error:
1995 @code
1996 return jv.try_as_uint64().value();
1997 @endcode
1998
1999 @par Complexity
2000 Constant.
2001
2002 @par Exception Safety
2003 No-throw guarantee.
2004
2005 @{
2006 */
2007 BOOST_JSON_DECL
2008 system::result<std::uint64_t&>
2009 try_as_uint64() noexcept;
2010
2011 BOOST_JSON_DECL
2012 system::result<std::uint64_t>
2013 try_as_uint64() const noexcept;
2014 /// @}
2015
2016 /** Return `result` with the underlying `double`
2017
2018 If @ref is_double() is `true`, the result contains a reference to **(1)**
2019 or a copy of **(2)** the underlying `double`, otherwise it
2020 contains an `error_code`.
2021
2022 @par Example
2023 The return value can be used in both a boolean context and
2024 to assign a variable:
2025 @code
2026 if( auto r = jv.try_as_double() )
2027 return *r;
2028 @endcode
2029
2030 But can also be used to throw an exception on error:
2031 @code
2032 return jv.try_as_double().value();
2033 @endcode
2034
2035 @par Complexity
2036 Constant.
2037
2038 @par Exception Safety
2039 No-throw guarantee.
2040
2041 @{
2042 */
2043 BOOST_JSON_DECL
2044 system::result<double&>
2045 try_as_double() noexcept;
2046
2047 BOOST_JSON_DECL
2048 system::result<double>
2049 try_as_double() const noexcept;
2050 /// @}
2051
2052 /** Return `result` with the underlying `bool`
2053
2054 If @ref is_bool() is `true`, the result contains a reference to **(1)**
2055 or a copy to **(2)** the underlying `bool`, otherwise it contains an
2056 `error_code`.
2057
2058 @par Example
2059 The return value can be used in both a boolean context and
2060 to assign a variable:
2061 @code
2062 if( auto r = jv.try_as_bool() )
2063 return *r;
2064 @endcode
2065
2066 But can also be used to throw an exception on error:
2067 @code
2068 return jv.try_as_bool().value();
2069 @endcode
2070
2071 @par Complexity
2072 Constant.
2073
2074 @par Exception Safety
2075 No-throw guarantee.
2076
2077 @{
2078 */
2079 BOOST_JSON_DECL
2080 system::result<bool&>
2081 try_as_bool() noexcept;
2082
2083 BOOST_JSON_DECL
2084 system::result<bool>
2085 try_as_bool() const noexcept;
2086 /// @}
2087
2088 /** Return engaged `result` if the `value` is null.
2089
2090 If @ref is_null() is `true`, the result is engaged, otherwise it
2091 contains an `error_code`.
2092
2093 @par Example
2094 The return value can be used in both a boolean context and
2095 to assign a variable:
2096 @code
2097 if( auto r = jv.try_as_null() )
2098 return *r;
2099 @endcode
2100
2101 But can also be used to throw an exception on error:
2102 @code
2103 return jv.try_as_null().value();
2104 @endcode
2105
2106 @par Complexity
2107 Constant.
2108
2109 @par Exception Safety
2110 No-throw guarantee.
2111 */
2112 BOOST_JSON_DECL
2113 system::result<std::nullptr_t>
2114 try_as_null() const noexcept;
2115
2116 //------------------------------------------------------
2117
2118 /** Return the underlying @ref object, or throw an exception.
2119
2120 If @ref is_object() is `true`, returns a reference to the underlying
2121 @ref object, otherwise throws an exception.
2122
2123 @par Exception Safety
2124 Strong guarantee.
2125
2126 @throw boost::system::system_error `! this->is_object()`.
2127
2128 @param loc @ref boost::source_location to use in thrown exception; the
2129 source location of the call site by default.
2130
2131 @par Complexity
2132 Constant.
2133
2134 @{
2135 */
2136 object&
2137 167x as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
2138 {
2139 167x auto& self = const_cast<value const&>(*this);
2140 167x return const_cast<object&>( self.as_object(loc) );
2141 }
2142
2143 /// Overload
2144 object&&
2145 97x as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2146 {
2147 97x return std::move( as_object(loc) );
2148 }
2149
2150 /// Overload
2151 BOOST_JSON_DECL
2152 object const&
2153 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2154 /// @}
2155
2156 /** Return the underlying @ref array, or throw an exception.
2157
2158 If @ref is_array() is `true`, returns a reference to the underlying
2159 @ref array, otherwise throws an exception.
2160
2161 @par Exception Safety
2162 Strong guarantee.
2163
2164 @throw boost::system::system_error `! this->is_array()`.
2165
2166 @param loc @ref boost::source_location to use in thrown exception; the
2167 source location of the call site by default.
2168
2169 @par Complexity
2170 Constant.
2171
2172 @{
2173 */
2174 array&
2175 95x as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
2176 {
2177 95x auto& self = const_cast<value const&>(*this);
2178 95x return const_cast<array&>( self.as_array(loc) );
2179 }
2180
2181 /// Overload
2182 array&&
2183 10x as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2184 {
2185 10x return std::move( as_array(loc) );
2186 }
2187
2188 /// Overload
2189 BOOST_JSON_DECL
2190 array const&
2191 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2192 /// @}
2193
2194 /** Return the underlying @ref string, or throw an exception.
2195
2196 If @ref is_string() is `true`, returns a reference to the underlying
2197 @ref string, otherwise throws an exception.
2198
2199 @par Exception Safety
2200 Strong guarantee.
2201
2202 @throw boost::system::system_error `! this->is_string()`.
2203
2204 @param loc @ref boost::source_location to use in thrown exception; the
2205 source location of the call site by default.
2206
2207 @par Complexity
2208 Constant.
2209
2210 @{
2211 */
2212 string&
2213 34x as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
2214 {
2215 34x auto& self = const_cast<value const&>(*this);
2216 34x return const_cast<string&>( self.as_string(loc) );
2217 }
2218
2219 /// Overload
2220 string&&
2221 12x as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
2222 {
2223 12x return std::move( as_string(loc) );
2224 }
2225
2226 /// Overload
2227 BOOST_JSON_DECL
2228 string const&
2229 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2230 /// @}
2231
2232 /** Return the underlying `std::int64_t`, or throw an exception.
2233
2234 If @ref is_int64() is `true`, returns a reference to **(1)** or a copy
2235 of **(2)** the underlying `std::int64_t`, otherwise throws an
2236 exception.
2237
2238 @note This function is the intended for direct access to the underlying
2239 object, __if__ it has the type `std::int64_t`. It does not convert the
2240 underlying object to the type `std::int64_t` even if a lossless
2241 conversion is possible. If you are not sure which kind your `value`
2242 has, and you only care about getting a `std::int64_t` number, consider
2243 using @ref to_number instead.
2244
2245 @par Exception Safety
2246 Strong guarantee.
2247
2248 @throw boost::system::system_error `! this->is_int64()`.
2249
2250 @param loc @ref boost::source_location to use in thrown exception; the
2251 source location of the call site by default.
2252
2253 @par Complexity
2254 Constant.
2255
2256 @{
2257 */
2258 BOOST_JSON_DECL
2259 std::int64_t&
2260 as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
2261
2262 /// Overload
2263 BOOST_JSON_DECL
2264 std::int64_t
2265 as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2266 /// @}
2267
2268 /** Return the underlying `std::uint64_t`, or throw an exception.
2269
2270 If @ref is_uint64() is `true`, returns a reference to **(1)** or a
2271 copy of **(2)** the underlying `std::uint64_t`, otherwise throws an
2272 exception.
2273
2274 @note This function is intended for direct access to the underlying
2275 object, __if__ it has the type `std::uint64_t`. It does not convert the
2276 underlying object to the type `std::uint64_t` even if a lossless
2277 conversion is possible. If you are not sure which kind your `value`
2278 has, and you only care about getting a `std::uint64_t` number, consider
2279 using @ref to_number instead.
2280
2281 @par Exception Safety
2282 Strong guarantee.
2283
2284 @throw boost::system::system_error `! this->is_uint64()`.
2285
2286 @param loc @ref boost::source_location to use in thrown exception; the
2287 source location of the call site by default.
2288
2289 @par Complexity
2290 Constant.
2291
2292 @{
2293 */
2294 BOOST_JSON_DECL
2295 std::uint64_t&
2296 as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
2297
2298 /// Overload
2299 BOOST_JSON_DECL
2300 std::uint64_t
2301 as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2302 /// @}
2303
2304 /** Return the underlying `double`, or throw an exception.
2305
2306 If @ref is_double() is `true`, returns a reference to **(1)** or a copy
2307 of **(2)** the underlying `double`, otherwise throws an exception.
2308
2309 @note This function is intended for direct access to the underlying
2310 object, __if__ it has the type `double`. It does not convert the
2311 underlying object to type `double` even if a lossless conversion is
2312 possible. If you are not sure which kind your `value` has, and you only
2313 care about getting a `double` number, consider using @ref to_number
2314 instead.
2315
2316 @par Exception Safety
2317 Strong guarantee.
2318
2319 @throw boost::system::system_error `! this->is_double()`.
2320
2321 @param loc @ref boost::source_location to use in thrown exception; the
2322 source location of the call site by default.
2323
2324 @par Complexity
2325 Constant.
2326
2327 @{
2328 */
2329 BOOST_JSON_DECL
2330 double&
2331 as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
2332
2333 /// Overload
2334 BOOST_JSON_DECL
2335 double
2336 as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2337 /// @}
2338
2339 /** Return the underlying `bool`, or throw an exception.
2340
2341 If @ref is_bool() is `true`, returns a reference to **(1)** or a copy
2342 of **(2)** the underlying `bool`, otherwise throws an exception.
2343
2344 @par Exception Safety
2345 Strong guarantee.
2346
2347 @throw boost::system::system_error `! this->is_bool()`.
2348
2349 @param loc @ref boost::source_location to use in thrown exception; the
2350 source location of the call site by default.
2351
2352 @par Complexity
2353 Constant.
2354
2355 @{
2356 */
2357 BOOST_JSON_DECL
2358 bool&
2359 as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
2360
2361 /// Overload
2362 BOOST_JSON_DECL
2363 bool
2364 as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
2365 /// @}
2366
2367 //------------------------------------------------------
2368
2369 /** Return the underlying @ref object, without checking.
2370
2371 This is the fastest way to access the underlying representation when
2372 the kind is known in advance.
2373
2374 @par Preconditions
2375
2376 @code
2377 this->is_object()
2378 @endcode
2379
2380 @par Complexity
2381 Constant.
2382
2383 @par Exception Safety
2384 No-throw guarantee.
2385
2386 @{
2387 */
2388 object&
2389 40x get_object() & noexcept
2390 {
2391 40x BOOST_ASSERT(is_object());
2392 40x return obj_;
2393 }
2394
2395 object&&
2396 1x get_object() && noexcept
2397 {
2398 1x BOOST_ASSERT(is_object());
2399 1x return std::move(obj_);
2400 }
2401
2402 object const&
2403 52947x get_object() const& noexcept
2404 {
2405 52947x BOOST_ASSERT(is_object());
2406 52947x return obj_;
2407 }
2408 /// @}
2409
2410 /** Return the underlying @ref array, without checking.
2411
2412 This is the fastest way to access the underlying representation when
2413 the kind is known in advance.
2414
2415 @par Preconditions
2416
2417 @code
2418 this->is_array()
2419 @endcode
2420
2421 @par Complexity
2422 Constant.
2423
2424 @par Exception Safety
2425 No-throw guarantee.
2426
2427 @{
2428 */
2429 array&
2430 27x get_array() & noexcept
2431 {
2432 27x BOOST_ASSERT(is_array());
2433 27x return arr_;
2434 }
2435
2436 array&&
2437 1x get_array() && noexcept
2438 {
2439 1x BOOST_ASSERT(is_array());
2440 1x return std::move(arr_);
2441 }
2442
2443 array const&
2444 5702x get_array() const& noexcept
2445 {
2446 5702x BOOST_ASSERT(is_array());
2447 5702x return arr_;
2448 }
2449 /// @}
2450
2451 /** Return the underlying @ref string, without checking.
2452
2453 This is the fastest way to access the underlying representation when
2454 the kind is known in advance.
2455
2456 @par Preconditions
2457
2458 @code
2459 this->is_string()
2460 @endcode
2461
2462 @par Complexity
2463 Constant.
2464
2465 @par Exception Safety
2466 No-throw guarantee.
2467
2468 @{
2469 */
2470 string&
2471 8973x get_string() & noexcept
2472 {
2473 8973x BOOST_ASSERT(is_string());
2474 8973x return str_;
2475 }
2476
2477 string&&
2478 1x get_string() && noexcept
2479 {
2480 1x BOOST_ASSERT(is_string());
2481 1x return std::move(str_);
2482 }
2483
2484 string const&
2485 40936x get_string() const& noexcept
2486 {
2487 40936x BOOST_ASSERT(is_string());
2488 40936x return str_;
2489 }
2490 /// @}
2491
2492 /** Return the underlying `std::int64_t`, without checking.
2493
2494 This is the fastest way to access the underlying representation when
2495 the kind is known in advance.
2496
2497 @par Preconditions
2498
2499 @code
2500 this->is_int64()
2501 @endcode
2502
2503 @par Complexity
2504 Constant.
2505
2506 @par Exception Safety
2507 No-throw guarantee.
2508
2509 @{
2510 */
2511 std::int64_t&
2512 3x get_int64() noexcept
2513 {
2514 3x BOOST_ASSERT(is_int64());
2515 3x return sca_.i;
2516 }
2517
2518 std::int64_t
2519 14227x get_int64() const noexcept
2520 {
2521 14227x BOOST_ASSERT(is_int64());
2522 14227x return sca_.i;
2523 }
2524 /// @}
2525
2526 /** Return the underlying `std::uint64_t`, without checking.
2527
2528 This is the fastest way to access the underlying representation when
2529 the kind is known in advance.
2530
2531 @par Preconditions
2532
2533 @code
2534 this->is_uint64()
2535 @endcode
2536
2537 @par Complexity
2538 Constant.
2539
2540 @par Exception Safety
2541 No-throw guarantee.
2542
2543 @{
2544 */
2545 std::uint64_t&
2546 3x get_uint64() noexcept
2547 {
2548 3x BOOST_ASSERT(is_uint64());
2549 3x return sca_.u;
2550 }
2551
2552 std::uint64_t
2553 195x get_uint64() const noexcept
2554 {
2555 195x BOOST_ASSERT(is_uint64());
2556 195x return sca_.u;
2557 }
2558 /// @}
2559
2560 /** Return the underlying `double`, without checking.
2561
2562 This is the fastest way to access the underlying
2563 representation when the kind is known in advance.
2564
2565 @par Preconditions
2566
2567 @code
2568 this->is_double()
2569 @endcode
2570
2571 @par Complexity
2572 Constant.
2573
2574 @par Exception Safety
2575 No-throw guarantee.
2576
2577 @{
2578 */
2579 double&
2580 3x get_double() noexcept
2581 {
2582 3x BOOST_ASSERT(is_double());
2583 3x return sca_.d;
2584 }
2585
2586 double
2587 39169x get_double() const noexcept
2588 {
2589 39169x BOOST_ASSERT(is_double());
2590 39169x return sca_.d;
2591 }
2592 /// @}
2593
2594 /** Return the underlying `bool`, without checking.
2595
2596 This is the fastest way to access the underlying representation when
2597 the kind is known in advance.
2598
2599 @par Preconditions
2600
2601 @code
2602 this->is_bool()
2603 @endcode
2604
2605 @par Complexity
2606 Constant.
2607
2608 @par Exception Safety
2609 No-throw guarantee.
2610
2611 @{
2612 */
2613 bool&
2614 3x get_bool() noexcept
2615 {
2616 3x BOOST_ASSERT(is_bool());
2617 3x return sca_.b;
2618 }
2619
2620 bool
2621 777x get_bool() const noexcept
2622 {
2623 777x BOOST_ASSERT(is_bool());
2624 777x return sca_.b;
2625 }
2626 /// @}
2627
2628 //------------------------------------------------------
2629
2630 /** Access an element, with bounds checking.
2631
2632 Returns `boost::system::result` containing a reference to the element
2633 of the underlying ccontainer, if such element exists. If the underlying
2634 value is not a container of the suitable type or the container doesn't
2635 have a corresponding element the result contains an `error_code`.
2636
2637 , if `pos` is within its range. If `pos` is
2638 outside of that range, or the underlying value is not an object the
2639
2640 Returns @ref boost::system::result containing a reference to the
2641 element of the underlying @ref array, if `pos` is within its range. If
2642 `pos` is outside of that range, or the underlying value is not an array
2643 the result contains an `error_code`.
2644
2645 This function is used to access elements of
2646 the underlying container, or throw an exception if that could not be
2647 done.
2648
2649 @li **(1)**, **(2)** require the underlying container to be an
2650 @ref object, and look for an element with the key `key`.
2651 @li **(3)**, **(4)** require the underlying container to be an
2652 @ref array, and look for an element at index `pos`.
2653
2654 @par Exception Safety
2655 No-throw guarantee.
2656
2657 @param key The key of the element to find.
2658
2659 @par Complexity
2660 Constant.
2661
2662 @par Exception Safety
2663 No-throw guarantee.
2664
2665 @{
2666 */
2667 BOOST_JSON_DECL
2668 boost::system::result<value&>
2669 try_at(string_view key) noexcept;
2670
2671 BOOST_JSON_DECL
2672 boost::system::result<value const&>
2673 try_at(string_view key) const noexcept;
2674
2675 /** Overload
2676
2677 @param pos A zero-based array index.
2678 */
2679 BOOST_JSON_DECL
2680 boost::system::result<value&>
2681 try_at(std::size_t pos) noexcept;
2682
2683 /// Overload
2684 BOOST_JSON_DECL
2685 boost::system::result<value const&>
2686 try_at(std::size_t pos) const noexcept;
2687 /// @}
2688
2689
2690 /** Access an element, with bounds checking.
2691
2692 This function is used to access elements of
2693 the underlying container, or throw an exception if that could not be
2694 done.
2695
2696 @li **(1)**--**(3)** is equivalent to
2697 `this->as_object(loc).at(key, loc)`.
2698 @li **(4)**--**(6)** is equivalent to
2699 `this->as_array(loc).at(pos, loc)`.
2700
2701 @par Complexity
2702 Constant.
2703
2704 @par Exception Safety
2705 Strong guarantee.
2706
2707 @param key The key of the element to find.
2708 @param loc @ref boost::source_location to use in thrown exception; the
2709 source location of the call site by default.
2710
2711 @throw boost::system::system_error The underlying type of value is not
2712 the container type corresponding to the first argument (i.e.
2713 using an index with an @ref object).
2714 @throw boost::system::system_error An element corresponding to the
2715 first argument was not found.
2716
2717 @see @ref as_array, @ref as_object.
2718
2719 @{
2720 */
2721 value&
2722 13x at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
2723 {
2724 13x return as_object(loc).at(key, loc);
2725 }
2726
2727 /// Overload
2728 value&&
2729 1x at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2730 {
2731 1x return std::move( as_object(loc) ).at(key, loc);
2732 }
2733
2734 /// Overload
2735 value const&
2736 18x at(
2737 string_view key,
2738 source_location const& loc = BOOST_CURRENT_LOCATION) const&
2739 {
2740 18x return as_object(loc).at(key, loc);
2741 }
2742
2743 /** Overload
2744
2745 @param pos A zero-based array index.
2746 @param loc
2747 */
2748 value &
2749 12x at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
2750 {
2751 12x return as_array(loc).at(pos, loc);
2752 }
2753
2754 /// Overload
2755 value&&
2756 10x at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
2757 {
2758 10x return std::move( as_array(loc) ).at(pos, loc);
2759 }
2760
2761 /// Overload
2762 value const&
2763 56x at(std::size_t pos,
2764 source_location const& loc = BOOST_CURRENT_LOCATION) const&
2765 {
2766 56x return as_array(loc).at(pos, loc);
2767 }
2768 /// @}
2769
2770 /** Access an element via JSON Pointer.
2771
2772 This function is used to access a (potentially nested) element of the
2773 value using a JSON Pointer string.
2774
2775 @par Complexity
2776 Linear in the sizes of `ptr` and underlying array, object, or string.
2777
2778 @par Exception Safety
2779 No-throw guarantee.
2780
2781 @param ptr JSON Pointer string.
2782
2783 @return @ref boost::system::result containing either a reference to the
2784 element identified by `ptr` or a corresponding `error_code`.
2785
2786 @see
2787 [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2788
2789 @{
2790 */
2791 BOOST_JSON_DECL
2792 system::result<value const&>
2793 try_at_pointer(string_view ptr) const noexcept;
2794
2795 BOOST_JSON_DECL
2796 system::result<value&>
2797 try_at_pointer(string_view ptr) noexcept;
2798 /// @}
2799
2800 /** Access an element via JSON Pointer.
2801
2802 This function is used to access a (potentially nested) element of the
2803 value using a JSON Pointer string.
2804
2805 @par Complexity
2806 Linear in the sizes of `ptr` and the underlying container.
2807
2808 @par Exception Safety
2809 Strong guarantee.
2810
2811 @param ptr JSON Pointer string.
2812 @param loc @ref boost::source_location to use in thrown exception; the
2813 source location of the call site by default.
2814
2815 @return reference to the element identified by `ptr`.
2816
2817 @throw boost::system::system_error if an error occurs.
2818
2819 @see
2820 [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2821
2822 @{
2823 */
2824 BOOST_JSON_DECL
2825 value const&
2826 at_pointer(
2827 string_view ptr,
2828 source_location const& loc = BOOST_CURRENT_LOCATION) const&;
2829
2830 /// Overload
2831 inline
2832 value&&
2833 at_pointer(
2834 string_view ptr,
2835 source_location const& loc = BOOST_CURRENT_LOCATION) &&;
2836
2837 /// Overload
2838 inline
2839 value&
2840 at_pointer(
2841 string_view ptr,
2842 source_location const& loc = BOOST_CURRENT_LOCATION) &;
2843 /// @}
2844
2845 /** Access an element via JSON Pointer.
2846
2847 This function is used to access a (potentially nested) element of the
2848 value using a JSON Pointer string.
2849
2850 @par Complexity
2851 Linear in the sizes of `ptr` and underlying container.
2852
2853 @par Exception Safety
2854 No-throw guarantee.
2855
2856 @param ptr JSON Pointer string.
2857 @param ec Set to the error, if any occurred.
2858
2859 @return pointer to the element identified by `ptr`.
2860
2861 @see
2862 [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901)
2863
2864 @{
2865 */
2866 BOOST_JSON_DECL
2867 value const*
2868 find_pointer(string_view ptr, system::error_code& ec) const noexcept;
2869
2870 BOOST_JSON_DECL
2871 value*
2872 find_pointer(string_view ptr, system::error_code& ec) noexcept;
2873
2874 BOOST_JSON_DECL
2875 value const*
2876 find_pointer(string_view ptr, std::error_code& ec) const noexcept;
2877
2878 BOOST_JSON_DECL
2879 value*
2880 find_pointer(string_view ptr, std::error_code& ec) noexcept;
2881 /// @}
2882
2883 //------------------------------------------------------
2884
2885 /** Set an element via JSON Pointer.
2886
2887 This function is used to insert or assign to a potentially nested
2888 element of the value using a JSON Pointer string. The function may
2889 create intermediate elements corresponding to pointer segments.
2890
2891 The particular conditions when and what kind of intermediate element
2892 is created is governed by the `ptr` parameter.
2893
2894 Each pointer token is considered in sequence. For each token
2895
2896 - if the containing value is an @ref object, then a new `null`
2897 element is created with key equal to unescaped token string;
2898 otherwise
2899
2900 - if the containing value is an @ref array, and the token represents a
2901 past-the-end marker, then a `null` element is appended to the array;
2902 otherwise
2903
2904 - if the containing value is an @ref array, and the token represents a
2905 number, then if the difference between the number and array's size
2906 is smaller than `opts.max_created_elements`, then the size of the
2907 array is increased, so that the number can reference an element in the
2908 array; otherwise
2909
2910 - if the containing value is of different @ref kind and
2911 `opts.replace_any_scalar` is `true`, or the value is `null`, then
2912
2913 - if `opts.create_arrays` is `true` and the token either represents
2914 past-the-end marker or a number, then the value is replaced with
2915 an empty array and the token is considered again; otherwise
2916
2917 - if `opts.create_objects` is `true`, then the value is replaced
2918 with an empty object and the token is considered again; otherwise
2919
2920 - an error is produced.
2921
2922 @par Complexity
2923 Linear in the sum of size of `ptr`, size of underlying array, object,
2924 or string and `opts.max_created_elements`.
2925
2926 @par Exception Safety
2927 Basic guarantee. Calls to `memory_resource::allocate` may throw.
2928
2929 @param sv JSON Pointer string.
2930 @param ref The value to assign to pointed element.
2931 @param opts The options for the algorithm.
2932
2933 @return @ref boost::system::result containing either a reference to the
2934 element identified by `ptr` or a corresponding `error_code`.
2935
2936 @see
2937 @ref set_pointer_options,
2938 [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
2939 */
2940 BOOST_JSON_DECL
2941 system::result<value&>
2942 try_set_at_pointer(
2943 string_view sv,
2944 value_ref ref,
2945 set_pointer_options const& opts = {} );
2946
2947 /** Set an element via JSON Pointer.
2948
2949 This function is used to insert or assign to a potentially nested
2950 element of the value using a JSON Pointer string. The function may
2951 create intermediate elements corresponding to pointer segments.
2952
2953 The particular conditions when and what kind of intermediate element
2954 is created is governed by the `ptr` parameter.
2955
2956 Each pointer token is considered in sequence. For each token
2957
2958 - if the containing value is an @ref object, then a new `null`
2959 element is created with key equal to unescaped token string; otherwise
2960
2961 - if the containing value is an @ref array, and the token represents a
2962 past-the-end marker, then a `null` element is appended to the array;
2963 otherwise
2964
2965 - if the containing value is an @ref array, and the token represents a
2966 number, then if the difference between the number and array's size
2967 is smaller than `opts.max_created_elements`, then the size of the
2968 array is increased, so that the number can reference an element in the
2969 array; otherwise
2970
2971 - if the containing value is of different @ref kind and
2972 `opts.replace_any_scalar` is `true`, or the value is `null`, then
2973
2974 - if `opts.create_arrays` is `true` and the token either represents
2975 past-the-end marker or a number, then the value is replaced with
2976 an empty array and the token is considered again; otherwise
2977
2978 - if `opts.create_objects` is `true`, then the value is replaced
2979 with an empty object and the token is considered again; otherwise
2980
2981 - an error is produced.
2982
2983 @par Complexity
2984 Linear in the sum of size of `ptr`, size of underlying array, object,
2985 or string and `opts.max_created_elements`.
2986
2987 @par Exception Safety
2988 Basic guarantee.
2989 Calls to `memory_resource::allocate` may throw.
2990
2991 @param sv JSON Pointer string.
2992
2993 @param ref The value to assign to pointed element.
2994
2995 @param opts The options for the algorithm.
2996
2997 @param loc @ref boost::source_location to use in thrown exception; the
2998 source location of the call site by default.
2999
3000 @return Reference to the element identified by `ptr`.
3001
3002 @throws boost::system::system_error Overload **(1)** reports errors by
3003 throwing exceptions.
3004
3005 @see @ref set_pointer_options,
3006 [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">).
3007
3008 @{
3009 */
3010 BOOST_JSON_DECL
3011 value&
3012 set_at_pointer(
3013 string_view sv,
3014 value_ref ref,
3015 set_pointer_options const& opts = {},
3016 source_location const& loc = BOOST_CURRENT_LOCATION);
3017
3018 /** Overload
3019
3020 @param ec Set to the error, if any occurred.
3021 @param sv
3022 @param ref
3023 @param opts
3024 */
3025 BOOST_JSON_DECL
3026 value*
3027 set_at_pointer(
3028 string_view sv,
3029 value_ref ref,
3030 system::error_code& ec,
3031 set_pointer_options const& opts = {} );
3032
3033 /// Overload
3034 BOOST_JSON_DECL
3035 value*
3036 set_at_pointer(
3037 string_view sv,
3038 value_ref ref,
3039 std::error_code& ec,
3040 set_pointer_options const& opts = {} );
3041 /// @}
3042
3043 //------------------------------------------------------
3044
3045 /** Check if two values are equal.
3046
3047 Two values are equal when they are the same kind and their referenced
3048 values are equal, or when they are both integral types and their
3049 integral representations are equal.
3050
3051 @par Complexity
3052 Constant or linear in the size of the underlying @ref array, @ref object,
3053 or @ref string.
3054
3055 @par Exception Safety
3056 No-throw guarantee.
3057 */
3058 // inline friend speeds up overload resolution
3059 friend
3060 bool
3061 4172x operator==(
3062 value const& lhs,
3063 value const& rhs) noexcept
3064 {
3065 4172x return lhs.equal(rhs);
3066 }
3067
3068 /** Check if two values are not equal.
3069
3070 Two values are equal when they are the same kind and their referenced
3071 values are equal, or when they are both integral types and their
3072 integral representations are equal.
3073
3074 @par Complexity
3075 Constant or linear in the size of the underlying @ref array,
3076 @ref object, or @ref string.
3077
3078 @par Exception Safety
3079 No-throw guarantee.
3080 */
3081 friend
3082 bool
3083 3989x operator!=(
3084 value const& lhs,
3085 value const& rhs) noexcept
3086 {
3087 3989x return ! (lhs == rhs);
3088 }
3089
3090 /** Serialize @ref value to an output stream.
3091
3092 This function serializes a `value` as JSON text into the output stream.
3093
3094 @return Reference to `os`.
3095
3096 @par Complexity
3097 Constant or linear in the size of `jv`.
3098
3099 @par Exception Safety
3100 Strong guarantee.
3101 Calls to `memory_resource::allocate` may throw.
3102
3103 @param os The output stream to serialize to.
3104
3105 @param jv The value to serialize.
3106 */
3107 BOOST_JSON_DECL
3108 friend
3109 std::ostream&
3110 operator<<(
3111 std::ostream& os,
3112 value const& jv);
3113
3114 /** Parse @ref value from an input stream.
3115
3116 This function parses JSON from an input stream into a `value`. If
3117 parsing fails, @ref std::ios_base::failbit will be set for `is` and
3118 `jv` will be left unchanged. Regardless of whether @ref
3119 std::ios_base::skipws flag is set on `is`, consumes whitespace before
3120 and after JSON, because whitespace is considered a part of JSON.
3121 Behaves as
3122 [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
3123
3124 @note This operator cannot assume that the stream only contains a
3125 single JSON document, which may result in **very underwhelming
3126 performance**, if the stream isn't cooperative. If you know that your
3127 input consists of a single JSON document, consider using @ref parse
3128 function instead.
3129
3130 @return Reference to `is`.
3131
3132 @par Complexity
3133 Linear in the size of JSON data.
3134
3135 @par Exception Safety
3136 Basic guarantee.
3137 Calls to `memory_resource::allocate` may throw.
3138 The stream may throw as configured by @ref std::ios::exceptions.
3139
3140 @param is The input stream to parse from.
3141
3142 @param jv The value to parse into.
3143
3144 @see @ref parse.
3145 */
3146 BOOST_JSON_DECL
3147 friend
3148 std::istream&
3149 operator>>(
3150 std::istream& is,
3151 value& jv);
3152
3153 /** Helper for @ref boost::hash support.
3154
3155 Computes a hash value for `jv`. This function is used by
3156 `boost::hash<value>`. Similar overloads for @ref array, @ref object,
3157 and @ref string do not exist, because those types are supported by
3158 `boost::hash` out of the box.
3159
3160 @return hash value for `jv`.
3161
3162 @param jv `value` for which a hash is to be computed.
3163
3164 @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
3165 */
3166 #ifndef BOOST_JSON_DOCS
3167 template<
3168 class T,
3169 typename std::enable_if<
3170 std::is_same< detail::remove_cvref<T>, value >::value >::type*
3171 = nullptr>
3172 friend
3173 std::size_t
3174 248x hash_value( T const& jv ) noexcept
3175 #else
3176 friend
3177 inline
3178 std::size_t
3179 hash_value( value const& jv ) noexcept
3180 #endif
3181 {
3182 248x return detail::hash_value_impl(jv);
3183 }
3184
3185 private:
3186 static
3187 void
3188 2133719x relocate(
3189 value* dest,
3190 value const& src) noexcept
3191 {
3192 2133719x std::memcpy(
3193 static_cast<void*>(dest),
3194 &src,
3195 sizeof(src));
3196 2133719x }
3197
3198 BOOST_JSON_DECL
3199 storage_ptr
3200 destroy() noexcept;
3201
3202 BOOST_JSON_DECL
3203 bool
3204 equal(value const& other) const noexcept;
3205
3206 template<class T>
3207 auto
3208 3408x to_number(error& e) const noexcept ->
3209 typename std::enable_if<
3210 std::is_signed<T>::value &&
3211 ! std::is_floating_point<T>::value,
3212 T>::type
3213 {
3214 3408x if(sca_.k == json::kind::int64)
3215 {
3216 3321x auto const i = sca_.i;
3217 6636x if( i >= (std::numeric_limits<T>::min)() &&
3218 3315x i <= (std::numeric_limits<T>::max)())
3219 {
3220 3309x e = {};
3221 3309x return static_cast<T>(i);
3222 }
3223 12x e = error::not_exact;
3224 }
3225 87x else if(sca_.k == json::kind::uint64)
3226 {
3227 20x auto const u = sca_.u;
3228 20x if(u <= static_cast<std::uint64_t>((
3229 20x std::numeric_limits<T>::max)()))
3230 {
3231 10x e = {};
3232 10x return static_cast<T>(u);
3233 }
3234 10x e = error::not_exact;
3235 }
3236 67x else if(sca_.k == json::kind::double_)
3237 {
3238 20x auto const d = sca_.d;
3239 20x if( d >= static_cast<double>(
3240 40x (detail::to_number_limit<T>::min)()) &&
3241 d <= static_cast<double>(
3242 40x (detail::to_number_limit<T>::max)()) &&
3243 20x static_cast<T>(d) == d)
3244 {
3245 9x e = {};
3246 9x return static_cast<T>(d);
3247 }
3248 11x e = error::not_exact;
3249 }
3250 else
3251 {
3252 47x e = error::not_number;
3253 }
3254 80x return T{};
3255 }
3256
3257 template<class T>
3258 auto
3259 119x to_number(error& e) const noexcept ->
3260 typename std::enable_if<
3261 std::is_unsigned<T>::value &&
3262 ! std::is_same<T, bool>::value,
3263 T>::type
3264 {
3265 119x if(sca_.k == json::kind::int64)
3266 {
3267 44x auto const i = sca_.i;
3268 72x if( i >= 0 && static_cast<std::uint64_t>(i) <=
3269 28x (std::numeric_limits<T>::max)())
3270 {
3271 22x e = {};
3272 22x return static_cast<T>(i);
3273 }
3274 22x e = error::not_exact;
3275 }
3276 75x else if(sca_.k == json::kind::uint64)
3277 {
3278 58x auto const u = sca_.u;
3279 58x if(u <= (std::numeric_limits<T>::max)())
3280 {
3281 52x e = {};
3282 52x return static_cast<T>(u);
3283 }
3284 6x e = error::not_exact;
3285 }
3286 17x else if(sca_.k == json::kind::double_)
3287 {
3288 12x auto const d = sca_.d;
3289 8x if( d >= 0 &&
3290 20x d <= (detail::to_number_limit<T>::max)() &&
3291 8x static_cast<T>(d) == d)
3292 {
3293 4x e = {};
3294 4x return static_cast<T>(d);
3295 }
3296 8x e = error::not_exact;
3297 }
3298 else
3299 {
3300 5x e = error::not_number;
3301 }
3302 41x return T{};
3303 }
3304
3305 template<class T>
3306 auto
3307 67x to_number(error& e) const noexcept ->
3308 typename std::enable_if<
3309 std::is_floating_point<
3310 T>::value, T>::type
3311 {
3312 67x if(sca_.k == json::kind::int64)
3313 {
3314 16x e = {};
3315 16x return static_cast<T>(sca_.i);
3316 }
3317 51x if(sca_.k == json::kind::uint64)
3318 {
3319 10x e = {};
3320 10x return static_cast<T>(sca_.u);
3321 }
3322 41x if(sca_.k == json::kind::double_)
3323 {
3324 27x e = {};
3325 27x return static_cast<T>(sca_.d);
3326 }
3327 14x e = error::not_number;
3328 14x return {};
3329 }
3330 };
3331
3332 // Make sure things are as big as we think they should be
3333 #if BOOST_JSON_ARCH == 64
3334 BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 );
3335 #elif BOOST_JSON_ARCH == 32
3336 BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 );
3337 #else
3338 # error Unknown architecture
3339 #endif
3340
3341 //----------------------------------------------------------
3342
3343 /** A key/value pair.
3344
3345 This is the type of element used by the @ref object container.
3346 */
3347 class key_value_pair
3348 {
3349 #ifndef BOOST_JSON_DOCS
3350 friend struct detail::access;
3351 using access = detail::access;
3352 #endif
3353
3354 BOOST_JSON_DECL
3355 static char const empty_[1];
3356
3357 inline
3358 key_value_pair(
3359 pilfered<json::value> k,
3360 pilfered<json::value> v) noexcept;
3361
3362 public:
3363 /** Assignment
3364
3365 This type is not copy or move-assignable. The copy assignment operator
3366 is deleted.
3367 */
3368 key_value_pair&
3369 operator=(key_value_pair const&) = delete;
3370
3371 /** Destructor.
3372
3373 The value is destroyed and all internally allocated memory is freed.
3374 */
3375 59054x ~key_value_pair() noexcept
3376 52301x {
3377 59054x auto const& sp = value_.storage();
3378 59054x if(sp.is_not_shared_and_deallocate_is_trivial())
3379 return;
3380 59054x if(key_ == empty_)
3381 6753x return;
3382 52301x sp->deallocate(const_cast<char*>(key_),
3383 52301x len_ + 1, alignof(char));
3384 59054x }
3385
3386 /** Constructors.
3387
3388 Construct a key/value pair.
3389
3390 @li **(1)** uses a copy of the characters of `key`, and constructs the
3391 value as if by `value(std::forward<Args>(args)...)`.
3392 @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`.
3393 @li **(3)** equivalent to
3394 `key_value_pair(p.first, std::move(p.second), sp)`.
3395 @li **(4)** equivalent to
3396 `key_value_pair(other.key(), other.value(), sp)`.
3397 @li **(5)** equivalent to
3398 `key_value_pair(other.key(), other.value(), other.storage())`.
3399 @li **(6)** the pair s constructed by acquiring ownership of the
3400 contents of `other` using move semantics.
3401 @li **(7)** the pair is constructed by acquiring ownership of the
3402 contents of `other` using pilfer semantics. This is more efficient
3403 than move construction, when it is known that the moved-from object
3404 will be immediately destroyed afterwards.
3405
3406 With **(2)**, **(3)**, **(4)** the pair uses the memory resource of
3407 `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of
3408 `other.storage()`. With **(1)** it uses whatever memory resource
3409 `value(std::forward<Args>(args)...)` would use. In any case the pair
3410 acquires shared ownership of its memory resource
3411
3412 After **(6)** `other` holds an empty key, and a null value with its
3413 current storage pointer.
3414
3415 After **(7)** `other` is not in a usable state and may only be destroyed.
3416
3417 @par Complexity
3418 Constant.
3419
3420 @par Exception Safety
3421 Strong guarantee. Calls to `memory_resource::allocate` may throw.
3422 @param key The key string to use.
3423 @param args Optional arguments forwarded to the @ref value constructor.
3424
3425 @throw boost::system::system_error The size of the key would exceed
3426 @ref string::max_size.
3427
3428 @see @ref pilfer,
3429 [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
3430
3431 @{
3432 */
3433 template<class... Args>
3434 explicit
3435 7885x key_value_pair(
3436 string_view key,
3437 Args&&... args)
3438 7886x : value_(std::forward<Args>(args)...)
3439 {
3440 7884x if(key.size() > string::max_size())
3441 {
3442 BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
3443 1x detail::throw_system_error( error::key_too_large, &loc );
3444 }
3445 auto s = reinterpret_cast<
3446 7883x char*>(value_.storage()->
3447 7883x allocate(key.size() + 1, alignof(char)));
3448 7577x std::memcpy(s, key.data(), key.size());
3449 7577x s[key.size()] = 0;
3450 7577x key_ = s;
3451 7577x len_ = static_cast<
3452 7577x std::uint32_t>(key.size());
3453 7884x }
3454
3455 /** Overload
3456
3457 @param p A `std::pair` with the key string and @ref value to construct
3458 with.
3459 @param sp A pointer to the @ref boost::container::pmr::memory_resource
3460 to use.
3461 */
3462 explicit
3463 key_value_pair(
3464 std::pair<
3465 string_view,
3466 json::value> const& p,
3467 storage_ptr sp = {})
3468 : key_value_pair(
3469 p.first,
3470 p.second,
3471 std::move(sp))
3472 {
3473 }
3474
3475 /// Overload
3476 explicit
3477 3125x key_value_pair(
3478 std::pair<
3479 string_view,
3480 json::value>&& p,
3481 storage_ptr sp = {})
3482 3125x : key_value_pair(
3483 p.first,
3484 3125x std::move(p).second,
3485 6250x std::move(sp))
3486 {
3487 2978x }
3488
3489 /** Overload
3490
3491 @param other Another key/value pair.
3492 @param sp
3493 */
3494 BOOST_JSON_DECL
3495 key_value_pair(
3496 key_value_pair const& other,
3497 storage_ptr sp);
3498
3499 /// Overload
3500 758x key_value_pair(
3501 key_value_pair const& other)
3502 758x : key_value_pair(other,
3503 758x other.storage())
3504 {
3505 758x }
3506
3507 /// Overload
3508 1x key_value_pair(
3509 key_value_pair&& other) noexcept
3510 1x : value_(std::move(other.value_))
3511 2x , key_(detail::exchange(
3512 1x other.key_, empty_))
3513 2x , len_(detail::exchange(
3514 1x other.len_, 0))
3515 {
3516 1x }
3517
3518 /// Overload
3519 6752x key_value_pair(
3520 pilfered<key_value_pair> other) noexcept
3521 6752x : value_(pilfer(other.get().value_))
3522 13504x , key_(detail::exchange(
3523 6752x other.get().key_, empty_))
3524 13504x , len_(detail::exchange(
3525 6752x other.get().len_, 0))
3526 {
3527 6752x }
3528 /// @}
3529
3530 /** The associated memory resource.
3531
3532 Returns a pointer to the memory resource used to construct the value.
3533
3534 @par Complexity
3535 Constant.
3536
3537 @par Exception Safety
3538 No-throw guarantee.
3539 */
3540 storage_ptr const&
3541 758x storage() const noexcept
3542 {
3543 758x return value_.storage();
3544 }
3545
3546 /** The pair's key.
3547
3548 After construction, the key may not be modified.
3549
3550 @par Complexity
3551 Constant.
3552
3553 @par Exception Safety
3554 No-throw guarantee.
3555 */
3556 string_view const
3557 143689x key() const noexcept
3558 {
3559 143689x return { key_, len_ };
3560 }
3561
3562 /** The pair's key as a null-terminated string.
3563
3564 @par Complexity
3565 Constant.
3566
3567 @par Exception Safety
3568 No-throw guarantee.
3569 */
3570 char const*
3571 1x key_c_str() const noexcept
3572 {
3573 1x return key_;
3574 }
3575
3576 /** The pair's value.
3577
3578 @par Complexity
3579 Constant.
3580
3581 @par Exception Safety
3582 No-throw guarantee.
3583
3584 @{
3585 */
3586 json::value const&
3587 65222x value() const& noexcept
3588 {
3589 65222x return value_;
3590 }
3591
3592 json::value&&
3593 value() && noexcept
3594 {
3595 return std::move( value() );
3596 }
3597
3598 json::value&
3599 1078x value() & noexcept
3600 {
3601 1078x return value_;
3602 }
3603 /// @}
3604
3605 private:
3606 json::value value_;
3607 char const* key_;
3608 std::uint32_t len_;
3609 std::uint32_t next_;
3610 };
3611
3612 //----------------------------------------------------------
3613
3614 #ifdef BOOST_JSON_DOCS
3615
3616 /** Tuple-like element access.
3617
3618 This overload of `get` permits the key and value of a @ref key_value_pair
3619 to be accessed by index. For example:
3620
3621 @code
3622 key_value_pair kvp("num", 42);
3623 string_view key = get<0>(kvp);
3624 value& jv = get<1>(kvp);
3625 @endcode
3626
3627 @par Structured Bindings
3628 When using C++17 or greater, objects of type @ref key_value_pair may be
3629 used to initialize structured bindings:
3630
3631 @code
3632 key_value_pair kvp("num", 42);
3633 auto& [key, value] = kvp;
3634 @endcode
3635
3636 Depending on the value of `I`, the return type will be:
3637
3638 @li `string_view const` if `I == 0`, or
3639 @li `value&`, `value const&`, or `value&&` if `I == 1`.
3640
3641 Using any other value for `I` is ill-formed.
3642
3643 @par Constraints
3644 `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
3645
3646 @tparam I The element index to access.
3647
3648 @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`.
3649
3650 @param kvp The @ref key_value_pair object to access.
3651 */
3652 template<
3653 std::size_t I,
3654 class T>
3655 __see_below__
3656 get(T&& kvp) noexcept;
3657
3658 #else
3659
3660 template<std::size_t I>
3661 auto
3662 get(key_value_pair const&) noexcept ->
3663 typename std::conditional<I == 0,
3664 string_view const,
3665 value const&>::type
3666 {
3667 static_assert(I == 0,
3668 "key_value_pair index out of range");
3669 }
3670
3671 template<std::size_t I>
3672 auto
3673 get(key_value_pair&) noexcept ->
3674 typename std::conditional<I == 0,
3675 string_view const,
3676 value&>::type
3677 {
3678 static_assert(I == 0,
3679 "key_value_pair index out of range");
3680 }
3681
3682 template<std::size_t I>
3683 auto
3684 get(key_value_pair&&) noexcept ->
3685 typename std::conditional<I == 0,
3686 string_view const,
3687 value&&>::type
3688 {
3689 static_assert(I == 0,
3690 "key_value_pair index out of range");
3691 }
3692
3693 /** Extracts a key_value_pair's key using tuple-like interface
3694 */
3695 template<>
3696 inline
3697 string_view const
3698 19609x get<0>(key_value_pair const& kvp) noexcept
3699 {
3700 19609x return kvp.key();
3701 }
3702
3703 /** Extracts a key_value_pair's key using tuple-like interface
3704 */
3705 template<>
3706 inline
3707 string_view const
3708 7x get<0>(key_value_pair& kvp) noexcept
3709 {
3710 7x return kvp.key();
3711 }
3712
3713 /** Extracts a key_value_pair's key using tuple-like interface
3714 */
3715 template<>
3716 inline
3717 string_view const
3718 get<0>(key_value_pair&& kvp) noexcept
3719 {
3720 return kvp.key();
3721 }
3722
3723 /** Extracts a key_value_pair's value using tuple-like interface
3724 */
3725 template<>
3726 inline
3727 value const&
3728 28299x get<1>(key_value_pair const& kvp) noexcept
3729 {
3730 28299x return kvp.value();
3731 }
3732
3733 /** Extracts a key_value_pair's value using tuple-like interface
3734 */
3735 template<>
3736 inline
3737 value&
3738 7x get<1>(key_value_pair& kvp) noexcept
3739 {
3740 7x return kvp.value();
3741 }
3742
3743 /** Extracts a key_value_pair's value using tuple-like interface
3744 */
3745 template<>
3746 inline
3747 value&&
3748 get<1>(key_value_pair&& kvp) noexcept
3749 {
3750 return std::move(kvp.value());
3751 }
3752
3753 #endif
3754
3755 } // namespace json
3756 } // namespace boost
3757
3758 #ifdef __clang__
3759 # pragma clang diagnostic push
3760 # pragma clang diagnostic ignored "-Wmismatched-tags"
3761 #endif
3762
3763 #ifndef BOOST_JSON_DOCS
3764
3765 namespace std {
3766
3767 /** Tuple-like size access for key_value_pair
3768 */
3769 template<>
3770 struct tuple_size< ::boost::json::key_value_pair >
3771 : std::integral_constant<std::size_t, 2>
3772 {
3773 };
3774
3775 /** Tuple-like access for the key type of key_value_pair
3776 */
3777 template<>
3778 struct tuple_element<0, ::boost::json::key_value_pair>
3779 {
3780 using type = ::boost::json::string_view const;
3781 };
3782
3783 /** Tuple-like access for the value type of key_value_pair
3784 */
3785 template<>
3786 struct tuple_element<1, ::boost::json::key_value_pair>
3787 {
3788 using type = ::boost::json::value&;
3789 };
3790
3791 /** Tuple-like access for the value type of key_value_pair
3792 */
3793 template<>
3794 struct tuple_element<1, ::boost::json::key_value_pair const>
3795 {
3796 using type = ::boost::json::value const&;
3797 };
3798
3799 } // std
3800
3801 #endif
3802
3803 // std::hash specialization
3804 #ifndef BOOST_JSON_DOCS
3805 namespace std {
3806 template <>
3807 struct hash< ::boost::json::value > {
3808 BOOST_JSON_DECL
3809 std::size_t
3810 operator()(::boost::json::value const& jv) const noexcept;
3811 };
3812 } // std
3813 #endif
3814
3815
3816 #ifdef __clang__
3817 # pragma clang diagnostic pop
3818 #endif
3819
3820 // These are here because value, array,
3821 // and object form cyclic references.
3822
3823 #include <boost/json/detail/impl/array.hpp>
3824 #include <boost/json/impl/array.hpp>
3825 #include <boost/json/impl/object.hpp>
3826 #include <boost/json/impl/value.hpp>
3827
3828 // These must come after array and object
3829 #include <boost/json/impl/value_ref.hpp>
3830
3831 #endif
3832