streams.hpp 6.0 KB

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