recursive_iterator_layer.hpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #pragma once
  2. #include "recursive_iterator_base.hpp"
  3. #include "recursive_iterator_traits.hpp"
  4. namespace iterator { namespace detail {
  5. /**
  6. * @class recursive_iterator_layer
  7. * @brief A single layer for recursing down a nested collection. Represents
  8. * non-associative containers.
  9. *
  10. * Provides dispatch/overloading for types and functions of recursive_iterator
  11. * chains to resolve ambiguous typedefs and operators.
  12. *
  13. * @see recursive_iterator_impl
  14. * @see bounded_recursive_iterator_impl
  15. * @tparam Iterator The underlying iterator type of the layer
  16. * @tparam RecursiveIterator_NextLayer The next layer, either a
  17. * recursive_iterator_impl, or a bounded_recursive_iterator_impl
  18. */
  19. template <typename Iterator, typename RecursiveIterator_NextLayer>
  20. class recursive_iterator_layer : public recursive_iterator_base<Iterator>,
  21. public RecursiveIterator_NextLayer {
  22. public:
  23. using super = RecursiveIterator_NextLayer;
  24. using layer = recursive_iterator_base<Iterator>;
  25. protected:
  26. using recursive_category = continue_layer_tag_t;
  27. public:
  28. using reference = decltype(*std::declval<super>());
  29. using value_type = std::remove_cv_t<std::remove_reference_t<reference>>;
  30. using pointer = decltype(std::declval<super>().operator->());
  31. using difference_type = std::ptrdiff_t;
  32. using iterator_category = std::forward_iterator_tag;
  33. public:
  34. recursive_iterator_layer() = default;
  35. explicit recursive_iterator_layer(layer v) : recursive_iterator_layer() {
  36. assign(v);
  37. update();
  38. }
  39. template <typename OIter, typename Rec>
  40. recursive_iterator_layer(recursive_iterator_layer<OIter, Rec> const & other)
  41. : layer(static_cast<recursive_iterator_base<OIter> const &>(other)),
  42. super(static_cast<Rec const &>(other)) {}
  43. decltype(auto) operator*() const { return super::get(); }
  44. decltype(auto) operator->() const { return super::operator->(); }
  45. bool operator==(recursive_iterator_layer const & other) const {
  46. return (static_cast<layer const &>(*this) == other) &&
  47. (static_cast<super const &>(*this) == other);
  48. }
  49. protected:
  50. decltype(auto) get() const { return operator*(); }
  51. /**
  52. * Advance the iterator step. If the next layer has reached the end, then
  53. * we advance this iterator until it reaches either its own end, or a
  54. * non-empty subcollection to start iterating over.
  55. */
  56. void next() {
  57. super::next();
  58. update();
  59. }
  60. /**
  61. * Update the underlying iterator and propogate updates down the chain so
  62. * that if there is data available, the iterator is in a dereferencable
  63. * state.
  64. */
  65. void assign(layer v) {
  66. static_cast<layer &>(*this) = v;
  67. if (!v.at_end()) { super::assign(make_end_aware_iterator(*v)); }
  68. }
  69. void update() {
  70. layer & self = static_cast<layer &>(*this);
  71. while (super::at_end() && !(++self).at_end()) {
  72. super::assign(make_end_aware_iterator(*self));
  73. }
  74. }
  75. using layer::at_end;
  76. };
  77. }}