| // __ _____ _____ _____ |
| // __| | __| | | | JSON for Modern C++ (supporting code) |
| // | | |__ | | | | | | version 3.11.2 |
| // |_____|_____|_____|_|___| https://github.com/nlohmann/json |
| // |
| // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> |
| // SPDX-License-Identifier: MIT |
| |
| #include "doctest_compatibility.h" |
| |
| #define JSON_TESTS_PRIVATE |
| #include <nlohmann/json.hpp> |
| using nlohmann::json; |
| |
| #include <deque> |
| #include <forward_list> |
| #include <fstream> |
| #include <list> |
| #include <set> |
| #include <unordered_map> |
| #include <unordered_set> |
| #include <valarray> |
| |
| TEST_CASE("constructors") |
| { |
| SECTION("create an empty value with a given type") |
| { |
| SECTION("null") |
| { |
| auto t = json::value_t::null; |
| json j(t); |
| CHECK(j.type() == t); |
| } |
| |
| SECTION("discarded") |
| { |
| auto t = json::value_t::discarded; |
| json j(t); |
| CHECK(j.type() == t); |
| } |
| |
| SECTION("object") |
| { |
| auto t = json::value_t::object; |
| json j(t); |
| CHECK(j.type() == t); |
| } |
| |
| SECTION("array") |
| { |
| auto t = json::value_t::array; |
| json j(t); |
| CHECK(j.type() == t); |
| } |
| |
| SECTION("boolean") |
| { |
| auto t = json::value_t::boolean; |
| json j(t); |
| CHECK(j.type() == t); |
| CHECK(j == false); |
| } |
| |
| SECTION("string") |
| { |
| auto t = json::value_t::string; |
| json j(t); |
| CHECK(j.type() == t); |
| CHECK(j == ""); |
| } |
| |
| SECTION("number_integer") |
| { |
| auto t = json::value_t::number_integer; |
| json j(t); |
| CHECK(j.type() == t); |
| CHECK(j == 0); |
| } |
| |
| SECTION("number_unsigned") |
| { |
| auto t = json::value_t::number_unsigned; |
| json j(t); |
| CHECK(j.type() == t); |
| CHECK(j == 0); |
| } |
| |
| SECTION("number_float") |
| { |
| auto t = json::value_t::number_float; |
| json j(t); |
| CHECK(j.type() == t); |
| CHECK(j == 0.0); |
| } |
| |
| SECTION("binary") |
| { |
| auto t = json::value_t::binary; |
| json j(t); |
| CHECK(j.type() == t); |
| CHECK(j == json::binary({})); |
| } |
| } |
| |
| SECTION("create a null object (implicitly)") |
| { |
| SECTION("no parameter") |
| { |
| json j{}; |
| CHECK(j.type() == json::value_t::null); |
| } |
| } |
| |
| SECTION("create a null object (explicitly)") |
| { |
| SECTION("parameter") |
| { |
| json j(nullptr); |
| CHECK(j.type() == json::value_t::null); |
| } |
| } |
| |
| SECTION("create an object (explicit)") |
| { |
| SECTION("empty object") |
| { |
| json::object_t o; |
| json j(o); |
| CHECK(j.type() == json::value_t::object); |
| } |
| |
| SECTION("filled object") |
| { |
| json::object_t o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; |
| json j(o); |
| CHECK(j.type() == json::value_t::object); |
| } |
| } |
| |
| SECTION("create an object (implicit)") |
| { |
| // reference object |
| json::object_t o_reference {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; |
| json j_reference(o_reference); |
| |
| SECTION("std::map<json::string_t, json>") |
| { |
| std::map<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; |
| json j(o); |
| CHECK(j.type() == json::value_t::object); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("std::map<std::string, std::string> #600") |
| { |
| std::map<std::string, std::string> m; |
| m["a"] = "b"; |
| m["c"] = "d"; |
| m["e"] = "f"; |
| |
| json j(m); |
| CHECK((j.get<decltype(m)>() == m)); |
| } |
| |
| SECTION("std::map<const char*, json>") |
| { |
| std::map<const char*, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; |
| json j(o); |
| CHECK(j.type() == json::value_t::object); |
| CHECK(j == j_reference); |
| } |
| |
| |
| SECTION("std::multimap<json::string_t, json>") |
| { |
| std::multimap<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; |
| json j(o); |
| CHECK(j.type() == json::value_t::object); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("std::unordered_map<json::string_t, json>") |
| { |
| std::unordered_map<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; |
| json j(o); |
| CHECK(j.type() == json::value_t::object); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("std::unordered_multimap<json::string_t, json>") |
| { |
| std::unordered_multimap<json::string_t, json> o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}; |
| json j(o); |
| CHECK(j.type() == json::value_t::object); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("associative container literal") |
| { |
| json j({{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}}); |
| CHECK(j.type() == json::value_t::object); |
| CHECK(j == j_reference); |
| } |
| } |
| |
| SECTION("create an array (explicit)") |
| { |
| SECTION("empty array") |
| { |
| json::array_t a; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("filled array") |
| { |
| json::array_t a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("create an array (implicit)") |
| { |
| // reference array |
| json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j_reference(a_reference); |
| |
| SECTION("std::list<json>") |
| { |
| std::list<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("std::pair") |
| { |
| std::pair<float, std::string> p{1.0f, "string"}; |
| json j(p); |
| |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j.get<decltype(p)>() == p); |
| REQUIRE(j.size() == 2); |
| CHECK(j[0] == std::get<0>(p)); |
| CHECK(j[1] == std::get<1>(p)); |
| } |
| |
| SECTION("std::pair with discarded values") |
| { |
| json j{1, 2.0, "string"}; |
| |
| const auto p = j.get<std::pair<int, float>>(); |
| CHECK(p.first == j[0]); |
| CHECK(p.second == j[1]); |
| } |
| |
| SECTION("std::tuple") |
| { |
| const auto t = std::make_tuple(1.0, std::string{"string"}, 42, std::vector<int> {0, 1}); |
| json j(t); |
| |
| CHECK(j.type() == json::value_t::array); |
| REQUIRE(j.size() == 4); |
| CHECK(j.get<decltype(t)>() == t); |
| CHECK(j[0] == std::get<0>(t)); |
| CHECK(j[1] == std::get<1>(t)); |
| CHECK(j[2] == std::get<2>(t)); |
| CHECK(j[3][0] == 0); |
| CHECK(j[3][1] == 1); |
| } |
| |
| SECTION("std::tuple with discarded values") |
| { |
| json j{1, 2.0, "string", 42}; |
| |
| const auto t = j.get<std::tuple<int, float, std::string>>(); |
| CHECK(std::get<0>(t) == j[0]); |
| CHECK(std::get<1>(t) == j[1]); |
| CHECK(std::get<2>(t) == j[2]); |
| } |
| |
| SECTION("std::pair/tuple/array failures") |
| { |
| json j{1}; |
| |
| CHECK_THROWS_WITH_AS((j.get<std::pair<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&); |
| CHECK_THROWS_WITH_AS((j.get<std::tuple<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&); |
| CHECK_THROWS_WITH_AS((j.get<std::array<int, 3>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&); |
| } |
| |
| SECTION("std::forward_list<json>") |
| { |
| std::forward_list<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("std::array<json, 6>") |
| { |
| std::array<json, 6> a {{json(1), json(1u), json(2.2), json(false), json("string"), json()}}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == j_reference); |
| |
| const auto a2 = j.get<std::array<json, 6>>(); |
| CHECK(a2 == a); |
| } |
| |
| SECTION("std::valarray<int>") |
| { |
| std::valarray<int> va = {1, 2, 3, 4, 5}; |
| json j(va); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == json({1, 2, 3, 4, 5})); |
| |
| auto jva = j.get<std::valarray<int>>(); |
| CHECK(jva.size() == va.size()); |
| for (size_t i = 0; i < jva.size(); ++i) |
| { |
| CHECK(va[i] == jva[i]); |
| } |
| } |
| |
| SECTION("std::valarray<double>") |
| { |
| std::valarray<double> va = {1.2, 2.3, 3.4, 4.5, 5.6}; |
| json j(va); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == json({1.2, 2.3, 3.4, 4.5, 5.6})); |
| |
| auto jva = j.get<std::valarray<double>>(); |
| CHECK(jva.size() == va.size()); |
| for (size_t i = 0; i < jva.size(); ++i) |
| { |
| CHECK(va[i] == jva[i]); |
| } |
| } |
| |
| SECTION("std::vector<json>") |
| { |
| std::vector<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("std::deque<json>") |
| { |
| std::deque<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("std::set<json>") |
| { |
| std::set<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| // we cannot really check for equality here |
| } |
| |
| SECTION("std::unordered_set<json>") |
| { |
| std::unordered_set<json> a {json(1), json(1u), json(2.2), json(false), json("string"), json()}; |
| json j(a); |
| CHECK(j.type() == json::value_t::array); |
| // we cannot really check for equality here |
| } |
| |
| SECTION("sequence container literal") |
| { |
| json j({json(1), json(1u), json(2.2), json(false), json("string"), json()}); |
| CHECK(j.type() == json::value_t::array); |
| CHECK(j == j_reference); |
| } |
| } |
| |
| SECTION("create a string (explicit)") |
| { |
| SECTION("empty string") |
| { |
| json::string_t s; |
| json j(s); |
| CHECK(j.type() == json::value_t::string); |
| } |
| |
| SECTION("filled string") |
| { |
| json::string_t s {"Hello world"}; |
| json j(s); |
| CHECK(j.type() == json::value_t::string); |
| } |
| } |
| |
| SECTION("create a string (implicit)") |
| { |
| // reference string |
| json::string_t s_reference {"Hello world"}; |
| json j_reference(s_reference); |
| |
| SECTION("std::string") |
| { |
| std::string s {"Hello world"}; |
| json j(s); |
| CHECK(j.type() == json::value_t::string); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("char[]") |
| { |
| char s[] {"Hello world"}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) |
| json j(s); |
| CHECK(j.type() == json::value_t::string); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("const char*") |
| { |
| const char* s {"Hello world"}; |
| json j(s); |
| CHECK(j.type() == json::value_t::string); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("string literal") |
| { |
| json j("Hello world"); |
| CHECK(j.type() == json::value_t::string); |
| CHECK(j == j_reference); |
| } |
| } |
| |
| SECTION("create a boolean (explicit)") |
| { |
| SECTION("empty boolean") |
| { |
| json::boolean_t b{}; |
| json j(b); |
| CHECK(j.type() == json::value_t::boolean); |
| } |
| |
| SECTION("filled boolean (true)") |
| { |
| json j(true); |
| CHECK(j.type() == json::value_t::boolean); |
| } |
| |
| SECTION("filled boolean (false)") |
| { |
| json j(false); |
| CHECK(j.type() == json::value_t::boolean); |
| } |
| |
| SECTION("from std::vector<bool>::reference") |
| { |
| std::vector<bool> v{true}; |
| json j(v[0]); |
| CHECK(std::is_same<decltype(v[0]), std::vector<bool>::reference>::value); |
| CHECK(j.type() == json::value_t::boolean); |
| } |
| |
| SECTION("from std::vector<bool>::const_reference") |
| { |
| const std::vector<bool> v{true}; |
| json j(v[0]); |
| CHECK(std::is_same<decltype(v[0]), std::vector<bool>::const_reference>::value); |
| CHECK(j.type() == json::value_t::boolean); |
| } |
| } |
| |
| SECTION("create a binary (explicit)") |
| { |
| SECTION("empty binary") |
| { |
| json::binary_t b{}; |
| json j(b); |
| CHECK(j.type() == json::value_t::binary); |
| } |
| |
| SECTION("filled binary") |
| { |
| json::binary_t b({1, 2, 3}); |
| json j(b); |
| CHECK(j.type() == json::value_t::binary); |
| } |
| } |
| |
| SECTION("create an integer number (explicit)") |
| { |
| SECTION("uninitialized value") |
| { |
| json::number_integer_t n{}; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| } |
| |
| SECTION("initialized value") |
| { |
| json::number_integer_t n(42); |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| } |
| } |
| |
| SECTION("create an integer number (implicit)") |
| { |
| // reference objects |
| json::number_integer_t n_reference = 42; |
| json j_reference(n_reference); |
| json::number_unsigned_t n_unsigned_reference = 42; |
| json j_unsigned_reference(n_unsigned_reference); |
| |
| SECTION("short") |
| { |
| short n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("unsigned short") |
| { |
| unsigned short n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("int") |
| { |
| int n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("unsigned int") |
| { |
| unsigned int n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("long") |
| { |
| long n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("unsigned long") |
| { |
| unsigned long n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("long long") |
| { |
| long long n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("unsigned long long") |
| { |
| unsigned long long n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("int8_t") |
| { |
| int8_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int16_t") |
| { |
| int16_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int32_t") |
| { |
| int32_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int64_t") |
| { |
| int64_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_fast8_t") |
| { |
| int_fast8_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_fast16_t") |
| { |
| int_fast16_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_fast32_t") |
| { |
| int_fast32_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_fast64_t") |
| { |
| int_fast64_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_least8_t") |
| { |
| int_least8_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_least16_t") |
| { |
| int_least16_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_least32_t") |
| { |
| int_least32_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("int_least64_t") |
| { |
| int_least64_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("uint8_t") |
| { |
| uint8_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint16_t") |
| { |
| uint16_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint32_t") |
| { |
| uint32_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint64_t") |
| { |
| uint64_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_fast8_t") |
| { |
| uint_fast8_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_fast16_t") |
| { |
| uint_fast16_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_fast32_t") |
| { |
| uint_fast32_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_fast64_t") |
| { |
| uint_fast64_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_least8_t") |
| { |
| uint_least8_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_least16_t") |
| { |
| uint_least16_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_least32_t") |
| { |
| uint_least32_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("uint_least64_t") |
| { |
| uint_least64_t n = 42; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("integer literal without suffix") |
| { |
| json j(42); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("integer literal with u suffix") |
| { |
| json j(42u); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("integer literal with l suffix") |
| { |
| json j(42L); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("integer literal with ul suffix") |
| { |
| json j(42ul); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| |
| SECTION("integer literal with ll suffix") |
| { |
| json j(42LL); |
| CHECK(j.type() == json::value_t::number_integer); |
| CHECK(j == j_reference); |
| } |
| |
| SECTION("integer literal with ull suffix") |
| { |
| json j(42ull); |
| CHECK(j.type() == json::value_t::number_unsigned); |
| CHECK(j == j_unsigned_reference); |
| } |
| } |
| |
| SECTION("create a floating-point number (explicit)") |
| { |
| SECTION("uninitialized value") |
| { |
| json::number_float_t n{}; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_float); |
| } |
| |
| SECTION("initialized value") |
| { |
| json::number_float_t n(42.23); |
| json j(n); |
| CHECK(j.type() == json::value_t::number_float); |
| } |
| |
| SECTION("NaN") |
| { |
| // NaN is stored properly, but serialized to null |
| json::number_float_t n(std::numeric_limits<json::number_float_t>::quiet_NaN()); |
| json j(n); |
| CHECK(j.type() == json::value_t::number_float); |
| |
| // check round trip of NaN |
| json::number_float_t d{j}; |
| CHECK((std::isnan(d) && std::isnan(n)) == true); |
| |
| // check that NaN is serialized to null |
| CHECK(j.dump() == "null"); |
| } |
| |
| SECTION("infinity") |
| { |
| // infinity is stored properly, but serialized to null |
| json::number_float_t n(std::numeric_limits<json::number_float_t>::infinity()); |
| json j(n); |
| CHECK(j.type() == json::value_t::number_float); |
| |
| // check round trip of infinity |
| json::number_float_t d{j}; |
| CHECK(d == n); |
| |
| // check that inf is serialized to null |
| CHECK(j.dump() == "null"); |
| } |
| } |
| |
| SECTION("create a floating-point number (implicit)") |
| { |
| // reference object |
| json::number_float_t n_reference = 42.23; |
| json j_reference(n_reference); |
| |
| SECTION("float") |
| { |
| float n = 42.23f; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_float); |
| CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); |
| } |
| |
| SECTION("double") |
| { |
| double n = 42.23; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_float); |
| CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); |
| } |
| |
| SECTION("long double") |
| { |
| long double n = 42.23L; |
| json j(n); |
| CHECK(j.type() == json::value_t::number_float); |
| CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); |
| } |
| |
| SECTION("floating-point literal without suffix") |
| { |
| json j(42.23); |
| CHECK(j.type() == json::value_t::number_float); |
| CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); |
| } |
| |
| SECTION("integer literal with f suffix") |
| { |
| json j(42.23f); |
| CHECK(j.type() == json::value_t::number_float); |
| CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); |
| } |
| |
| SECTION("integer literal with l suffix") |
| { |
| json j(42.23L); |
| CHECK(j.type() == json::value_t::number_float); |
| CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); |
| } |
| } |
| |
| SECTION("create a container (array or object) from an initializer list") |
| { |
| SECTION("empty initializer list") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {}); |
| CHECK(j.type() == json::value_t::object); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {}; |
| CHECK(j.type() == json::value_t::null); |
| } |
| } |
| |
| SECTION("one element") |
| { |
| SECTION("array") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {json(json::array_t())}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {json::array_t()}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("object") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {json(json::object_t())}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {json::object_t()}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("string") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {json("Hello world")}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {"Hello world"}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("boolean") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {json(true)}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {true}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("number (integer)") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {json(1)}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {1}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("number (unsigned)") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {json(1u)}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {1u}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("number (floating-point)") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {json(42.23)}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {42.23}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| } |
| |
| SECTION("more elements") |
| { |
| SECTION("explicit") |
| { |
| json j(json::initializer_list_t {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()}); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("implicit") |
| { |
| json j {1, 1u, 42.23, true, nullptr, json::object_t(), json::array_t()}; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("implicit type deduction") |
| { |
| SECTION("object") |
| { |
| json j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} }; |
| CHECK(j.type() == json::value_t::object); |
| } |
| |
| SECTION("array") |
| { |
| json j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }; |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("explicit type deduction") |
| { |
| SECTION("empty object") |
| { |
| json j = json::object(); |
| CHECK(j.type() == json::value_t::object); |
| } |
| |
| SECTION("object") |
| { |
| json j = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} }); |
| CHECK(j.type() == json::value_t::object); |
| } |
| |
| SECTION("object with error") |
| { |
| json _; |
| CHECK_THROWS_WITH_AS(_ = json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), "[json.exception.type_error.301] cannot create object from initializer list", json::type_error&); |
| } |
| |
| SECTION("empty array") |
| { |
| json j = json::array(); |
| CHECK(j.type() == json::value_t::array); |
| } |
| |
| SECTION("array") |
| { |
| json j = json::array({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} }); |
| CHECK(j.type() == json::value_t::array); |
| } |
| } |
| |
| SECTION("move from initializer_list") |
| { |
| SECTION("string") |
| { |
| SECTION("constructor with implicit types (array)") |
| { |
| // This should break through any short string optimization in std::string |
| std::string source(1024, '!'); |
| const auto* source_addr = source.data(); |
| json j = {std::move(source)}; |
| const auto* target_addr = j[0].get_ref<std::string const&>().data(); |
| const bool success = (target_addr == source_addr); |
| CHECK(success); |
| } |
| |
| SECTION("constructor with implicit types (object)") |
| { |
| // This should break through any short string optimization in std::string |
| std::string source(1024, '!'); |
| const auto* source_addr = source.data(); |
| json j = {{"key", std::move(source)}}; |
| const auto* target_addr = j["key"].get_ref<std::string const&>().data(); |
| const bool success = (target_addr == source_addr); |
| CHECK(success); |
| } |
| |
| SECTION("constructor with implicit types (object key)") |
| { |
| // This should break through any short string optimization in std::string |
| std::string source(1024, '!'); |
| const auto* source_addr = source.data(); |
| json j = {{std::move(source), 42}}; |
| const auto* target_addr = j.get_ref<json::object_t&>().begin()->first.data(); |
| const bool success = (target_addr == source_addr); |
| CHECK(success); |
| } |
| } |
| |
| SECTION("array") |
| { |
| SECTION("constructor with implicit types (array)") |
| { |
| json::array_t source = {1, 2, 3}; |
| const auto* source_addr = source.data(); |
| json j {std::move(source)}; |
| const auto* target_addr = j[0].get_ref<json::array_t const&>().data(); |
| const bool success = (target_addr == source_addr); |
| CHECK(success); |
| } |
| |
| SECTION("constructor with implicit types (object)") |
| { |
| json::array_t source = {1, 2, 3}; |
| const auto* source_addr = source.data(); |
| json j {{"key", std::move(source)}}; |
| const auto* target_addr = j["key"].get_ref<json::array_t const&>().data(); |
| const bool success = (target_addr == source_addr); |
| CHECK(success); |
| } |
| |
| SECTION("assignment with implicit types (array)") |
| { |
| json::array_t source = {1, 2, 3}; |
| const auto* source_addr = source.data(); |
| json j = {std::move(source)}; |
| const auto* target_addr = j[0].get_ref<json::array_t const&>().data(); |
| const bool success = (target_addr == source_addr); |
| CHECK(success); |
| } |
| |
| SECTION("assignment with implicit types (object)") |
| { |
| json::array_t source = {1, 2, 3}; |
| const auto* source_addr = source.data(); |
| json j = {{"key", std::move(source)}}; |
| const auto* target_addr = j["key"].get_ref<json::array_t const&>().data(); |
| const bool success = (target_addr == source_addr); |
| CHECK(success); |
| } |
| } |
| |
| SECTION("object") |
| { |
| SECTION("constructor with implicit types (array)") |
| { |
| json::object_t source = {{"hello", "world"}}; |
| const json* source_addr = &source.at("hello"); |
| json j {std::move(source)}; |
| CHECK(&(j[0].get_ref<json::object_t const&>().at("hello")) == source_addr); |
| } |
| |
| SECTION("constructor with implicit types (object)") |
| { |
| json::object_t source = {{"hello", "world"}}; |
| const json* source_addr = &source.at("hello"); |
| json j {{"key", std::move(source)}}; |
| CHECK(&(j["key"].get_ref<json::object_t const&>().at("hello")) == source_addr); |
| } |
| |
| SECTION("assignment with implicit types (array)") |
| { |
| json::object_t source = {{"hello", "world"}}; |
| const json* source_addr = &source.at("hello"); |
| json j = {std::move(source)}; |
| CHECK(&(j[0].get_ref<json::object_t const&>().at("hello")) == source_addr); |
| } |
| |
| SECTION("assignment with implicit types (object)") |
| { |
| json::object_t source = {{"hello", "world"}}; |
| const json* source_addr = &source.at("hello"); |
| json j = {{"key", std::move(source)}}; |
| CHECK(&(j["key"].get_ref<json::object_t const&>().at("hello")) == source_addr); |
| } |
| } |
| |
| SECTION("json") |
| { |
| SECTION("constructor with implicit types (array)") |
| { |
| json source {1, 2, 3}; |
| const json* source_addr = &source[0]; |
| json j {std::move(source), {}}; |
| CHECK(&j[0][0] == source_addr); |
| } |
| |
| SECTION("constructor with implicit types (object)") |
| { |
| json source {1, 2, 3}; |
| const json* source_addr = &source[0]; |
| json j {{"key", std::move(source)}}; |
| CHECK(&j["key"][0] == source_addr); |
| } |
| |
| SECTION("assignment with implicit types (array)") |
| { |
| json source {1, 2, 3}; |
| const json* source_addr = &source[0]; |
| json j = {std::move(source), {}}; |
| CHECK(&j[0][0] == source_addr); |
| } |
| |
| SECTION("assignment with implicit types (object)") |
| { |
| json source {1, 2, 3}; |
| const json* source_addr = &source[0]; |
| json j = {{"key", std::move(source)}}; |
| CHECK(&j["key"][0] == source_addr); |
| } |
| } |
| |
| } |
| } |
| |
| SECTION("create an array of n copies of a given value") |
| { |
| SECTION("cnt = 0") |
| { |
| json v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}}; |
| json arr(0, v); |
| CHECK(arr.size() == 0); |
| } |
| |
| SECTION("cnt = 1") |
| { |
| json v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}}; |
| json arr(1, v); |
| CHECK(arr.size() == 1); |
| for (auto& x : arr) |
| { |
| CHECK(x == v); |
| } |
| } |
| |
| SECTION("cnt = 3") |
| { |
| json v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}}; |
| json arr(3, v); |
| CHECK(arr.size() == 3); |
| for (auto& x : arr) |
| { |
| CHECK(x == v); |
| } |
| } |
| } |
| |
| SECTION("create a JSON container from an iterator range") |
| { |
| SECTION("object") |
| { |
| SECTION("json(begin(), end())") |
| { |
| { |
| json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; |
| json j_new(jobject.begin(), jobject.end()); |
| CHECK(j_new == jobject); |
| } |
| { |
| json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; |
| json j_new(jobject.cbegin(), jobject.cend()); |
| CHECK(j_new == jobject); |
| } |
| } |
| |
| SECTION("json(begin(), begin())") |
| { |
| { |
| json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; |
| json j_new(jobject.begin(), jobject.begin()); |
| CHECK(j_new == json::object()); |
| } |
| { |
| json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; |
| json j_new(jobject.cbegin(), jobject.cbegin()); |
| CHECK(j_new == json::object()); |
| } |
| } |
| |
| SECTION("construct from subrange") |
| { |
| json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; |
| json j_new(jobject.find("b"), jobject.find("e")); |
| CHECK(j_new == json({{"b", 1}, {"c", 17u}, {"d", false}})); |
| } |
| |
| SECTION("incompatible iterators") |
| { |
| { |
| json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; |
| json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; |
| CHECK_THROWS_WITH_AS(json(jobject.begin(), jobject2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(jobject2.begin(), jobject.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| } |
| { |
| json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; |
| json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; |
| CHECK_THROWS_WITH_AS(json(jobject.cbegin(), jobject2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(jobject2.cbegin(), jobject.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| } |
| } |
| } |
| |
| SECTION("array") |
| { |
| SECTION("json(begin(), end())") |
| { |
| { |
| json jarray = {1, 2, 3, 4, 5}; |
| json j_new(jarray.begin(), jarray.end()); |
| CHECK(j_new == jarray); |
| } |
| { |
| json jarray = {1, 2, 3, 4, 5}; |
| json j_new(jarray.cbegin(), jarray.cend()); |
| CHECK(j_new == jarray); |
| } |
| } |
| |
| SECTION("json(begin(), begin())") |
| { |
| { |
| json jarray = {1, 2, 3, 4, 5}; |
| json j_new(jarray.begin(), jarray.begin()); |
| CHECK(j_new == json::array()); |
| } |
| { |
| json jarray = {1, 2, 3, 4, 5}; |
| json j_new(jarray.cbegin(), jarray.cbegin()); |
| CHECK(j_new == json::array()); |
| } |
| } |
| |
| SECTION("construct from subrange") |
| { |
| { |
| json jarray = {1, 2, 3, 4, 5}; |
| json j_new(jarray.begin() + 1, jarray.begin() + 3); |
| CHECK(j_new == json({2, 3})); |
| } |
| { |
| json jarray = {1, 2, 3, 4, 5}; |
| json j_new(jarray.cbegin() + 1, jarray.cbegin() + 3); |
| CHECK(j_new == json({2, 3})); |
| } |
| } |
| |
| SECTION("incompatible iterators") |
| { |
| { |
| json jarray = {1, 2, 3, 4}; |
| json jarray2 = {2, 3, 4, 5}; |
| CHECK_THROWS_WITH_AS(json(jarray.begin(), jarray2.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(jarray2.begin(), jarray.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| } |
| { |
| json jarray = {1, 2, 3, 4}; |
| json jarray2 = {2, 3, 4, 5}; |
| CHECK_THROWS_WITH_AS(json(jarray.cbegin(), jarray2.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(jarray2.cbegin(), jarray.cend()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator&); |
| } |
| } |
| } |
| |
| SECTION("other values") |
| { |
| SECTION("construct with two valid iterators") |
| { |
| SECTION("null") |
| { |
| { |
| json j; |
| CHECK_THROWS_WITH_AS(json(j.begin(), j.end()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&); |
| } |
| { |
| json j; |
| CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cend()), "[json.exception.invalid_iterator.206] cannot construct with iterators from null", json::invalid_iterator&); |
| } |
| } |
| |
| SECTION("string") |
| { |
| { |
| json j = "foo"; |
| json j_new(j.begin(), j.end()); |
| CHECK(j == j_new); |
| } |
| { |
| json j = "bar"; |
| json j_new(j.cbegin(), j.cend()); |
| CHECK(j == j_new); |
| } |
| } |
| |
| SECTION("number (boolean)") |
| { |
| { |
| json j = false; |
| json j_new(j.begin(), j.end()); |
| CHECK(j == j_new); |
| } |
| { |
| json j = true; |
| json j_new(j.cbegin(), j.cend()); |
| CHECK(j == j_new); |
| } |
| } |
| |
| SECTION("number (integer)") |
| { |
| { |
| json j = 17; |
| json j_new(j.begin(), j.end()); |
| CHECK(j == j_new); |
| } |
| { |
| json j = 17; |
| json j_new(j.cbegin(), j.cend()); |
| CHECK(j == j_new); |
| } |
| } |
| |
| SECTION("number (unsigned)") |
| { |
| { |
| json j = 17u; |
| json j_new(j.begin(), j.end()); |
| CHECK(j == j_new); |
| } |
| { |
| json j = 17u; |
| json j_new(j.cbegin(), j.cend()); |
| CHECK(j == j_new); |
| } |
| } |
| |
| SECTION("number (floating point)") |
| { |
| { |
| json j = 23.42; |
| json j_new(j.begin(), j.end()); |
| CHECK(j == j_new); |
| } |
| { |
| json j = 23.42; |
| json j_new(j.cbegin(), j.cend()); |
| CHECK(j == j_new); |
| } |
| } |
| |
| SECTION("binary") |
| { |
| { |
| json j = json::binary({1, 2, 3}); |
| json j_new(j.begin(), j.end()); |
| CHECK((j == j_new)); |
| } |
| { |
| json j = json::binary({1, 2, 3}); |
| json j_new(j.cbegin(), j.cend()); |
| CHECK((j == j_new)); |
| } |
| } |
| } |
| |
| SECTION("construct with two invalid iterators") |
| { |
| SECTION("string") |
| { |
| { |
| json j = "foo"; |
| CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| { |
| json j = "bar"; |
| CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| } |
| |
| SECTION("number (boolean)") |
| { |
| { |
| json j = false; |
| CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| { |
| json j = true; |
| CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| } |
| |
| SECTION("number (integer)") |
| { |
| { |
| json j = 17; |
| CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| { |
| json j = 17; |
| CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| } |
| |
| SECTION("number (integer)") |
| { |
| { |
| json j = 17u; |
| CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| { |
| json j = 17u; |
| CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| } |
| |
| SECTION("number (floating point)") |
| { |
| { |
| json j = 23.42; |
| CHECK_THROWS_WITH_AS(json(j.end(), j.end()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.begin(), j.begin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| { |
| json j = 23.42; |
| CHECK_THROWS_WITH_AS(json(j.cend(), j.cend()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| CHECK_THROWS_WITH_AS(json(j.cbegin(), j.cbegin()), "[json.exception.invalid_iterator.204] iterators out of range", json::invalid_iterator&); |
| } |
| } |
| } |
| } |
| } |
| } |