streams.hpp 7.1 KB

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