fixed iterator_wrapper

This commit is contained in:
Niels 2015-08-13 10:08:55 +02:00
parent 66ec58639b
commit fadccc34eb
3 changed files with 349 additions and 156 deletions

View file

@ -5712,10 +5712,41 @@ class basic_json
json_iterator anchor;
/// an index for arrays
size_t array_index = 0;
size_t container_size = 0;
/// calculate a key for the iterator
std::string calculate_key()
public:
/// construct wrapper given an iterator
iterator_wrapper_internal(json_iterator i) : anchor(i)
{}
/// dereference operator (needed for range-based for)
iterator_wrapper_internal& operator*()
{
return *this;
}
/// increment operator (needed for range-based for)
iterator_wrapper_internal& operator++()
{
++anchor;
++array_index;
return *this;
}
/// inequality operator (needed for range-based for)
bool operator!= (const iterator_wrapper_internal& o)
{
return anchor != o.anchor;
}
/// stream operator
friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
{
return o << w.value();
}
/// return key of the iterator
typename basic_json::string_t key() const
{
switch (anchor.m_object->type())
{
@ -5739,61 +5770,11 @@ class basic_json
}
}
public:
/// construct wrapper given an iterator
iterator_wrapper_internal(json_iterator i, size_t s)
: anchor(i), container_size(s), first(calculate_key()), second(*i)
{}
/// dereference operator (needed for range-based for)
iterator_wrapper_internal operator*()
{
return *this;
}
/// increment operator (needed for range-based for)
iterator_wrapper_internal& operator++()
{
++anchor;
++array_index;
if (array_index < container_size)
{
first = calculate_key();
second = *anchor;
}
return *this;
}
/// inequality operator (needed for range-based for)
bool operator!= (const iterator_wrapper_internal& o)
{
return anchor != o.anchor;
}
/// stream operator
friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
{
return o << w.value();
}
/// return key of the iterator
typename basic_json::string_t key() const
{
return first;
}
/// return value of the iterator
basic_json value() const
typename json_iterator::reference value() const
{
return second;
return anchor.value();
}
/// public member to simulate std::map::iterator access
typename basic_json::string_t first;
/// public member to simulate std::map::iterator access
basic_json& second;
};
public:
@ -5805,13 +5786,13 @@ class basic_json
/// return iterator begin (needed for range-based for)
iterator_wrapper_internal begin()
{
return iterator_wrapper_internal(container.begin(), container.size());
return iterator_wrapper_internal(container.begin());
}
/// return iterator end (needed for range-based for)
iterator_wrapper_internal end()
{
return iterator_wrapper_internal(container.end(), container.size());
return iterator_wrapper_internal(container.end());
}
};

View file

@ -5712,10 +5712,41 @@ class basic_json
json_iterator anchor;
/// an index for arrays
size_t array_index = 0;
size_t container_size = 0;
/// calculate a key for the iterator
std::string calculate_key()
public:
/// construct wrapper given an iterator
iterator_wrapper_internal(json_iterator i) : anchor(i)
{}
/// dereference operator (needed for range-based for)
iterator_wrapper_internal& operator*()
{
return *this;
}
/// increment operator (needed for range-based for)
iterator_wrapper_internal& operator++()
{
++anchor;
++array_index;
return *this;
}
/// inequality operator (needed for range-based for)
bool operator!= (const iterator_wrapper_internal& o)
{
return anchor != o.anchor;
}
/// stream operator
friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
{
return o << w.value();
}
/// return key of the iterator
typename basic_json::string_t key() const
{
switch (anchor.m_object->type())
{
@ -5739,61 +5770,11 @@ class basic_json
}
}
public:
/// construct wrapper given an iterator
iterator_wrapper_internal(json_iterator i, size_t s)
: anchor(i), container_size(s), first(calculate_key()), second(*i)
{}
/// dereference operator (needed for range-based for)
iterator_wrapper_internal operator*()
{
return *this;
}
/// increment operator (needed for range-based for)
iterator_wrapper_internal& operator++()
{
++anchor;
++array_index;
if (array_index < container_size)
{
first = calculate_key();
second = *anchor;
}
return *this;
}
/// inequality operator (needed for range-based for)
bool operator!= (const iterator_wrapper_internal& o)
{
return anchor != o.anchor;
}
/// stream operator
friend std::ostream& operator<<(std::ostream& o, const iterator_wrapper_internal& w)
{
return o << w.value();
}
/// return key of the iterator
typename basic_json::string_t key() const
{
return first;
}
/// return value of the iterator
basic_json value() const
typename json_iterator::reference value() const
{
return second;
return anchor.value();
}
/// public member to simulate std::map::iterator access
typename basic_json::string_t first;
/// public member to simulate std::map::iterator access
basic_json& second;
};
public:
@ -5805,13 +5786,13 @@ class basic_json
/// return iterator begin (needed for range-based for)
iterator_wrapper_internal begin()
{
return iterator_wrapper_internal(container.begin(), container.size());
return iterator_wrapper_internal(container.begin());
}
/// return iterator end (needed for range-based for)
iterator_wrapper_internal end()
{
return iterator_wrapper_internal(container.end(), container.size());
return iterator_wrapper_internal(container.end());
}
};

