streams.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #pragma once
  2. #include <algorithm>
  3. #include <memory>
  4. #include <numeric>
  5. #define EQ_MEM(x) x == dynamic_cast<iterator const&>(other).x
  6. #define DELEGATE_ITERATOR_IMPL_BASE(impl) \
  7. super* clone() const override { return new iterator{*this}; } \
  8. bool operator==(super const&other) const override { return EQ_MEM(impl); } \
  9. #define DELEGATE_ITERATOR_IMPL(impl) \
  10. super& operator++() override { ++impl; return *this; } \
  11. DELEGATE_ITERATOR_IMPL_BASE(impl)
  12. namespace stream {
  13. template <typename T>
  14. class iterator {
  15. public:
  16. using value_type = T;
  17. using reference = value_type &;
  18. using pointer = value_type *;
  19. using difference_type = std::ptrdiff_t;
  20. using iterator_category = std::forward_iterator_tag;
  21. public:
  22. iterator(detail::iterator_impl<T>* impl) : impl_(impl) {}
  23. iterator(iterator const& other) : impl_(other.impl_->clone()) { }
  24. iterator(iterator&& other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
  25. ~iterator() { if (impl_) delete impl_; }
  26. T operator*() const { return **impl_; }
  27. iterator& operator++() { ++(*impl_); return *this; }
  28. bool operator==(iterator const&other) const { return *impl_ == *(other.impl_); }
  29. bool operator!=(iterator const&other) const { return *impl_ != *(other.impl_); }
  30. private:
  31. detail::iterator_impl<T>* impl_;
  32. };
  33. namespace detail {
  34. template <typename T>
  35. class iterator_impl {
  36. public:
  37. virtual ~iterator_impl() {}
  38. virtual iterator_impl<T>* clone() const = 0;
  39. virtual T operator*() = 0;
  40. virtual iterator_impl<T>& operator++() = 0;
  41. virtual bool operator==(iterator_impl<T> const&other) const = 0;
  42. bool operator!=(iterator_impl<T> const&other) const {
  43. return !operator==(other);
  44. }
  45. };
  46. template <typename T>
  47. class stream_impl {
  48. public:
  49. virtual ~stream_impl() { }
  50. virtual ::stream::iterator<T> begin() = 0;
  51. virtual ::stream::iterator<T> end() = 0;
  52. };
  53. template <typename T>
  54. class stream_base {
  55. private:
  56. template <typename F>
  57. using map_f = decltype(std::declval<F>()(std::declval<T>()));
  58. template <typename F>
  59. using flatmap_f = typename decltype(std::declval<F>()(std::declval<T>()))::value_type;
  60. using self = stream_base<T>;
  61. public:
  62. stream_base(std::shared_ptr<stream_impl<T>> const & impl) : impl_(impl) {}
  63. ::stream::iterator<T> begin() const { return impl_->begin(); }
  64. ::stream::iterator<T> end () const { return impl_->end (); }
  65. std::vector<T> collect() const {
  66. std::vector<T> coll;
  67. collect(coll);
  68. return coll;
  69. }
  70. template <typename C, typename = typename std::enable_if<!std::is_void<typename C::value_type>::value, void>::type>
  71. C& collect(C & coll) const {
  72. std::copy(begin(), end(), std::inserter(coll, coll.end()));
  73. return coll;
  74. }
  75. template <typename F>
  76. T accumulate(F&& fold, T const& accum) {
  77. return std::accumulate(begin(), end(), accum, fold);
  78. }
  79. template <typename F>
  80. stream_base<map_f<F>> map(F&& func) const;
  81. template <typename F>
  82. stream_base<T> filter(F&& func) const;
  83. template <typename F>
  84. stream_base<flatmap_f<F>> flatmap(F&& func) const;
  85. private:
  86. std::shared_ptr<stream_impl<T>> impl_;
  87. };
  88. }
  89. }