Browse Source

refactor: use std::invoke to minimize transform design

Sam Jaffe 2 years ago
parent
commit
a96196f9d5
1 changed files with 12 additions and 43 deletions
  1. 12 43
      include/stream/transform_view.h

+ 12 - 43
include/stream/transform_view.h

@@ -26,10 +26,7 @@ public:
   }
 };
 
-template <typename S, typename T> class transform_view {
-public:
-  using Proj = std::function<T(traits::cref_t<S>)>;
-
+template <typename S, typename Proj> class transform_view {
 private:
   S stream_;
   Proj projection_;
@@ -37,23 +34,22 @@ private:
 public:
   transform_view(S && stream, Proj projection)
       : stream_(FWD(stream)), projection_(projection) {}
-  template <typename F>
-  transform_view(S && stream, F projection)
-      : stream_(FWD(stream)), projection_(projection) {}
 
-  auto begin() const {
-    return transform_iterator(stream_.begin(), projection_);
-  }
-  auto end() const { return transform_iterator(stream_.end(), projection_); }
+  auto begin() const { return transform_iterator(stream_.begin(), invoke()); }
+  auto end() const { return transform_iterator(stream_.end(), invoke()); }
   bool empty() const { return stream_.empty(); }
   size_t size() const { return stream_.size(); }
+
+private:
+  auto invoke() const {
+    return std::function([this](traits::cref_t<S> t) -> decltype(auto) {
+      return std::invoke(projection_, t);
+    });
+  }
 };
 
-template <typename S, typename R, typename T>
-transform_view(S &&, std::function<R(T)>) -> transform_view<S, R>;
-template <typename S, typename F>
-transform_view(S &&, F)
-    -> transform_view<S, std::invoke_result_t<F, traits::cref_t<S>>>;
+template <typename S, typename Proj>
+transform_view(S &&, Proj) -> transform_view<S, Proj>;
 }
 
 MAKE_ITERATOR_FACADE_TYPEDEFS_T(stream::ranges::transform_iterator);
@@ -63,22 +59,6 @@ template <typename Proj> class transform {
 public:
   transform(Proj const & projection) : projection_(projection) {}
 
-  template <typename T, typename R>
-  transform(R (*ptr)(T))
-      : projection_([ptr](auto & t) -> R { return ptr(t); }) {}
-
-  template <typename T, typename R>
-  transform(R T::*ptr)
-      : projection_([ptr](auto & t) -> R const & { return t.*ptr; }) {}
-
-  template <typename T, typename R>
-  transform(R (T::*ptr)() const)
-      : projection_([ptr](auto & t) -> R { return (t.*ptr)(); }) {}
-
-  template <typename T, typename R>
-  transform(R (T::*ptr)() const noexcept)
-      : projection_([ptr](auto & t) -> R { return (t.*ptr)(); }) {}
-
   template <typename Stream>
   friend auto operator|(Stream && stream, transform map) {
     // TODO: if constexpr transform_view
@@ -88,17 +68,6 @@ public:
 private:
   Proj projection_;
 };
-
-template <typename Proj> transform(Proj const &) -> transform<Proj>;
-template <typename T, typename R>
-transform(R (*ptr)(T)) -> transform<std::function<R(T const &)>>;
-template <typename T, typename R>
-transform(R T::*ptr) -> transform<std::function<R const &(T const &)>>;
-template <typename T, typename R>
-transform(R (T::*ptr)() const) -> transform<std::function<R(T const &)>>;
-template <typename T, typename R>
-transform(R (T::*ptr)() const noexcept)
-    -> transform<std::function<R(T const &)>>;
 }
 
 #undef FWD