join.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #pragma once
  2. #include <iterator>
  3. namespace stream { namespace detail {
  4. #define JOIN_CTOR( mod ) \
  5. start_ = mod(other.start_); \
  6. finish_ = mod(other.finish_); \
  7. std::ptrdiff_t n = std::distance(other.mem_.cbegin(), other.curr_); \
  8. mem_ = mod(other.mem_); \
  9. curr_ = mem_.begin(); \
  10. std::advance(curr_, n); \
  11. end_ = mem_.end();
  12. namespace join {
  13. template <typename C>
  14. class iterator {
  15. public:
  16. iterator(::stream::iterator<C>&& f, ::stream::iterator<C>&& l)
  17. : start_(std::forward<::stream::iterator<C>>(f))
  18. , finish_(std::forward<::stream::iterator<C>>(l))
  19. {
  20. if (start_ != finish_) {
  21. mem_ = *(start_);
  22. curr_ = mem_.begin();
  23. end_ = mem_.end();
  24. advance();
  25. }
  26. }
  27. iterator(iterator const & other) {
  28. JOIN_CTOR( )
  29. }
  30. iterator(iterator && other) {
  31. JOIN_CTOR( std::move )
  32. }
  33. iterator & operator=(iterator const & other) {
  34. JOIN_CTOR( )
  35. return *this;
  36. }
  37. iterator & operator=(iterator && other) {
  38. JOIN_CTOR( std::move )
  39. return *this;
  40. }
  41. typename C::value_type operator*() { return *curr_; }
  42. iterator& operator++() {
  43. ++curr_;
  44. advance();
  45. return *this;
  46. }
  47. DELEGATE_ITERATOR_IMPL_BASE(start_)
  48. private:
  49. void advance() {
  50. while (curr_ == end_ && start_ != finish_) {
  51. if ( ++start_ == finish_ ) { break; }
  52. mem_ = *start_;
  53. curr_ = mem_.begin();
  54. end_ = mem_.end();
  55. }
  56. }
  57. ::stream::iterator<C> start_, finish_;
  58. C mem_;
  59. typename C::const_iterator curr_, end_;
  60. };
  61. }
  62. template <typename C>
  63. class join_stream {
  64. public:
  65. using T = typename C::value_type;
  66. explicit join_stream(stream_base<C> const& sb) : source_(sb) {}
  67. ::stream::iterator<T> begin() {
  68. return {join::iterator<C>{source_.begin(), source_.end()}};
  69. }
  70. ::stream::iterator<T> end() {
  71. return {join::iterator<C>{source_.end(), source_.end()}};
  72. }
  73. private:
  74. stream_base<C> source_;
  75. };
  76. template <typename C>
  77. auto make_join(stream_base<C> const& sb) -> stream_base<typename C::value_type> {
  78. using T = typename C::value_type;
  79. return std::make_shared<join_stream<C>>(sb);
  80. }
  81. template <typename T>
  82. template <typename F>
  83. auto stream_base<T>::flatmap(F&& func) const -> stream_base<flatmap_f<F>> {
  84. return make_join((*this).map(func));
  85. }
  86. } }