diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index 52ede17b..08108a22 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -583,7 +583,7 @@ class iter_impl @brief return the key of an object iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - typename object_t::key_type key() const + const typename object_t::key_type& key() const { assert(m_object != nullptr); diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index 7547d038..047e1855 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -21,6 +21,12 @@ template class iteration_proxy IteratorType anchor; /// an index for arrays (used to create key names) std::size_t array_index = 0; + /// 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"; + /// an empty string (to return a reference for primitive values) + const std::string empty_str = ""; public: explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {} @@ -47,7 +53,7 @@ template class iteration_proxy } /// return key of the iterator - std::string key() const + const std::string& key() const { assert(anchor.m_object != nullptr); @@ -55,7 +61,14 @@ template class iteration_proxy { // use integer array index as key case value_t::array: - return std::to_string(array_index); + { + if (array_index != array_index_last) + { + array_index_str = std::to_string(array_index); + array_index_last = array_index; + } + return array_index_str; + } // use key from the object case value_t::object: @@ -63,7 +76,7 @@ template class iteration_proxy // use an empty key for all primitive types default: - return ""; + return empty_str; } } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 6559d23d..c880f457 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -5210,7 +5210,7 @@ class iter_impl @brief return the key of an object iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - typename object_t::key_type key() const + const typename object_t::key_type& key() const { assert(m_object != nullptr); @@ -5265,6 +5265,12 @@ template class iteration_proxy IteratorType anchor; /// an index for arrays (used to create key names) std::size_t array_index = 0; + /// 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"; + /// an empty string (to return a reference for primitive values) + const std::string empty_str = ""; public: explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {} @@ -5291,7 +5297,7 @@ template class iteration_proxy } /// return key of the iterator - std::string key() const + const std::string& key() const { assert(anchor.m_object != nullptr); @@ -5299,7 +5305,14 @@ template class iteration_proxy { // use integer array index as key case value_t::array: - return std::to_string(array_index); + { + if (array_index != array_index_last) + { + array_index_str = std::to_string(array_index); + array_index_last = array_index; + } + return array_index_str; + } // use key from the object case value_t::object: @@ -5307,7 +5320,7 @@ template class iteration_proxy // use an empty key for all primitive types default: - return ""; + return empty_str; } }