| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- //
- // view.h
- // stream
- //
- // Created by Sam Jaffe on 3/29/23.
- //
- #pragma once
- namespace stream::ranges {
- template <typename T>
- class view_iterator : public facade<view_iterator<T>> {
- private:
- T (*dereference_)(void *){nullptr};
- bool (*equal_to_)(void *, void *){nullptr};
- void (*increment_)(void *){nullptr};
- std::shared_ptr<void> impl_{nullptr};
- public:
- template <typename It>
- view_iterator(It impl)
- : dereference_([](void * p) -> T { return **((It *)p); }),
- equal_to_(
- [](void * l, void * r) { return *((It *)l) == *((It *)r); }),
- increment_([](void * p) { ++(*(It *)(p)); }),
- impl_(std::make_shared<It>(impl)) {}
- T dereference() const { return dereference_(impl_.get()); }
-
- void increment() { increment_(impl_.get()); }
-
- bool equal_to(view_iterator const & other) const {
- return impl_ == other.impl_ ||
- (impl_ && other.impl_ &&
- equal_to_(impl_.get(), other.impl_.get()));
- }
- };
- template <typename T> class view {
- private:
- using make_iter_t = view_iterator<T>(*)(void*);
- private:
- std::shared_ptr<void> impl_{nullptr};
- make_iter_t begin_{nullptr};
- make_iter_t end_{nullptr};
- public:
- template <typename S>
- view(std::shared_ptr<S> impl)
- : impl_(impl), begin_(begin_function<S>()), end_(end_function<S>()) {}
- template <typename S>
- view(S & impl) : view(std::shared_ptr<S>(&impl, [](void *) {})) {}
- template <typename S>
- view(S const & impl) : view(std::shared_ptr<S const>(&impl, [](void *) {})) {}
- template <typename S>
- view(S && impl) : view(std::make_shared<S>(std::forward<S>(impl))) {}
- auto begin() const { return begin_(impl_.get()); }
- auto end() const { return end_(impl_.get()); }
-
- private:
- template <typename S>
- static make_iter_t begin_function() {
- if constexpr (traits::is_sentinal_v<S>) {
- return [](void *p) -> view_iterator<T> {
- return iterator::sentinel_iterator(static_cast<S *>(p)->begin());
- };
- } else {
- return [](void * p) -> view_iterator<T> {
- return static_cast<S *>(p)->begin();
- };
- }
- }
-
- template <typename S>
- static make_iter_t end_function() {
- if constexpr (traits::is_sentinal_v<S>) {
- return [](void *p) -> view_iterator<T> {
- return iterator::sentinel_iterator<iter<S>>();
- };
- } else {
- return [](void * p) -> view_iterator<T> {
- return static_cast<S *>(p)->end();
- };
- }
- }
- };
- template <typename S> view(std::shared_ptr<S>) -> view<traits::value_type<S>>;
- template <typename S> view(S &) -> view<traits::value_type<S>>;
- template <typename S> view(S const &) -> view<traits::value_type<S>>;
- template <typename S> view(S &&) -> view<traits::value_type<S>>;
- }
|