fixed iterator_wrapper
This commit is contained in:
parent
66ec58639b
commit
fadccc34eb
3 changed files with 349 additions and 156 deletions
95
src/json.hpp
95
src/json.hpp
|
@ -5712,10 +5712,41 @@ class basic_json
|
||||||
json_iterator anchor;
|
json_iterator anchor;
|
||||||
/// an index for arrays
|
/// an index for arrays
|
||||||
size_t array_index = 0;
|
size_t array_index = 0;
|
||||||
size_t container_size = 0;
|
|
||||||
|
|
||||||
/// calculate a key for the iterator
|
public:
|
||||||
std::string calculate_key()
|
/// 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())
|
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
|
/// 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:
|
public:
|
||||||
|
@ -5805,13 +5786,13 @@ class basic_json
|
||||||
/// return iterator begin (needed for range-based for)
|
/// return iterator begin (needed for range-based for)
|
||||||
iterator_wrapper_internal begin()
|
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)
|
/// return iterator end (needed for range-based for)
|
||||||
iterator_wrapper_internal end()
|
iterator_wrapper_internal end()
|
||||||
{
|
{
|
||||||
return iterator_wrapper_internal(container.end(), container.size());
|
return iterator_wrapper_internal(container.end());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5712,10 +5712,41 @@ class basic_json
|
||||||
json_iterator anchor;
|
json_iterator anchor;
|
||||||
/// an index for arrays
|
/// an index for arrays
|
||||||
size_t array_index = 0;
|
size_t array_index = 0;
|
||||||
size_t container_size = 0;
|
|
||||||
|
|
||||||
/// calculate a key for the iterator
|
public:
|
||||||
std::string calculate_key()
|
/// 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())
|
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
|
/// 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:
|
public:
|
||||||
|
@ -5805,13 +5786,13 @@ class basic_json
|
||||||
/// return iterator begin (needed for range-based for)
|
/// return iterator begin (needed for range-based for)
|
||||||
iterator_wrapper_internal begin()
|
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)
|
/// return iterator end (needed for range-based for)
|
||||||
iterator_wrapper_internal end()
|
iterator_wrapper_internal end()
|
||||||
{
|
{
|
||||||
return iterator_wrapper_internal(container.end(), container.size());
|
return iterator_wrapper_internal(container.end());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
315
test/unit.cpp
315
test/unit.cpp
|
@ -9260,70 +9260,301 @@ TEST_CASE("concepts")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
TEST_CASE("iterator_wrapper")
|
TEST_CASE("iterator_wrapper")
|
||||||
{
|
{
|
||||||
SECTION("object")
|
SECTION("object")
|
||||||
{
|
{
|
||||||
json j = {{"A", 1}, {"B", 2}};
|
SECTION("value")
|
||||||
int counter = 1;
|
|
||||||
|
|
||||||
for (auto i : json::iterator_wrapper(j))
|
|
||||||
{
|
{
|
||||||
switch (counter++)
|
json j = {{"A", 1}, {"B", 2}};
|
||||||
{
|
int counter = 1;
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
CHECK(i.key() == "A");
|
|
||||||
CHECK(i.value() == json(1));
|
|
||||||
CHECK(i.first == "A");
|
|
||||||
CHECK(i.second == json(1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
for (auto i : json::iterator_wrapper(j))
|
||||||
|
{
|
||||||
|
switch (counter++)
|
||||||
{
|
{
|
||||||
CHECK(i.key() == "B");
|
case 1:
|
||||||
CHECK(i.value() == json(2));
|
{
|
||||||
CHECK(i.first == "B");
|
CHECK(i.key() == "A");
|
||||||
CHECK(i.second == json(2));
|
CHECK(i.value() == json(1));
|
||||||
break;
|
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")
|
SECTION("array")
|
||||||
{
|
{
|
||||||
json j = {"A", "B"};
|
SECTION("value")
|
||||||
int counter = 1;
|
|
||||||
|
|
||||||
for (auto i : json::iterator_wrapper(j))
|
|
||||||
{
|
{
|
||||||
switch (counter++)
|
json j = {"A", "B"};
|
||||||
{
|
int counter = 1;
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
CHECK(i.key() == "0");
|
|
||||||
CHECK(i.value() == "A");
|
|
||||||
CHECK(i.first == "0");
|
|
||||||
CHECK(i.second == "A");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
for (auto i : json::iterator_wrapper(j))
|
||||||
|
{
|
||||||
|
switch (counter++)
|
||||||
{
|
{
|
||||||
CHECK(i.key() == "1");
|
case 1:
|
||||||
CHECK(i.value() == "B");
|
{
|
||||||
CHECK(i.first == "1");
|
CHECK(i.key() == "0");
|
||||||
CHECK(i.second == "B");
|
CHECK(i.value() == "A");
|
||||||
break;
|
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")
|
TEST_CASE("compliance tests from json.org")
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue