streams.hpp 7.7 KB

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