streams.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. namespace detail {
  14. template <typename F> struct map_member_object;
  15. template <typename T, typename R>
  16. struct map_member_object<R T::*> {
  17. using type = R const &;
  18. type operator()(T const & val) const { return val.*mem; }
  19. R T::*mem;
  20. };
  21. template <typename F> struct map_member_function;
  22. template <typename T, typename R>
  23. struct map_member_function<R (T::*)() const> {
  24. using type = R;
  25. type operator()(T const & val) const { return val.*mem(); }
  26. R (T::* mem)() const;
  27. };
  28. template <typename T, typename = void>
  29. struct is_dereferencable : public std::false_type {};
  30. template <typename T>
  31. struct is_dereferencable<T, typename std::enable_if<!std::is_void<decltype(*std::declval<T>())>::value>::type> : public std::true_type {};
  32. }
  33. template <typename T>
  34. class iterator {
  35. public:
  36. using value_type = typename std::remove_reference<T>::type;
  37. using reference = value_type &;
  38. using pointer = value_type *;
  39. using difference_type = std::ptrdiff_t;
  40. using iterator_category = std::forward_iterator_tag;
  41. public:
  42. iterator(detail::iterator_impl<T>* impl) : impl_(impl) {}
  43. iterator(iterator const& other) : impl_(other.impl_->clone()) { }
  44. iterator(iterator&& other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
  45. ~iterator() { if (impl_) delete impl_; }
  46. T operator*() const { return **impl_; }
  47. iterator& operator++() { ++(*impl_); return *this; }
  48. bool operator==(iterator const&other) const { return *impl_ == *(other.impl_); }
  49. bool operator!=(iterator const&other) const { return *impl_ != *(other.impl_); }
  50. private:
  51. detail::iterator_impl<T>* impl_;
  52. };
  53. namespace detail {
  54. template <typename T>
  55. class iterator_impl {
  56. public:
  57. virtual ~iterator_impl() {}
  58. virtual iterator_impl<T>* clone() const = 0;
  59. virtual T operator*() = 0;
  60. virtual iterator_impl<T>& operator++() = 0;
  61. virtual bool operator==(iterator_impl<T> const&other) const = 0;
  62. bool operator!=(iterator_impl<T> const&other) const {
  63. return !operator==(other);
  64. }
  65. };
  66. template <typename T>
  67. class stream_impl {
  68. public:
  69. virtual ~stream_impl() { }
  70. virtual ::stream::iterator<T> begin() = 0;
  71. virtual ::stream::iterator<T> end() = 0;
  72. };
  73. template <typename T, typename = void>
  74. class stream_base_pointer_impl {};
  75. template <typename T>
  76. class stream_base_pointer_impl<T, typename std::enable_if<detail::is_dereferencable<typename std::remove_reference<T>::type>::value>::type> {
  77. private:
  78. using self = stream_base<T>;
  79. using noref = typename std::remove_reference<T>::type;
  80. using element_type = typename std::pointer_traits<noref>::element_type;
  81. public:
  82. auto deref() const -> stream_base<element_type &> {
  83. return static_cast<stream_base<T> const *>(this)->map([](T const & p) -> element_type & { return *p; });
  84. }
  85. };
  86. template <typename T>
  87. class stream_base : public stream_base_pointer_impl<T> {
  88. private:
  89. template <typename F>
  90. using map_f = decltype(std::declval<F>()(std::declval<T>()));
  91. template <typename F>
  92. using flatmap_f = typename decltype(std::declval<F>()(std::declval<T>()))::value_type;
  93. using self = stream_base<T>;
  94. using noref = typename std::remove_reference<T>::type;
  95. using clean = typename std::decay<T>::type;
  96. public:
  97. stream_base(std::shared_ptr<stream_impl<T>> const & impl) : impl_(impl) {}
  98. ::stream::iterator<T> begin() const { return impl_->begin(); }
  99. ::stream::iterator<T> end () const { return impl_->end (); }
  100. bool empty() const { return begin() == end(); }
  101. std::vector<clean> collect() const {
  102. std::vector<clean> coll;
  103. collect(coll);
  104. return coll;
  105. }
  106. template <typename C, typename = typename std::enable_if<!std::is_void<typename C::value_type>::value, void>::type>
  107. C& collect(C & coll) const {
  108. std::copy(begin(), end(), std::inserter(coll, coll.end()));
  109. return coll;
  110. }
  111. template <typename F>
  112. clean accumulate(F&& fold, clean const& accum) {
  113. return std::accumulate(begin(), end(), accum, fold);
  114. }
  115. clean accumulate(clean const& accum) {
  116. return std::accumulate(begin(), end(), accum);
  117. }
  118. template <typename F>
  119. void each(F && consumer) {
  120. std::for_each(begin(), end(), consumer);
  121. }
  122. template <typename F>
  123. stream_base<map_f<F>> map(F&& func) const;
  124. template <typename F, typename = typename std::enable_if<std::is_member_object_pointer<F>::value>::type>
  125. auto map(F && memvar) const -> stream_base<typename map_member_object<F>::type> {
  126. return map(map_member_object<F>{memvar});
  127. }
  128. template <typename F, typename = typename std::enable_if<std::is_member_function_pointer<F>::value>::type>
  129. auto map(F && memvar) const -> stream_base<typename map_member_function<F>::type> {
  130. return map(map_member_function<F>{memvar});
  131. }
  132. template <typename Cast>
  133. auto cast() const -> stream_base<Cast const &> {
  134. return map([](T const & p) -> Cast const & { return p; });
  135. }
  136. template <typename F>
  137. stream_base<T> filter(F&& func) const;
  138. template <typename F>
  139. stream_base<flatmap_f<F>> flatmap(F&& func) const;
  140. private:
  141. std::shared_ptr<stream_impl<T>> impl_;
  142. };
  143. }
  144. }