layer.hpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #pragma once
  2. #include "base.hpp"
  3. #include "traits.hpp"
  4. namespace iterator::recursive {
  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 Next The next layer, either a
  17. * recursive_iterator_impl, or a bounded_recursive_iterator_impl
  18. */
  19. template <typename Iterator, typename Next>
  20. class layer : public base<Iterator>, public Next {
  21. protected:
  22. using recursive_category = continue_layer_tag_t;
  23. public:
  24. layer() = default;
  25. explicit layer(base<Iterator> v) : layer() {
  26. assign(v);
  27. update();
  28. }
  29. template <typename OIter, typename Rec>
  30. layer(layer<OIter, Rec> const & other)
  31. : base<Iterator>(static_cast<base<OIter> const &>(other)),
  32. Next(static_cast<Rec const &>(other)) {}
  33. decltype(auto) operator*() const { return Next::get(); }
  34. decltype(auto) operator->() const { return Next::operator->(); }
  35. bool operator==(layer const & other) const {
  36. return (static_cast<base<Iterator> const &>(*this) == other) &&
  37. (static_cast<Next const &>(*this) == other);
  38. }
  39. protected:
  40. decltype(auto) get() const { return operator*(); }
  41. /**
  42. * Advance the iterator step. If the next layer has reached the end, then
  43. * we advance this iterator until it reaches either its own end, or a
  44. * non-empty subcollection to start iterating over.
  45. */
  46. void next() {
  47. Next::next();
  48. update();
  49. }
  50. /**
  51. * Update the underlying iterator and propogate updates down the chain so
  52. * that if there is data available, the iterator is in a dereferencable
  53. * state.
  54. */
  55. void assign(base<Iterator> v) {
  56. static_cast<base<Iterator> &>(*this) = v;
  57. if (!v.at_end()) { Next::assign(make_end_aware_iterator(*v)); }
  58. }
  59. void update() {
  60. base<Iterator> & self = static_cast<base<Iterator> &>(*this);
  61. while (Next::at_end() && !(++self).at_end()) {
  62. Next::assign(make_end_aware_iterator(*self));
  63. }
  64. }
  65. using base<Iterator>::at_end;
  66. };
  67. }