streams.hpp 6.1 KB

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