Przeglądaj źródła

fix: fix some type errors

Sam Jaffe 2 lat temu
rodzic
commit
d55f4e4552

+ 13 - 2
include/stream/common_view.h

@@ -9,6 +9,7 @@
 
 #include <iterator/sentinel_iterator.h>
 #include <stream/forward.h>
+#include <stream/detail/traits.h>
 
 #define FWD(x) std::forward<decltype(x)>(x)
 
@@ -22,8 +23,18 @@ public:
 
   auto begin() const { return iterator::sentinel_iterator(stream_.begin()); }
   auto end() const { return decltype(begin())(); }
-  bool empty() const { return stream_.empty(); }
-  size_t size() const { return stream_.size(); }
+  
+  auto empty() const {
+    if constexpr (traits::has_empty_v<S>) {
+      return stream_.empty();
+    }
+  }
+  
+  auto size() {
+    if constexpr (traits::has_size_v<S>) {
+      return stream_.size();
+    }
+  }
 };
 
 template <typename S> common_view(S &&) -> common_view<S>;

+ 3 - 3
include/stream/detail/traits.h

@@ -23,16 +23,16 @@ template <typename C> using begin_t = decltype(std::begin(_val(C)));
 template <typename C> using end_t = decltype(std::end(_val(C)));
 
 template <typename C> using ref_t = decltype(*_val(begin_t<C>));
-template <typename C> using value_type = std::decay_t<ref_t<C>>;
+template <typename C> using value_type = std::remove_reference_t<ref_t<C>>;
 template <typename C> using cref_t = std::add_const_t<ref_t<C>>;
 
 template <typename, typename = void> struct has_size : std::false_type {};
 template <typename, typename = void> struct has_empty : std::false_type {};
 
 template <typename C>
-struct has_size<C, exists(_val(C).size())> : std::true_type {};
+struct has_size<C, std::enable_if_t<std::is_integral_v<decltype(_val(C).size())>>> : std::true_type {};
 template <typename C>
-struct has_empty<C, exists(_val(C).empty())> : std::true_type {};
+struct has_empty<C, std::enable_if_t<std::is_same_v<decltype(_val(C).empty()), bool>>> : std::true_type {};
 
 template <typename It, typename S, typename = void>
 struct is_comparable : std::false_type {};

+ 13 - 2
include/stream/transform_view.h

@@ -40,6 +40,7 @@ public:
       : stream_(FWD(stream)), projection_(projection) {}
 
   auto begin() const { return transform_iterator(stream_.begin(), invoke()); }
+  
   auto end() const {
     if constexpr (traits::is_sentinal_v<S>) {
       return stream_.end();
@@ -47,8 +48,18 @@ public:
       return transform_iterator(stream_.end(), invoke());
     }
   }
-  bool empty() const { return stream_.empty(); }
-  size_t size() const { return stream_.size(); }
+  
+  auto empty() const {
+    if constexpr (traits::has_empty_v<S>) {
+      return stream_.empty();
+    }
+  }
+  
+  auto size() {
+    if constexpr (traits::has_size_v<S>) {
+      return stream_.size();
+    }
+  }
 
 private:
   auto invoke() const {

+ 64 - 31
include/stream/view.h

@@ -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>>;
+
 }