filter.hpp 1.7 KB

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