|
|
@@ -9,45 +9,46 @@
|
|
|
|
|
|
namespace stream::ranges {
|
|
|
|
|
|
-template <typename T> class view {
|
|
|
-public:
|
|
|
- class iterator : public facade<iterator> {
|
|
|
- private:
|
|
|
- T (*dereference_)(void *){nullptr};
|
|
|
- bool (*equal_to_)(void *, void *){nullptr};
|
|
|
- void (*increment_)(void *){nullptr};
|
|
|
- std::shared_ptr<void> impl_{nullptr};
|
|
|
+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>
|
|
|
- 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)) {}
|
|
|
+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(iterator const & other) const {
|
|
|
- return impl_ == other.impl_ ||
|
|
|
- (impl_ && other.impl_ &&
|
|
|
- equal_to_(impl_.get(), other.impl_.get()));
|
|
|
- }
|
|
|
- };
|
|
|
+ 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};
|
|
|
- iterator (*begin_)(void *){nullptr};
|
|
|
- iterator (*end_)(void *){nullptr};
|
|
|
+ make_iter_t begin_{nullptr};
|
|
|
+ make_iter_t end_{nullptr};
|
|
|
|
|
|
public:
|
|
|
template <typename S>
|
|
|
view(std::shared_ptr<S> impl)
|
|
|
- : impl_(impl), begin_([](void * p) -> iterator {
|
|
|
- return static_cast<S *>(p)->begin();
|
|
|
- }),
|
|
|
- end_([](void * p) -> iterator { return static_cast<S *>(p)->end(); }) {}
|
|
|
+ : impl_(impl), begin_(begin_function<S>()), end_(end_function<S>()) {}
|
|
|
|
|
|
template <typename S>
|
|
|
view(S & impl) : view(std::shared_ptr<S>(&impl, [](void *) {})) {}
|
|
|
@@ -60,7 +61,39 @@ public:
|
|
|
|
|
|
auto begin() const { return begin_(impl_.get()); }
|
|
|
auto end() const { return end_(impl_.get()); }
|
|
|
- bool empty() const { return begin() == end(); }
|
|
|
+
|
|
|
+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>>;
|
|
|
+
|
|
|
}
|