瀏覽代碼

Making recursive_iterator able to replace joining_iterator, for bucket_hash_map, etc.

Samuel Jaffe 9 年之前
父節點
當前提交
16e1b21243
共有 3 個文件被更改,包括 66 次插入7 次删除
  1. 3 0
      end_aware_iterator.hpp
  2. 3 0
      iterator_fwd.hpp
  3. 60 7
      recursive_iterator.hpp

+ 3 - 0
end_aware_iterator.hpp

@@ -78,6 +78,9 @@ namespace iterator {
   };
 }
 
+template <typename Iter>
+iterator::end_aware_iterator<Iter> make_end_aware_iterator(Iter a, Iter b) { return {a, b}; }
+
 template <typename C>
 auto make_end_aware_iterator(C & collect) -> iterator::end_aware_iterator<decltype(std::begin(collect))> {
   return { std::begin(collect), std::end(collect) };

+ 3 - 0
iterator_fwd.hpp

@@ -18,6 +18,9 @@ namespace iterator {
     using mapped_iterator = decltype(std::begin(std::declval<IterType>()->second));
   }
   
+  struct {} in_place;
+  using in_place_t = decltype(in_place);
+  
   template <typename Iterator> class end_aware_iterator;
   template <typename MetaIterator> class joining_iterator;
   template <typename Iterator> class recursive_iterator;

+ 60 - 7
recursive_iterator.hpp

@@ -8,6 +8,7 @@
 #pragma once
 
 #include "iterator_fwd.hpp"
+#include "end_aware_iterator.hpp"
 
 namespace iterator {
   namespace detail {
@@ -26,6 +27,8 @@ namespace iterator {
       using recursive_category = terminal_layer_tag_t;
     public:
       using super::super;
+      recursive_iterator_base() = default;
+      operator super() const { return *this; }
     protected:
       typename super::reference get() { return super::operator*(); }
     };
@@ -56,6 +59,8 @@ namespace iterator {
       using reference = std::tuple<first_type &, second_type &>;
     public:
       using super::super;
+      recursive_iterator_base() = default;
+      operator super() const { return *this; }
     protected:
       /**
        * An alternative function to operator*(), which allows single layer
@@ -100,8 +105,16 @@ namespace iterator {
       recursive_iterator_layer() = default;
       recursive_iterator_layer(layer v) : recursive_iterator_layer() {
         assign(v);
+        update();
       }
-      
+      template <typename OIter, typename Rec>
+      recursive_iterator_layer(recursive_iterator_layer<OIter, Rec> const & other) : layer(static_cast<recursive_iterator_base<OIter>const&>(other)), next_layer(static_cast<Rec const&>(other)) {}
+      template <typename OIter, typename... Iterators>
+      recursive_iterator_layer(in_place_t, OIter it, Iterators && ...iter)
+      : layer(it), next_layer(in_place, iter...) {
+        update();
+      }
+
       reference operator*() {
         return next_layer::get();
       }
@@ -122,11 +135,8 @@ namespace iterator {
        * non-empty subcollection to start iterating over.
        */
       void next() {
-        layer & self = static_cast<layer&>(*this);
         next_layer::next();
-        while ( next_layer::done() && !(++self).done() ) {
-          next_layer::assign(make_end_aware_iterator(*self));
-        }
+        update();
       }
       
       /**
@@ -141,6 +151,13 @@ namespace iterator {
         }
       }
       
+      void update() {
+        layer & self = static_cast<layer&>(*this);
+        while ( next_layer::done() && !(++self).done() ) {
+          next_layer::assign(make_end_aware_iterator(*self));
+        }
+      }
+      
       bool done() const { return layer::done(); }
     };
     
@@ -183,6 +200,14 @@ namespace iterator {
       flatten_iterator_layer() = default;
       flatten_iterator_layer(layer v) : flatten_iterator_layer() {
         assign(v);
+        update();
+      }
+      template <typename OIter, typename Rec>
+      flatten_iterator_layer(flatten_iterator_layer<OIter, Rec> const & other) : layer(static_cast<recursive_iterator_base<OIter>const&>(other)), next_layer(static_cast<Rec const&>(other)) {}
+      template <typename OIter, typename... Iterators>
+      flatten_iterator_layer(in_place_t, OIter it, Iterators && ...iter)
+      : layer(it), next_layer(in_place, iter...) {
+        update();
       }
       
       /**
@@ -215,8 +240,12 @@ namespace iterator {
        * @copydoc recursive_iterator_layer::next
        */
       void next() {
-        layer & self = static_cast<layer&>(*this);
         next_layer::next();
+        update();
+      }
+      
+      void update() {
+        layer & self = static_cast<layer&>(*this);
         while ( next_layer::done() && !(++self).done() ) {
           next_layer::assign(make_end_aware_iterator(self->second));
         }
@@ -251,6 +280,9 @@ namespace iterator {
       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(iter) {}
     protected:
       void next() { super::operator++(); }
       void assign(super eat) { static_cast<super&>(*this) = eat; }
@@ -278,6 +310,9 @@ namespace iterator {
        */
       auto operator*() -> 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, iter...) {}
     };
     
     /**
@@ -293,6 +328,9 @@ namespace iterator {
       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(iter) {}
     protected:
       void next() { super::operator++(); }
       void assign(super eat) { static_cast<super&>(*this) = eat; }
@@ -320,6 +358,9 @@ namespace iterator {
        */
       auto operator*() -> 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, iter...) {}
     };
     
     /**
@@ -337,6 +378,9 @@ namespace iterator {
       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, iter...) {}
     };
     
     /**
@@ -354,6 +398,9 @@ namespace 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, iter...) {}
     };
   }
   
@@ -375,7 +422,10 @@ namespace iterator {
     using super = detail::recursive_iterator_impl< Iterator >;
   public:
     using super::super;
-    
+    recursive_iterator() = default;
+    template <typename... Iterators>
+    recursive_iterator(in_place_t, Iterators && ...iter) : super(in_place, iter...) {}
+
     recursive_iterator & operator++() {
       (void) super::next();
       return *this;
@@ -413,6 +463,9 @@ namespace iterator {
     using super = detail::bounded_recursive_iterator_impl< Iterator, 1, N >;
   public:
     using super::super;
+    recursive_iterator_n() = default;
+    template <typename... Iterators>
+    recursive_iterator_n(in_place_t, Iterators && ...iter) : super(in_place, iter...) {}
     
     recursive_iterator_n & operator++() {
       (void) super::next();