From 0f073e26eb62df4743b8da03679ed8e43cc95583 Mon Sep 17 00:00:00 2001 From: Julien Hamaide Date: Thu, 26 Sep 2019 13:13:01 +0200 Subject: [PATCH 1/2] Allow items() to be used with custom string --- .../detail/iterators/iteration_proxy.hpp | 13 ++++--- single_include/nlohmann/json.hpp | 13 ++++--- test/src/unit-alt-string.cpp | 34 +++++++++++++++++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index da2e32b4..30c5e0c5 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -12,6 +12,10 @@ namespace nlohmann { namespace detail { +void int_to_string( std::string& target, int value ) +{ + target = std::to_string(value); +} template class iteration_proxy_value { public: @@ -20,6 +24,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 +34,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 +69,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 +80,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 d27940b8..9b4df8a1 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3186,6 +3186,10 @@ namespace nlohmann { namespace detail { +void int_to_string( std::string& target, int value ) +{ + target = std::to_string(value); +} template class iteration_proxy_value { public: @@ -3194,6 +3198,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 +3208,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 +3243,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 +3254,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 6a9e36a3..57ddc83a 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; From 4615f5a980af447b372b953df7632818cd4fd44e Mon Sep 17 00:00:00 2001 From: Julien Hamaide Date: Tue, 1 Oct 2019 10:34:21 +0200 Subject: [PATCH 2/2] Provide default implementation for int_to_string, but allow for overloaded function --- include/nlohmann/detail/iterators/iteration_proxy.hpp | 3 ++- single_include/nlohmann/json.hpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index 30c5e0c5..8c54746f 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -12,7 +12,8 @@ namespace nlohmann { namespace detail { -void int_to_string( std::string& target, int value ) +template +void int_to_string( string_type& target, int value ) { target = std::to_string(value); } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 9b4df8a1..84fa6882 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3186,7 +3186,8 @@ namespace nlohmann { namespace detail { -void int_to_string( std::string& target, int value ) +template +void int_to_string( string_type& target, int value ) { target = std::to_string(value); }