| // __ _____ _____ _____ | |
| // __| | __| | | | 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> | |
| #include <string> | |
| #include <vector> | |
| using nlohmann::json; | |
| TEST_CASE("iterators 1") | |
| { | |
| SECTION("basic behavior") | |
| { | |
| SECTION("uninitialized") | |
| { | |
| json::iterator it; // NOLINT(misc-const-correctness) | |
| CHECK(it.m_object == nullptr); | |
| json::const_iterator cit; // NOLINT(misc-const-correctness) | |
| CHECK(cit.m_object == nullptr); | |
| } | |
| SECTION("boolean") | |
| { | |
| json j = true; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| json::iterator it = j.begin(); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| it--; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| --it; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| json::const_iterator it = j_const.begin(); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| it--; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| --it; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| json::const_iterator it = j.cbegin(); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| it--; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| --it; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| json::const_iterator it = j_const.cbegin(); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| it--; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| --it; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| json::reverse_iterator it = j.rbegin(); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| it--; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| --it; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j.crbegin(); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| it--; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| --it; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j_const.crbegin(); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| it--; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| --it; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("additional tests") | |
| { | |
| SECTION("!(begin != begin)") | |
| { | |
| CHECK(!(j.begin() != j.begin())); | |
| } | |
| SECTION("!(end != end)") | |
| { | |
| CHECK(!(j.end() != j.end())); | |
| } | |
| SECTION("begin < end") | |
| { | |
| CHECK(j.begin() < j.end()); | |
| } | |
| SECTION("begin <= end") | |
| { | |
| CHECK(j.begin() <= j.end()); | |
| } | |
| SECTION("end > begin") | |
| { | |
| CHECK(j.end() > j.begin()); | |
| } | |
| SECTION("end >= begin") | |
| { | |
| CHECK(j.end() >= j.begin()); | |
| } | |
| SECTION("end == end") | |
| { | |
| CHECK(j.end() == j.end()); | |
| } | |
| SECTION("end <= end") | |
| { | |
| CHECK(j.end() <= j.end()); | |
| } | |
| SECTION("begin == begin") | |
| { | |
| CHECK(j.begin() == j.begin()); | |
| } | |
| SECTION("begin <= begin") | |
| { | |
| CHECK(j.begin() <= j.begin()); | |
| } | |
| SECTION("begin >= begin") | |
| { | |
| CHECK(j.begin() >= j.begin()); | |
| } | |
| SECTION("!(begin == end)") | |
| { | |
| CHECK(!(j.begin() == j.end())); | |
| } | |
| SECTION("begin != end") | |
| { | |
| CHECK(j.begin() != j.end()); | |
| } | |
| SECTION("begin+1 == end") | |
| { | |
| CHECK(j.begin() + 1 == j.end()); | |
| } | |
| SECTION("begin == end-1") | |
| { | |
| CHECK(j.begin() == j.end() - 1); | |
| } | |
| SECTION("begin != end+1") | |
| { | |
| CHECK(j.begin() != j.end() + 1); | |
| } | |
| SECTION("end != end+1") | |
| { | |
| CHECK(j.end() != j.end() + 1); | |
| } | |
| SECTION("begin+1 != begin+2") | |
| { | |
| CHECK(j.begin() + 1 != j.begin() + 2); | |
| } | |
| SECTION("begin+1 < begin+2") | |
| { | |
| CHECK(j.begin() + 1 < j.begin() + 2); | |
| } | |
| SECTION("begin+1 <= begin+2") | |
| { | |
| CHECK(j.begin() + 1 <= j.begin() + 2); | |
| } | |
| SECTION("end+1 != end+2") | |
| { | |
| CHECK(j.end() + 1 != j.end() + 2); | |
| } | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK_THROWS_WITH_AS(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(it.value() == json(true)); | |
| CHECK_THROWS_WITH_AS(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(cit.value() == json(true)); | |
| auto rit = j.rend(); | |
| auto crit = j.crend(); | |
| CHECK_THROWS_WITH_AS(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(rit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| } | |
| } | |
| SECTION("string") | |
| { | |
| json j = "hello world"; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| json::iterator it = j.begin(); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| it--; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| --it; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| json::const_iterator it = j_const.begin(); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| it--; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| --it; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| json::const_iterator it = j.cbegin(); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| it--; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| --it; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| json::const_iterator it = j_const.cbegin(); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| it--; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| --it; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| json::reverse_iterator it = j.rbegin(); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| it--; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| --it; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j.crbegin(); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| it--; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| --it; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j_const.crbegin(); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| it--; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| --it; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK_THROWS_WITH_AS(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(it.value() == json("hello world")); | |
| CHECK_THROWS_WITH_AS(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(cit.value() == json("hello world")); | |
| auto rit = j.rend(); | |
| auto crit = j.crend(); | |
| CHECK_THROWS_WITH_AS(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(rit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| } | |
| } | |
| SECTION("array") | |
| { | |
| json j = {1, 2, 3}; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| json::iterator it_begin = j.begin(); | |
| json::iterator it_end = j.end(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j[0]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[1]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[2]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| json::const_iterator it_begin = j_const.begin(); | |
| json::const_iterator it_end = j_const.end(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const[0]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const[1]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const[2]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| json::const_iterator it_begin = j.cbegin(); | |
| json::const_iterator it_end = j.cend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j[0]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[1]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[2]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| json::const_iterator it_begin = j_const.cbegin(); | |
| json::const_iterator it_end = j_const.cend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j[0]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[1]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[2]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| json::reverse_iterator it_begin = j.rbegin(); | |
| json::reverse_iterator it_end = j.rend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j[2]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[1]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[0]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it_begin = j.crbegin(); | |
| json::const_reverse_iterator it_end = j.crend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j[2]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[1]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[0]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it_begin = j_const.crbegin(); | |
| json::const_reverse_iterator it_end = j_const.crend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j[2]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[1]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j[0]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK_THROWS_WITH_AS(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(it.value() == json(1)); | |
| CHECK_THROWS_WITH_AS(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(cit.value() == json(1)); | |
| } | |
| } | |
| SECTION("object") | |
| { | |
| json j = {{"A", 1}, {"B", 2}, {"C", 3}}; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| json::iterator it_begin = j.begin(); | |
| json::iterator it_end = j.end(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j["A"]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["B"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["C"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| json::const_iterator it_begin = j_const.begin(); | |
| json::const_iterator it_end = j_const.end(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const["A"]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const["B"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const["C"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| json::const_iterator it_begin = j.cbegin(); | |
| json::const_iterator it_end = j.cend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j["A"]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["B"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["C"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| json::const_iterator it_begin = j_const.cbegin(); | |
| json::const_iterator it_end = j_const.cend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const["A"]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const["B"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j_const["C"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| json::reverse_iterator it_begin = j.rbegin(); | |
| json::reverse_iterator it_end = j.rend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j["C"]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["B"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["A"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it_begin = j.crbegin(); | |
| json::const_reverse_iterator it_end = j.crend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j["C"]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["B"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["A"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it_begin = j_const.crbegin(); | |
| json::const_reverse_iterator it_end = j_const.crend(); | |
| auto it = it_begin; | |
| CHECK(it != it_end); | |
| CHECK(*it == j["C"]); | |
| it++; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["B"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it != it_end); | |
| CHECK(*it == j["A"]); | |
| ++it; | |
| CHECK(it != it_begin); | |
| CHECK(it == it_end); | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK(it.key() == "A"); | |
| CHECK(it.value() == json(1)); | |
| CHECK(cit.key() == "A"); | |
| CHECK(cit.value() == json(1)); | |
| } | |
| } | |
| SECTION("number (integer)") | |
| { | |
| json j = 23; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| json::iterator it = j.begin(); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| it--; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| --it; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| json::const_iterator it = j_const.begin(); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| it--; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| --it; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| json::const_iterator it = j.cbegin(); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| it--; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| --it; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| json::const_iterator it = j_const.cbegin(); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| it--; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| --it; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| json::reverse_iterator it = j.rbegin(); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| it--; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| --it; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j.crbegin(); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| it--; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| --it; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j_const.crbegin(); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| it--; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| --it; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK_THROWS_WITH_AS(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(it.value() == json(23)); | |
| CHECK_THROWS_WITH_AS(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(cit.value() == json(23)); | |
| auto rit = j.rend(); | |
| auto crit = j.crend(); | |
| CHECK_THROWS_WITH_AS(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(rit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| } | |
| } | |
| SECTION("number (unsigned)") | |
| { | |
| json j = 23u; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| json::iterator it = j.begin(); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| it--; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| --it; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| json::const_iterator it = j_const.begin(); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| it--; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| --it; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| json::const_iterator it = j.cbegin(); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| it--; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| --it; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| json::const_iterator it = j_const.cbegin(); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| it--; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| --it; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| json::reverse_iterator it = j.rbegin(); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| it--; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| --it; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j.crbegin(); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| it--; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| --it; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j_const.crbegin(); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| it--; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| --it; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK_THROWS_WITH_AS(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(it.value() == json(23)); | |
| CHECK_THROWS_WITH_AS(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(cit.value() == json(23)); | |
| auto rit = j.rend(); | |
| auto crit = j.crend(); | |
| CHECK_THROWS_WITH_AS(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(rit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| } | |
| } | |
| SECTION("number (float)") | |
| { | |
| json j = 23.42; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| json::iterator it = j.begin(); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| it--; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.begin()); | |
| CHECK(it == j.end()); | |
| --it; | |
| CHECK(it == j.begin()); | |
| CHECK(it != j.end()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| json::const_iterator it = j_const.begin(); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| it--; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.begin()); | |
| CHECK(it == j_const.end()); | |
| --it; | |
| CHECK(it == j_const.begin()); | |
| CHECK(it != j_const.end()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| json::const_iterator it = j.cbegin(); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| it--; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.cbegin()); | |
| CHECK(it == j.cend()); | |
| --it; | |
| CHECK(it == j.cbegin()); | |
| CHECK(it != j.cend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| json::const_iterator it = j_const.cbegin(); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| it--; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.cbegin()); | |
| CHECK(it == j_const.cend()); | |
| --it; | |
| CHECK(it == j_const.cbegin()); | |
| CHECK(it != j_const.cend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| json::reverse_iterator it = j.rbegin(); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| it--; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.rbegin()); | |
| CHECK(it == j.rend()); | |
| --it; | |
| CHECK(it == j.rbegin()); | |
| CHECK(it != j.rend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j.crbegin(); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| it++; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| it--; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| ++it; | |
| CHECK(it != j.crbegin()); | |
| CHECK(it == j.crend()); | |
| --it; | |
| CHECK(it == j.crbegin()); | |
| CHECK(it != j.crend()); | |
| CHECK(*it == j); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| json::const_reverse_iterator it = j_const.crbegin(); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| it++; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| it--; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| ++it; | |
| CHECK(it != j_const.crbegin()); | |
| CHECK(it == j_const.crend()); | |
| --it; | |
| CHECK(it == j_const.crbegin()); | |
| CHECK(it != j_const.crend()); | |
| CHECK(*it == j_const); | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK_THROWS_WITH_AS(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(it.value() == json(23.42)); | |
| CHECK_THROWS_WITH_AS(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK(cit.value() == json(23.42)); | |
| auto rit = j.rend(); | |
| auto crit = j.crend(); | |
| CHECK_THROWS_WITH_AS(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(rit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| } | |
| } | |
| SECTION("null") | |
| { | |
| json j = nullptr; | |
| json j_const(j); | |
| SECTION("json + begin/end") | |
| { | |
| const json::iterator it = j.begin(); | |
| CHECK(it == j.end()); | |
| } | |
| SECTION("const json + begin/end") | |
| { | |
| const json::const_iterator it_begin = j_const.begin(); | |
| json::const_iterator it_end = j_const.end(); | |
| CHECK(it_begin == it_end); | |
| } | |
| SECTION("json + cbegin/cend") | |
| { | |
| const json::const_iterator it_begin = j.cbegin(); | |
| json::const_iterator it_end = j.cend(); | |
| CHECK(it_begin == it_end); | |
| } | |
| SECTION("const json + cbegin/cend") | |
| { | |
| const json::const_iterator it_begin = j_const.cbegin(); | |
| json::const_iterator it_end = j_const.cend(); | |
| CHECK(it_begin == it_end); | |
| } | |
| SECTION("json + rbegin/rend") | |
| { | |
| const json::reverse_iterator it = j.rbegin(); | |
| CHECK(it == j.rend()); | |
| } | |
| SECTION("json + crbegin/crend") | |
| { | |
| const json::const_reverse_iterator it = j.crbegin(); | |
| CHECK(it == j.crend()); | |
| } | |
| SECTION("const json + crbegin/crend") | |
| { | |
| const json::const_reverse_iterator it = j_const.crbegin(); | |
| CHECK(it == j_const.crend()); | |
| } | |
| SECTION("key/value") | |
| { | |
| auto it = j.begin(); | |
| auto cit = j_const.cbegin(); | |
| CHECK_THROWS_WITH_AS(it.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(it.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(cit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(cit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| auto rit = j.rend(); | |
| auto crit = j.crend(); | |
| CHECK_THROWS_WITH_AS(rit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(rit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.key(), "[json.exception.invalid_iterator.207] cannot use key() for non-object iterators", json::invalid_iterator&); | |
| CHECK_THROWS_WITH_AS(crit.value(), "[json.exception.invalid_iterator.214] cannot get value", json::invalid_iterator&); | |
| } | |
| } | |
| } | |
| SECTION("conversion from iterator to const iterator") | |
| { | |
| SECTION("boolean") | |
| { | |
| json j = true; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| SECTION("string") | |
| { | |
| json j = "hello world"; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| SECTION("array") | |
| { | |
| json j = {1, 2, 3}; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| SECTION("object") | |
| { | |
| json j = {{"A", 1}, {"B", 2}, {"C", 3}}; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| SECTION("number (integer)") | |
| { | |
| json j = 23; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| SECTION("number (unsigned)") | |
| { | |
| json j = 23u; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| SECTION("number (float)") | |
| { | |
| json j = 23.42; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| SECTION("null") | |
| { | |
| json j = nullptr; | |
| json::const_iterator it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| it = j.begin(); | |
| CHECK(it == j.cbegin()); | |
| } | |
| } | |
| } | |
| TEST_CASE_TEMPLATE("reverse iteration and member access", Json, nlohmann::json, nlohmann::ordered_json) | |
| { | |
| SECTION("array: -- and rbegin/rend") | |
| { | |
| Json j = {1, 2, 3, 4}; | |
| const std::vector<int> reversed = {4, 3, 2, 1}; | |
| auto it = j.end(); | |
| std::vector<int> seen; | |
| while (it != j.begin()) | |
| { | |
| --it; | |
| seen.push_back(it->template get<int>()); | |
| } | |
| CHECK(seen == reversed); | |
| auto it2 = j.end(); | |
| auto old = it2--; | |
| CHECK(old == j.end()); | |
| CHECK(*it2 == 4); | |
| seen.clear(); | |
| for (auto r = j.rbegin(); r != j.rend(); ++r) | |
| { | |
| seen.push_back(r->template get<int>()); | |
| } | |
| CHECK(seen == reversed); | |
| seen.clear(); | |
| for (auto r = j.crbegin(); r != j.crend(); ++r) | |
| { | |
| seen.push_back(r->template get<int>()); | |
| } | |
| CHECK(seen == reversed); | |
| } | |
| SECTION("object: -- and rbegin/rend") | |
| { | |
| Json j = {{"a", 1}, {"b", 2}, {"c", 3}}; | |
| // order of keys depends on the object type; use the forward order as reference | |
| std::vector<std::string> fwd; | |
| for (auto it = j.begin(); it != j.end(); ++it) | |
| { | |
| fwd.push_back(it.key()); | |
| } | |
| std::vector<std::string> rev(fwd.rbegin(), fwd.rend()); | |
| std::vector<std::string> seen; | |
| auto it = j.end(); | |
| while (it != j.begin()) | |
| { | |
| --it; | |
| seen.push_back(it.key()); | |
| } | |
| CHECK(seen == rev); | |
| auto it2 = j.end(); | |
| auto old = it2--; | |
| CHECK(old == j.end()); | |
| CHECK(it2.key() == rev.front()); | |
| seen.clear(); | |
| for (auto r = j.rbegin(); r != j.rend(); ++r) | |
| { | |
| seen.push_back(r.key()); | |
| } | |
| CHECK(seen == rev); | |
| } | |
| SECTION("object: operator-> reads and writes the mapped value") | |
| { | |
| Json j = {{"a", 1}, {"s", "str"}}; | |
| auto it = j.find("s"); | |
| REQUIRE(it != j.end()); | |
| CHECK(it->is_string()); | |
| CHECK(it->size() == 1); | |
| *it = Json::array({1, 2}); | |
| CHECK(it->is_array()); | |
| it->push_back(3); | |
| CHECK(j["s"].size() == 3); | |
| const Json& cj = j; | |
| auto cit = cj.find("a"); | |
| REQUIRE(cit != cj.end()); | |
| CHECK(cit->is_number_integer()); | |
| CHECK(cit->template get<int>() == 1); | |
| } | |
| SECTION("primitives: -- and ->") | |
| { | |
| Json j = 42; | |
| auto it = j.end(); | |
| --it; | |
| CHECK(it == j.begin()); | |
| CHECK(it->template get<int>() == 42); | |
| } | |
| SECTION("comparing iterators of different containers throws") | |
| { | |
| Json a = {1, 2}; | |
| Json b = {1, 2}; | |
| CHECK_THROWS_WITH_AS(a.begin() == b.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", nlohmann::json::invalid_iterator); | |
| CHECK_THROWS_WITH_AS(a.begin() < b.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", nlohmann::json::invalid_iterator); | |
| } | |
| } |