|
|
@@ -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};
|
|
|
};
|
|
|
}
|
|
|
}
|