// // recursive_iterator_meta.hpp // iterator // // Created by Sam Jaffe on 2/21/17. // #pragma once namespace iterator { namespace detail { /** * @class recursive_iterator_impl * @brief The default (terminal) implementation of an unbounded recursive iterator. * * @see recursive_iterator_base * @param Iterator The iterator type being processed, such as std::vector::iterator */ template class recursive_iterator_impl : public recursive_iterator_base< Iterator > { public: using super = recursive_iterator_base< Iterator >; public: using super::super; recursive_iterator_impl() = default; template recursive_iterator_impl(in_place_t, OIter && iter) : super(std::forward(iter)) {} 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< Iterator, typename void_t>::type > : public recursive_iterator_layer< Iterator, recursive_iterator_impl< value_iterator > > { public: using next_layer = recursive_iterator_impl< value_iterator >; using super = recursive_iterator_layer< Iterator, next_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; template recursive_iterator_impl(in_place_t, Iterators && ...iter) : super(in_place, std::forward(iter)...) {} }; /** * @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< Iterator, typename void_t>::type > : public flatten_iterator_layer< Iterator, recursive_iterator_impl< mapped_iterator > > { public: using next_layer = recursive_iterator_impl< mapped_iterator >; using super = flatten_iterator_layer< Iterator, next_layer >; public: using super::super; recursive_iterator_impl() = default; template recursive_iterator_impl(in_place_t, Iterators && ...iter) : super(in_place, std::forward(iter)...) {} }; /** * @class bounded_recursive_iterator_impl * @brief The default (terminal) implementation of a recursive iterator up to Max levels deep. * * @see recursive_iterator_base * @param Iterator The iterator type being processed, such as std::vector::iterator * @param N The current layer of depth, starts at 1. * @param 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< Iterator > { public: using super = recursive_iterator_base< Iterator >; public: using super::super; bounded_recursive_iterator_impl() = default; template bounded_recursive_iterator_impl(in_place_t, OIter && iter) : super(std::forward(iter)) {} 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< Iterator, N, Max, typename std::enable_if>::type>::type > : public recursive_iterator_layer< Iterator , bounded_recursive_iterator_impl< value_iterator, N+1, Max > > { public: using next_layer = bounded_recursive_iterator_impl< value_iterator, N+1, Max >; using super = recursive_iterator_layer< Iterator, next_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; template bounded_recursive_iterator_impl(in_place_t, Iterators && ...iter) : super(in_place, std::forward(iter)...) {} }; /** * @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< Iterator, N, Max, typename std::enable_if>::type>::type > : public flatten_iterator_layer< Iterator , bounded_recursive_iterator_impl< mapped_iterator, N+1, Max > > { public: using next_layer = bounded_recursive_iterator_impl< mapped_iterator, N+1, Max >; using super = flatten_iterator_layer< Iterator, next_layer >; public: using super::super; bounded_recursive_iterator_impl() = default; template bounded_recursive_iterator_impl(in_place_t, Iterators && ...iter) : super(in_place, std::forward(iter)...) {} }; } } namespace iterator { namespace detail { template struct accessor; template struct accessor<0, end_aware_iterator> { using type = end_aware_iterator; }; template struct accessor<0, recursive_iterator_layer> { using type = end_aware_iterator; }; template struct accessor<0, flatten_iterator_layer> { using type = end_aware_iterator; }; template struct accessor<0, It> { using type = typename accessor<0, typename It::super>::type; }; template struct accessor::type> { using type = typename accessor::type; }; template struct accessor, typename std::enable_if::type> { using type = typename accessor::type; }; template struct accessor, typename std::enable_if::type> { using type = typename accessor::type; }; } }