Bläddra i källkod

Use if constexpr for recursive_iterator_base handling to improve readability.

Sam Jaffe 4 år sedan
förälder
incheckning
6c2da45660
1 ändrade filer med 13 tillägg och 51 borttagningar
  1. 13 51
      include/iterator/detail/recursive_iterator_base.hpp

+ 13 - 51
include/iterator/detail/recursive_iterator_base.hpp

@@ -3,72 +3,34 @@
 #include "../end_aware_iterator.hpp"
 #include "recursive_iterator_traits.hpp"
 
-namespace iterator { namespace detail {
-
-  template <typename Iterator, typename = void> class recursive_iterator_base;
-
+namespace iterator::detail {
   /**
    * @class recursive_iterator_base
    * @brief A thin wrapper around end_aware_iterator for the purposes of
    * template metaprogramming.
    */
-  template <typename Iterator, typename>
-  class recursive_iterator_base : public end_aware_iterator<Iterator> {
-  public:
-    using super = end_aware_iterator<Iterator>;
-
-  protected:
-    using recursive_category = terminal_layer_tag_t;
-
-  public:
-    using super::super;
-    recursive_iterator_base(super const & iter) : super(iter) {}
-    recursive_iterator_base(super && iter) : super(std::move(iter)) {}
-    recursive_iterator_base() = default;
-
-  protected:
-    decltype(auto) get() const { return super::operator*(); }
-  };
-
-  /**
-   * @class recursive_iterator_base
-   * @brief An SFINAE specialization of recursive_iterator_base for associative
-   * containers
-   *
-   * Because it is possible for recursive iterator to step over multiple layers
-   * of associative containers, the return type is made into a tuple, so that
-   * the caller does not need to write something like
-   * `it->second.second.second'. Instead, the return type is a tuple of
-   * references, so that the caller can write code like `std::get<3>(*it)'.
-   *
-   * For example, the ref type for std::map<int, std::map<float, double> >
-   * with this would be std::tuple<int const&, float const&, double &>.
-   */
   template <typename Iterator>
-  class recursive_iterator_base<Iterator, is_associative_t<Iterator>>
-      : public end_aware_iterator<Iterator> {
+  class recursive_iterator_base : public end_aware_iterator<Iterator> {
   public:
     using super = end_aware_iterator<Iterator>;
-    using first_type = decltype((std::declval<Iterator>()->first));
-    using second_type = decltype((std::declval<Iterator>()->second));
 
   protected:
-    using recursive_category = continue_layer_tag_t;
+    using recursive_category =
+        std::conditional_t<detail::is_associative<Iterator>{},
+                           continue_layer_tag_t, terminal_layer_tag_t>;
 
   public:
     using super::super;
     recursive_iterator_base(super const & iter) : super(iter) {}
     recursive_iterator_base(super && iter) : super(std::move(iter)) {}
-    recursive_iterator_base() = default;
 
   protected:
-    /**
-     * An alternative function to operator*(), which allows single layer
-     * recursive iterators (on associative containers) to return the
-     * underlying value/reference type, and nested containers to propogate
-     * a tuple or a pair as necessary.
-     */
-    auto get() const { return std::tie((**this).first, (**this).second); }
+    decltype(auto) get() const {
+      if constexpr (detail::is_associative<Iterator>{}) {
+        return std::tie((**this).first, (**this).second);
+      } else {
+        return **this;
+      }
+    }
   };
-
-}}
+}