// // recursive_iterator_meta.hpp // iterator // // Created by Sam Jaffe on 2/21/17. // #pragma once #include "flatten_iterator_layer.hpp" #include "recursive_iterator_base.hpp" #include "recursive_iterator_layer.hpp" #include "recursive_iterator_traits.hpp" namespace iterator { namespace detail { template ::value> class recursive_iterator_impl; /** * A bounded_recursive_iterator_impl where N == Max is always a terminal node. */ template , typeclass_t>::value> class bounded_recursive_iterator_impl; /** * @class recursive_iterator_impl * @brief The default (terminal) implementation of an unbounded recursive * iterator. * * @see recursive_iterator_base * @tparam Iterator The iterator type being processed, such as * std::vector::iterator */ template class recursive_iterator_impl : public recursive_iterator_base { public: using super = recursive_iterator_base; public: using super::super; recursive_iterator_impl() = default; protected: void next() { super::operator++(); } void assign(super eat) { static_cast(*this) = eat; } }; /** * @class recursive_iterator_impl * * An SFINAE specialization of bounded_recursive_iterator_impl for * non-associative container types. * @see recursive_iterator_layer */ template class recursive_iterator_impl : public recursive_iterator_layer< Iterator, recursive_iterator_impl>> { public: using next_layer = recursive_iterator_impl>; using super = recursive_iterator_layer; public: /** * A special override of operator* that allows collections like * std::vector>> still use the value/reference * type of the map. Works only for nested collections with one associative * container at the bottom level. */ auto operator*() const -> decltype(*(next_layer &)(*this)) { return next_layer::operator*(); } using super::super; recursive_iterator_impl() = default; }; /** * @class recursive_iterator_impl * * An SFINAE specialization of bounded_recursive_iterator_impl for * associative container types. * @see flatten_iterator_layer */ template class recursive_iterator_impl : public flatten_iterator_layer< Iterator, recursive_iterator_impl>> { public: using next_layer = recursive_iterator_impl>; using super = flatten_iterator_layer; public: using super::super; recursive_iterator_impl() = default; }; /** * @class bounded_recursive_iterator_impl * @brief The default (terminal) implementation of a recursive iterator up to * Max levels deep. * * @see recursive_iterator_base * @tparam Iterator The iterator type being processed, such as * std::vector::iterator * @tparam N The current layer of depth, starts at 1. * @tparam Max The maximum recursive depth to dive down, in case you need to * process some sub-collection in a specific manner. */ template class bounded_recursive_iterator_impl : public recursive_iterator_base { public: using super = recursive_iterator_base; public: using super::super; bounded_recursive_iterator_impl() = default; protected: void next() { super::operator++(); } void assign(super eat) { static_cast(*this) = eat; } }; /** * @class bounded_recursive_iterator_impl * * An SFINAE specialization of bounded_recursive_iterator_impl for * non-associative container types. * @see recursive_iterator_layer */ template class bounded_recursive_iterator_impl : public recursive_iterator_layer< Iterator, bounded_recursive_iterator_impl, N + 1, Max>> { public: using next_layer = bounded_recursive_iterator_impl, N + 1, Max>; using super = recursive_iterator_layer; public: /** * A special override of operator* that allows collections like * std::vector>> still use the value/reference * type of the map. Works only for nested collections with one associative * container at the bottom/Max level. */ auto operator*() const -> decltype(*(next_layer &)(*this)) { return next_layer::operator*(); } using super::super; bounded_recursive_iterator_impl() = default; }; /** * @class bounded_recursive_iterator_impl * * An SFINAE specialization of bounded_recursive_iterator_impl for * associative container types. * @see flatten_iterator_layer */ template class bounded_recursive_iterator_impl : public flatten_iterator_layer< Iterator, bounded_recursive_iterator_impl, N + 1, Max>> { public: using next_layer = bounded_recursive_iterator_impl, N + 1, Max>; using super = flatten_iterator_layer; public: using super::super; bounded_recursive_iterator_impl() = default; }; }}