diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index da2e32b42e..8c54746f6b 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -12,6 +12,11 @@ namespace nlohmann { namespace detail { +template +void int_to_string( string_type& target, int value ) +{ + target = std::to_string(value); +} template class iteration_proxy_value { public: @@ -20,6 +25,7 @@ template class iteration_proxy_value using pointer = value_type * ; using reference = value_type & ; using iterator_category = std::input_iterator_tag; + using string_type = typename std::remove_cv< typename std::remove_reference().key() ) >::type >::type; private: /// the iterator @@ -29,9 +35,9 @@ template class iteration_proxy_value /// last stringified array index mutable std::size_t array_index_last = 0; /// a string representation of the array index - mutable std::string array_index_str = "0"; + mutable string_type array_index_str = "0"; /// an empty string (to return a reference for primitive values) - const std::string empty_str = ""; + const string_type empty_str = ""; public: explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {} @@ -64,7 +70,7 @@ template class iteration_proxy_value } /// return key of the iterator - const std::string& key() const + const string_type& key() const { assert(anchor.m_object != nullptr); @@ -75,7 +81,7 @@ template class iteration_proxy_value { if (array_index != array_index_last) { - array_index_str = std::to_string(array_index); + int_to_string( array_index_str, array_index ); array_index_last = array_index; } return array_index_str; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index f7aedd1028..c51f4f8bf1 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3186,6 +3186,11 @@ namespace nlohmann { namespace detail { +template +void int_to_string( string_type& target, int value ) +{ + target = std::to_string(value); +} template class iteration_proxy_value { public: @@ -3194,6 +3199,7 @@ template class iteration_proxy_value using pointer = value_type * ; using reference = value_type & ; using iterator_category = std::input_iterator_tag; + using string_type = typename std::remove_cv< typename std::remove_reference().key() ) >::type >::type; private: /// the iterator @@ -3203,9 +3209,9 @@ template class iteration_proxy_value /// last stringified array index mutable std::size_t array_index_last = 0; /// a string representation of the array index - mutable std::string array_index_str = "0"; + mutable string_type array_index_str = "0"; /// an empty string (to return a reference for primitive values) - const std::string empty_str = ""; + const string_type empty_str = ""; public: explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {} @@ -3238,7 +3244,7 @@ template class iteration_proxy_value } /// return key of the iterator - const std::string& key() const + const string_type& key() const { assert(anchor.m_object != nullptr); @@ -3249,7 +3255,7 @@ template class iteration_proxy_value { if (array_index != array_index_last) { - array_index_str = std::to_string(array_index); + int_to_string( array_index_str, array_index ); array_index_last = array_index; } return array_index_str; diff --git a/test/src/unit-alt-string.cpp b/test/src/unit-alt-string.cpp index 6a9e36a3a2..57ddc83a3d 100644 --- a/test/src/unit-alt-string.cpp +++ b/test/src/unit-alt-string.cpp @@ -154,6 +154,11 @@ class alt_string friend bool ::operator<(const char*, const alt_string&); }; +void int_to_string( alt_string& target, int value ) +{ + target = std::to_string(value).c_str(); +} + using alt_json = nlohmann::basic_json < std::map, std::vector, @@ -232,6 +237,35 @@ TEST_CASE("alternative string type") CHECK(dump == R"({"foo":"bar"})"); } + SECTION("items") + { + auto doc = alt_json::parse("{\"foo\": \"bar\"}"); + + for ( auto item : doc.items() ) + { + CHECK( item.key() == "foo" ); + CHECK( item.value() == "bar" ); + } + + auto doc_array = alt_json::parse("[\"foo\", \"bar\"]"); + + for ( auto item : doc_array.items() ) + { + if (item.key() == "0" ) + { + CHECK( item.value() == "foo" ); + } + else if (item.key() == "1" ) + { + CHECK( item.value() == "bar" ); + } + else + { + CHECK( false ); + } + } + } + SECTION("equality") { alt_json doc;