#pragma once #include // size_t #include // string, to_string #include "detail/value_t.hpp" namespace nlohmann { namespace detail { /// proxy class for the iterator_wrapper functions template class iteration_proxy { private: /// helper class for iteration class iteration_proxy_internal { private: /// the iterator IteratorType anchor; /// an index for arrays (used to create key names) std::size_t array_index = 0; public: explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {} /// dereference operator (needed for range-based for) iteration_proxy_internal& operator*() { return *this; } /// increment operator (needed for range-based for) iteration_proxy_internal& operator++() { ++anchor; ++array_index; return *this; } /// inequality operator (needed for range-based for) bool operator!=(const iteration_proxy_internal& o) const noexcept { return anchor != o.anchor; } /// return key of the iterator std::string key() const { assert(anchor.m_object != nullptr); switch (anchor.m_object->type()) { // use integer array index as key case value_t::array: return std::to_string(array_index); // use key from the object case value_t::object: return anchor.key(); // use an empty key for all primitive types default: return ""; } } /// return value of the iterator typename IteratorType::reference value() const { return anchor.value(); } }; /// the container to iterate typename IteratorType::reference container; public: /// construct iteration proxy from a container explicit iteration_proxy(typename IteratorType::reference cont) : container(cont) {} /// return iterator begin (needed for range-based for) iteration_proxy_internal begin() noexcept { return iteration_proxy_internal(container.begin()); } /// return iterator end (needed for range-based for) iteration_proxy_internal end() noexcept { return iteration_proxy_internal(container.end()); } }; } }