Merge pull request #595 from HenryRLee/iterator_arithmetic

Issue #593 Fix the arithmetic operators in the iterator and reverse iterator
This commit is contained in:
Niels Lohmann 2017-06-10 18:26:48 +02:00 committed by GitHub
commit 6caad48e44
2 changed files with 59 additions and 23 deletions

View file

@ -8503,18 +8503,29 @@ class basic_json
@brief add to iterator @brief add to iterator
@pre The iterator is initialized; i.e. `m_object != nullptr`. @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; auto result = *this;
result += i; result += i;
return result; 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 @brief subtract from iterator
@pre The iterator is initialized; i.e. `m_object != nullptr`. @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; auto result = *this;
result -= i; result -= i;
@ -8656,56 +8667,49 @@ class basic_json
/// post-increment (it++) /// post-increment (it++)
json_reverse_iterator operator++(int) json_reverse_iterator operator++(int)
{ {
return base_iterator::operator++(1); return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
} }
/// pre-increment (++it) /// pre-increment (++it)
json_reverse_iterator& operator++() json_reverse_iterator& operator++()
{ {
base_iterator::operator++(); return static_cast<json_reverse_iterator&>(base_iterator::operator++());
return *this;
} }
/// post-decrement (it--) /// post-decrement (it--)
json_reverse_iterator operator--(int) json_reverse_iterator operator--(int)
{ {
return base_iterator::operator--(1); return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
} }
/// pre-decrement (--it) /// pre-decrement (--it)
json_reverse_iterator& operator--() json_reverse_iterator& operator--()
{ {
base_iterator::operator--(); return static_cast<json_reverse_iterator&>(base_iterator::operator--());
return *this;
} }
/// add to iterator /// add to iterator
json_reverse_iterator& operator+=(difference_type i) json_reverse_iterator& operator+=(difference_type i)
{ {
base_iterator::operator+=(i); return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
return *this;
} }
/// add to iterator /// add to iterator
json_reverse_iterator operator+(difference_type i) const json_reverse_iterator operator+(difference_type i) const
{ {
auto result = *this; return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
result += i;
return result;
} }
/// subtract from iterator /// subtract from iterator
json_reverse_iterator operator-(difference_type i) const json_reverse_iterator operator-(difference_type i) const
{ {
auto result = *this; return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
result -= i;
return result;
} }
/// return difference /// return difference
difference_type operator-(const json_reverse_iterator& other) const difference_type operator-(const json_reverse_iterator& other) const
{ {
return this->base() - other.base(); return base_iterator(*this) - base_iterator(other);
} }
/// access to successor /// access to successor

View file

