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