|
|
@@ -13,16 +13,30 @@
|
|
|
#include "traits.hpp"
|
|
|
|
|
|
namespace iterator::recursive {
|
|
|
- template <typename Iterator, typeclass = typeclass_t<Iterator>::value>
|
|
|
+ template <size_t N, size_t I = 1> struct bounded {
|
|
|
+ template <typename It>
|
|
|
+ static constexpr typeclass const value =
|
|
|
+ I == N ? typeclass::TERMINAL : typeclass_t<It>::value;
|
|
|
+ using next = std::conditional_t<I == N, void, bounded<N, I + 1>>;
|
|
|
+ };
|
|
|
+
|
|
|
+ struct unbounded {
|
|
|
+ template <typename It>
|
|
|
+ static constexpr typeclass const value = typeclass_t<It>::value;
|
|
|
+ using next = unbounded;
|
|
|
+ };
|
|
|
+
|
|
|
+ template <typename Iterator, typename Bound = unbounded,
|
|
|
+ typeclass = Bound::template value<Iterator>>
|
|
|
class impl;
|
|
|
|
|
|
- /**
|
|
|
- * A bounded_impl where N == Max is always a terminal node.
|
|
|
- */
|
|
|
- template <typename Iterator, std::size_t N, std::size_t Max,
|
|
|
- typeclass = std::conditional_t<N == Max, typeclass_t<void>,
|
|
|
- typeclass_t<Iterator>>::value>
|
|
|
- class bounded_impl;
|
|
|
+ template <typename Iterator, size_t N>
|
|
|
+ using bounded_impl = impl<Iterator, bounded<N>>;
|
|
|
+
|
|
|
+ template <typename It, typename Bnd>
|
|
|
+ using value_impl = impl<value<It>, typename Bnd::next>;
|
|
|
+ template <typename It, typename Bnd>
|
|
|
+ using mapped_impl = impl<mapped<It>, typename Bnd::next>;
|
|
|
|
|
|
/**
|
|
|
* @class impl
|
|
|
@@ -30,17 +44,16 @@ namespace iterator::recursive {
|
|
|
* iterator.
|
|
|
*
|
|
|
* @see base
|
|
|
- * @tparam Iterator The iterator type being processed, such as
|
|
|
+ * @tparam It The iterator type being processed, such as
|
|
|
* std::vector<int>::iterator
|
|
|
*/
|
|
|
- template <typename Iterator>
|
|
|
- class impl<Iterator, typeclass::TERMINAL> : public base<Iterator> {
|
|
|
+ template <typename It, typename Bound>
|
|
|
+ class impl<It, Bound, typeclass::TERMINAL> : public base<It> {
|
|
|
public:
|
|
|
- using super = base<Iterator>;
|
|
|
+ using super = base<It>;
|
|
|
|
|
|
public:
|
|
|
using super::super;
|
|
|
- impl() = default;
|
|
|
|
|
|
protected:
|
|
|
void next() { super::operator++(); }
|
|
|
@@ -54,12 +67,11 @@ namespace iterator::recursive {
|
|
|
* non-associative container types.
|
|
|
* @see layer
|
|
|
*/
|
|
|
- template <typename Iterator>
|
|
|
- class impl<Iterator, typeclass::CONTAINER>
|
|
|
- : public layer<Iterator, impl<value<Iterator>>> {
|
|
|
+ template <typename It, typename Bound>
|
|
|
+ class impl<It, Bound, typeclass::CONTAINER>
|
|
|
+ : public layer<It, value_impl<It, Bound>> {
|
|
|
public:
|
|
|
- using next_layer = impl<value<Iterator>>;
|
|
|
- using super = layer<Iterator, next_layer>;
|
|
|
+ using super = layer<It, value_impl<It, Bound>>;
|
|
|
|
|
|
public:
|
|
|
/**
|
|
|
@@ -68,9 +80,10 @@ namespace iterator::recursive {
|
|
|
* type of the map. Works only for nested collections with one associative
|
|
|
* container at the bottom level.
|
|
|
*/
|
|
|
- decltype(auto) operator*() const { return next_layer::operator*(); }
|
|
|
+ decltype(auto) operator*() const {
|
|
|
+ return value_impl<It, Bound>::operator*();
|
|
|
+ }
|
|
|
using super::super;
|
|
|
- impl() = default;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
@@ -78,90 +91,15 @@ namespace iterator::recursive {
|
|
|
*
|
|
|
* An SFINAE specialization of bounded_impl for
|
|
|
* associative container types.
|
|
|
- * @see flatten_iterator_layer
|
|
|
- */
|
|
|
- template <typename Iterator>
|
|
|
- class impl<Iterator, typeclass::ASSOCIATIVE_CONTAINER>
|
|
|
- : public flatten_layer<Iterator, impl<mapped<Iterator>>> {
|
|
|
- public:
|
|
|
- using next_layer = impl<mapped<Iterator>>;
|
|
|
- using super = flatten_layer<Iterator, next_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<int>::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 <typename Iterator, std::size_t N, std::size_t Max>
|
|
|
- class bounded_impl<Iterator, N, Max, typeclass::TERMINAL>
|
|
|
- : public base<Iterator> {
|
|
|
- public:
|
|
|
- using super = base<Iterator>;
|
|
|
-
|
|
|
- public:
|
|
|
- using super::super;
|
|
|
- bounded_impl() = default;
|
|
|
-
|
|
|
- protected:
|
|
|
- void next() { super::operator++(); }
|
|
|
- void assign(super eat) { static_cast<super &>(*this) = eat; }
|
|
|
- };
|
|
|
-
|
|
|
- /**
|
|
|
- * @class bounded_impl
|
|
|
- *
|
|
|
- * An SFINAE specialization of bounded_impl for
|
|
|
- * non-associative container types.
|
|
|
- * @see layer
|
|
|
- */
|
|
|
- template <typename Iterator, std::size_t N, std::size_t Max>
|
|
|
- class bounded_impl<Iterator, N, Max, typeclass::CONTAINER>
|
|
|
- : public layer<Iterator, bounded_impl<value<Iterator>, N + 1, Max>> {
|
|
|
- public:
|
|
|
- using next_layer = bounded_impl<value<Iterator>, N + 1, Max>;
|
|
|
- using super = 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.
|
|
|
- */
|
|
|
- decltype(auto) operator*() const { 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
|
|
|
+ * @see flatten_layer
|
|
|
*/
|
|
|
- template <typename Iterator, std::size_t N, std::size_t Max>
|
|
|
- class bounded_impl<Iterator, N, Max, typeclass::ASSOCIATIVE_CONTAINER>
|
|
|
- : public flatten_layer<Iterator,
|
|
|
- bounded_impl<mapped<Iterator>, N + 1, Max>> {
|
|
|
+ template <typename It, typename Bound>
|
|
|
+ class impl<It, Bound, typeclass::ASSOCIATIVE_CONTAINER>
|
|
|
+ : public flatten_layer<It, mapped_impl<It, Bound>> {
|
|
|
public:
|
|
|
- using next_layer = bounded_impl<mapped<Iterator>, N + 1, Max>;
|
|
|
- using super = flatten_layer<Iterator, next_layer>;
|
|
|
+ using super = flatten_layer<It, mapped_impl<It, Bound>>;
|
|
|
|
|
|
public:
|
|
|
using super::super;
|
|
|
- bounded_impl() = default;
|
|
|
};
|
|
|
}
|