filter.hpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #pragma once
  2. namespace stream {
  3. template <typename T>
  4. struct filter_t {
  5. template <typename F>
  6. explicit filter_t(F&& f) : pred(f) {}
  7. std::function<bool(const T&)> pred;
  8. };
  9. }
  10. template <typename T, bool B>
  11. stream::detail::stream_base<T, true> operator|(stream::detail::stream_base<T, B> const&s, stream::filter_t<T>&& f) {
  12. return s.filter(f.pred);
  13. }
  14. template <typename T, bool B>
  15. stream::detail::stream_base<T, true> operator|(stream::detail::stream_base<T, B> &&s, stream::filter_t<T>&& f) {
  16. return std::move(s).filter(f.pred);
  17. }
  18. namespace stream {
  19. namespace detail {
  20. template <typename T, bool B>
  21. class filter_stream : public stream_impl<T> {
  22. public:
  23. class iterator : public iterator_impl<T> {
  24. public:
  25. typedef iterator_impl<T> super;
  26. iterator(std::function<bool(T const&)> f, ::stream::iterator<T>&& impl)
  27. : pred_(f), impl_(std::forward<::stream::iterator<T>>(impl)), next_(impl_) {
  28. advance();
  29. }
  30. ~iterator() {}
  31. T operator*() override { return mem_; }
  32. super& operator++() override {
  33. ++impl_;
  34. advance();
  35. return *this;
  36. }
  37. DELEGATE_ITERATOR_IMPL_BASE(impl_)
  38. private:
  39. void advance() {
  40. while (!pred_(mem_ = *impl_)) {
  41. ++impl_;
  42. }
  43. }
  44. std::function<bool(T const&)> pred_;
  45. T mem_; // To avoid re-calcs, we store this
  46. ::stream::iterator<T> impl_, next_;
  47. };
  48. template <typename F>
  49. filter_stream(F&& func, stream_base<T, B> const& sb) : pred_(func), source_(sb) {}
  50. template <typename F>
  51. filter_stream(F&& func, stream_base<T, B> && sb) : pred_(func), source_(std::forward<stream_base<T, B>>(sb)) { }
  52. ~filter_stream() override {}
  53. ::stream::iterator<T> begin() override { return new iterator{pred_, source_.begin()};}
  54. ::stream::iterator<T> end() override { return new iterator{pred_, source_.end()}; }
  55. private:
  56. std::function<bool(T const&)> pred_;
  57. stream_base<T, B> source_;
  58. };
  59. template <typename T, bool Own>
  60. template <typename F>
  61. auto stream_base<T, Own>::filter(F&& pred) const& -> stream_base<T, true> {
  62. using impl_t = filter_stream<T, false>;
  63. return stream_base<T, true>{new impl_t{pred, *this}};
  64. }
  65. template <typename T, bool Own>
  66. template <typename F>
  67. auto stream_base<T, Own>::filter(F&& pred) && -> stream_base<T, true> {
  68. using impl_t = filter_stream<T, Own>;
  69. return stream_base<T, true>{new impl_t{pred, std::forward<stream_base<T, Own>>(*this)}};
  70. }
  71. }
  72. }