瀏覽代碼

Two changes -
Moving iterator objects for stream operations out of class.
Moving operator| and operator> fluency functions into streams/fluent.hpp

Samuel Jaffe 8 年之前
父節點
當前提交
c92f1ace88
共有 10 個文件被更改,包括 251 次插入289 次删除
  1. 9 7
      stream.t.h
  2. 2 2
      stream.xcodeproj/project.pbxproj
  3. 50 69
      streams/filter.hpp
  4. 67 0
      streams/fluent.hpp
  5. 0 23
      streams/fold.hpp
  6. 2 2
      streams/forward.hpp
  7. 61 92
      streams/join.hpp
  8. 34 55
      streams/map.hpp
  9. 16 12
      streams/source.hpp
  10. 10 27
      streams/streams.hpp

+ 9 - 7
stream.t.h

@@ -16,6 +16,7 @@
 
 class stream_TestSuite : public CxxTest::TestSuite {
 public:
+  using int_t = int const &;
   using vec_t = std::vector<int>;
 public:
   void test_preserved() {
@@ -46,7 +47,7 @@ public:
   
   void test_map_identity() {
     vec_t v{1, 2, 3, 4, 5};
-    auto identity = [](int const & i) { return i; };
+    auto identity = [](int_t i) { return i; };
     auto s = stream::make_stream(v).map( identity );
     vec_t o{s.begin(), s.end()};
     TS_ASSERT_EQUALS(v, o);
@@ -55,7 +56,7 @@ public:
   void test_map_change() {
     vec_t v{1, 2, 3, 4, 5};
     vec_t expected{3, 5, 7, 9, 11};
-    auto fmap = [](int const & i) { return 2*i+1; };
+    auto fmap = [](int_t i) { return 2*i+1; };
     auto s = stream::make_stream(v).map( fmap );
     vec_t o{s.begin(), s.end()};
     TS_ASSERT_EQUALS(expected, o);
@@ -63,7 +64,7 @@ public:
   
   void test_filter_noop() {
     vec_t v{1, 2, 3, 4, 5};
-    auto pass = [](int const & i) { return true; };
+    auto pass = [](int_t i) { return true; };
     auto s = stream::make_stream(v).filter( pass );
     vec_t o{s.begin(), s.end()};
     TS_ASSERT_EQUALS(v, o);
@@ -72,7 +73,7 @@ public:
   void test_filter_value() {
     vec_t v{1, 2, 3, 4, 5};
     vec_t expected{2, 4};
-    auto even = [](int const & i) { return i%2 == 0; };
+    auto even = [](int_t i) { return i%2 == 0; };
     auto s = stream::make_stream(v).filter( even );
     vec_t o{s.begin(), s.end()};
     TS_ASSERT_EQUALS(expected, o);
@@ -80,15 +81,16 @@ public:
   
   void test_accumulate() {
     vec_t v{1, 2, 3, 4, 5};
-    auto even = [](int const & i) { return i%2 == 0; };
+    auto even = [](int_t i) { return i%2 == 0; };
+    auto sum =[](int_t lhs, int_t rhs) { return lhs + rhs; };
     auto s = stream::make_stream(v).filter( even );
-    TS_ASSERT_EQUALS( 6 , s.accumulate([](int const & lhs, int const & rhs) { return lhs + rhs; }, 0) );
+    TS_ASSERT_EQUALS( 6 , s.accumulate(sum, 0) );
   }
   
   void test_flatmap_joins_lists() {
     std::vector<vec_t> vv{{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}, {5, 6, 7}};
     vec_t expected{1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7};
-    auto identity = [](int const & i) { return i; };
+    auto identity = [](int_t i) { return i; };
     auto s = stream::make_stream(vv).flatmap( identity );
     vec_t o{s.begin(), s.end()};
     TS_ASSERT_EQUALS(expected, o);

+ 2 - 2
stream.xcodeproj/project.pbxproj

@@ -30,10 +30,10 @@
 		0EB833511BBF45FD00DDC844 /* source.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = source.hpp; sourceTree = "<group>"; };
 		0EB833521BBF45FD00DDC844 /* streams.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = streams.hpp; sourceTree = "<group>"; };
 		0EB833541BBF45FD00DDC844 /* streams.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = streams.hpp; sourceTree = "<group>"; };
-		CD35DCF21D61385F00BE3686 /* fold.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = fold.hpp; sourceTree = "<group>"; };
 		CD9337271E3CD78B00699FF5 /* stream_tc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = stream_tc.cpp; sourceTree = "<group>"; };
 		CD9337281E3CD78B00699FF5 /* stream.t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stream.t.h; sourceTree = "<group>"; };
 		CD93372D1E3CD79E00699FF5 /* stream_tc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = stream_tc; sourceTree = BUILT_PRODUCTS_DIR; };
+		CDF9374C1E3D81D4003E5D5C /* fluent.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = fluent.hpp; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -60,12 +60,12 @@
 			isa = PBXGroup;
 			children = (
 				0EB8334D1BBF45FD00DDC844 /* filter.hpp */,
-				CD35DCF21D61385F00BE3686 /* fold.hpp */,
 				0EB8334E1BBF45FD00DDC844 /* forward.hpp */,
 				0EB8334F1BBF45FD00DDC844 /* join.hpp */,
 				0EB833501BBF45FD00DDC844 /* map.hpp */,
 				0EB833511BBF45FD00DDC844 /* source.hpp */,
 				0EB833521BBF45FD00DDC844 /* streams.hpp */,
+				CDF9374C1E3D81D4003E5D5C /* fluent.hpp */,
 			);
 			path = streams;
 			sourceTree = "<group>";

+ 50 - 69
streams/filter.hpp

@@ -1,82 +1,63 @@
 #pragma once
 
-namespace stream {
-  template <typename T>
-  struct filter_t {
-    template <typename F>
-    explicit filter_t(F&& f) : pred(f) {}
-    std::function<bool(const T&)> pred;
-  };
-}
-
-template <typename T, bool B>
-stream::detail::stream_base<T, true> operator|(stream::detail::stream_base<T, B> const&s, stream::filter_t<T>&& f) {
-  return s.filter(f.pred);
-}
-template <typename T, bool B>
-stream::detail::stream_base<T, true> operator|(stream::detail::stream_base<T, B> &&s, stream::filter_t<T>&& f) {
-  return std::move(s).filter(f.pred);
-}
-
-namespace stream {
-  namespace detail {
-    template <typename T, bool B>
-    class filter_stream : public stream_impl<T> {
+namespace stream { namespace detail {
+  namespace filter {
+    template <typename T>
+    class iterator : public iterator_impl<T> {
     public:
-      class iterator : public iterator_impl<T> {
-      public:
-        typedef iterator_impl<T> super;
-        iterator(std::function<bool(T const&)> f, ::stream::iterator<T>&& impl)
-        : pred_(f), impl_(std::forward<::stream::iterator<T>>(impl)), next_(impl_) {
-          advance();
-        }
-        ~iterator() {}
-        T operator*() override { return mem_; }
-        
-        super& operator++() override {
-          ++impl_;
-          advance();
-          return *this;
-        }
-        
-        DELEGATE_ITERATOR_IMPL_BASE(impl_)
-      private:
-        void advance() {
-          while (!pred_(mem_ = *impl_)) {
-            ++impl_;
-          }
-        }
-        
-        std::function<bool(T const&)> pred_;
-        T mem_; // To avoid re-calcs, we store this
-        ::stream::iterator<T> impl_, next_;
-      };
+      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))
+      , end_(std::forward<::stream::iterator<T>>(end)) {
+        advance();
+      }
+      ~iterator() {}
+      T operator*() override { return mem_; }
       
-      template <typename F>
-      filter_stream(F&& func, stream_base<T, B> const& sb) : pred_(func), source_(sb) {}
-      template <typename F>
-      filter_stream(F&& func, stream_base<T, B> && sb) : pred_(func), source_(std::forward<stream_base<T, B>>(sb)) { }
-      ~filter_stream() override {}
+      super& operator++() override {
+        ++impl_;
+        advance();
+        return *this;
+      }
       
-      ::stream::iterator<T> begin() override { return ::stream::iterator<T>{new iterator{pred_, source_.begin()}};}
-      ::stream::iterator<T> end() override { return ::stream::iterator<T>{new iterator{pred_, source_.end()}}; }
+      DELEGATE_ITERATOR_IMPL_BASE(impl_)
     private:
+      void advance() {
+        while (impl_ != end_ && !pred_(mem_ = *impl_)) {
+          ++impl_;
+        }
+      }
+      
       std::function<bool(T const&)> pred_;
-      stream_base<T, B> source_;
+      T mem_; // To avoid re-calcs, we store this
+      ::stream::iterator<T> impl_, end_;
     };
-    
-    template <typename T, bool Own>
+  }
+  
+  template <typename T>
+  class filter_stream : public stream_impl<T> {
+  public:
     template <typename F>
-    auto stream_base<T, Own>::filter(F&& pred) const& -> stream_base<T, true>  {
-      using impl_t = filter_stream<T, false>;
-      return stream_base<T, true>{new impl_t{pred, *this}};
+    filter_stream(F&& func, stream_base<T> const& sb) : pred_(func), source_(sb) {}
+    ~filter_stream() override {}
+    
+    iterator<T> begin() override {
+      return {new filter::iterator<T>{pred_, source_.begin(), source_.end()}};
     }
     
-    template <typename T, bool Own>
-    template <typename F>
-    auto stream_base<T, Own>::filter(F&& pred) && -> stream_base<T, true> {
-      using impl_t = filter_stream<T, Own>;
-      return stream_base<T, true>{new impl_t{pred, std::forward<stream_base<T, Own>>(*this)}};
+    iterator<T> end() override {
+      return {new filter::iterator<T>{pred_, source_.end(), source_.end()}};
     }
+  private:
+    std::function<bool(T const&)> pred_;
+    stream_base<T> source_;
+  };
+  
+  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)};
   }
-}
+} }

+ 67 - 0
streams/fluent.hpp

@@ -0,0 +1,67 @@
+//
+//  fluent.hpp
+//  stream
+//
+//  Created by Sam Jaffe on 1/28/17.
+//
+
+#pragma once
+
+#include "../streams.hpp"
+
+#include <numeric>
+
+namespace stream {
+  template <typename T, typename R>
+  struct map {
+    template <typename F>
+    explicit map(F&& f) : func(f) {}
+    std::function<R(const T&)> func;
+  };
+  
+  template <typename T, typename R>
+  struct flatmap {
+    template <typename F>
+    explicit flatmap(F&& f) : func(f) {}
+    std::function<R(const T&)> func;
+  };
+  
+  template <typename T>
+  struct filter {
+    template <typename F>
+    explicit filter(F&& f) : pred(f) {}
+    std::function<bool(const T&)> pred;
+  };
+
+  template <typename L, typename R>
+  struct fold_left {
+    template <typename F>
+    explicit fold_left(F&& f) : init(), fold(f) {}
+    template <typename F>
+    fold_left(L const & i, F&& f) : init(i), fold(f) {}
+    L init;
+    std::function<L(const L&, const R&)> fold;
+  };
+}
+
+namespace stream { namespace detail {
+  template <typename T, typename R>
+  stream_base<R> operator|(stream_base<T> const&s, ::stream::map<T, R>&& f) {
+    return s.map(f.func);
+  }
+  
+  template <typename T, typename C>
+  stream_base<typename C::value_type> operator|(stream_base<T> const&s, ::stream::flatmap<T, C>&& f) {
+    return s.flatmap(f.func);
+  }
+  
+  template <typename T>
+  stream_base<T> operator|(stream_base<T> const&s, ::stream::filter<T>&& f) {
+    return s.filter(f.pred);
+  }
+
+  template <typename L, typename R>
+  L operator >(stream_base<R> const &s, ::stream::fold_left<L, R> && f) {
+    return std::accumulate(s.begin(), s.end(), f.init, f.fold);
+  }
+} }

+ 0 - 23
streams/fold.hpp

@@ -1,23 +0,0 @@
-//
-//  fold.hpp
-//  stream
-//
-//  Created by Sam Jaffe on 8/14/16.
-//
-
-#pragma once
-
-#include <numeric>
-
-namespace stream {
-  template <typename L, typename R>
-  struct fold_left_t {
-    L init;
-    std::function<L(const L&, const R&)> fold;
-  };
-}
-
-template <typename L, typename R, bool B>
-L operator >(stream::detail::stream_base<R, B> const &s, stream::fold_left_t<L, R> && f) {
-  return std::accumulate(s.begin(), s.end(), f.fold, f.init);
-}

+ 2 - 2
streams/forward.hpp

@@ -2,7 +2,7 @@
 
 namespace stream {
   namespace detail {
-    template <typename, bool> class stream_base;
+    template <typename> class stream_base;
     template <typename> class iterator_impl;
   }
 }
@@ -13,5 +13,5 @@ namespace stream {
   template <typename> struct filter_t;
   template <typename, typename> struct flatmap_t;
   template <typename T>
-  using stream = detail::stream_base<T, true>; // Should I override instead?
+  using stream = detail::stream_base<T>; // Should I override instead?
 }

+ 61 - 92
streams/join.hpp

@@ -1,105 +1,74 @@
 #pragma once
 
-template <typename T, typename C, bool B>
-stream::detail::stream_base<typename C::value_type, true> operator|(stream::detail::stream_base<T, B> const&s, stream::flatmap_t<T, C>&& f) {
-  return s.flatmap(f.func);
-}
-template <typename T, typename C, bool B>
-stream::detail::stream_base<typename C::value_type, true> operator|(stream::detail::stream_base<T, B> &&s, stream::flatmap_t<T, C>&& f) {
-  return std::move(s).flatmap(f.func);
-}
-
-namespace stream {
-  template <typename T, typename R>
-  struct flatmap_t {
-    template <typename F>
-    explicit flatmap_t(F&& f) : func(f) {}
-    std::function<R(const T&)> func;
-  };
-}
-
-namespace stream {
-  namespace detail {
-    template <typename C, bool B>
-    class join_stream : public stream_impl<typename C::value_type> {
+namespace stream { namespace detail {
+  namespace join {
+    template <typename C>
+    class iterator : public iterator_impl<typename C::value_type> {
     public:
-      using T = typename C::value_type;
-      class iterator : public iterator_impl<T> {
-      public:
-        typedef iterator_impl<T> super;
-        iterator(::stream::iterator<C>&& f, ::stream::iterator<C>&& l)
-        : start_(std::forward<::stream::iterator<C>>(f))
-        , finish_(std::forward<::stream::iterator<C>>(l))
-        {
-          if (start_ != finish_) {
-            mem_ = *(start_);
-            curr_ = mem_.begin();
-            end_ = mem_.end();
-            advance();
-          }
-        }
-        ~iterator() {}
-        T operator*() override { return *curr_; }
-        
-        super& operator++() override {
-          ++curr_;
+      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))
+      {
+        if (start_ != finish_) {
+          mem_ = *(start_);
+          curr_ = mem_.begin();
+          end_ = mem_.end();
           advance();
-          return *this;
-        }
-        
-        DELEGATE_ITERATOR_IMPL_BASE(start_)
-      private:
-        void advance() {
-          while (curr_ == end_ && start_ != finish_) {
-            if ( ++start_ == finish_ ) { break; }
-            mem_ = *start_;
-            curr_ = mem_.begin();
-            end_ = mem_.end();
-          }
         }
-        ::stream::iterator<C> start_, finish_;
-        C mem_;
-        typename C::iterator curr_, end_;
-      };
-      
-      explicit join_stream(stream_base<C, B> const& sb) : source_(sb) {}
-      explicit join_stream(stream_base<C, B> && sb) : source_(std::forward<stream_base<C, B>>(sb)) { }
-      ~join_stream() override {}
-      
-      ::stream::iterator<T> begin() override {
-        return ::stream::iterator<T>{new iterator{source_.begin(), source_.end()}};
       }
-      ::stream::iterator<T> end() override {
-        return ::stream::iterator<T>{new iterator{source_.end(), source_.end()}};
+      ~iterator() {}
+      typename C::value_type operator*() override { return *curr_; }
+      
+      super& operator++() override {
+        ++curr_;
+        advance();
+        return *this;
       }
+      
+      DELEGATE_ITERATOR_IMPL_BASE(start_)
     private:
-      stream_base<C, B> source_;
+      void advance() {
+        while (curr_ == end_ && start_ != finish_) {
+          if ( ++start_ == finish_ ) { break; }
+          mem_ = *start_;
+          curr_ = mem_.begin();
+          end_ = mem_.end();
+        }
+      }
+      ::stream::iterator<C> start_, finish_;
+      C mem_;
+      typename C::iterator curr_, end_;
     };
+  }
+  
+  template <typename C>
+  class join_stream : public stream_impl<typename C::value_type> {
+  public:
+    using T = typename C::value_type;
+    explicit join_stream(stream_base<C> const& sb) : source_(sb) {}
+    ~join_stream() override {}
     
-    template <typename C, bool Own>
-    auto join(stream_base<C, Own> const& sb) -> stream_base<typename C::value_type, true>  {
-      using T = typename C::value_type;
-      using impl_t = join_stream<C, false>;
-      return stream_base<T, true>{new impl_t{falsify(sb)}};
-    }
-    
-    template <typename C, bool Own>
-    auto join(stream_base<C, Own> && sb) -> stream_base<typename C::value_type, true> {
-      using T = typename C::value_type;
-      using impl_t = join_stream<C, Own>;
-      return stream_base<T, true>{new impl_t(std::forward<stream_base<C, Own>>(sb))};
-    }
-    
-    template <typename T, bool Own>
-    template <typename F>
-    auto stream_base<T, Own>::flatmap(F&& func) const& -> stream_base<flatmap_f<F>, true>  {
-      return join((*this)).map(func);
+    ::stream::iterator<T> begin() override {
+      return {new join::iterator<C>{source_.begin(), source_.end()}};
     }
-    
-    template <typename T, bool Own>
-    template <typename F>
-    auto stream_base<T, Own>::flatmap(F&& func) && -> stream_base<flatmap_f<F>, true> {
-      return join(std::forward<self>(*this)).map(func);
+    ::stream::iterator<T> end() override {
+      return {new join::iterator<C>{source_.end(), source_.end()}};
     }
+  private:
+    stream_base<C> source_;
+  };
+  
+  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)};
+  }
+  
+  template <typename T>
+  template <typename F>
+  auto stream_base<T>::flatmap(F&& func) const -> stream_base<flatmap_f<F>>  {
+    return make_join((*this)).map(func);
   }
-}
+} }

+ 34 - 55
streams/map.hpp

@@ -1,66 +1,45 @@
 #pragma once
 
-namespace stream {
-  template <typename T, typename R>
-  struct map_t {
-    template <typename F>
-    explicit map_t(F&& f) : func(f) {}
-    std::function<R(const T&)> func;
-  };
-}
-
-template <typename T, typename R, bool B>
-stream::detail::stream_base<R, true> operator|(stream::detail::stream_base<T, B> const&s, stream::map_t<T, R>&& f) {
-  return s.map(f.func);
-}
-template <typename T, typename R, bool B>
-stream::detail::stream_base<R, true> operator|(stream::detail::stream_base<T, B> &&s, stream::map_t<T, R>&& f) {
-  return std::move(s).map(f.func);
-}
-
-namespace stream {
-  namespace detail {
-    template <typename T, typename R, bool B>
-    class map_stream : public stream_impl<R> {
+namespace stream { namespace detail {
+  namespace map {
+    template <typename T, typename R>
+    class iterator : public iterator_impl<R> {
     public:
-      class iterator : public iterator_impl<R> {
-      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_); }
-        DELEGATE_ITERATOR_IMPL(impl_)
-      private:
-        std::function<R(T const&)> fun_;
-        ::stream::iterator<T> impl_;
-      };
-      
-      template <typename F>
-      map_stream(F&& func, stream_base<T, B> const& sb) : fun_(func), source_(sb) {}
-      template <typename F>
-      map_stream(F&& func, stream_base<T, B> && sb) : fun_(func), source_(std::forward<stream_base<T, B>>(sb)) { }
-      ~map_stream() override {}
-      
-      ::stream::iterator<R> begin() override { return ::stream::iterator<R>{new iterator{fun_, source_.begin()}};}
-      ::stream::iterator<R> end() override { return ::stream::iterator<R>{new iterator{fun_, source_.end()}}; }
+      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_); }
+      DELEGATE_ITERATOR_IMPL(impl_)
     private:
       std::function<R(T const&)> fun_;
-      stream_base<T, B> source_;
+      ::stream::iterator<T> impl_;
     };
-    
-    template <typename T, bool Own>
+  }
+  
+  template <typename T, typename R>
+  class map_stream : public stream_impl<R> {
+  public:
     template <typename F>
-    auto stream_base<T, Own>::map(F&& func) const& -> stream_base<map_f<F>, true>  {
-      using impl_t = map_stream<T, map_f<F>, false>;
-      return stream_base<map_f<F>, true>{new impl_t(func, falsify(*this))};
+    map_stream(F&& func, stream_base<T> const& sb) : fun_(func), source_(sb) {}
+    ~map_stream() override {}
+    
+    iterator<R> begin() override {
+      return {new map::iterator<T, R>{fun_, source_.begin()}};
     }
     
-    template <typename T, bool Own>
-    template <typename F>
-    auto stream_base<T, Own>::map(F&& func) && -> stream_base<map_f<F>, true> {
-      using impl_t = map_stream<T, map_f<F>, Own>;
-      return stream_base<map_f<F>, true>{new impl_t(func, std::forward<self>(*this))};
+    iterator<R> end() override {
+      return {new map::iterator<T, R>{fun_, source_.end()}};
     }
+  private:
+    std::function<R(T const&)> fun_;
+    stream_base<T> source_;
+  };
+  
+  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)};
   }
-}
+} }

+ 16 - 12
streams/source.hpp

@@ -2,33 +2,37 @@
 
 namespace stream {
   namespace detail {
-    template <typename C>
-    class source_stream : public stream_impl<typename C::value_type> {
-    public:
-      typedef typename C::value_type value_type;
-      class iterator : public iterator_impl<value_type> {
+    namespace source {
+      template <typename C>
+      class iterator : public iterator_impl<typename C::value_type> {
       public:
-        typedef iterator_impl<value_type> super;
+        typedef iterator_impl<typename C::value_type> super;
         explicit iterator(typename C::iterator it) : impl_(it) {}
         ~iterator() {}
-        value_type operator*() override { return *impl_; }
+        typename C::value_type operator*() override { return *impl_; }
         DELEGATE_ITERATOR_IMPL(impl_)
       private:
-        typename C::iterator impl_;
+        typename C::const_iterator impl_;
       };
+    }
+    
+    template <typename C>
+    class source_stream : public stream_impl<typename C::value_type> {
+    public:
+      typedef typename C::value_type value_type;
       
       explicit source_stream(C const& cont) : source_(cont) {}
       explicit source_stream(C && cont) : source_(std::forward(cont)) {}
       ~source_stream() override {}
-      ::stream::iterator<value_type> begin() override { return ::stream::iterator<value_type>{new iterator{source_.begin()}}; }
-      ::stream::iterator<value_type> end() override { return ::stream::iterator<value_type>{new iterator{source_.end()}}; }
+      iterator<value_type> begin() override { return {new source::iterator<C>{source_.begin()}}; }
+      iterator<value_type> end() override { return {new source::iterator<C>{source_.end()}}; }
     private:
       C source_;
     };
   }
   
   template <typename C>
-  detail::stream_base<typename C::value_type, true> make_stream(C const& cont) {
-    return detail::stream_base<typename C::value_type, true>{new detail::source_stream<C>{cont}};
+  detail::stream_base<typename C::value_type> make_stream(C const& cont) {
+    return {std::make_shared<detail::source_stream<C>>(cont)};
   }
 }

+ 10 - 27
streams/streams.hpp

@@ -24,7 +24,7 @@ namespace stream {
     using difference_type = std::ptrdiff_t;
     using iterator_category = std::forward_iterator_tag;
   public:
-    explicit iterator(detail::iterator_impl<T>* impl) : impl_(impl) {}
+    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_; }
@@ -37,9 +37,6 @@ namespace stream {
   };
   
   namespace detail {
-    template <typename T>
-    stream_base<T, false> falsify(stream_base<T, true> const& in);
-    
     template <typename T>
     class iterator_impl {
     public:
@@ -73,7 +70,7 @@ namespace stream {
       using flatmap_f = decltype(std::declval<F>()(std::declval<typename T::value_type>()));
     };
     
-    template <typename T, bool Own>
+    template <typename T>
     class stream_base {
     private:
       template <typename F>
@@ -81,11 +78,9 @@ namespace stream {
       template <typename F>
       using flatmap_f = typename has_value_type<T>::template flatmap_f<F>;
 
-      using self = stream_base<T, Own>;
+      using self = stream_base<T>;
     public:
-      explicit stream_base(stream_impl<T>* impl) : impl_(impl) {}
-      stream_base(stream_base&&other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
-      ~stream_base() { if (Own && impl_) delete impl_; }
+      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  (); }
       
@@ -107,27 +102,15 @@ namespace stream {
       }
       
       template <typename F>
-      stream_base<map_f<F>, true> map(F&& func) const&;
-      template <typename F>
-      stream_base<map_f<F>, true> map(F&& func) &&;
-      template <typename F>
-      stream_base<T, true> filter(F&& func) const&;
-      template <typename F>
-      stream_base<T, true> filter(F&& func) &&;
+      stream_base<map_f<F>> map(F&& func) const;
+      
       template <typename F>
-      stream_base<flatmap_f<F>, true> flatmap(F&& func) const&;
+      stream_base<T> filter(F&& func) const;
+      
       template <typename F>
-      stream_base<flatmap_f<F>, true> flatmap(F&& func) &&;
+      stream_base<flatmap_f<F>> flatmap(F&& func) const;
     private:
-      friend stream_base<T, false> falsify<T>(stream_base<T, true>const&);
-      stream_impl<T>* impl_;
+      std::shared_ptr<stream_impl<T>> impl_;
     };
-    
-    template <typename T>
-    stream_base<T, false> const& falsify(stream_base<T, false> const& in) { return in; }
-    template <typename T>
-    stream_base<T, false> falsify(stream_base<T, true> const& in) {
-      return stream_base<T, false>{in.impl_};
-    }
   }
 }