streams.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 = typename std::remove_reference<T>::type;
  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, typename = void>
  54. class stream_base_pointer_impl {};
  55. template <typename T>
  56. class stream_base_pointer_impl<T, typename std::enable_if<detail::is_dereferencable<typename std::remove_reference<T>::type>::value>::type> {
  57. private:
  58. using self = stream_base<T>;
  59. using noref = typename std::remove_reference<T>::type;
  60. using element_type = typename std::pointer_traits<noref>::element_type;
  61. public:
  62. auto deref() const -> stream_base<element_type &> {
  63. return static_cast<stream_base<T> const *>(this)->map([](T const & p) -> element_type & { return *p; });
  64. }
  65. };
  66. template <typename T>
  67. class stream_base : public stream_base_pointer_impl<T> {
  68. private:
  69. template <typename F>
  70. using map_f = decltype(std::declval<F>()(std::declval<T>()));
  71. template <typename F>
  72. using flatmap_f = typename decltype(std::declval<F>()(std::declval<T>()))::value_type;
  73. using self = stream_base<T>;
  74. using noref = typename std::remove_reference<T>::type;
  75. using clean = typename std::decay<T>::type;
  76. public:
  77. stream_base(std::shared_ptr<stream_impl<T>> const & impl) : impl_(impl) {}
  78. ::stream::iterator<T> begin() const { return impl_->begin(); }
  79. ::stream::iterator<T> end () const { return impl_->end (); }
  80. bool empty() const { return begin() == end(); }
  81. std::vector<clean> collect() const {
  82. std::vector<clean> coll;
  83. collect(coll);
  84. return coll;
  85. }
  86. template <typename C, typename = typename std::enable_if<!std::is_void<typename C::value_type>::value, void>::type>
  87. C& collect(C & coll) const {
  88. std::copy(begin(), end(), std::inserter(coll, coll.end()));
  89. return coll;
  90. }
  91. template <typename F>
  92. clean accumulate(F&& fold, clean const& accum) {
  93. return std::accumulate(begin(), end(), accum, fold);
  94. }
  95. clean accumulate(clean const& accum) {
  96. return std::accumulate(begin(), end(), accum);
  97. }
  98. template <typename F>
  99. void each(F && consumer) {
  100. std::for_each(begin(), end(), consumer);
  101. }
  102. template <typename F>
  103. stream_base<map_f<F>> map(F&& func) const;
  104. template <typename F, typename = typename std::enable_if<std::is_member_object_pointer<F>::value>::type>
  105. auto map(F && memvar) const -> stream_base<typename map_member_object<F>::type> {
  106. return map(map_member_object<F>{memvar});
  107. }
  108. template <typename F, typename = typename std::enable_if<std::is_member_function_pointer<F>::value>::type>
  109. auto map(F && memvar) const -> stream_base<typename map_member_function<F>::type> {
  110. return map(map_member_function<F>{memvar});
  111. }
  112. template <typename Cast>
  113. auto cast() const -> stream_base<Cast const &> {
  114. return map([](T const & p) -> Cast const & { return p; });
  115. }
  116. template <typename F>
  117. stream_base<T> filter(F&& func) const;
  118. template <typename F>
  119. stream_base<flatmap_f<F>> flatmap(F&& func) const;
  120. private:
  121. std::shared_ptr<stream_impl<T>> impl_;
  122. };
  123. }
  124. }