streams.hpp 6.0 KB

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