| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- #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) && -> stream_base<T> {
- return std::make_shared<filter_stream<T>>(pred, std::move(*this));
- }
- template <typename T>
- template <typename F>
- auto stream_base<T>::filter(F && pred) const & -> stream_base<T> {
- return std::make_shared<filter_stream<T>>(pred, *this);
- }
- }}
|