Browse Source

Switching to using impossibly fast delegate pattern for stream iterators.

Samuel Jaffe 8 years ago
parent
commit
ce2e544d63
5 changed files with 111 additions and 48 deletions
  1. 5 6
      streams/filter.hpp
  2. 36 7
      streams/join.hpp
  3. 4 5
      streams/map.hpp
  4. 4 5
      streams/source.hpp
  5. 62 25
      streams/streams.hpp

+ 5 - 6
streams/filter.hpp

@@ -3,9 +3,8 @@
 namespace stream { namespace detail {
   namespace filter {
     template <typename T>
-    class iterator : public iterator_impl<T> {
+    class iterator {
     public:
-      typedef iterator_impl<T> super;
       iterator(std::function<bool(T const&)> f, ::stream::iterator<T>&& impl, ::stream::iterator<T>&& end)
       : pred_(f)
       , impl_(std::forward<::stream::iterator<T>>(impl))
@@ -13,9 +12,9 @@ namespace stream { namespace detail {
         advance();
       }
       ~iterator() {}
-      T operator*() override { return mem_; }
+      T operator*() { return mem_; }
       
-      super& operator++() override {
+      iterator& operator++() {
         ++impl_;
         advance();
         return *this;
@@ -43,11 +42,11 @@ namespace stream { namespace detail {
     ~filter_stream() override {}
     
     iterator<T> begin() override {
-      return {new filter::iterator<T>{pred_, source_.begin(), source_.end()}};
+      return {filter::iterator<T>{pred_, source_.begin(), source_.end()}};
     }
     
     iterator<T> end() override {
-      return {new filter::iterator<T>{pred_, source_.end(), source_.end()}};
+      return {filter::iterator<T>{pred_, source_.end(), source_.end()}};
     }
   private:
     std::function<bool(T const&)> pred_;

+ 36 - 7
streams/join.hpp

@@ -1,11 +1,21 @@
 #pragma once
 
+#include <iterator>
+
 namespace stream { namespace detail {
+#define JOIN_CTOR( mod ) \
+  start_ = mod(other.start_); \
+  finish_ = mod(other.finish_); \
+  std::ptrdiff_t n = std::distance(other.mem_.cbegin(), other.curr_); \
+  mem_ = mod(other.mem_); \
+  curr_ = mem_.begin(); \
+  std::advance(curr_, n); \
+  end_ = mem_.end();
+
   namespace join {
     template <typename C>
-    class iterator : public iterator_impl<typename C::value_type> {
+    class iterator {
     public:
-      typedef iterator_impl<typename C::value_type> super;
       iterator(::stream::iterator<C>&& f, ::stream::iterator<C>&& l)
       : start_(std::forward<::stream::iterator<C>>(f))
       , finish_(std::forward<::stream::iterator<C>>(l))
@@ -17,10 +27,29 @@ namespace stream { namespace detail {
           advance();
         }
       }
+      
+      iterator(iterator const & other) {
+        JOIN_CTOR( )
+      }
+      
+      iterator(iterator && other) {
+        JOIN_CTOR( std::move )
+      }
+      
+      iterator & operator=(iterator const & other) {
+        JOIN_CTOR( )
+        return *this;
+      }
+      
+      iterator & operator=(iterator && other) {
+        JOIN_CTOR( std::move )
+        return *this;
+      }
+      
       ~iterator() {}
-      typename C::value_type operator*() override { return *curr_; }
+      typename C::value_type operator*() { return *curr_; }
       
-      super& operator++() override {
+      iterator& operator++() {
         ++curr_;
         advance();
         return *this;
@@ -38,7 +67,7 @@ namespace stream { namespace detail {
       }
       ::stream::iterator<C> start_, finish_;
       C mem_;
-      typename C::iterator curr_, end_;
+      typename C::const_iterator curr_, end_;
     };
   }
   
@@ -50,10 +79,10 @@ namespace stream { namespace detail {
     ~join_stream() override {}
     
     ::stream::iterator<T> begin() override {
-      return {new join::iterator<C>{source_.begin(), source_.end()}};
+      return {join::iterator<C>{source_.begin(), source_.end()}};
     }
     ::stream::iterator<T> end() override {
-      return {new join::iterator<C>{source_.end(), source_.end()}};
+      return {join::iterator<C>{source_.end(), source_.end()}};
     }
   private:
     stream_base<C> source_;

+ 4 - 5
streams/map.hpp

@@ -3,13 +3,12 @@
 namespace stream { namespace detail {
   namespace map {
     template <typename T, typename R>
-    class iterator : public iterator_impl<R> {
+    class iterator {
     public:
-      typedef iterator_impl<R> super;
       iterator(std::function<R(T const&)> f, ::stream::iterator<T>&& impl)
       : fun_(f), impl_(std::forward<::stream::iterator<T>>(impl)) {}
       ~iterator() {}
-      R operator*() override { return fun_(*impl_); }
+      R operator*() { return fun_(*impl_); }
       DELEGATE_ITERATOR_IMPL(impl_)
     private:
       std::function<R(T const&)> fun_;
@@ -25,11 +24,11 @@ namespace stream { namespace detail {
     ~map_stream() override {}
     
     iterator<R> begin() override {
-      return {new map::iterator<T, R>{fun_, source_.begin()}};
+      return {map::iterator<T, R>{fun_, source_.begin()}};
     }
     
     iterator<R> end() override {
-      return {new map::iterator<T, R>{fun_, source_.end()}};
+      return {map::iterator<T, R>{fun_, source_.end()}};
     }
   private:
     std::function<R(T const&)> fun_;

+ 4 - 5
streams/source.hpp

@@ -4,13 +4,12 @@ namespace stream {
   namespace detail {
     namespace source {
       template <typename Iter>
-      class iterator : public iterator_impl<typename std::iterator_traits<Iter>::reference> {
+      class iterator {
       public:
         using value_type = typename std::iterator_traits<Iter>::reference;
-        typedef iterator_impl<value_type> super;
         explicit iterator(Iter it) : impl_(it) {}
         ~iterator() {}
-        value_type operator*() override { return *impl_; }
+        value_type operator*() { return *impl_; }
         DELEGATE_ITERATOR_IMPL(impl_)
       private:
         Iter impl_;
@@ -28,8 +27,8 @@ namespace stream {
       
       explicit source_stream(C && cont) : source_(std::forward<C>(cont)) {}
       ~source_stream() override {}
-      iterator<reference> begin() override { return {new source::iterator<_iterator>{source_.begin()}}; }
-      iterator<reference> end() override { return {new source::iterator<_iterator>{source_.end()}}; }
+      iterator<reference> begin() override { return {source::iterator<_iterator>{source_.begin()}}; }
+      iterator<reference> end() override { return {source::iterator<_iterator>{source_.end()}}; }
     private:
       C source_;
     };

+ 62 - 25
streams/streams.hpp

@@ -7,13 +7,14 @@
 #define EQ_MEM(x) x == dynamic_cast<iterator const&>(other).x
 
 #define DELEGATE_ITERATOR_IMPL_BASE(impl) \
-super* clone() const override { return new iterator{*this}; } \
-bool operator==(super const&other) const override { return EQ_MEM(impl); } \
+bool operator==(iterator const&other) const { return EQ_MEM(impl); } \
 
 #define DELEGATE_ITERATOR_IMPL(impl) \
-super& operator++() override { ++impl; return *this; } \
+iterator& operator++() { ++impl; return *this; } \
 DELEGATE_ITERATOR_IMPL_BASE(impl)
 
+std::map<void*, bool> data;
+
 namespace stream {
   template <typename T>
   class iterator {
@@ -24,32 +25,68 @@ namespace stream {
     using difference_type = std::ptrdiff_t;
     using iterator_category = std::forward_iterator_tag;
   public:
-    iterator(detail::iterator_impl<T>* impl) : impl_(impl) {}
-    iterator(iterator const& other) : impl_(other.impl_->clone()) { }
-    iterator(iterator&& other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
-    ~iterator() { if (impl_) delete impl_; }
-    T operator*() const { return **impl_; }
-    iterator& operator++() { ++(*impl_); return *this; }
-    bool operator==(iterator const&other) const { return *impl_ == *(other.impl_); }
-    bool operator!=(iterator const&other) const { return *impl_ != *(other.impl_); }
+    iterator() = default;
+    
+    template <typename Iter>
+    iterator(Iter impl) {
+      copy = [](void * p) { return (void*) new Iter(*(Iter*)(p)); };
+      dereference = [](void * p) -> T { return **((Iter*)p); };
+      compare = [](void * l, void * r) { return *((Iter*)l) == *((Iter*)r); };
+      destroy = [](void * p) { delete (Iter*)(p); };
+      advance = [](void * p) { ++(*(Iter*)(p)); };
+      type_ = typeid(Iter).name();
+      impl_ = copy(&impl);
+    }
+    
+    iterator(iterator const& other)
+    : copy(other.copy)
+    , dereference(other.dereference)
+    , compare(other.compare)
+    , destroy(other.destroy)
+    , advance(other.advance)
+    , type_(other.type_)
+    , impl_(copy(other.impl_)) {
+    }
+    
+    iterator & operator=(iterator const & other) {
+      iterator tmp{other};
+      swap(*this, tmp);
+      return *this;
+    }
+    
+    ~iterator() { if (destroy) destroy(impl_); }
+    
+    T operator*() const { return dereference(impl_); }
+    iterator& operator++() { advance(impl_); return *this; }
+    bool operator==(iterator const&other) const {
+      if (strcmp(type_, other.type_)) { return false; }
+      return compare(impl_, other.impl_);
+    }
+    bool operator!=(iterator const&other) const {
+      if (strcmp(type_, other.type_)) { return false; }
+      return !compare(impl_, other.impl_);
+    }
   private:
-    detail::iterator_impl<T>* impl_;
+    friend void swap(iterator & lhs, iterator & rhs) {
+      using std::swap;
+      swap(lhs.copy, rhs.copy);
+      swap(lhs.dereference, rhs.dereference);
+      swap(lhs.compare, rhs.compare);
+      swap(lhs.destroy, rhs.destroy);
+      swap(lhs.advance, rhs.advance);
+      swap(lhs.type_, rhs.type_);
+      swap(lhs.impl_, rhs.impl_);
+    }
+    using delegate = void(*)(void*);
+    void* (*copy)(void*){nullptr};
+    T (*dereference)(void*){nullptr};
+    bool (*compare)(void*, void*){nullptr};
+    delegate destroy{nullptr}, advance{nullptr};
+    char const * type_{nullptr};
+    void * impl_{nullptr};
   };
   
   namespace detail {
-    template <typename T>
-    class iterator_impl {
-    public:
-      virtual ~iterator_impl() {}
-      virtual iterator_impl<T>* clone() const = 0;
-      virtual T operator*() = 0;
-      virtual iterator_impl<T>& operator++() = 0;
-      virtual bool operator==(iterator_impl<T> const&other) const = 0;
-      bool operator!=(iterator_impl<T> const&other) const {
-        return !operator==(other);
-      }
-    };
-    
     template <typename T>
     class stream_impl {
     public: