diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index c4bcde2d9d..a8a44774b5 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -132,10 +132,70 @@ class input_stream_adapter }; #endif // JSON_NO_IO +template +struct has_char_traits : std::false_type {}; + +template<> +struct has_char_traits : std::true_type {}; + +template<> +struct has_char_traits : std::true_type {}; + +#ifdef JSON_HAS_CPP_20 +template<> +struct has_char_traits : std::true_type {}; + +template<> +struct has_char_traits : std::true_type {}; + +template<> +struct has_char_traits : std::true_type {}; +#endif + +template +struct is_iterator_of_char : has_char_traits::value_type> {}; + // General-purpose iterator-based adapter. It might not be as fast as // theoretically possible for some containers, but it is extremely versatile. -template +template class iterator_input_adapter +{ + public: + using char_type = char; + using value_type = typename std::iterator_traits::value_type; + + iterator_input_adapter(IteratorType first, IteratorType last) + : current(std::move(first)), end(std::move(last)) + {} + + typename std::char_traits::int_type get_character() + { + if (JSON_HEDLEY_LIKELY(current != end)) + { + // Cast to unsigned to avoid EOF and 0xFF having same value + auto result = static_cast::type>(*current); + std::advance(current, 1); + return static_cast::int_type>(result); + } + + return std::char_traits::eof(); + } + + private: + IteratorType current; + IteratorType end; + + template + friend struct wide_string_input_helper; + + bool empty() const + { + return current == end; + } +}; + +template +class iterator_input_adapter::value>> { public: using char_type = typename std::iterator_traits::value_type; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 14bc07d5fe..c6f8e64ff3 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6208,10 +6208,70 @@ class input_stream_adapter }; #endif // JSON_NO_IO +template +struct has_char_traits : std::false_type {}; + +template<> +struct has_char_traits : std::true_type {}; + +template<> +struct has_char_traits : std::true_type {}; + +#ifdef JSON_HAS_CPP_20 +template<> +struct has_char_traits : std::true_type {}; + +template<> +struct has_char_traits : std::true_type {}; + +template<> +struct has_char_traits : std::true_type {}; +#endif + +template +struct is_iterator_of_char : has_char_traits::value_type> {}; + // General-purpose iterator-based adapter. It might not be as fast as // theoretically possible for some containers, but it is extremely versatile. -template +template class iterator_input_adapter +{ + public: + using char_type = char; + using value_type = typename std::iterator_traits::value_type; + + iterator_input_adapter(IteratorType first, IteratorType last) + : current(std::move(first)), end(std::move(last)) + {} + + typename std::char_traits::int_type get_character() + { + if (JSON_HEDLEY_LIKELY(current != end)) + { + // Cast to unsigned to avoid EOF and 0xFF having same value + auto result = static_cast::type>(*current); + std::advance(current, 1); + return static_cast::int_type>(result); + } + + return std::char_traits::eof(); + } + + private: + IteratorType current; + IteratorType end; + + template + friend struct wide_string_input_helper; + + bool empty() const + { + return current == end; + } +}; + +template +class iterator_input_adapter::value>> { public: using char_type = typename std::iterator_traits::value_type;