object_iterator.h 2.0 KB

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