| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- #pragma once
- #include "recursive_iterator_base.hpp"
- #include "recursive_iterator_traits.hpp"
- namespace iterator { namespace detail {
- /**
- * @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 RecursiveIterator_NextLayer The next layer, either a
- * recursive_iterator_impl, or a bounded_recursive_iterator_impl
- */
- template <typename Iterator, typename RecursiveIterator_NextLayer>
- class recursive_iterator_layer : public recursive_iterator_base<Iterator>,
- public RecursiveIterator_NextLayer {
- public:
- using super = RecursiveIterator_NextLayer;
- using layer = recursive_iterator_base<Iterator>;
- protected:
- using recursive_category = continue_layer_tag_t;
- public:
- using value_type = typename super::value_type;
- using reference = typename super::reference;
- using pointer = typename super::pointer;
- using difference_type = typename super::difference_type;
- using iterator_category = std::forward_iterator_tag;
- public:
- recursive_iterator_layer() = default;
- recursive_iterator_layer(layer v) : recursive_iterator_layer() {
- assign(v);
- update();
- }
- template <typename OIter, typename Rec>
- recursive_iterator_layer(recursive_iterator_layer<OIter, Rec> const & other)
- : layer(static_cast<recursive_iterator_base<OIter> const &>(other)),
- super(static_cast<Rec const &>(other)) {}
- reference operator*() const { return super::get(); }
- pointer operator->() const { return super::operator->(); }
- bool operator==(recursive_iterator_layer const & other) const {
- return layer::operator==(other) && super::operator==(other);
- }
- protected:
- reference 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() {
- super::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(layer v) {
- static_cast<layer &>(*this) = v;
- if (!v.done()) { super::assign(make_end_aware_iterator(*v)); }
- }
- void update() {
- layer & self = static_cast<layer &>(*this);
- while (super::done() && !(++self).done()) {
- super::assign(make_end_aware_iterator(*self));
- }
- }
- bool done() const { return layer::done(); }
- };
- }}
|