@ -269,6 +269,16 @@ TEST_CASE("iterators 2")
CHECK_THROWS_AS(it + 1, json::invalid_iterator); CHECK_THROWS_AS(it + 1, json::invalid_iterator);
CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); 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(); auto it = j_object.begin();
CHECK_THROWS_AS(it -= 1, json::invalid_iterator); CHECK_THROWS_AS(it -= 1, json::invalid_iterator);
@ -307,6 +317,7 @@ TEST_CASE("iterators 2")
auto it = j_array.begin(); auto it = j_array.begin();
it += 3; it += 3;
CHECK((j_array.begin() + 3) == it); CHECK((j_array.begin() + 3) == it);
CHECK(json::iterator(3 + j_array.begin()) == it);
CHECK((it - 3) == j_array.begin()); CHECK((it - 3) == j_array.begin());
CHECK((it - j_array.begin()) == 3); CHECK((it - j_array.begin()) == 3);
CHECK(*it == json(4)); CHECK(*it == json(4));
@ -317,6 +328,7 @@ TEST_CASE("iterators 2")
auto it = j_array.cbegin(); auto it = j_array.cbegin();
it += 3; it += 3;
CHECK((j_array.cbegin() + 3) == it); CHECK((j_array.cbegin() + 3) == it);
CHECK(json::const_iterator(3 + j_array.cbegin()) == it);
CHECK((it - 3) == j_array.cbegin()); CHECK((it - 3) == j_array.cbegin());
CHECK((it - j_array.cbegin()) == 3); CHECK((it - j_array.cbegin()) == 3);
CHECK(*it == json(4)); CHECK(*it == json(4));
@ -331,6 +343,7 @@ TEST_CASE("iterators 2")
auto it = j_null.begin(); auto it = j_null.begin();
it += 3; it += 3;
CHECK((j_null.begin() + 3) == it); CHECK((j_null.begin() + 3) == it);
CHECK(json::iterator(3 + j_null.begin()) == it);
CHECK((it - 3) == j_null.begin()); CHECK((it - 3) == j_null.begin());
CHECK((it - j_null.begin()) == 3); CHECK((it - j_null.begin()) == 3);
CHECK(it != j_null.end()); CHECK(it != j_null.end());
@ -341,6 +354,7 @@ TEST_CASE("iterators 2")
auto it = j_null.cbegin(); auto it = j_null.cbegin();
it += 3; it += 3;
CHECK((j_null.cbegin() + 3) == it); CHECK((j_null.cbegin() + 3) == it);
CHECK(json::const_iterator(3 + j_null.cbegin()) == it);
CHECK((it - 3) == j_null.cbegin()); CHECK((it - 3) == j_null.cbegin());
CHECK((it - j_null.cbegin()) == 3); CHECK((it - j_null.cbegin()) == 3);
CHECK(it != j_null.cend()); CHECK(it != j_null.cend());
@ -355,6 +369,7 @@ TEST_CASE("iterators 2")
auto it = j_value.begin(); auto it = j_value.begin();
it += 3; it += 3;
CHECK((j_value.begin() + 3) == it); CHECK((j_value.begin() + 3) == it);
CHECK(json::iterator(3 + j_value.begin()) == it);
CHECK((it - 3) == j_value.begin()); CHECK((it - 3) == j_value.begin());
CHECK((it - j_value.begin()) == 3); CHECK((it - j_value.begin()) == 3);
CHECK(it != j_value.end()); CHECK(it != j_value.end());
@ -365,6 +380,7 @@ TEST_CASE("iterators 2")
auto it = j_value.cbegin(); auto it = j_value.cbegin();
it += 3; it += 3;
CHECK((j_value.cbegin() + 3) == it); CHECK((j_value.cbegin() + 3) == it);
CHECK(json::const_iterator(3 + j_value.cbegin()) == it);
CHECK((it - 3) == j_value.cbegin()); CHECK((it - 3) == j_value.cbegin());
CHECK((it - j_value.cbegin()) == 3); CHECK((it - j_value.cbegin()) == 3);
CHECK(it != j_value.cend()); CHECK(it != j_value.cend());
@ -688,6 +704,16 @@ TEST_CASE("iterators 2")
CHECK_THROWS_AS(it + 1, json::invalid_iterator); CHECK_THROWS_AS(it + 1, json::invalid_iterator);
CHECK_THROWS_WITH(it + 1, "[json.exception.invalid_iterator.209] cannot use offsets with object iterators"); 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(); auto it = j_object.rbegin();
CHECK_THROWS_AS(it -= 1, json::invalid_iterator); CHECK_THROWS_AS(it -= 1, json::invalid_iterator);
@ -726,8 +752,9 @@ TEST_CASE("iterators 2")
auto it = j_array.rbegin(); auto it = j_array.rbegin();
it += 3; it += 3;
CHECK((j_array.rbegin() + 3) == it); CHECK((j_array.rbegin() + 3) == it);
CHECK(json::reverse_iterator(3 + j_array.rbegin()) == it);
CHECK((it - 3) == j_array.rbegin()); CHECK((it - 3) == j_array.rbegin());
CHECK((j_array.rbegin() - it) == 3); CHECK((it - j_array.rbegin()) == 3);
CHECK(*it == json(3)); CHECK(*it == json(3));
it -= 2; it -= 2;
CHECK(*it == json(5)); CHECK(*it == json(5));
@ -736,8 +763,9 @@ TEST_CASE("iterators 2")
auto it = j_array.crbegin(); auto it = j_array.crbegin();
it += 3; it += 3;
CHECK((j_array.crbegin() + 3) == it); CHECK((j_array.crbegin() + 3) == it);
CHECK(json::const_reverse_iterator(3 + j_array.crbegin()) == it);
CHECK((it - 3) == j_array.crbegin()); CHECK((it - 3) == j_array.crbegin());
CHECK((j_array.crbegin() - it) == 3); CHECK((it - j_array.crbegin()) == 3);
CHECK(*it == json(3)); CHECK(*it == json(3));
it -= 2; it -= 2;
CHECK(*it == json(5)); CHECK(*it == json(5));
@ -750,8 +778,9 @@ TEST_CASE("iterators 2")
auto it = j_null.rbegin(); auto it = j_null.rbegin();
it += 3; it += 3;
CHECK((j_null.rbegin() + 3) == it); CHECK((j_null.rbegin() + 3) == it);
CHECK(json::reverse_iterator(3 + j_null.rbegin()) == it);
CHECK((it - 3) == j_null.rbegin()); CHECK((it - 3) == j_null.rbegin());
CHECK((j_null.rbegin() - it) == 3); CHECK((it - j_null.rbegin()) == 3);
CHECK(it != j_null.rend()); CHECK(it != j_null.rend());
it -= 3; it -= 3;
CHECK(it == j_null.rend()); CHECK(it == j_null.rend());
@ -760,8 +789,9 @@ TEST_CASE("iterators 2")
auto it = j_null.crbegin(); auto it = j_null.crbegin();
it += 3; it += 3;
CHECK((j_null.crbegin() + 3) == it); CHECK((j_null.crbegin() + 3) == it);
CHECK(json::const_reverse_iterator(3 + j_null.crbegin()) == it);
CHECK((it - 3) == j_null.crbegin()); CHECK((it - 3) == j_null.crbegin());
CHECK((j_null.crbegin() - it) == 3); CHECK((it - j_null.crbegin()) == 3);
CHECK(it != j_null.crend()); CHECK(it != j_null.crend());
it -= 3; it -= 3;
CHECK(it == j_null.crend()); CHECK(it == j_null.crend());
@ -774,8 +804,9 @@ TEST_CASE("iterators 2")
auto it = j_value.rbegin(); auto it = j_value.rbegin();
it += 3; it += 3;
CHECK((j_value.rbegin() + 3) == it); CHECK((j_value.rbegin() + 3) == it);
CHECK(json::reverse_iterator(3 + j_value.rbegin()) == it);
CHECK((it - 3) == j_value.rbegin()); CHECK((it - 3) == j_value.rbegin());
CHECK((j_value.rbegin() - it) == 3); CHECK((it - j_value.rbegin()) == 3);
CHECK(it != j_value.rend()); CHECK(it != j_value.rend());
it -= 3; it -= 3;
CHECK(*it == json(42)); CHECK(*it == json(42));
@ -784,8 +815,9 @@ TEST_CASE("iterators 2")
auto it = j_value.crbegin(); auto it = j_value.crbegin();
it += 3; it += 3;
CHECK((j_value.crbegin() + 3) == it); CHECK((j_value.crbegin() + 3) == it);
CHECK(json::const_reverse_iterator(3 + j_value.crbegin()) == it);
CHECK((it - 3) == j_value.crbegin()); CHECK((it - 3) == j_value.crbegin());
CHECK((j_value.crbegin() - it) == 3); CHECK((it - j_value.crbegin()) == 3);
CHECK(it != j_value.crend()); CHECK(it != j_value.crend());
it -= 3; it -= 3;
CHECK(*it == json(42)); CHECK(*it == json(42));