#pragma once #include #include #include namespace jvalidate::adapter::detail { /** * @brief An iterator for binding JSON values of type Object - which are * congruent to a map. * * Conventionally - many JSON libraries use the same iterator object to * represent both Array iteration and Object iteration, either by returning * the Array index as a string-key, or by providing a special method e.g. * `key()` which accesses the Object key, while dereferencing the iterator * always returns the pointed-to JSON, regardless of Array/Object-ness. * * @tparam It The underlying iterator type being operated on * @tparam Adapter The owning adapter type, must fulfill the following * contracts: * - is constructible from the value_type of It * - has a static method key() which extracts the Object key from an It * Additionally, Adapter is expected to conform to the jvalidate::Adapter * concept. */ template class JsonObjectIterator : public It { public: using value_type = std::pair; // Cannot return key by reference - because we don't know for certain // that the key-extraction function on It will return a string by reference // (such as if they do not store a default empty key). using reference = std::pair; using pointer = ::jvalidate::detail::DerefProxy; using difference_type = std::ptrdiff_t; using iterator_category = std::forward_iterator_tag; JsonObjectIterator() = default; // Sentinel for handling null objects JsonObjectIterator(It it) : It(it) {} reference operator*() const { return { Adapter::key(*this), Adapter(It::operator->()) }; } pointer operator->() const { return {operator*()}; } JsonObjectIterator operator++(int) { auto tmp = *this; ++*this; return tmp; } JsonObjectIterator & operator++() { It::operator++(); return *this; } }; }