| 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 reference = decltype(*std::declval<super>());
- using value_type = std::remove_cv_t<std::remove_reference_t<reference>>;
- using pointer = decltype(std::declval<super>().operator->());
- using difference_type = std::ptrdiff_t;
- using iterator_category = std::forward_iterator_tag;
- public:
- recursive_iterator_layer() = default;
- explicit 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)) {}
- decltype(auto) operator*() const { return super::get(); }
- decltype(auto) operator->() const { return super::operator->(); }
- bool operator==(recursive_iterator_layer const & other) const {
- return (static_cast<layer const &>(*this) == other) &&
- (static_cast<super 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() {
- 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.at_end()) { super::assign(make_end_aware_iterator(*v)); }
- }
- void update() {
- layer & self = static_cast<layer &>(*this);
- while (super::at_end() && !(++self).at_end()) {
- super::assign(make_end_aware_iterator(*self));
- }
- }
- using layer::at_end;
- };
- }}
|