diff --git a/src/json.hpp b/src/json.hpp index 6e8f145a..d79fb841 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -5248,16 +5248,22 @@ class basic_json it) : std::reverse_iterator(it) {} + reverse_iterator(const std::reverse_iterator& it) + : std::reverse_iterator(it) + {} + /// return the key of an object iterator typename object_t::key_type key() const { - return this->base().key(); + auto it = --this->base(); + return it.key(); } /// return the value of an iterator reference value() const { - return this->base().operator * (); + auto it = --this->base(); + return it.operator * (); } }; @@ -5272,13 +5278,15 @@ class basic_json /// return the key of an object iterator typename object_t::key_type key() const { - return this->base().key(); + auto it = --this->base(); + return it.key(); } /// return the value of an iterator const_reference value() const { - return this->base().operator * (); + auto it = --this->base(); + return it.operator * (); } }; diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 9081dab8..a8fefe61 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -5248,16 +5248,22 @@ class basic_json it) : std::reverse_iterator(it) {} + reverse_iterator(const std::reverse_iterator& it) + : std::reverse_iterator(it) + {} + /// return the key of an object iterator typename object_t::key_type key() const { - return this->base().key(); + auto it = --this->base(); + return it.key(); } /// return the value of an iterator reference value() const { - return this->base().operator * (); + auto it = --this->base(); + return it.operator * (); } }; @@ -5272,13 +5278,15 @@ class basic_json /// return the key of an object iterator typename object_t::key_type key() const { - return this->base().key(); + auto it = --this->base(); + return it.key(); } /// return the value of an iterator const_reference value() const { - return this->base().operator * (); + auto it = --this->base(); + return it.operator * (); } }; diff --git a/test/unit.cpp b/test/unit.cpp index 51b6d4aa..ccb79823 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -4093,9 +4093,9 @@ TEST_CASE("iterators") auto rit = j.rend(); auto crit = j.crend(); CHECK_THROWS_AS(rit.key(), std::domain_error); - CHECK(rit.value() == json(true)); + CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(crit.key(), std::domain_error); - CHECK(crit.value() == json(true)); + CHECK_THROWS_AS(crit.value(), std::out_of_range); } } @@ -4291,9 +4291,9 @@ TEST_CASE("iterators") auto rit = j.rend(); auto crit = j.crend(); CHECK_THROWS_AS(rit.key(), std::domain_error); - CHECK(rit.value() == json("hello world")); + CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(crit.key(), std::domain_error); - CHECK(crit.value() == json("hello world")); + CHECK_THROWS_AS(crit.value(), std::out_of_range); } } @@ -4478,13 +4478,6 @@ TEST_CASE("iterators") CHECK(it.value() == json(1)); CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK(cit.value() == json(1)); - - auto rit = j.rend(); - auto crit = j.crend(); - CHECK_THROWS_AS(rit.key(), std::domain_error); - CHECK(rit.value() == json(1)); - CHECK_THROWS_AS(crit.key(), std::domain_error); - CHECK(crit.value() == json(1)); } } @@ -4669,13 +4662,6 @@ TEST_CASE("iterators") CHECK(it.value() == json(1)); CHECK(cit.key() == "A"); CHECK(cit.value() == json(1)); - - auto rit = j.rend(); - auto crit = j.crend(); - CHECK(rit.key() == "A"); - CHECK(rit.value() == json(1)); - CHECK(crit.key() == "A"); - CHECK(crit.value() == json(1)); } } @@ -4871,9 +4857,9 @@ TEST_CASE("iterators") auto rit = j.rend(); auto crit = j.crend(); CHECK_THROWS_AS(rit.key(), std::domain_error); - CHECK(rit.value() == json(23)); + CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(crit.key(), std::domain_error); - CHECK(crit.value() == json(23)); + CHECK_THROWS_AS(crit.value(), std::out_of_range); } } @@ -5069,9 +5055,9 @@ TEST_CASE("iterators") auto rit = j.rend(); auto crit = j.crend(); CHECK_THROWS_AS(rit.key(), std::domain_error); - CHECK(rit.value() == json(23.42)); + CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(crit.key(), std::domain_error); - CHECK(crit.value() == json(23.42)); + CHECK_THROWS_AS(crit.value(), std::out_of_range); } } @@ -9277,6 +9263,61 @@ TEST_CASE("regression tests") CHECK(static_cast(j["int_1"]) == 1); } + SECTION("issue #93 reverse_iterator operator inheritance problem") + { + { + json a = {1, 2, 3}; + json::reverse_iterator rit = a.rbegin(); + ++rit; + CHECK(*rit == json(2)); + CHECK(rit.value() == json(2)); + } + { + json a = {1, 2, 3}; + json::reverse_iterator rit = ++a.rbegin(); + } + { + json a = {1, 2, 3}; + json::reverse_iterator rit = a.rbegin(); + ++rit; + json b = {0, 0, 0}; + std::transform(rit, a.rend(), b.rbegin(), [](json el) + { + return el; + }); + CHECK(b == json({0, 1, 2})); + } + { + // json a = {1,2,3}; + // json b = {0,0,0}; + // std::transform(++a.rbegin(),a.rend(),b.rbegin(),[](json el){return el;}); + } + } + + SECTION("issue #100 - failed to iterator json object with reverse_iterator") + { + json config = + { + { "111", 111 }, + { "112", 112 }, + { "113", 113 } + }; + + std::stringstream ss; + + for (auto it = config.begin(); it != config.end(); ++it) + { + ss << it.key() << ": " << it.value() << '\n'; + } + + for (auto it = config.rbegin(); it != config.rend(); ++it) + { + ss << it.key() << ": " << it.value() << '\n'; + } + + CHECK(ss.str() == "111: 111\n112: 112\n113: 113\n113: 113\n112: 112\n111: 111\n"); + } + SECTION("issue #101 - binary string causes numbers to be dumped as hex") { int64_t number = 10;