| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- #pragma once
- namespace stream { namespace detail {
- namespace filter {
- template <typename T>
- class iterator : public iterator_impl<T> {
- public:
- 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_; }
-
- super& operator++() override {
- ++impl_;
- advance();
- return *this;
- }
-
- DELEGATE_ITERATOR_IMPL_BASE(impl_)
- private:
- void advance() {
- while (impl_ != end_ && !pred_(mem_ = *impl_)) {
- ++impl_;
- }
- }
-
- std::function<bool(T const&)> pred_;
- ref_or_val<T> mem_; // To avoid re-calcs, we store this
- ::stream::iterator<T> impl_, end_;
- };
- }
-
- template <typename T>
- class filter_stream : public stream_impl<T> {
- public:
- template <typename F>
- 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()}};
- }
-
- 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)};
- }
- } }
|