diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index d196aec54..49d04395c 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -123,6 +123,7 @@ class input_stream_adapter }; #endif // JSON_NO_IO + // General-purpose iterator-based adapter. It might not be as fast as // theoretically possible for some containers, but it is extremely versatile. template @@ -132,30 +133,46 @@ class iterator_input_adapter using char_type = typename std::iterator_traits::value_type; iterator_input_adapter(IteratorType first, IteratorType last) - : current(std::move(first)), end(std::move(last)) + : current(std::move(first)), end(std::move(last)), current_has_been_consumed(false) {} typename std::char_traits::int_type get_character() { - if (JSON_HEDLEY_LIKELY(current != end)) + + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) { - auto result = std::char_traits::to_int_type(*current); std::advance(current, 1); - return result; } - return std::char_traits::eof(); + if (JSON_HEDLEY_LIKELY(current != end)) + { + current_has_been_consumed = true; + return std::char_traits::to_int_type(*current); + } + else + { + current_has_been_consumed = false; + return std::char_traits::eof(); + } + } private: IteratorType current; IteratorType end; + bool current_has_been_consumed = false; template friend struct wide_string_input_helper; - bool empty() const + bool empty() { + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) + { + std::advance(current, 1); + current_has_been_consumed = false; + } + return current == end; } }; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a29c52997..fdcf4e818 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -5533,6 +5533,7 @@ class input_stream_adapter }; #endif // JSON_NO_IO + // General-purpose iterator-based adapter. It might not be as fast as // theoretically possible for some containers, but it is extremely versatile. template @@ -5542,30 +5543,46 @@ class iterator_input_adapter using char_type = typename std::iterator_traits::value_type; iterator_input_adapter(IteratorType first, IteratorType last) - : current(std::move(first)), end(std::move(last)) + : current(std::move(first)), end(std::move(last)), current_has_been_consumed(false) {} typename std::char_traits::int_type get_character() { - if (JSON_HEDLEY_LIKELY(current != end)) + + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) { - auto result = std::char_traits::to_int_type(*current); std::advance(current, 1); - return result; } - return std::char_traits::eof(); + if (JSON_HEDLEY_LIKELY(current != end)) + { + current_has_been_consumed = true; + return std::char_traits::to_int_type(*current); + } + else + { + current_has_been_consumed = false; + return std::char_traits::eof(); + } + } private: IteratorType current; IteratorType end; + bool current_has_been_consumed = false; template friend struct wide_string_input_helper; - bool empty() const + bool empty() { + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) + { + std::advance(current, 1); + current_has_been_consumed = false; + } + return current == end; } };