Browse Source

Switching back to using shared_ptr, but also IFD.
This is because streams are effectively stateless/nesting dolls, and so copying the chain is unnecessary.

Samuel Jaffe 8 years ago
parent
commit
70c7891722
5 changed files with 12 additions and 42 deletions
  1. 1 1
      streams/filter.hpp
  2. 1 1
      streams/join.hpp
  3. 1 1
      streams/map.hpp
  4. 2 2
      streams/source.hpp
  5. 7 37
      streams/streams.hpp

+ 1 - 1
streams/filter.hpp

@@ -55,6 +55,6 @@ namespace stream { namespace detail {
   template <typename T>
   template <typename F>
   auto stream_base<T>::filter(F&& pred) const -> stream_base<T>  {
-    return new filter_stream<T>(pred, *this);
+    return std::make_shared<filter_stream<T>>(pred, *this);
   }
 } }

+ 1 - 1
streams/join.hpp

@@ -89,7 +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;
-    return new join_stream<C>(sb);
+    return std::make_shared<join_stream<C>>(sb);
   }
   
   template <typename T>

+ 1 - 1
streams/map.hpp

@@ -37,6 +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>> {
-    return new map_stream<T, map_f<F>>(func, *this);
+    return std::make_shared<map_stream<T, map_f<F>>>(func, *this);
   }
 } }

+ 2 - 2
streams/source.hpp

@@ -49,7 +49,7 @@ namespace stream {
   
   template <typename C>
   detail::stream_base<detail::source::reference<C>> make_stream(C && cont) {
-    return new detail::source_stream<C>(cont);
+    return std::make_shared<detail::source_stream<C>>(cont);
   }
   
   template <typename T>
@@ -59,6 +59,6 @@ namespace stream {
 
   template <typename It>
   detail::stream_base<typename It::reference> make_stream(It begin, It end) {
-    return new detail::range_stream<It>(begin, end);
+    return std::make_shared<detail::range_stream<It>>(begin, end);
   }
 }

+ 7 - 37
streams/streams.hpp

@@ -112,9 +112,6 @@ 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:
@@ -128,37 +125,12 @@ namespace stream {
       using clean = typename std::decay<T>::type;
     public:
       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_ = 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(std::shared_ptr<Stream> && impl) {
+        do_begin = [](std::shared_ptr<void> p) -> iterator<T> { return std::static_pointer_cast<Stream>(p)->begin(); };
+        do_end = [](std::shared_ptr<void> p) -> iterator<T> { return std::static_pointer_cast<Stream>(p)->end(); };
+        impl_ = std::static_pointer_cast<void>(impl);
       }
       
-      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_); }
       
@@ -214,11 +186,9 @@ namespace stream {
       template <typename F>
       stream_base<flatmap_f<F>> flatmap(F&& func) const;
     private:
-      void* (*copy)(void*){nullptr};
-      iterator<T> (*do_begin)(void*){nullptr};
-      iterator<T> (*do_end)(void*){nullptr};
-      void(*destroy)(void*){nullptr};
-      void* impl_{nullptr};
+      iterator<T> (*do_begin)(std::shared_ptr<void>){nullptr};
+      iterator<T> (*do_end)(std::shared_ptr<void>){nullptr};
+      std::shared_ptr<void> impl_{nullptr};
     };
   }
 }