Skip to content

Commit bb9eda1

Browse files
Make sure iterator_input_adapter advances iterators correctly
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.
1 parent 87cda1d commit bb9eda1

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

tests/src/unit-deserialization.cpp

+69
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ SOFTWARE.
2929

3030
#include "doctest_compatibility.h"
3131

32+
#include <iterator>
3233
#include <nlohmann/json.hpp>
3334
using nlohmann::json;
3435

@@ -184,6 +185,52 @@ struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
184185
return false;
185186
}
186187
};
188+
189+
template <typename T>
190+
class proxy_iterator
191+
{
192+
public:
193+
using iterator = typename T::iterator;
194+
using value_type = typename std::iterator_traits<iterator>::value_type;
195+
using reference = typename std::iterator_traits<iterator>::reference;
196+
using pointer = typename std::iterator_traits<iterator>::pointer;
197+
using difference_type =
198+
typename std::iterator_traits<iterator>::difference_type;
199+
using iterator_category = std::input_iterator_tag;
200+
201+
proxy_iterator() = default;
202+
proxy_iterator(iterator& it) : m_it(std::addressof(it)) {}
203+
204+
proxy_iterator& operator++()
205+
{
206+
++*m_it;
207+
return *this;
208+
}
209+
210+
proxy_iterator& operator--()
211+
{
212+
--*m_it;
213+
return *this;
214+
}
215+
216+
bool operator==(const proxy_iterator& rhs) const
217+
{
218+
return (m_it && rhs.m_it) ? (*m_it == *rhs.m_it) : (m_it == rhs.m_it);
219+
}
220+
221+
bool operator!=(const proxy_iterator& rhs) const
222+
{
223+
return !(*this == rhs);
224+
}
225+
226+
reference operator*() const
227+
{
228+
return **m_it;
229+
}
230+
231+
private:
232+
iterator* m_it = nullptr;
233+
};
187234
} // namespace
188235

189236
TEST_CASE("deserialization")
@@ -538,6 +585,28 @@ TEST_CASE("deserialization")
538585
CHECK(l.events.size() == 1);
539586
CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
540587
}
588+
589+
SECTION("iterator_input_adapter advances iterators correctly")
590+
{
591+
using nlohmann::json;
592+
using nlohmann::detail::input_format_t;
593+
using nlohmann::detail::json_sax_dom_parser;
594+
using proxy = proxy_iterator<std::string>;
595+
596+
std::string str1 = "[1]";
597+
std::string str2 = "[2]";
598+
std::string str = str1 + str2;
599+
600+
auto first = str.begin();
601+
auto last = str.end();
602+
json j;
603+
json_sax_dom_parser<json> sax(j, true);
604+
605+
CHECK(json::sax_parse(proxy(first), proxy(last), &sax,
606+
input_format_t::json, false));
607+
CHECK(j.dump() == str1);
608+
CHECK(std::string(first, last) == str2);
609+
}
541610
}
542611

543612
// these cases are required for 100% line coverage

0 commit comments

Comments
 (0)