streams.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #pragma once
  2. #include <algorithm>
  3. #include <memory>
  4. #include <numeric>
  5. #include <vector>
  6. #define DELEGATE_ITERATOR_IMPL_BASE(impl) \
  7. bool operator==(iterator const & other) const { return impl == other.impl; }
  8. #define DELEGATE_ITERATOR_IMPL(impl) \
  9. DELEGATE_ITERATOR_IMPL_BASE(impl) \
  10. iterator & operator++() { \
  11. ++impl; \
  12. return *this; \
  13. }
  14. namespace stream {
  15. #define STREAM_ITERATOR_COPY() \
  16. copy(other.copy), dereference(other.dereference), compare(other.compare), \
  17. destroy(other.destroy), advance(other.advance), type_(other.type_)
  18. template <typename T> class iterator {
  19. public:
  20. using value_type = typename std::remove_reference<T>::type;
  21. using reference = value_type &;
  22. using pointer = value_type *;
  23. using difference_type = std::ptrdiff_t;
  24. using iterator_category = std::forward_iterator_tag;
  25. public:
  26. iterator() = default;
  27. template <typename Iter> iterator(Iter impl) {
  28. copy = [](void * p) { return (void *)new Iter(*(Iter *)(p)); };
  29. dereference = [](void * p) -> T { return **((Iter *)p); };
  30. compare = [](void * l, void * r) { return *((Iter *)l) == *((Iter *)r); };
  31. destroy = [](void * p) { delete (Iter *)(p); };
  32. advance = [](void * p) { ++(*(Iter *)(p)); };
  33. type_ = typeid(Iter).name();
  34. impl_ = copy(&impl);
  35. }
  36. iterator(iterator const & other)
  37. : STREAM_ITERATOR_COPY(), impl_(copy(other.impl_)) {}
  38. iterator(iterator && other) : STREAM_ITERATOR_COPY(), impl_(other.impl_) {
  39. other.impl_ = nullptr;
  40. }
  41. iterator & operator=(iterator const & other) {
  42. return *this = iterator{other};
  43. }
  44. iterator & operator=(iterator && other) {
  45. swap(*this, other);
  46. return *this;
  47. }
  48. ~iterator() {
  49. if (destroy) destroy(impl_);
  50. }
  51. T operator*() const { return dereference(impl_); }
  52. iterator & operator++() {
  53. advance(impl_);
  54. return *this;
  55. }
  56. bool operator==(iterator const & other) const {
  57. if (strcmp(type_, other.type_)) { return false; }
  58. return compare(impl_, other.impl_);
  59. }
  60. bool operator!=(iterator const & other) const {
  61. if (strcmp(type_, other.type_)) { return false; }
  62. return !compare(impl_, other.impl_);
  63. }
  64. private:
  65. friend void swap(iterator & lhs, iterator & rhs) {
  66. using std::swap;
  67. swap(lhs.copy, rhs.copy);
  68. swap(lhs.dereference, rhs.dereference);
  69. swap(lhs.compare, rhs.compare);
  70. swap(lhs.destroy, rhs.destroy);
  71. swap(lhs.advance, rhs.advance);
  72. swap(lhs.type_, rhs.type_);
  73. swap(lhs.impl_, rhs.impl_);
  74. }
  75. using delegate = void (*)(void *);
  76. void * (*copy)(void *){nullptr};
  77. T (*dereference)(void *){nullptr};
  78. bool (*compare)(void *, void *){nullptr};
  79. delegate destroy{nullptr}, advance{nullptr};
  80. char const * type_{nullptr};
  81. void * impl_{nullptr};
  82. };
  83. namespace detail {
  84. template <typename T, typename = void> class stream_base_pointer_impl {};
  85. template <typename T>
  86. class stream_base_pointer_impl<
  87. T, typename std::enable_if<traits::is_dereferencable<T>::value>::type> {
  88. private:
  89. using self_t = stream_base<T>;
  90. using pointer = typename std::remove_reference<T>::type;
  91. using element_type = typename std::pointer_traits<pointer>::element_type;
  92. public:
  93. auto deref() const & -> stream_base<element_type &> {
  94. return static_cast<self_t const *>(this)->map(
  95. [](T const & p) -> element_type & { return *p; });
  96. }
  97. auto deref() && -> stream_base<element_type &> {
  98. return static_cast<self_t &&>(*this).map(
  99. [](T const & p) -> element_type & { return *p; });
  100. }
  101. };
  102. template <typename T>
  103. class stream_base : public stream_base_pointer_impl<T> {
  104. private:
  105. using value_type = typename std::decay<T>::type;
  106. public:
  107. template <typename Stream> stream_base(std::shared_ptr<Stream> && impl) {
  108. do_begin = [](std::shared_ptr<void> p) -> iterator<T> {
  109. return std::static_pointer_cast<Stream>(p)->begin();
  110. };
  111. do_end = [](std::shared_ptr<void> p) -> iterator<T> {
  112. return std::static_pointer_cast<Stream>(p)->end();
  113. };
  114. impl_ = std::static_pointer_cast<void>(impl);
  115. }
  116. ::stream::iterator<T> begin() const { return do_begin(impl_); }
  117. ::stream::iterator<T> end() const { return do_end(impl_); }
  118. bool empty() const { return begin() == end(); }
  119. std::vector<value_type> collect() const {
  120. std::vector<value_type> coll;
  121. collect(coll);
  122. return coll;
  123. }
  124. template <typename C,
  125. typename = typename std::enable_if<
  126. !std::is_void<typename C::value_type>::value, void>::type>
  127. C & collect(C & coll) const {
  128. std::copy(begin(), end(), std::inserter(coll, coll.end()));
  129. return coll;
  130. }
  131. template <typename F>
  132. value_type accumulate(F && fold, value_type const & accum) const {
  133. return std::accumulate(begin(), end(), accum, fold);
  134. }
  135. value_type accumulate(value_type const & accum) const {
  136. return std::accumulate(begin(), end(), accum);
  137. }
  138. template <typename F> void each(F && consumer) const {
  139. std::for_each(begin(), end(), consumer);
  140. }
  141. template <typename F>
  142. stream_base<traits::mapped_t<T, F>> map(F && func) const &;
  143. template <typename F> stream_base<T> filter(F && func) const &;
  144. template <typename F>
  145. stream_base<traits::fmapped_t<T, F>> flatmap(F && func) const &;
  146. template <typename F>
  147. stream_base<traits::mapped_t<T, F>> map(F && func) &&;
  148. template <typename F> stream_base<T> filter(F && func) &&;
  149. template <typename F>
  150. stream_base<traits::fmapped_t<T, F>> flatmap(F && func) &&;
  151. template <typename Cast> stream_base<Cast const &> cast() const & {
  152. return map([](T const & p) -> Cast const & { return p; });
  153. }
  154. template <typename Cast> stream_base<Cast const &> cast() && {
  155. return std::move(*this).map(
  156. [](T const & p) -> Cast const & { return p; });
  157. }
  158. template <typename F, typename = traits::is_memvar_t<F>>
  159. stream_base<traits::memvar_f<F>> map(F && memvar) const & {
  160. return map(map_member_object<F>{memvar});
  161. }
  162. template <typename F, typename = traits::is_memfun_t<F>>
  163. stream_base<traits::memfun_f<F>> map(F && memvar) const & {
  164. return map(map_member_function<F>{memvar});
  165. }
  166. template <typename F, typename = traits::is_memvar_t<F>>
  167. stream_base<traits::memvar_f<F>> map(F && memvar) && {
  168. return std::move(*this).map(map_member_object<F>{memvar});
  169. }
  170. template <typename F, typename = traits::is_memfun_t<F>>
  171. stream_base<traits::memfun_f<F>> map(F && memvar) && {
  172. return std::move(*this).map(map_member_function<F>{memvar});
  173. }
  174. private:
  175. iterator<T> (*do_begin)(std::shared_ptr<void>){nullptr};
  176. iterator<T> (*do_end)(std::shared_ptr<void>){nullptr};
  177. std::shared_ptr<void> impl_{nullptr};
  178. };
  179. }
  180. }