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..39c35a2e 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -21,6 +21,10 @@ template class iteration_proxy IteratorType anchor; /// an index for arrays (used to create key names) std::size_t array_index = 0; + /// a string representation of the array index + 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) {} @@ -35,7 +39,13 @@ template class iteration_proxy iteration_proxy_internal& operator++() { ++anchor; - ++array_index; + + assert(anchor.m_object != nullptr); + if (anchor.m_object->is_array()) + { + // update array index and string representation + array_index_str = std::to_string(++array_index); + } return *this; } @@ -47,7 +57,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 +65,7 @@ template class iteration_proxy { // use integer array index as key case value_t::array: - return std::to_string(array_index); + return array_index_str; // use key from the object case value_t::object: @@ -63,7 +73,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 8c9942bb..0b2e055c 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -4636,7 +4636,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); @@ -4691,6 +4691,10 @@ template class iteration_proxy IteratorType anchor; /// an index for arrays (used to create key names) std::size_t array_index = 0; + /// a string representation of the array index + 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) {} @@ -4705,7 +4709,13 @@ template class iteration_proxy iteration_proxy_internal& operator++() { ++anchor; - ++array_index; + + assert(anchor.m_object != nullptr); + if (anchor.m_object->is_array()) + { + // update array index and string representation + array_index_str = std::to_string(++array_index); + } return *this; } @@ -4717,7 +4727,7 @@ template class iteration_proxy } /// return key of the iterator - std::string key() const + const std::string& key() const { assert(anchor.m_object != nullptr); @@ -4725,7 +4735,7 @@ template class iteration_proxy { // use integer array index as key case value_t::array: - return std::to_string(array_index); + return array_index_str; // use key from the object case value_t::object: @@ -4733,7 +4743,7 @@ template class iteration_proxy // use an empty key for all primitive types default: - return ""; + return empty_str; } }