summaryrefslogtreecommitdiff
path: root/json4cpp/tests/src/unit-constructor1.cpp
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:42:50 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:42:50 +0300
commit5fad10f89c485cfdc7b99011f07609f8871160d4 (patch)
tree1860b39753b652dfe54d3cbbc80c875f40198d1f /json4cpp/tests/src/unit-constructor1.cpp
parent292baed7ac0cf84263263966ed32ed113cae857f (diff)
parent9a737481aed085fd289f82dff1fa8c3c66627a7e (diff)
downloadProject-Tick-5fad10f89c485cfdc7b99011f07609f8871160d4.tar.gz
Project-Tick-5fad10f89c485cfdc7b99011f07609f8871160d4.zip
Add 'json4cpp/' from commit '9a737481aed085fd289f82dff1fa8c3c66627a7e'
git-subtree-dir: json4cpp git-subtree-mainline: 292baed7ac0cf84263263966ed32ed113cae857f git-subtree-split: 9a737481aed085fd289f82dff1fa8c3c66627a7e
Diffstat (limited to 'json4cpp/tests/src/unit-constructor1.cpp')
-rw-r--r--json4cpp/tests/src/unit-constructor1.cpp1654
1 files changed, 1654 insertions, 0 deletions
diff --git a/json4cpp/tests/src/unit-constructor1.cpp b/json4cpp/tests/src/unit-constructor1.cpp
new file mode 100644
index 0000000000..9917cd358f
--- /dev/null
+++ b/json4cpp/tests/src/unit-constructor1.cpp
@@ -0,0 +1,1654 @@
+// __ _____ _____ _____
+// __| | __| | | | JSON for Modern C++ (supporting code)
+// | | |__ | | | | | | version 3.12.0
+// |_____|_____|_____|_|___| https://github.com/nlohmann/json
+//
+// SPDX-FileCopyrightText: 2013-2026 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 const t = json::value_t::null;
+ json const j(t);
+ CHECK(j.type() == t);
+ }
+
+ SECTION("discarded")
+ {
+ auto const t = json::value_t::discarded;
+ json const j(t);
+ CHECK(j.type() == t);
+ }
+
+ SECTION("object")
+ {
+ auto const t = json::value_t::object;
+ json const j(t);
+ CHECK(j.type() == t);
+ }
+
+ SECTION("array")
+ {
+ auto const t = json::value_t::array;
+ json const j(t);
+ CHECK(j.type() == t);
+ }
+
+ SECTION("boolean")
+ {
+ auto const t = json::value_t::boolean;
+ json const j(t);
+ CHECK(j.type() == t);
+ CHECK(j == false);
+ }
+
+ SECTION("string")
+ {
+ auto const t = json::value_t::string;
+ json const j(t);
+ CHECK(j.type() == t);
+ CHECK(j == "");
+ }
+
+ SECTION("number_integer")
+ {
+ auto const t = json::value_t::number_integer;
+ json const j(t);
+ CHECK(j.type() == t);
+ CHECK(j == 0);
+ }
+
+ SECTION("number_unsigned")
+ {
+ auto const t = json::value_t::number_unsigned;
+ json const j(t);
+ CHECK(j.type() == t);
+ CHECK(j == 0);
+ }
+
+ SECTION("number_float")
+ {
+ auto const t = json::value_t::number_float;
+ json const j(t);
+ CHECK(j.type() == t);
+ CHECK(j == 0.0);
+ }
+
+ SECTION("binary")
+ {
+ auto const t = json::value_t::binary;
+ json const j(t);
+ CHECK(j.type() == t);
+ CHECK(j == json::binary({}));
+ }
+ }
+
+ SECTION("create a null object (implicitly)")
+ {
+ SECTION("no parameter")
+ {
+ json const j{};
+ CHECK(j.type() == json::value_t::null);
+ }
+ }
+
+ SECTION("create a null object (explicitly)")
+ {
+ SECTION("parameter")
+ {
+ json const j(nullptr);
+ CHECK(j.type() == json::value_t::null);
+ }
+ }
+
+ SECTION("create an object (explicit)")
+ {
+ SECTION("empty object")
+ {
+ json::object_t const o{};
+ json const j(o);
+ CHECK(j.type() == json::value_t::object);
+ }
+
+ SECTION("filled object")
+ {
+ json::object_t const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
+ json const j(o);
+ CHECK(j.type() == json::value_t::object);
+ }
+ }
+
+ SECTION("create an object (implicit)")
+ {
+ // reference object
+ json::object_t const o_reference {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
+ json const j_reference(o_reference);
+
+ SECTION("std::map<json::string_t, json>")
+ {
+ std::map<json::string_t, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
+ json const j(o);
+ CHECK(j.type() == json::value_t::object);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("std::map<std::string, std::string> #600")
+ {
+ const std::map<std::string, std::string> m
+ {
+ {"a", "b"},
+ {"c", "d"},
+ {"e", "f"},
+ };
+
+ json const j(m);
+ CHECK((j.get<decltype(m)>() == m));
+ }
+
+ SECTION("std::map<const char*, json>")
+ {
+ std::map<const char*, json> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
+ json const 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> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
+ json const 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> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
+ json const 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> const o {{"a", json(1)}, {"b", json(1u)}, {"c", json(2.2)}, {"d", json(false)}, {"e", json("string")}, {"f", json()}};
+ json const j(o);
+ CHECK(j.type() == json::value_t::object);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("associative container literal")
+ {
+ json const 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 const a{};
+ json const j(a);
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("filled array")
+ {
+ json::array_t const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const j(a);
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+
+ SECTION("create an array (implicit)")
+ {
+ // reference array
+ json::array_t const a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const j_reference(a_reference);
+
+ SECTION("std::list<json>")
+ {
+ std::list<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const j(a);
+ CHECK(j.type() == json::value_t::array);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("std::pair")
+ {
+ std::pair<float, std::string> const p{1.0f, "string"};
+ json const 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 const 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 const 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 const 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]); // commented out due to CI issue, see https://github.com/nlohmann/json/pull/3985 and https://github.com/nlohmann/json/issues/4025
+ }
+
+ SECTION("std::tuple tie")
+ {
+ const auto a = 1.0;
+ const auto* const b = "string";
+ const auto c = 42;
+ const auto d = std::vector<int> {0, 2};
+ const size_t e = 1234;
+ auto t = std::tie(a, b, c, d, e);
+ json const j(t);
+
+ double a_out = 0;
+ std::string b_out;
+ int c_out = 0;
+ std::vector<int> d_out;
+ int64_t e_out = 0;
+ auto t_out = std::tie(a_out, b_out, c_out, d_out, e_out);
+ j.get_to(t_out);
+ CHECK(a_out == a);
+ CHECK(b_out == b);
+ CHECK(c_out == c);
+ CHECK(d_out == d);
+ CHECK(e_out == e);
+ }
+
+ SECTION("std::tuple of references to elements")
+ {
+ const auto a = 1.0;
+ const auto* const b = "string";
+ const auto c = 42;
+ const size_t d = 1234;
+ const auto t = std::tie(a, b, c, d);
+ json const j(t);
+
+ auto t_out = j.get<std::tuple<const json::number_float_t&,
+ const json::string_t&,
+ const json::number_integer_t&,
+ const json::number_unsigned_t&>>();
+ CHECK(&std::get<0>(t_out) == j[0].get_ptr<const json::number_float_t*>());
+ CHECK(&std::get<1>(t_out) == j[1].get_ptr<const json::string_t*>());
+ CHECK(&std::get<2>(t_out) == j[2].get_ptr<const json::number_integer_t*>());
+ CHECK(&std::get<3>(t_out) == j[3].get_ptr<const json::number_unsigned_t*>());
+ CHECK(std::get<0>(t_out) == a);
+ CHECK(std::get<1>(t_out) == b);
+ CHECK(std::get<2>(t_out) == c);
+ CHECK(std::get<3>(t_out) == d);
+ }
+
+ SECTION("std::tuple mixed arithmetic types")
+ {
+ using j_float_t = json::number_float_t;
+ using j_int_t = json::number_integer_t;
+ using j_uint_t = json::number_unsigned_t;
+ const j_float_t a = 1.0;
+ const j_int_t b = 1234;
+ const j_uint_t c = 42;
+ json const j(std::tie(a, b, c, c));
+
+ auto t1 = j.get<std::tuple<j_int_t, j_uint_t, j_float_t, const j_uint_t&>>();
+ j_uint_t a2 = 0;
+ j_float_t b2 = 0;
+ j_int_t c2 = 0;
+ auto t2 = std::tie(a2, b2, c2);
+ j.get_to(t2);
+
+ CHECK(std::get<0>(t1) == static_cast<j_int_t>(a));
+ CHECK(std::get<1>(t1) == static_cast<j_uint_t>(b));
+ CHECK(std::get<2>(t1) == static_cast<j_float_t>(c));
+ // t1[3] exists only to force usage of the no-default-constructor version
+ CHECK(a2 == static_cast<j_uint_t>(a));
+ CHECK(b2 == static_cast<j_float_t>(b));
+ CHECK(c2 == static_cast<j_int_t>(c));
+ }
+
+ SECTION("std::pair/tuple/array failures")
+ {
+ json const 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> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const j(a);
+ CHECK(j.type() == json::value_t::array);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("std::array<json, 6>")
+ {
+ std::array<json, 6> const a {{json(1), json(1u), json(2.2), json(false), json("string"), json()}};
+ json const 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> const va = {1, 2, 3, 4, 5};
+ json const 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> const va = {1.2, 2.3, 3.4, 4.5, 5.6};
+ json const 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> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const j(a);
+ CHECK(j.type() == json::value_t::array);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("std::deque<json>")
+ {
+ std::deque<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const j(a);
+ CHECK(j.type() == json::value_t::array);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("std::set<json>")
+ {
+ std::set<json> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const 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> const a {json(1), json(1u), json(2.2), json(false), json("string"), json()};
+ json const j(a);
+ CHECK(j.type() == json::value_t::array);
+ // we cannot really check for equality here
+ }
+
+ SECTION("sequence container literal")
+ {
+ json const 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 const s{};
+ json const j(s);
+ CHECK(j.type() == json::value_t::string);
+ }
+
+ SECTION("filled string")
+ {
+ json::string_t const s {"Hello world"};
+ json const j(s);
+ CHECK(j.type() == json::value_t::string);
+ }
+ }
+
+ SECTION("create a string (implicit)")
+ {
+ // reference string
+ json::string_t const s_reference {"Hello world"};
+ json const j_reference(s_reference);
+
+ SECTION("std::string")
+ {
+ std::string const s {"Hello world"};
+ json const j(s);
+ CHECK(j.type() == json::value_t::string);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("char[]")
+ {
+ const char s[] {"Hello world"}; // NOLINT(misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
+ json const j(s);
+ CHECK(j.type() == json::value_t::string);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("const char*")
+ {
+ const char* s {"Hello world"};
+ json const j(s);
+ CHECK(j.type() == json::value_t::string);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("string literal")
+ {
+ json const 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 const b{};
+ json const j(b);
+ CHECK(j.type() == json::value_t::boolean);
+ }
+
+ SECTION("filled boolean (true)")
+ {
+ json const j(true);
+ CHECK(j.type() == json::value_t::boolean);
+ }
+
+ SECTION("filled boolean (false)")
+ {
+ json const j(false);
+ CHECK(j.type() == json::value_t::boolean);
+ }
+
+ SECTION("from std::vector<bool>::reference")
+ {
+ std::vector<bool> v{true};
+ json const 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 const 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 const b{};
+ json const j(b);
+ CHECK(j.type() == json::value_t::binary);
+ }
+
+ SECTION("filled binary")
+ {
+ json::binary_t const b({1, 2, 3});
+ json const j(b);
+ CHECK(j.type() == json::value_t::binary);
+ }
+ }
+
+ SECTION("create an integer number (explicit)")
+ {
+ SECTION("uninitialized value")
+ {
+ json::number_integer_t const n{};
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ }
+
+ SECTION("initialized value")
+ {
+ json::number_integer_t const n(42);
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ }
+ }
+
+ SECTION("create an integer number (implicit)")
+ {
+ // reference objects
+ json::number_integer_t const n_reference = 42;
+ json const j_reference(n_reference);
+ json::number_unsigned_t const n_unsigned_reference = 42;
+ json const j_unsigned_reference(n_unsigned_reference);
+
+ SECTION("short")
+ {
+ short const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("unsigned short")
+ {
+ unsigned short const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("int")
+ {
+ int const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("unsigned int")
+ {
+ unsigned int const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("long")
+ {
+ long const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("unsigned long")
+ {
+ unsigned long const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("long long")
+ {
+ long long const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("unsigned long long")
+ {
+ unsigned long long const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("int8_t")
+ {
+ int8_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int16_t")
+ {
+ int16_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int32_t")
+ {
+ int32_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int64_t")
+ {
+ int64_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_fast8_t")
+ {
+ int_fast8_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_fast16_t")
+ {
+ int_fast16_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_fast32_t")
+ {
+ int_fast32_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_fast64_t")
+ {
+ int_fast64_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_least8_t")
+ {
+ int_least8_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_least16_t")
+ {
+ int_least16_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_least32_t")
+ {
+ int_least32_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("int_least64_t")
+ {
+ int_least64_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("uint8_t")
+ {
+ uint8_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint16_t")
+ {
+ uint16_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint32_t")
+ {
+ uint32_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint64_t")
+ {
+ uint64_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_fast8_t")
+ {
+ uint_fast8_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_fast16_t")
+ {
+ uint_fast16_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_fast32_t")
+ {
+ uint_fast32_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_fast64_t")
+ {
+ uint_fast64_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_least8_t")
+ {
+ uint_least8_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_least16_t")
+ {
+ uint_least16_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_least32_t")
+ {
+ uint_least32_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("uint_least64_t")
+ {
+ uint_least64_t const n = 42;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("integer literal without suffix")
+ {
+ json const j(42);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("integer literal with u suffix")
+ {
+ const json j(42u);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("integer literal with l suffix")
+ {
+ json const j(42L);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("integer literal with ul suffix")
+ {
+ const json j(42ul);
+ CHECK(j.type() == json::value_t::number_unsigned);
+ CHECK(j == j_unsigned_reference);
+ }
+
+ SECTION("integer literal with ll suffix")
+ {
+ json const j(42LL);
+ CHECK(j.type() == json::value_t::number_integer);
+ CHECK(j == j_reference);
+ }
+
+ SECTION("integer literal with ull suffix")
+ {
+ const 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 const n{};
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_float);
+ }
+
+ SECTION("initialized value")
+ {
+ json::number_float_t const n(42.23);
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_float);
+ }
+
+ SECTION("NaN")
+ {
+ // NaN is stored properly, but serialized to null
+ json::number_float_t const n(std::numeric_limits<json::number_float_t>::quiet_NaN());
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_float);
+
+ // check round trip of NaN
+ json::number_float_t const 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 const n(std::numeric_limits<json::number_float_t>::infinity());
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_float);
+
+ // check round trip of infinity
+ json::number_float_t const 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 const n_reference = 42.23;
+ json const j_reference(n_reference);
+
+ SECTION("float")
+ {
+ float const n = 42.23f;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_float);
+ CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
+ }
+
+ SECTION("double")
+ {
+ double const n = 42.23;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_float);
+ CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
+ }
+
+ SECTION("long double")
+ {
+ long double const n = 42.23L;
+ json const j(n);
+ CHECK(j.type() == json::value_t::number_float);
+ CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
+ }
+
+ SECTION("floating-point literal without suffix")
+ {
+ json const j(42.23);
+ CHECK(j.type() == json::value_t::number_float);
+ CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
+ }
+
+ SECTION("integer literal with f suffix")
+ {
+ json const j(42.23f);
+ CHECK(j.type() == json::value_t::number_float);
+ CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
+ }
+
+ SECTION("integer literal with l suffix")
+ {
+ json const j(42.23L);
+ CHECK(j.type() == json::value_t::number_float);
+ CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
+ }
+ }
+
+ SECTION("create a container (array or object) from an initializer list")
+ {
+ SECTION("empty initializer list")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {});
+ CHECK(j.type() == json::value_t::object);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {};
+ CHECK(j.type() == json::value_t::null);
+ }
+ }
+
+ SECTION("one element")
+ {
+ SECTION("array")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {json(json::array_t())});
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {json::array_t()};
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+
+ SECTION("object")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {json(json::object_t())});
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {json::object_t()};
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+
+ SECTION("string")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {json("Hello world")});
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {"Hello world"};
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+
+ SECTION("boolean")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {json(true)});
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {true};
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+
+ SECTION("number (integer)")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {json(1)});
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {1};
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+
+ SECTION("number (unsigned)")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {json(1u)});
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {1u};
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+
+ SECTION("number (floating-point)")
+ {
+ SECTION("explicit")
+ {
+ json const j(json::initializer_list_t {json(42.23)});
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("implicit")
+ {
+ json const j {42.23};
+ CHECK(j.type() == json::value_t::array);
+ }
+ }
+ }
+
+ SECTION("more elements")
+ {
+ SECTION("explicit")
+ {
+ json const 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 const 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 const j { {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false} };
+ CHECK(j.type() == json::value_t::object);
+ }
+
+ SECTION("array")
+ {
+ json const 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 const j = json::object();
+ CHECK(j.type() == json::value_t::object);
+ }
+
+ SECTION("object")
+ {
+ json const 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 const j = json::array();
+ CHECK(j.type() == json::value_t::array);
+ }
+
+ SECTION("array")
+ {
+ json const 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 const 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 const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}};
+ json const arr(0, v);
+ CHECK(arr.size() == 0);
+ }
+
+ SECTION("cnt = 1")
+ {
+ json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}};
+ json const arr(1, v);
+ CHECK(arr.size() == 1);
+ for (const auto& x : arr)
+ {
+ CHECK(x == v);
+ }
+ }
+
+ SECTION("cnt = 3")
+ {
+ json const v = {1, "foo", 34.23, {1, 2, 3}, {{"A", 1}, {"B", 2u}}};
+ json const arr(3, v);
+ CHECK(arr.size() == 3);
+ for (const 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 const j_new(jobject.begin(), jobject.end());
+ CHECK(j_new == jobject);
+ }
+ {
+ json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
+ json const j_new(jobject.cbegin(), jobject.cend());
+ CHECK(j_new == jobject);
+ }
+ }
+
+ SECTION("json(begin(), begin())")
+ {
+ {
+ json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
+ json const j_new(jobject.begin(), jobject.begin());
+ CHECK(j_new == json::object());
+ }
+ {
+ json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
+ json const j_new(jobject.cbegin(), jobject.cbegin());
+ CHECK(j_new == json::object());
+ }
+ }
+
+ SECTION("construct from subrange")
+ {
+ json const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
+ json const 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 const jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
+ json const 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 const j_new(jarray.begin(), jarray.end());
+ CHECK(j_new == jarray);
+ }
+ {
+ json const jarray = {1, 2, 3, 4, 5};
+ json const j_new(jarray.cbegin(), jarray.cend());
+ CHECK(j_new == jarray);
+ }
+ }
+
+ SECTION("json(begin(), begin())")
+ {
+ {
+ json jarray = {1, 2, 3, 4, 5};
+ const json j_new(jarray.begin(), jarray.begin());
+ CHECK(j_new == json::array());
+ }
+ {
+ json const jarray = {1, 2, 3, 4, 5};
+ json const j_new(jarray.cbegin(), jarray.cbegin());
+ CHECK(j_new == json::array());
+ }
+ }
+
+ SECTION("construct from subrange")
+ {
+ {
+ json jarray = {1, 2, 3, 4, 5};
+ json const j_new(jarray.begin() + 1, jarray.begin() + 3);
+ CHECK(j_new == json({2, 3}));
+ }
+ {
+ json const jarray = {1, 2, 3, 4, 5};
+ json const 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 const jarray = {1, 2, 3, 4};
+ json const 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 const 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 const j_new(j.begin(), j.end());
+ CHECK(j == j_new);
+ }
+ {
+ json const j = "bar";
+ json const j_new(j.cbegin(), j.cend());
+ CHECK(j == j_new);
+ }
+ }
+
+ SECTION("number (boolean)")
+ {
+ {
+ json j = false;
+ json const j_new(j.begin(), j.end());
+ CHECK(j == j_new);
+ }
+ {
+ json const j = true;
+ json const j_new(j.cbegin(), j.cend());
+ CHECK(j == j_new);
+ }
+ }
+
+ SECTION("number (integer)")
+ {
+ {
+ json j = 17;
+ json const j_new(j.begin(), j.end());
+ CHECK(j == j_new);
+ }
+ {
+ json const j = 17;
+ json const j_new(j.cbegin(), j.cend());
+ CHECK(j == j_new);
+ }
+ }
+
+ SECTION("number (unsigned)")
+ {
+ {
+ json j = 17u;
+ json const j_new(j.begin(), j.end());
+ CHECK(j == j_new);
+ }
+ {
+ json const j = 17u;
+ json const j_new(j.cbegin(), j.cend());
+ CHECK(j == j_new);
+ }
+ }
+
+ SECTION("number (floating point)")
+ {
+ {
+ json j = 23.42;
+ json const j_new(j.begin(), j.end());
+ CHECK(j == j_new);
+ }
+ {
+ json const j = 23.42;
+ json const j_new(j.cbegin(), j.cend());
+ CHECK(j == j_new);
+ }
+ }
+
+ SECTION("binary")
+ {
+ {
+ json j = json::binary({1, 2, 3});
+ json const j_new(j.begin(), j.end());
+ CHECK((j == j_new));
+ }
+ {
+ json const j = json::binary({1, 2, 3});
+ json const 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 const 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 const 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 const 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 const 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 const 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&);
+ }
+ }
+ }
+ }
+ }
+}