streams.hpp 7.0 KB

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