Make sure iterator_input_adapter advances iterators correctly (#3548)

When parsing a string containing two JSON values using iterators, after
parsing, iterator_input_adapter should have advanced to the first
character of the second value.
Add a unit test to check that this is true.
pull/3599/head
Florian Albrechtskirchinger 2022-07-23 14:36:10 +02:00 committed by GitHub
parent dbfd33a70a
commit e91686cc17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 69 additions and 0 deletions

View File

@ -13,6 +13,7 @@
using nlohmann::json;
#include <iostream>
#include <iterator>
#include <sstream>
#include <valarray>
@ -164,6 +165,52 @@ struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
return false;
}
};
template <typename T>
class proxy_iterator
{
public:
using iterator = typename T::iterator;
using value_type = typename std::iterator_traits<iterator>::value_type;
using reference = typename std::iterator_traits<iterator>::reference;
using pointer = typename std::iterator_traits<iterator>::pointer;
using difference_type =
typename std::iterator_traits<iterator>::difference_type;
using iterator_category = std::input_iterator_tag;
proxy_iterator() = default;
explicit proxy_iterator(iterator& it) : m_it(std::addressof(it)) {}
proxy_iterator& operator++()
{
++*m_it;
return *this;
}
proxy_iterator& operator--()
{
--*m_it;
return *this;
}
bool operator==(const proxy_iterator& rhs) const
{
return (m_it && rhs.m_it) ? (*m_it == *rhs.m_it) : (m_it == rhs.m_it);
}
bool operator!=(const proxy_iterator& rhs) const
{
return !(*this == rhs);
}
reference operator*() const
{
return **m_it;
}
private:
iterator* m_it = nullptr;
};
} // namespace
TEST_CASE("deserialization")
@ -518,6 +565,28 @@ TEST_CASE("deserialization")
CHECK(l.events.size() == 1);
CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
}
SECTION("iterator_input_adapter advances iterators correctly")
{
using nlohmann::json;
using nlohmann::detail::input_format_t;
using nlohmann::detail::json_sax_dom_parser;
using proxy = proxy_iterator<std::string>;
std::string str1 = "[1]";
std::string str2 = "[2]";
std::string str = str1 + str2;
auto first = str.begin();
auto last = str.end();
json j;
json_sax_dom_parser<json> sax(j, true);
CHECK(json::sax_parse(proxy(first), proxy(last), &sax,
input_format_t::json, false));
CHECK(j.dump() == str1);
CHECK(std::string(first, last) == str2);
}
}
// these cases are required for 100% line coverage