| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- //
- // 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<int>::iterator
- */
- template <typename Iterator, typename = void>
- 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 <typename OIter>
- recursive_iterator_impl(in_place_t, OIter && iter)
- : super(std::forward<OIter>(iter)) {}
- protected:
- void next() { super::operator++(); }
- void assign(super eat) { static_cast<super &>(*this) = eat; }
- };
- /**
- * @class recursive_iterator_impl
- *
- * An SFINAE specialization of bounded_recursive_iterator_impl for
- * non-associative container types.
- * @see recursive_iterator_layer
- */
- template <typename Iterator>
- class recursive_iterator_impl<Iterator,
- typename void_t<value_iterator<Iterator>>::type>
- : public recursive_iterator_layer<
- Iterator, recursive_iterator_impl<value_iterator<Iterator>>> {
- public:
- using next_layer = recursive_iterator_impl<value_iterator<Iterator>>;
- using super = recursive_iterator_layer<Iterator, next_layer>;
- public:
- /**
- * A special override of operator* that allows collections like
- * std::vector<std::vector<std::map<K, V>>> 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 <typename... Iterators>
- recursive_iterator_impl(in_place_t, Iterators &&... iter)
- : super(in_place, std::forward<Iterators>(iter)...) {}
- };
- /**
- * @class recursive_iterator_impl
- *
- * An SFINAE specialization of bounded_recursive_iterator_impl for
- * associative container types.
- * @see flatten_iterator_layer
- */
- template <typename Iterator>
- class recursive_iterator_impl<
- Iterator, typename void_t<mapped_iterator<Iterator>>::type>
- : public flatten_iterator_layer<
- Iterator, recursive_iterator_impl<mapped_iterator<Iterator>>> {
- public:
- using next_layer = recursive_iterator_impl<mapped_iterator<Iterator>>;
- using super = flatten_iterator_layer<Iterator, next_layer>;
- public:
- using super::super;
- recursive_iterator_impl() = default;
- template <typename... Iterators>
- recursive_iterator_impl(in_place_t, Iterators &&... iter)
- : super(in_place, std::forward<Iterators>(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<int>::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 <typename Iterator, std::size_t N, std::size_t Max, typename = void>
- 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 <typename OIter>
- bounded_recursive_iterator_impl(in_place_t, OIter && iter)
- : super(std::forward<OIter>(iter)) {}
- protected:
- void next() { super::operator++(); }
- void assign(super eat) { static_cast<super &>(*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 <typename Iterator, std::size_t N, std::size_t Max>
- class bounded_recursive_iterator_impl < Iterator,
- N, Max,
- typename std::enable_if<
- N<Max, typename void_t<value_iterator<Iterator>>::type>::type>
- : public recursive_iterator_layer<
- Iterator, bounded_recursive_iterator_impl<value_iterator<Iterator>,
- N + 1, Max>> {
- public:
- using next_layer =
- bounded_recursive_iterator_impl<value_iterator<Iterator>, N + 1, Max>;
- using super = recursive_iterator_layer<Iterator, next_layer>;
- public:
- /**
- * A special override of operator* that allows collections like
- * std::vector<std::vector<std::map<K, V>>> 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 <typename... Iterators>
- bounded_recursive_iterator_impl(in_place_t, Iterators &&... iter)
- : super(in_place, std::forward<Iterators>(iter)...) {}
- };
- /**
- * @class bounded_recursive_iterator_impl
- *
- * An SFINAE specialization of bounded_recursive_iterator_impl for
- * associative container types.
- * @see flatten_iterator_layer
- */
- template <typename Iterator, std::size_t N, std::size_t Max>
- class bounded_recursive_iterator_impl < Iterator,
- N, Max,
- typename std::enable_if<
- N<Max, typename void_t<mapped_iterator<Iterator>>::type>::type>
- : public flatten_iterator_layer<
- Iterator, bounded_recursive_iterator_impl<mapped_iterator<Iterator>,
- N + 1, Max>> {
- public:
- using next_layer =
- bounded_recursive_iterator_impl<mapped_iterator<Iterator>, N + 1, Max>;
- using super = flatten_iterator_layer<Iterator, next_layer>;
- public:
- using super::super;
- bounded_recursive_iterator_impl() = default;
- template <typename... Iterators>
- bounded_recursive_iterator_impl(in_place_t, Iterators &&... iter)
- : super(in_place, std::forward<Iterators>(iter)...) {}
- };
- }}
- namespace iterator { namespace detail {
- template <std::size_t I, typename It, typename = void> struct accessor;
- template <typename It> struct accessor<0, end_aware_iterator<It>> {
- using type = end_aware_iterator<It>;
- };
- template <typename It, typename Rec>
- struct accessor<0, recursive_iterator_layer<It, Rec>> {
- using type = end_aware_iterator<It>;
- };
- template <typename It, typename Rec>
- struct accessor<0, flatten_iterator_layer<It, Rec>> {
- using type = end_aware_iterator<It>;
- };
- template <typename It> struct accessor<0, It> {
- using type = typename accessor<0, typename It::super>::type;
- };
- template <std::size_t I, typename It>
- struct accessor<I, It, typename std::enable_if<I != 0>::type> {
- using type = typename accessor<I, typename It::super>::type;
- };
- template <std::size_t I, typename It, typename Rec>
- struct accessor<I, recursive_iterator_layer<It, Rec>,
- typename std::enable_if<I != 0>::type> {
- using type = typename accessor<I - 1, Rec>::type;
- };
- template <std::size_t I, typename It, typename Rec>
- struct accessor<I, flatten_iterator_layer<It, Rec>,
- typename std::enable_if<I != 0>::type> {
- using type = typename accessor<I - 1, Rec>::type;
- };
- }}
|