streams.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. explicit 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. stream_base<T, false> falsify(stream_base<T, true> const& in);
  36. template <typename T>
  37. class iterator_impl {
  38. public:
  39. virtual ~iterator_impl() {}
  40. virtual iterator_impl<T>* clone() const = 0;
  41. virtual T operator*() = 0;
  42. virtual iterator_impl<T>& operator++() = 0;
  43. virtual bool operator==(iterator_impl<T> const&other) const = 0;
  44. bool operator!=(iterator_impl<T> const&other) const {
  45. return !operator==(other);
  46. }
  47. };
  48. template <typename T>
  49. class stream_impl {
  50. public:
  51. virtual ~stream_impl() { }
  52. virtual ::stream::iterator<T> begin() = 0;
  53. virtual ::stream::iterator<T> end() = 0;
  54. };
  55. template <typename T, typename = void>
  56. struct has_value_type {
  57. template <typename F>
  58. using flatmap_f = void;
  59. };
  60. template <typename T>
  61. struct has_value_type<T, typename std::enable_if<!std::is_void<typename T::value_type>::value>::type> {
  62. template <typename F>
  63. using flatmap_f = decltype(std::declval<F>()(std::declval<typename T::value_type>()));
  64. };
  65. template <typename T, bool Own>
  66. class stream_base {
  67. private:
  68. template <typename F>
  69. using map_f = decltype(std::declval<F>()(std::declval<T>()));
  70. template <typename F>
  71. using flatmap_f = typename has_value_type<T>::template flatmap_f<F>;
  72. using self = stream_base<T, Own>;
  73. public:
  74. explicit stream_base(stream_impl<T>* impl) : impl_(impl) {}
  75. stream_base(stream_base&&other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
  76. ~stream_base() { if (Own && impl_) delete impl_; }
  77. ::stream::iterator<T> begin() const { return impl_->begin(); }
  78. ::stream::iterator<T> end () const { return impl_->end (); }
  79. std::vector<T> collect() const {
  80. std::vector<T> coll;
  81. collect(coll);
  82. return coll;
  83. }
  84. template <typename C, typename = typename std::enable_if<!std::is_void<typename C::value_type>::value, void>::type>
  85. C& collect(C & coll) const {
  86. std::copy(begin(), end(), std::inserter(coll, coll.end()));
  87. return coll;
  88. }
  89. template <typename F>
  90. T accumulate(F&& fold, T const& accum) {
  91. return std::accumulate(begin(), end(), accum, fold);
  92. }
  93. template <typename F>
  94. stream_base<map_f<F>, true> map(F&& func) const&;
  95. template <typename F>
  96. stream_base<map_f<F>, true> map(F&& func) &&;
  97. template <typename F>
  98. stream_base<T, true> filter(F&& func) const&;
  99. template <typename F>
  100. stream_base<T, true> filter(F&& func) &&;
  101. template <typename F>
  102. stream_base<flatmap_f<F>, true> flatmap(F&& func) const&;
  103. template <typename F>
  104. stream_base<flatmap_f<F>, true> flatmap(F&& func) &&;
  105. private:
  106. friend stream_base<T, false> falsify<T>(stream_base<T, true>const&);
  107. stream_impl<T>* impl_;
  108. };
  109. template <typename T>
  110. stream_base<T, false> const& falsify(stream_base<T, false> const& in) { return in; }
  111. template <typename T>
  112. stream_base<T, false> falsify(stream_base<T, true> const& in) {
  113. return stream_base<T, false>{in.impl_};
  114. }
  115. }
  116. }