| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- #pragma once
- namespace stream { namespace detail {
- namespace filter {
- template <typename T>
- class iterator {
- public:
- 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();
- }
- T operator*() { return mem_; }
-
- iterator& operator++() {
- ++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:
- template <typename F>
- filter_stream(F&& func, stream_base<T> const& sb) : pred_(func), source_(sb) {}
-
- iterator<T> begin() {
- return {filter::iterator<T>{pred_, source_.begin(), source_.end()}};
- }
-
- iterator<T> end() {
- return {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> {
- return new filter_stream<T>(pred, *this);
- }
- } }
|