// // impl.hpp // iterator // // Created by Sam Jaffe on 2/21/17. // #pragma once #include "base.hpp" #include "flatten_layer.hpp" #include "layer.hpp" #include "traits.hpp" namespace iterator::recursive { template ::value> class impl; /** * A bounded_impl where N == Max is always a terminal node. */ template , typeclass_t>::value> class bounded_impl; /** * @class impl * @brief The default (terminal) implementation of an unbounded recursive * iterator. * * @see base * @tparam Iterator The iterator type being processed, such as * std::vector::iterator */ template class impl : public base { public: using super = base; public: using super::super; impl() = default; protected: void next() { super::operator++(); } void assign(super eat) { static_cast(*this) = eat; } }; /** * @class impl * * An SFINAE specialization of bounded_impl for * non-associative container types. * @see layer */ template class impl : public layer>> { public: using next_layer = impl>; using super = 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; impl() = default; }; /** * @class impl * * An SFINAE specialization of bounded_impl for * associative container types. * @see flatten_iterator_layer */ template class impl : public flatten_layer>> { public: using next_layer = impl>; using super = flatten_layer; public: using super::super; impl() = default; }; /** * @class bounded_impl * @brief The default (terminal) implementation of a recursive iterator up to * Max levels deep. * * @see 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_impl : public base { public: using super = base; public: using super::super; bounded_impl() = default; protected: void next() { super::operator++(); } void assign(super eat) { static_cast(*this) = eat; } }; /** * @class bounded_impl * * An SFINAE specialization of bounded_impl for * non-associative container types. * @see layer */ template class bounded_impl : public layer, N + 1, Max>> { public: using next_layer = bounded_impl, N + 1, Max>; using super = 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_impl() = default; }; /** * @class bounded_impl * * An SFINAE specialization of bounded_impl for * associative container types. * @see flatten_iterator_layer */ template class bounded_impl : public flatten_layer, N + 1, Max>> { public: using next_layer = bounded_impl, N + 1, Max>; using super = flatten_layer; public: using super::super; bounded_impl() = default; }; }