View file

@ -9260,70 +9260,301 @@ TEST_CASE("concepts")
}
}
/*
TEST_CASE("iterator_wrapper")
{
SECTION("object")
{
json j = {{"A", 1}, {"B", 2}};
int counter = 1;
for (auto i : json::iterator_wrapper(j))
SECTION("value")
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "A");
CHECK(i.value() == json(1));
CHECK(i.first == "A");
CHECK(i.second == json(1));
break;
}
json j = {{"A", 1}, {"B", 2}};
int counter = 1;
case 2:
for (auto i : json::iterator_wrapper(j))
{
switch (counter++)
{
CHECK(i.key() == "B");
CHECK(i.value() == json(2));
CHECK(i.first == "B");
CHECK(i.second == json(2));
break;
case 1:
{
CHECK(i.key() == "A");
CHECK(i.value() == json(1));
break;
}
case 2:
{
CHECK(i.key() == "B");
CHECK(i.value() == json(2));
break;
}
}
}
CHECK(counter == 3);
}
SECTION("reference")
{
json j = {{"A", 1}, {"B", 2}};
int counter = 1;
for (auto& i : json::iterator_wrapper(j))
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "A");
CHECK(i.value() == json(1));
break;
}
case 2:
{
CHECK(i.key() == "B");
CHECK(i.value() == json(2));
break;
}
}
}
CHECK(counter == 3);
}
SECTION("const value")
{
json j = {{"A", 1}, {"B", 2}};
int counter = 1;
for (const auto i : json::iterator_wrapper(j))
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "A");
CHECK(i.value() == json(1));
break;
}
case 2:
{
CHECK(i.key() == "B");
CHECK(i.value() == json(2));
break;
}
}
}
CHECK(counter == 3);
}
SECTION("const reference")
{
json j = {{"A", 1}, {"B", 2}};
int counter = 1;
for (const auto& i : json::iterator_wrapper(j))
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "A");
CHECK(i.value() == json(1));
break;
}
case 2:
{
CHECK(i.key() == "B");
CHECK(i.value() == json(2));
break;
}
}
}
CHECK(counter == 3);
}
}
SECTION("array")
{
json j = {"A", "B"};
int counter = 1;
for (auto i : json::iterator_wrapper(j))
SECTION("value")
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "0");
CHECK(i.value() == "A");
CHECK(i.first == "0");
CHECK(i.second == "A");
break;
}
json j = {"A", "B"};
int counter = 1;
case 2:
for (auto i : json::iterator_wrapper(j))
{
switch (counter++)
{
CHECK(i.key() == "1");
CHECK(i.value() == "B");
CHECK(i.first == "1");
CHECK(i.second == "B");
break;
case 1:
{
CHECK(i.key() == "0");
CHECK(i.value() == "A");
break;
}
case 2:
{
CHECK(i.key() == "1");
CHECK(i.value() == "B");
break;
}
}
}
CHECK(counter == 3);
}
SECTION("reference")
{
json j = {"A", "B"};
int counter = 1;
for (auto& i : json::iterator_wrapper(j))
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "0");
CHECK(i.value() == "A");
break;
}
case 2:
{
CHECK(i.key() == "1");
CHECK(i.value() == "B");
break;
}
}
}
CHECK(counter == 3);
}
SECTION("const value")
{
json j = {"A", "B"};
int counter = 1;
for (const auto i : json::iterator_wrapper(j))
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "0");
CHECK(i.value() == "A");
break;
}
case 2:
{
CHECK(i.key() == "1");
CHECK(i.value() == "B");
break;
}
}
}
CHECK(counter == 3);
}
SECTION("const reference")
{
json j = {"A", "B"};
int counter = 1;
for (const auto& i : json::iterator_wrapper(j))
{
switch (counter++)
{
case 1:
{
CHECK(i.key() == "0");
CHECK(i.value() == "A");
break;
}
case 2:
{
CHECK(i.key() == "1");
CHECK(i.value() == "B");
break;
}
}
}
CHECK(counter == 3);
}
}
SECTION("primitive")
{
SECTION("value")
{
json j = 1;
int counter = 1;
for (auto i : json::iterator_wrapper(j))
{
++counter;
CHECK(i.key() == "");
CHECK(i.value() == json(1));
}
CHECK(counter == 2);
}
SECTION("reference")
{
json j = 1;
int counter = 1;
for (auto& i : json::iterator_wrapper(j))
{
++counter;
CHECK(i.key() == "");
CHECK(i.value() == json(1));
}
CHECK(counter == 2);
}
SECTION("const value")
{
json j = 1;
int counter = 1;
for (const auto i : json::iterator_wrapper(j))
{
++counter;
CHECK(i.key() == "");
CHECK(i.value() == json(1));
}
CHECK(counter == 2);
}
SECTION("reference")
{
json j = 1;
int counter = 1;
for (const auto& i : json::iterator_wrapper(j))
{
++counter;
CHECK(i.key() == "");
CHECK(i.value() == json(1));
}
CHECK(counter == 2);
}
}
}
*/
TEST_CASE("compliance tests from json.org")
{