Browse Source

Two changes to recursive_iterator:
1) Remove redundant recursive_iterator_terminal<T> class
2) Allow recursive_iterator on std::map<K, V> return the actual underlying pair object, instead of wrapping it in a tuple. This change does not extend the behavior so that std::vector<std::map<K, V>> supports this feature.

Samuel Jaffe 9 years ago
parent
commit
98cf896534
2 changed files with 24 additions and 42 deletions
  1. 22 40
      recursive_iterator.hpp
  2. 2 2
      recursive_iterator_nested_map.t.h

+ 22 - 40
recursive_iterator.hpp

@@ -22,6 +22,8 @@ namespace iterator {
       using recursive_category = terminal_layer_tag_t;
     public:
       using super::super;
+    protected:
+      typename super::reference get() { return super::operator*(); }
     };
     
     template <typename Iterator>
@@ -36,39 +38,12 @@ namespace iterator {
       using value_type = std::tuple<first_type, second_type>;
       using reference = std::tuple<first_type &, second_type &>;
     public:
-      reference operator*() {
-        auto & pair = super::operator*();
-        return std::tie(pair.first, pair.second);
-      }
-      
       using super::super;
-    };
-    
-    template <typename Iterator, typename = void>
-    class recursive_iterator_terminal : public recursive_iterator_base< Iterator > {
-    private:
-      using layer = recursive_iterator_base< Iterator >;
-    public:
-      recursive_iterator_terminal() = default;
-      recursive_iterator_terminal(layer v) : layer(v) {}
-      
-      typename layer::reference operator*() {
-        return layer::operator*();
-      }
-      
-      typename layer::pointer operator->() {
-        return layer::operator->();
-      }
     protected:
-      void next() {
-        layer::operator++();
-      }
-      
-      void assign(layer eat) {
-        static_cast<layer&>(*this) = eat;
+      reference get() {
+        auto & pair = super::operator*();
+        return std::tie(pair.first, pair.second);
       }
-      
-      bool done() const { return layer::done(); }
     };
     
     template <typename Iterator, typename RecursiveIterator_NextLayer>
@@ -93,7 +68,7 @@ namespace iterator {
       }
       
       reference operator*() {
-        return next_layer::operator*();
+        return next_layer::get();
       }
       
       pointer operator->() {
@@ -104,6 +79,8 @@ namespace iterator {
         return layer::operator==(other) && next_layer::operator==(other);
       }
     protected:
+      reference get() { return operator*(); }
+
       void next() {
         layer & self = static_cast<layer&>(*this);
         next_layer::next();
@@ -154,19 +131,18 @@ namespace iterator {
       }
       
       reference operator*() {
-        return std::tuple_cat(std::forward_as_tuple(std::get<0>(layer::operator*())),
-                              next_reference(next_layer::operator*()));
+        return std::tuple_cat(std::forward_as_tuple(std::get<0>(layer::get())),
+                              next_reference(next_layer::get()));
       }
       
       pointer operator->();
-      //    pointer operator->() {
-      //      return next_layer::operator->();
-      //    }
       
       bool operator==(flatten_iterator_layer const & other) const {
         return layer::operator==(other) && next_layer::operator==(other);
       }
     protected:
+      reference get() { return operator*(); }
+
       void next() {
         layer & self = static_cast<layer&>(*this);
         next_layer::next();
@@ -187,11 +163,14 @@ namespace iterator {
     
     template <typename Iterator, std::size_t N, std::size_t Max, typename = void>
     class bounded_recursive_iterator_impl :
-    public recursive_iterator_terminal< Iterator > {
+    public recursive_iterator_base< Iterator > {
     private:
-      using super = recursive_iterator_terminal< Iterator >;
+      using super = recursive_iterator_base< Iterator >;
     public:
       using super::super;
+    protected:
+      void next() { super::operator++(); }
+      void assign(super eat) { static_cast<super&>(*this) = eat; }
     };
     
     template <typename Iterator, std::size_t N, std::size_t Max>
@@ -205,11 +184,14 @@ namespace iterator {
     };
     
     template <typename Iterator, typename = void>
-    class recursive_iterator_impl : public recursive_iterator_terminal< Iterator > {
+    class recursive_iterator_impl : public recursive_iterator_base< Iterator > {
     private:
-      using super = recursive_iterator_terminal< Iterator >;
+      using super = recursive_iterator_base< Iterator >;
     public:
       using super::super;
+    protected:
+      void next() { super::operator++(); }
+      void assign(super eat) { static_cast<super&>(*this) = eat; }
     };
     
     template <typename Iterator>

+ 2 - 2
recursive_iterator_nested_map.t.h

@@ -24,7 +24,7 @@ public:
     std::map<int, int> const map{{1, 1}, {2, 2}, {3, 3}};
     auto rit = make_recursive_iterator(map);
     for (auto it = map.begin(), end = map.end(); it != end; ++it, ++rit) {
-      TS_ASSERT_EQUALS(std::tuple_cat(*it), *rit);
+      TS_ASSERT_EQUALS(*it, *rit);
     }
   }
   
@@ -72,7 +72,7 @@ public:
     auto rit = make_recursive_iterator<1>(map);
     
     for (auto it = map.begin(), end = map.end(); it != end; ++it, ++rit) {
-      TS_ASSERT_EQUALS(std::tuple_cat(*it), *rit);
+      TS_ASSERT_EQUALS(*it, *rit);
     }
   }