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