| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- #pragma once
- #include <iterator/filter_iterator.hpp>
- #include <stream/iterator.hpp>
- namespace stream::detail {
- template <typename T> class filter_iterator {
- public:
- filter_iterator(std::function<bool(T const &)> f, iterator<T> && impl,
- iterator<T> && end)
- : pred_(f), impl_(std::forward<iterator<T>>(impl)),
- end_(std::forward<iterator<T>>(end)) {
- advance();
- }
- T operator*() { return mem_; }
- filter_iterator & operator++() {
- ++impl_;
- advance();
- return *this;
- }
- bool operator==(filter_iterator const & rhs) const {
- return impl_ == rhs.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
- 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 ::iterator::filter_iterator(pred_, source_); }
- iterator<T> end() { return ::iterator::filter_iterator<iterator<T>>(); }
- private:
- typename ::iterator::filter_iterator<iterator<T>>::predicate_t 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);
- }
- }
|