瀏覽代碼

Extract make_stream functions to their own file.

Sam Jaffe 5 年之前
父節點
當前提交
036e673130
共有 3 個文件被更改,包括 98 次插入75 次删除
  1. 1 0
      include/stream/streams.hpp
  2. 61 0
      include/stream/streams/make_stream.hpp
  3. 36 75
      include/stream/streams/source.hpp

+ 1 - 0
include/stream/streams.hpp

@@ -3,6 +3,7 @@
 #include "streams/forward.hpp"
 
 #include "streams/streams.hpp"
+#include "streams/make_stream.hpp"
 
 #include "streams/source.hpp"
 

+ 61 - 0
include/stream/streams/make_stream.hpp

@@ -0,0 +1,61 @@
+#pragma once
+
+#include "source.hpp"
+
+namespace stream {
+  /**
+   * Construct a stream out of the given container. If C && is an rvalue reference, the returned object
+   * will take ownership of cont. Otherwise, we capture cont by reference to maximise performance.
+   */
+  template <typename C>
+  detail::stream_base<detail::source::reference<C>> make_stream(C && cont) {
+    return std::make_shared<detail::source_stream<C>>(std::forward<C>(cont));
+  }
+
+  /**
+   * Construct a single element stream containing the pointer given
+   */
+  template <typename T> detail::stream_base<T &> make_stream(T * ptr) {
+    return std::make_shared<detail::range_stream<T *, T &>>(ptr, ptr + 1);
+  }
+
+  /**
+   * Construct a stream from input iterators representing the start and end
+   * Requirements: It must be an iterator type that provides the trait 'reference'
+   */
+  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);
+  }
+
+  /**
+   * Construct a stream given certain start and end bounds.
+   * e.g. stream::make_range_stream(0, 10)
+   */
+  template <typename T>
+  detail::stream_base<T &> make_range_stream(T start, T const & end) {
+    std::vector<T> vec;
+    vec.reserve(end - start);
+    while (end < start) {
+      vec.emplace_back(start++);
+    }
+    return make_stream(std::move(vec));
+  }
+
+  /**
+   * Construct a stream given certain start and end bounds, as well as an increment amount.
+   * e.g. stream::make_range_stream(0, 10, 2)
+   */
+  template <typename T>
+  detail::stream_base<T &> make_range_stream(T start, T const & end,
+                                             T const & increment) {
+    int elems{(end - start) / increment};
+    if (elems < 0 || end == start) { return {}; }
+    std::vector<T> vec{start};
+    vec.reserve(elems + 1);
+    while (elems-- > 0) {
+      vec.emplace_back(start += increment);
+    }
+    return make_stream(std::move(vec));
+  }
+}

+ 36 - 75
include/stream/streams/source.hpp

@@ -1,90 +1,51 @@
 #pragma once
 
-namespace stream {
-  namespace detail {
-    namespace source {
-      template <typename Iter> class iterator {
-      public:
-        using value_type = typename std::iterator_traits<Iter>::reference;
-        explicit iterator(Iter it) : impl_(it) {}
-
-        value_type operator*() { return *impl_; }
-        DELEGATE_ITERATOR_IMPL(impl_)
-      private:
-        Iter impl_;
-      };
-
-      template <typename C>
-      using reference = decltype(*std::declval<C>().begin());
-    }
-
-    template <typename C> class source_stream {
+namespace stream { namespace detail {
+  namespace source {
+    template <typename Iter> class iterator {
     public:
-      typedef source::reference<C> reference;
-      typedef decltype(std::declval<C>().begin()) _iterator;
-
-      explicit source_stream(C && cont) : source_(std::forward<C>(cont)) {}
-
-      iterator<reference> begin() {
-        return {source::iterator<_iterator>{source_.begin()}};
-      }
-      iterator<reference> end() {
-        return {source::iterator<_iterator>{source_.end()}};
-      }
+      using value_type = typename std::iterator_traits<Iter>::reference;
+      explicit iterator(Iter it) : impl_(it) {}
 
+      value_type operator*() { return *impl_; }
+      DELEGATE_ITERATOR_IMPL(impl_)
     private:
-      C source_;
+      Iter impl_;
     };
 
-    template <typename It, typename V = typename It::value_type>
-    class range_stream {
-    public:
-      typedef V & reference;
+    template <typename C>
+    using reference = decltype(*std::declval<C>().begin());
+  }
 
-      explicit range_stream(It b, It e) : begin_(b), end_(e) {}
+  template <typename C> class source_stream {
+  public:
+    typedef source::reference<C> reference;
+    typedef decltype(std::declval<C>().begin()) _iterator;
 
-      iterator<reference> begin() { return {source::iterator<It>{begin_}}; }
-      iterator<reference> end() { return {source::iterator<It>{end_}}; }
+    explicit source_stream(C && cont) : source_(std::forward<C>(cont)) {}
 
-    private:
-      It begin_, end_;
-    };
-  }
+    iterator<reference> begin() {
+      return {source::iterator<_iterator>{source_.begin()}};
+    }
+    iterator<reference> end() {
+      return {source::iterator<_iterator>{source_.end()}};
+    }
 
-  template <typename C>
-  detail::stream_base<detail::source::reference<C>> make_stream(C && cont) {
-    return std::make_shared<detail::source_stream<C>>(std::forward<C>(cont));
-  }
+  private:
+    C source_;
+  };
 
-  template <typename T> detail::stream_base<T &> make_stream(T * ptr) {
-    return std::make_shared<detail::range_stream<T *, T &>>(ptr, ptr + 1);
-  }
+  template <typename It, typename V = typename It::value_type>
+  class range_stream {
+  public:
+    typedef V & reference;
 
-  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);
-  }
+    explicit range_stream(It b, It e) : begin_(b), end_(e) {}
 
-  template <typename T>
-  detail::stream_base<T &> make_range_stream(T start, T const & end) {
-    std::vector<T> vec;
-    vec.reserve(end - start);
-    while (end < start) {
-      vec.emplace_back(start++);
-    }
-    return make_stream(std::move(vec));
-  }
+    iterator<reference> begin() { return {source::iterator<It>{begin_}}; }
+    iterator<reference> end() { return {source::iterator<It>{end_}}; }
 
-  template <typename T>
-  detail::stream_base<T &> make_range_stream(T start, T const & end,
-                                             T const & increment) {
-    int elems{(end - start) / increment};
-    if (elems < 0 || end == start) { return {}; }
-    std::vector<T> vec{start};
-    vec.reserve(elems + 1);
-    while (elems-- > 0) {
-      vec.emplace_back(start += increment);
-    }
-    return make_stream(std::move(vec));
-  }
-}
+  private:
+    It begin_, end_;
+  };
+}}