| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- #pragma once
- #include <algorithm>
- #include <memory>
- #include <numeric>
- #include <vector>
- #define DELEGATE_ITERATOR_IMPL_BASE(impl) \
- bool operator==(iterator const&other) const { \
- return impl == other.impl; \
- }
- #define DELEGATE_ITERATOR_IMPL(impl) \
- DELEGATE_ITERATOR_IMPL_BASE(impl) \
- iterator& operator++() { \
- ++impl; \
- return *this; \
- }
- namespace stream {
- #define STREAM_ITERATOR_COPY() \
- copy(other.copy), dereference(other.dereference), compare(other.compare), destroy(other.destroy), advance(other.advance), type_(other.type_)
-
- template <typename T>
- class iterator {
- public:
- using value_type = typename std::remove_reference<T>::type;
- using reference = value_type &;
- using pointer = value_type *;
- using difference_type = std::ptrdiff_t;
- using iterator_category = std::forward_iterator_tag;
- public:
- iterator() = default;
-
- template <typename Iter>
- iterator(Iter impl) {
- copy = [](void * p) { return (void*) new Iter(*(Iter*)(p)); };
- dereference = [](void * p) -> T { return **((Iter*)p); };
- compare = [](void * l, void * r) { return *((Iter*)l) == *((Iter*)r); };
- destroy = [](void * p) { delete (Iter*)(p); };
- advance = [](void * p) { ++(*(Iter*)(p)); };
- type_ = typeid(Iter).name();
- impl_ = copy(&impl);
- }
-
- iterator(iterator const& other)
- : STREAM_ITERATOR_COPY()
- , impl_(copy(other.impl_)) {
- }
-
- iterator(iterator && other)
- : STREAM_ITERATOR_COPY()
- , impl_(other.impl_) {
- other.impl_ = nullptr;
- }
-
- iterator & operator=(iterator const & other) {
- return *this = iterator{other};
- }
- iterator & operator=(iterator && other) {
- swap(*this, other);
- return *this;
- }
- ~iterator() { if (destroy) destroy(impl_); }
-
- T operator*() const { return dereference(impl_); }
- iterator& operator++() { advance(impl_); return *this; }
- bool operator==(iterator const&other) const {
- if (strcmp(type_, other.type_)) { return false; }
- return compare(impl_, other.impl_);
- }
- bool operator!=(iterator const&other) const {
- if (strcmp(type_, other.type_)) { return false; }
- return !compare(impl_, other.impl_);
- }
- private:
- friend void swap(iterator & lhs, iterator & rhs) {
- using std::swap;
- swap(lhs.copy, rhs.copy);
- swap(lhs.dereference, rhs.dereference);
- swap(lhs.compare, rhs.compare);
- swap(lhs.destroy, rhs.destroy);
- swap(lhs.advance, rhs.advance);
- swap(lhs.type_, rhs.type_);
- swap(lhs.impl_, rhs.impl_);
- }
- using delegate = void(*)(void*);
- void* (*copy)(void*){nullptr};
- T (*dereference)(void*){nullptr};
- bool (*compare)(void*, void*){nullptr};
- delegate destroy{nullptr}, advance{nullptr};
- char const * type_{nullptr};
- void * impl_{nullptr};
- };
-
- namespace detail {
- template <typename T, typename = void>
- class stream_base_pointer_impl {};
-
- template <typename T>
- class stream_base_pointer_impl<T, typename std::enable_if<traits::is_dereferencable<T>::value>::type> {
- private:
- using self_t = stream_base<T>;
- using pointer = typename std::remove_reference<T>::type;
- using element_type = typename std::pointer_traits<pointer>::element_type;
- public:
- auto deref() const & -> stream_base<element_type &> {
- return static_cast<self_t const *>(this)->map([](T const & p) -> element_type & { return *p; });
- }
-
- auto deref() && -> stream_base<element_type &> {
- return static_cast<self_t &&>(*this).map([](T const & p) -> element_type & { return *p; });
- }
- };
-
- template <typename T>
- class stream_base : public stream_base_pointer_impl<T> {
- private:
- using value_type = typename std::decay<T>::type;
- public:
- template <typename Stream>
- stream_base(std::shared_ptr<Stream> && impl) {
- do_begin = [](std::shared_ptr<void> p) -> iterator<T> { return std::static_pointer_cast<Stream>(p)->begin(); };
- do_end = [](std::shared_ptr<void> p) -> iterator<T> { return std::static_pointer_cast<Stream>(p)->end(); };
- impl_ = std::static_pointer_cast<void>(impl);
- }
-
- ::stream::iterator<T> begin() const { return do_begin(impl_); }
- ::stream::iterator<T> end () const { return do_end (impl_); }
-
- bool empty() const { return begin() == end(); }
-
- std::vector<value_type> collect() const {
- std::vector<value_type> coll;
- collect(coll);
- return coll;
- }
-
- template <typename C, typename = typename std::enable_if<!std::is_void<typename C::value_type>::value, void>::type>
- C & collect(C & coll) const {
- std::copy(begin(), end(), std::inserter(coll, coll.end()));
- return coll;
- }
-
- template <typename F>
- value_type accumulate(F&& fold, value_type const& accum) const {
- return std::accumulate(begin(), end(), accum, fold);
- }
-
- value_type accumulate(value_type const& accum) const {
- return std::accumulate(begin(), end(), accum);
- }
-
- template <typename F>
- void each(F && consumer) const {
- std::for_each(begin(), end(), consumer);
- }
-
- template <typename F>
- stream_base<traits::mapped_t<T, F>> map(F&& func) const &;
- template <typename F>
- stream_base<T> filter(F&& func) const &;
- template <typename F>
- stream_base<traits::fmapped_t<T, F>> flatmap(F&& func) const &;
-
- template <typename F>
- stream_base<traits::mapped_t<T, F>> map(F&& func) &&;
- template <typename F>
- stream_base<T> filter(F&& func) &&;
- template <typename F>
- stream_base<traits::fmapped_t<T, F>> flatmap(F&& func) &&;
-
- template <typename Cast>
- stream_base<Cast const &> cast() const & {
- return map([](T const & p) -> Cast const & { return p; });
- }
-
- template <typename Cast>
- stream_base<Cast const &> cast() && {
- return std::move(*this).map([](T const & p) -> Cast const & { return p; });
- }
-
- template <typename F, typename = traits::is_memvar_t<F>>
- stream_base<traits::memvar_f<F>> map(F && memvar) const & {
- return map(map_member_object<F>{memvar});
- }
-
- template <typename F, typename = traits::is_memfun_t<F>>
- stream_base<traits::memfun_f<F>> map(F && memvar) const & {
- return map(map_member_function<F>{memvar});
- }
- template <typename F, typename = traits::is_memvar_t<F>>
- stream_base<traits::memvar_f<F>> map(F && memvar) && {
- return std::move(*this).map(map_member_object<F>{memvar});
- }
- template <typename F, typename = traits::is_memfun_t<F>>
- stream_base<traits::memfun_f<F>> map(F && memvar) && {
- return std::move(*this).map(map_member_function<F>{memvar});
- }
- private:
- iterator<T> (*do_begin)(std::shared_ptr<void>){nullptr};
- iterator<T> (*do_end)(std::shared_ptr<void>){nullptr};
- std::shared_ptr<void> impl_{nullptr};
- };
- }
- }
|