Quellcode durchsuchen

Deduplicate impl.

Sam Jaffe vor 4 Jahren
Ursprung
Commit
d2d840be26
2 geänderte Dateien mit 41 neuen und 103 gelöschten Zeilen
  1. 38 100
      include/iterator/recursive/impl.hpp
  2. 3 3
      include/iterator/recursive_iterator.hpp

+ 38 - 100
include/iterator/recursive/impl.hpp

@@ -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;
   };
 }

+ 3 - 3
include/iterator/recursive_iterator.hpp

@@ -75,10 +75,10 @@ namespace iterator {
    *
    * @tparam N The maximum depth to recurse into the object
    */
-  template <typename Iterator, std::size_t N>
-  class recursive_iterator_n : public recursive::bounded_impl<Iterator, 1, N> {
+  template <typename It, std::size_t N>
+  class recursive_iterator_n : public recursive::bounded_impl<It, N> {
   public:
-    using super = recursive::bounded_impl<Iterator, 1, N>;
+    using super = recursive::bounded_impl<It, N>;
     using reference = decltype(*std::declval<super>());
     using value_type = std::remove_cv_t<std::remove_reference_t<reference>>;
     using pointer = decltype(std::declval<super>().operator->());