Browse Source

Replacing stream::detail::stream_impl virtual tree with IFD calls.

Samuel Jaffe 8 years ago
parent
commit
e50eb57c0b
5 changed files with 63 additions and 39 deletions
  1. 4 6
      streams/filter.hpp
  2. 4 6
      streams/join.hpp
  3. 4 6
      streams/map.hpp
  4. 9 9
      streams/source.hpp
  5. 42 12
      streams/streams.hpp

+ 4 - 6
streams/filter.hpp

@@ -35,17 +35,16 @@ namespace stream { namespace detail {
   }
   
   template <typename T>
-  class filter_stream : public stream_impl<T> {
+  class filter_stream {
   public:
     template <typename F>
     filter_stream(F&& func, stream_base<T> const& sb) : pred_(func), source_(sb) {}
-    ~filter_stream() override {}
     
-    iterator<T> begin() override {
+    iterator<T> begin() {
       return {filter::iterator<T>{pred_, source_.begin(), source_.end()}};
     }
     
-    iterator<T> end() override {
+    iterator<T> end() {
       return {filter::iterator<T>{pred_, source_.end(), source_.end()}};
     }
   private:
@@ -56,7 +55,6 @@ namespace stream { namespace detail {
   template <typename T>
   template <typename F>
   auto stream_base<T>::filter(F&& pred) const -> stream_base<T>  {
-    using impl_t = filter_stream<T>;
-    return {std::make_shared<impl_t>(pred, *this)};
+    return filter_stream<T>(pred, *this);
   }
 } }

+ 4 - 6
streams/join.hpp

@@ -71,16 +71,15 @@ namespace stream { namespace detail {
   }
   
   template <typename C>
-  class join_stream : public stream_impl<typename C::value_type> {
+  class join_stream {
   public:
     using T = typename C::value_type;
     explicit join_stream(stream_base<C> const& sb) : source_(sb) {}
-    ~join_stream() override {}
     
-    ::stream::iterator<T> begin() override {
+    ::stream::iterator<T> begin() {
       return {join::iterator<C>{source_.begin(), source_.end()}};
     }
-    ::stream::iterator<T> end() override {
+    ::stream::iterator<T> end() {
       return {join::iterator<C>{source_.end(), source_.end()}};
     }
   private:
@@ -90,8 +89,7 @@ namespace stream { namespace detail {
   template <typename C>
   auto make_join(stream_base<C> const& sb) -> stream_base<typename C::value_type>  {
     using T = typename C::value_type;
-    using impl_t = join_stream<C>;
-    return {std::make_shared<impl_t>(sb)};
+    return join_stream<C>(sb);
   }
   
   template <typename T>

+ 4 - 6
streams/map.hpp

@@ -17,17 +17,16 @@ namespace stream { namespace detail {
   }
   
   template <typename T, typename R>
-  class map_stream : public stream_impl<R> {
+  class map_stream {
   public:
     template <typename F>
     map_stream(F&& func, stream_base<T> const& sb) : fun_(func), source_(sb) {}
-    ~map_stream() override {}
     
-    iterator<R> begin() override {
+    iterator<R> begin() {
       return {map::iterator<T, R>{fun_, source_.begin()}};
     }
     
-    iterator<R> end() override {
+    iterator<R> end() {
       return {map::iterator<T, R>{fun_, source_.end()}};
     }
   private:
@@ -38,7 +37,6 @@ namespace stream { namespace detail {
   template <typename T>
   template <typename F>
   auto stream_base<T>::map(F&& func) const -> stream_base<map_f<F>> {
-    using impl_t = map_stream<T, map_f<F>>;
-    return {std::make_shared<impl_t>(func, *this)};
+    return map_stream<T, map_f<F>>(func, *this);
   }
 } }

+ 9 - 9
streams/source.hpp

@@ -20,26 +20,26 @@ namespace stream {
     }
     
     template <typename C>
-    class source_stream : public stream_impl<source::reference<C>> {
+    class source_stream {
     public:
       typedef source::reference<C> reference;
       typedef decltype(std::declval<C>().begin()) _iterator;
       
       explicit source_stream(C && cont) : source_(std::forward<C>(cont)) {}
-      ~source_stream() override {}
-      iterator<reference> begin() override { return {source::iterator<_iterator>{source_.begin()}}; }
-      iterator<reference> end() override { return {source::iterator<_iterator>{source_.end()}}; }
+
+      iterator<reference> begin() { return {source::iterator<_iterator>{source_.begin()}}; }
+      iterator<reference> end() { return {source::iterator<_iterator>{source_.end()}}; }
     private:
       C source_;
     };
     
     template <typename It, typename V = typename It::value_type>
-    class range_stream : public stream_impl<V &> {
+    class range_stream {
     public:
       typedef V & reference;
       
       explicit range_stream(It b, It e) : begin_(b), end_(e) {}
-      ~range_stream() override {}
+
       iterator<reference> begin() { return {source::iterator<It>{begin_}}; }
       iterator<reference> end() { return {source::iterator<It>{end_}}; }
     private:
@@ -49,16 +49,16 @@ namespace stream {
   
   template <typename C>
   detail::stream_base<detail::source::reference<C>> make_stream(C && cont) {
-    return {std::make_shared<detail::source_stream<C>>(cont)};
+    return detail::source_stream<C>(cont);
   }
   
   template <typename T>
   detail::stream_base<T&> make_stream(T * ptr) {
-    return {std::make_shared<detail::range_stream<T*, T>>(ptr, ptr+1)};
+    return detail::range_stream<T*, T>(ptr, ptr+1);
   }
 
   template <typename It>
   detail::stream_base<typename It::reference> make_stream(It begin, It end) {
-    return {std::make_shared<detail::range_stream<It>>(begin, end)};
+    return detail::range_stream<It>(begin, end);
   }
 }

+ 42 - 12
streams/streams.hpp

@@ -97,14 +97,6 @@ namespace stream {
   };
   
   namespace detail {
-    template <typename T>
-    class stream_impl {
-    public:
-      virtual ~stream_impl() { }
-      virtual ::stream::iterator<T> begin() = 0;
-      virtual ::stream::iterator<T> end() = 0;
-    };
-    
     template <typename T, typename = void>
     class stream_base_pointer_impl {};
     
@@ -120,6 +112,9 @@ namespace stream {
       }
     };
 
+#define STREAM_BASE_COPY() \
+  copy(other.copy), do_begin(other.do_begin), do_end(other.do_end), destroy(other.destroy)
+
     template <typename T>
     class stream_base : public stream_base_pointer_impl<T> {
     private:
@@ -132,9 +127,40 @@ namespace stream {
       using noref = typename std::remove_reference<T>::type;
       using clean = typename std::decay<T>::type;
     public:
-      stream_base(std::shared_ptr<stream_impl<T>> const & impl) : impl_(impl) {}
-      ::stream::iterator<T> begin() const { return impl_->begin(); }
-      ::stream::iterator<T> end  () const { return impl_->end  (); }
+      template <typename Stream>
+      stream_base(Stream && impl) {
+        copy = [](void * p) { return (void*) new Stream(*(Stream*)(p)); };
+        do_begin = [](void * p) -> iterator<T> { return ((Stream*) p)->begin(); };
+        do_end = [](void * p) -> iterator<T> { return ((Stream*) p)->end(); };
+        destroy = [](void * p) { delete ((Stream*) p); };
+        impl_ = copy(&impl);
+      }
+      
+      stream_base(stream_base const & other)
+      : STREAM_BASE_COPY()
+      , impl_(copy(other.impl_)) {
+        
+      }
+      
+      stream_base(stream_base && other)
+      : STREAM_BASE_COPY()
+      , impl_(other.impl_) {
+        other.impl_ = nullptr;
+      }
+      
+      stream_base & operator=(stream_base const & other) {
+        return *this = stream_base{other};
+      }
+      
+      stream_base & operator=(stream_base && other) {
+        swap(*this, other);
+        return *this;
+      }
+      
+      ~stream_base() { if (destroy) destroy(impl_); }
+      
+      ::stream::iterator<T> begin() const { return do_begin(impl_); }
+      ::stream::iterator<T> end  () const { return do_end  (impl_); }
       
       bool empty() const { return begin() == end(); }
       
@@ -188,7 +214,11 @@ namespace stream {
       template <typename F>
       stream_base<flatmap_f<F>> flatmap(F&& func) const;
     private:
-      std::shared_ptr<stream_impl<T>> impl_;
+      void* (*copy)(void*){nullptr};
+      iterator<T> (*do_begin)(void*){nullptr};
+      iterator<T> (*do_end)(void*){nullptr};
+      void(*destroy)(void*){nullptr};
+      void* impl_{nullptr};
     };
   }
 }