filter.hpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #pragma once
  2. namespace stream { namespace detail {
  3. namespace filter {
  4. template <typename T>
  5. class iterator {
  6. public:
  7. iterator(std::function<bool(T const&)> f, ::stream::iterator<T>&& impl, ::stream::iterator<T>&& end)
  8. : pred_(f)
  9. , impl_(std::forward<::stream::iterator<T>>(impl))
  10. , end_(std::forward<::stream::iterator<T>>(end)) {
  11. advance();
  12. }
  13. ~iterator() {}
  14. T operator*() { return mem_; }
  15. iterator& operator++() {
  16. ++impl_;
  17. advance();
  18. return *this;
  19. }
  20. DELEGATE_ITERATOR_IMPL_BASE(impl_)
  21. private:
  22. void advance() {
  23. while (impl_ != end_ && !pred_(mem_ = *impl_)) {
  24. ++impl_;
  25. }
  26. }
  27. std::function<bool(T const&)> pred_;
  28. ref_or_val<T> mem_; // To avoid re-calcs, we store this
  29. ::stream::iterator<T> impl_, end_;
  30. };
  31. }
  32. template <typename T>
  33. class filter_stream : public stream_impl<T> {
  34. public:
  35. template <typename F>
  36. filter_stream(F&& func, stream_base<T> const& sb) : pred_(func), source_(sb) {}
  37. ~filter_stream() override {}
  38. iterator<T> begin() override {
  39. return {filter::iterator<T>{pred_, source_.begin(), source_.end()}};
  40. }
  41. iterator<T> end() override {
  42. return {filter::iterator<T>{pred_, source_.end(), source_.end()}};
  43. }
  44. private:
  45. std::function<bool(T const&)> pred_;
  46. stream_base<T> source_;
  47. };
  48. template <typename T>
  49. template <typename F>
  50. auto stream_base<T>::filter(F&& pred) const -> stream_base<T> {
  51. using impl_t = filter_stream<T>;
  52. return {std::make_shared<impl_t>(pred, *this)};
  53. }
  54. } }