diff --git a/src/json.hpp b/src/json.hpp index e80e2e296c..2dd55104aa 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8503,18 +8503,29 @@ class basic_json @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - iter_impl operator+(difference_type i) + iter_impl operator+(difference_type i) const { auto result = *this; result += i; return result; } + /*! + @brief addition of distance and iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + friend iter_impl operator+(difference_type i, const iter_impl& it) + { + auto result = it; + result += i; + return result; + } + /*! @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - iter_impl operator-(difference_type i) + iter_impl operator-(difference_type i) const { auto result = *this; result -= i; @@ -8656,56 +8667,49 @@ class basic_json /// post-increment (it++) json_reverse_iterator operator++(int) { - return base_iterator::operator++(1); + return static_cast(base_iterator::operator++(1)); } /// pre-increment (++it) json_reverse_iterator& operator++() { - base_iterator::operator++(); - return *this; + return static_cast(base_iterator::operator++()); } /// post-decrement (it--) json_reverse_iterator operator--(int) { - return base_iterator::operator--(1); + return static_cast(base_iterator::operator--(1)); } /// pre-decrement (--it) json_reverse_iterator& operator--() { - base_iterator::operator--(); - return *this; + return static_cast(base_iterator::operator--()); } /// add to iterator json_reverse_iterator& operator+=(difference_type i) { - base_iterator::operator+=(i); - return *this; + return static_cast(base_iterator::operator+=(i)); } /// add to iterator json_reverse_iterator operator+(difference_type i) const { - auto result = *this; - result += i; - return result; + return static_cast(base_iterator::operator+(i)); } /// subtract from iterator json_reverse_iterator operator-(difference_type i) const { - auto result = *this; - result -= i; - return result; + return static_cast(base_iterator::operator-(i)); } /// return difference difference_type operator-(const json_reverse_iterator& other) const { - return this->base() - other.base(); + return base_iterator(*this) - base_iterator(other); } /// access to successor diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp index e20417a176..ae8ce6872a 100644 --- a/test/src/unit-iterators2.cpp +++ b/test/src/unit-iterators2.cpp @@ -269,6 +269,16 @@ TEST_CASE("iterators 2") CHECK_THROWS_AS(it + 1, json::invalid_iterator); CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); } + { + auto it = j_object.begin(); + CHECK_THROWS_AS(1 + it, json::invalid_iterator); + CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); + } + { + auto it = j_object.cbegin(); + CHECK_THROWS_AS(1 + it, json::invalid_iterator); + CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); + } { auto it = j_object.begin(); CHECK_THROWS_AS(it -= 1, json::invalid_iterator); @@ -307,6 +317,7 @@ TEST_CASE("iterators 2") auto it = j_array.begin(); it += 3; CHECK((j_array.begin() + 3) == it); + CHECK(json::iterator(3 + j_array.begin()) == it); CHECK((it - 3) == j_array.begin()); CHECK((it - j_array.begin()) == 3); CHECK(*it == json(4)); @@ -317,6 +328,7 @@ TEST_CASE("iterators 2") auto it = j_array.cbegin(); it += 3; CHECK((j_array.cbegin() + 3) == it); + CHECK(json::const_iterator(3 + j_array.cbegin()) == it); CHECK((it - 3) == j_array.cbegin()); CHECK((it - j_array.cbegin()) == 3); CHECK(*it == json(4)); @@ -331,6 +343,7 @@ TEST_CASE("iterators 2") auto it = j_null.begin(); it += 3; CHECK((j_null.begin() + 3) == it); + CHECK(json::iterator(3 + j_null.begin()) == it); CHECK((it - 3) == j_null.begin()); CHECK((it - j_null.begin()) == 3); CHECK(it != j_null.end()); @@ -341,6 +354,7 @@ TEST_CASE("iterators 2") auto it = j_null.cbegin(); it += 3; CHECK((j_null.cbegin() + 3) == it); + CHECK(json::const_iterator(3 + j_null.cbegin()) == it); CHECK((it - 3) == j_null.cbegin()); CHECK((it - j_null.cbegin()) == 3); CHECK(it != j_null.cend()); @@ -355,6 +369,7 @@ TEST_CASE("iterators 2") auto it = j_value.begin(); it += 3; CHECK((j_value.begin() + 3) == it); + CHECK(json::iterator(3 + j_value.begin()) == it); CHECK((it - 3) == j_value.begin()); CHECK((it - j_value.begin()) == 3); CHECK(it != j_value.end()); @@ -365,6 +380,7 @@ TEST_CASE("iterators 2") auto it = j_value.cbegin(); it += 3; CHECK((j_value.cbegin() + 3) == it); + CHECK(json::const_iterator(3 + j_value.cbegin()) == it); CHECK((it - 3) == j_value.cbegin()); CHECK((it - j_value.cbegin()) == 3); CHECK(it != j_value.cend()); @@ -688,6 +704,16 @@ TEST_CASE("iterators 2") CHECK_THROWS_AS(it + 1, json::invalid_iterator); CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); } + { + auto it = j_object.rbegin(); + CHECK_THROWS_AS(1 + it, json::invalid_iterator); + CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); + } + { + auto it = j_object.crbegin(); + CHECK_THROWS_AS(1 + it, json::invalid_iterator); + CHECK_THROWS_WITH(1 + it, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); + } { auto it = j_object.rbegin(); CHECK_THROWS_AS(it -= 1, json::invalid_iterator); @@ -726,8 +752,9 @@ TEST_CASE("iterators 2") auto it = j_array.rbegin(); it += 3; CHECK((j_array.rbegin() + 3) == it); + CHECK(json::reverse_iterator(3 + j_array.rbegin()) == it); CHECK((it - 3) == j_array.rbegin()); - CHECK((j_array.rbegin() - it) == 3); + CHECK((it - j_array.rbegin()) == 3); CHECK(*it == json(3)); it -= 2; CHECK(*it == json(5)); @@ -736,8 +763,9 @@ TEST_CASE("iterators 2") auto it = j_array.crbegin(); it += 3; CHECK((j_array.crbegin() + 3) == it); + CHECK(json::const_reverse_iterator(3 + j_array.crbegin()) == it); CHECK((it - 3) == j_array.crbegin()); - CHECK((j_array.crbegin() - it) == 3); + CHECK((it - j_array.crbegin()) == 3); CHECK(*it == json(3)); it -= 2; CHECK(*it == json(5)); @@ -750,8 +778,9 @@ TEST_CASE("iterators 2") auto it = j_null.rbegin(); it += 3; CHECK((j_null.rbegin() + 3) == it); + CHECK(json::reverse_iterator(3 + j_null.rbegin()) == it); CHECK((it - 3) == j_null.rbegin()); - CHECK((j_null.rbegin() - it) == 3); + CHECK((it - j_null.rbegin()) == 3); CHECK(it != j_null.rend()); it -= 3; CHECK(it == j_null.rend()); @@ -760,8 +789,9 @@ TEST_CASE("iterators 2") auto it = j_null.crbegin(); it += 3; CHECK((j_null.crbegin() + 3) == it); + CHECK(json::const_reverse_iterator(3 + j_null.crbegin()) == it); CHECK((it - 3) == j_null.crbegin()); - CHECK((j_null.crbegin() - it) == 3); + CHECK((it - j_null.crbegin()) == 3); CHECK(it != j_null.crend()); it -= 3; CHECK(it == j_null.crend()); @@ -774,8 +804,9 @@ TEST_CASE("iterators 2") auto it = j_value.rbegin(); it += 3; CHECK((j_value.rbegin() + 3) == it); + CHECK(json::reverse_iterator(3 + j_value.rbegin()) == it); CHECK((it - 3) == j_value.rbegin()); - CHECK((j_value.rbegin() - it) == 3); + CHECK((it - j_value.rbegin()) == 3); CHECK(it != j_value.rend()); it -= 3; CHECK(*it == json(42)); @@ -784,8 +815,9 @@ TEST_CASE("iterators 2") auto it = j_value.crbegin(); it += 3; CHECK((j_value.crbegin() + 3) == it); + CHECK(json::const_reverse_iterator(3 + j_value.crbegin()) == it); CHECK((it - 3) == j_value.crbegin()); - CHECK((j_value.crbegin() - it) == 3); + CHECK((it - j_value.crbegin()) == 3); CHECK(it != j_value.crend()); it -= 3; CHECK(*it == json(42));