| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- #pragma once
- #include "base.hpp"
- #include "traits.hpp"
- namespace iterator::recursive {
- /**
- * @class recursive_iterator_layer
- * @brief A single layer for recursing down a nested collection. Represents
- * non-associative containers.
- *
- * Provides dispatch/overloading for types and functions of recursive_iterator
- * chains to resolve ambiguous typedefs and operators.
- *
- * @see recursive_iterator_impl
- * @see bounded_recursive_iterator_impl
- * @tparam Iterator The underlying iterator type of the layer
- * @tparam Next The next layer, either a
- * recursive_iterator_impl, or a bounded_recursive_iterator_impl
- */
- template <typename Iterator, typename Next>
- class layer : public base<Iterator>, public Next {
- protected:
- using recursive_category = continue_layer_tag_t;
- public:
- layer() = default;
- explicit layer(base<Iterator> v) : layer() {
- assign(v);
- update();
- }
- template <typename OIter, typename Rec>
- layer(layer<OIter, Rec> const & other)
- : base<Iterator>(static_cast<base<OIter> const &>(other)),
- Next(static_cast<Rec const &>(other)) {}
- decltype(auto) operator*() const { return Next::get(); }
- decltype(auto) operator->() const { return Next::operator->(); }
- bool operator==(layer const & other) const {
- return (static_cast<base<Iterator> const &>(*this) == other) &&
- (static_cast<Next const &>(*this) == other);
- }
- protected:
- decltype(auto) get() const { return operator*(); }
- /**
- * Advance the iterator step. If the next layer has reached the end, then
- * we advance this iterator until it reaches either its own end, or a
- * non-empty subcollection to start iterating over.
- */
- void next() {
- Next::next();
- update();
- }
- /**
- * Update the underlying iterator and propogate updates down the chain so
- * that if there is data available, the iterator is in a dereferencable
- * state.
- */
- void assign(base<Iterator> v) {
- static_cast<base<Iterator> &>(*this) = v;
- if (!v.at_end()) { Next::assign(make_end_aware_iterator(*v)); }
- }
- void update() {
- base<Iterator> & self = static_cast<base<Iterator> &>(*this);
- while (Next::at_end() && !(++self).at_end()) {
- Next::assign(make_end_aware_iterator(*self));
- }
- }
- using base<Iterator>::at_end;
- };
- }
|