| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #pragma once
- #include <algorithm>
- #include <memory>
- #include <numeric>
- #define EQ_MEM(x) x == dynamic_cast<iterator const&>(other).x
- #define DELEGATE_ITERATOR_IMPL_BASE(impl) \
- super* clone() const override { return new iterator{*this}; } \
- bool operator==(super const&other) const override { return EQ_MEM(impl); } \
- #define DELEGATE_ITERATOR_IMPL(impl) \
- super& operator++() override { ++impl; return *this; } \
- DELEGATE_ITERATOR_IMPL_BASE(impl)
- namespace stream {
- template <typename T>
- class iterator {
- public:
- explicit iterator(detail::iterator_impl<T>* impl) : impl_(impl) {}
- iterator(iterator const& other) : impl_(other.impl_->clone()) { }
- iterator(iterator&& other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
- ~iterator() { if (impl_) delete impl_; }
- T operator*() const { return **impl_; }
- iterator& operator++() { ++(*impl_); return *this; }
- bool operator==(iterator const&other) const { return *impl_ == *(other.impl_); }
- bool operator!=(iterator const&other) const { return *impl_ != *(other.impl_); }
- private:
- detail::iterator_impl<T>* impl_;
- };
-
- namespace detail {
- template <typename T>
- stream_base<T, false> falsify(stream_base<T, true> const& in);
-
- template <typename T>
- class iterator_impl {
- public:
- virtual ~iterator_impl() {}
- virtual iterator_impl<T>* clone() const = 0;
- virtual T operator*() = 0;
- virtual iterator_impl<T>& operator++() = 0;
- virtual bool operator==(iterator_impl<T> const&other) const = 0;
- bool operator!=(iterator_impl<T> const&other) const {
- return !operator==(other);
- }
- };
-
- template <typename T>
- class stream_impl {
- public:
- virtual ~stream_impl() { }
- virtual ::stream::iterator<T> begin() = 0;
- virtual ::stream::iterator<T> end() = 0;
- };
-
- template <typename T, bool Own>
- class stream_base {
- private:
- template <typename F>
- using map_f = decltype(std::declval<F>()(std::declval<T>()));
- template <typename F>
- using flatmap_f = typename decltype(std::declval<F>()(std::declval<T>()))::value_type;
-
- using self = stream_base<T, Own>;
- public:
- explicit stream_base(stream_impl<T>* impl) : impl_(impl) {}
- stream_base(stream_base&&other) : impl_(nullptr) { std::swap(impl_, other.impl_); }
- ~stream_base() { if (Own && impl_) delete impl_; }
- ::stream::iterator<T> begin() const { return impl_->begin(); }
- ::stream::iterator<T> end () const { return impl_->end (); }
-
- std::vector<T> collect() const {
- std::vector<T> coll;
- collect(coll);
- return coll;
- }
-
- template <typename C>
- C& collect(typename std::enable_if<!
- std::is_void<typename C::value_type>::value, C>::type& coll) const {
- std::copy(begin(), end(), std::inserter(coll.end(), coll));
- return coll;
- }
-
- template <typename F>
- T accumulate(F&& fold, T const& accum) {
- return std::accumulate(begin(), end(), accum, fold);
- }
-
- template <typename F>
- stream_base<map_f<F>, true> map(F&& func) const&;
- template <typename F>
- stream_base<map_f<F>, true> map(F&& func) &&;
- template <typename F>
- stream_base<T, true> filter(F&& func) const&;
- template <typename F>
- stream_base<T, true> filter(F&& func) &&;
- template <typename F>
- stream_base<flatmap_f<F>, true> flatmap(F&& func) const&;
- template <typename F>
- stream_base<flatmap_f<F>, true> flatmap(F&& func) &&;
- private:
- friend stream_base<T, false> falsify<T>(stream_base<T, true>const&);
- stream_impl<T>* impl_;
- };
-
- template <typename T>
- stream_base<T, false> const& falsify(stream_base<T, false> const& in) { return in; }
- template <typename T>
- stream_base<T, false> falsify(stream_base<T, true> const& in) {
- return stream_base<T, false>{in.impl_};
- }
- }
- }
|