object_iterator.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #pragma once
  2. #include <cstddef>
  3. #include <iterator>
  4. #include <string>
  5. #include <utility>
  6. #include <jvalidate/detail/deref_proxy.h>
  7. namespace jvalidate::adapter::detail {
  8. /**
  9. * @brief An iterator for binding JSON values of type Object - which are
  10. * congruent to a map<string, JSON>.
  11. *
  12. * Conventionally - many JSON libraries use the same iterator object to
  13. * represent both Array iteration and Object iteration, either by returning
  14. * the Array index as a string-key, or by providing a special method e.g.
  15. * `key()` which accesses the Object key, while dereferencing the iterator
  16. * always returns the pointed-to JSON, regardless of Array/Object-ness.
  17. *
  18. * @tparam It The underlying iterator type being operated on
  19. * @tparam Adapter The owning adapter type, must fulfill the following
  20. * contracts:
  21. * - is constructible from the value_type of It
  22. * - has a static method key() which extracts the Object key from an It
  23. * Additionally, Adapter is expected to conform to the jvalidate::Adapter
  24. * concept.
  25. */
  26. template <typename It, typename Adapter> class JsonObjectIterator : public It {
  27. public:
  28. using value_type = std::pair<std::string, Adapter>;
  29. // Cannot return key by reference - because we don't know for certain
  30. // that the key-extraction function on It will return a string by reference
  31. // (such as if they do not store a default empty key).
  32. using reference = std::pair<std::string, Adapter>;
  33. using pointer = ::jvalidate::detail::DerefProxy<reference>;
  34. using difference_type = ptrdiff_t;
  35. using iterator_category = std::forward_iterator_tag;
  36. JsonObjectIterator() = default; // Sentinel for handling null objects
  37. explicit(false) JsonObjectIterator(It const & it) : It(it) {}
  38. reference operator*() const { return {Adapter::key(*this), Adapter(It::operator->())}; }
  39. pointer operator->() const { return {operator*()}; }
  40. JsonObjectIterator operator++(int) {
  41. auto tmp = *this;
  42. ++*this;
  43. return tmp;
  44. }
  45. JsonObjectIterator & operator++() {
  46. It::operator++();
  47. return *this;
  48. }
  49. };
  50. }