| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- #pragma once
- #include <iterator>
- namespace stream { namespace detail {
- #define JOIN_CTOR( mod ) \
- start_ = mod(other.start_); \
- finish_ = mod(other.finish_); \
- std::ptrdiff_t n = std::distance(other.mem_.cbegin(), other.curr_); \
- mem_ = mod(other.mem_); \
- curr_ = mem_.begin(); \
- std::advance(curr_, n); \
- end_ = mem_.end();
- namespace join {
- template <typename C>
- class iterator {
- public:
- iterator(::stream::iterator<C>&& f, ::stream::iterator<C>&& l)
- : start_(std::forward<::stream::iterator<C>>(f))
- , finish_(std::forward<::stream::iterator<C>>(l))
- {
- if (start_ != finish_) {
- mem_ = *(start_);
- curr_ = mem_.begin();
- end_ = mem_.end();
- advance();
- }
- }
-
- iterator(iterator const & other) {
- JOIN_CTOR( )
- }
-
- iterator(iterator && other) {
- JOIN_CTOR( std::move )
- }
-
- iterator & operator=(iterator const & other) {
- JOIN_CTOR( )
- return *this;
- }
-
- iterator & operator=(iterator && other) {
- JOIN_CTOR( std::move )
- return *this;
- }
-
- typename C::value_type operator*() { return *curr_; }
-
- iterator& operator++() {
- ++curr_;
- advance();
- return *this;
- }
-
- DELEGATE_ITERATOR_IMPL_BASE(start_)
- private:
- void advance() {
- while (curr_ == end_ && start_ != finish_) {
- if ( ++start_ == finish_ ) { break; }
- mem_ = *start_;
- curr_ = mem_.begin();
- end_ = mem_.end();
- }
- }
- ::stream::iterator<C> start_, finish_;
- C mem_;
- typename C::const_iterator curr_, end_;
- };
- }
-
- template <typename C>
- class join_stream {
- public:
- using T = typename C::value_type;
- explicit join_stream(stream_base<C> const& sb) : source_(sb) {}
-
- ::stream::iterator<T> begin() {
- return {join::iterator<C>{source_.begin(), source_.end()}};
- }
- ::stream::iterator<T> end() {
- return {join::iterator<C>{source_.end(), source_.end()}};
- }
- private:
- stream_base<C> source_;
- };
-
- template <typename C>
- auto make_join(stream_base<C> const& sb) -> stream_base<typename C::value_type> {
- using T = typename C::value_type;
- return join_stream<C>(sb);
- }
-
- template <typename T>
- template <typename F>
- auto stream_base<T>::flatmap(F&& func) const -> stream_base<flatmap_f<F>> {
- return make_join((*this).map(func));
- }
- } }
|