Bläddra i källkod

refactor: add std::ref as appropriate
refactor: add size check in ranges::equal when useful

Sam Jaffe 2 år sedan
förälder
incheckning
1f8efc34db

+ 1 - 1
include/stream/algorithm/all_of.h

@@ -24,6 +24,6 @@ bool all_of(It it, S end, Pred pred, Proj proj = {}) {
 
 template <typename Stream, typename Pred, typename Proj = detail::identity>
 bool all_of(Stream const & stream, Pred pred, Proj proj = {}) {
-  return all_of(stream.begin(), stream.end(), pred, proj);
+  return all_of(stream.begin(), stream.end(), std::ref(pred), std::ref(proj));
 }
 }

+ 1 - 1
include/stream/algorithm/any_of.h

@@ -24,6 +24,6 @@ bool any_of(It it, S end, Pred pred, Proj proj = {}) {
 
 template <typename Stream, typename Pred, typename Proj = detail::identity>
 bool any_of(Stream const & stream, Pred pred, Proj proj = {}) {
-  return any_of(stream.begin(), stream.end(), pred, proj);
+  return any_of(stream.begin(), stream.end(), std::ref(pred), std::ref(proj));
 }
 }

+ 1 - 1
include/stream/algorithm/count.h

@@ -23,6 +23,6 @@ bool count(It it, S end, T const & value, Proj proj = {}) {
 
 template <typename Stream, typename T, typename Proj = detail::identity>
 bool count(Stream const & stream, T const & value, Proj proj = {}) {
-  return count(stream.begin(), stream.end(), value, proj);
+  return count(stream.begin(), stream.end(), value, std::ref(proj));
 }
 }

+ 1 - 1
include/stream/algorithm/count_if.h

@@ -25,6 +25,6 @@ auto count_if(It it, S end, Pred pred, Proj proj = {}) {
 
 template <typename Stream, typename Pred, typename Proj = detail::identity>
 auto count_if(Stream const & stream, Pred pred, Proj proj = {}) {
-  return count_if(stream.begin(), stream.end(), pred, proj);
+  return count_if(stream.begin(), stream.end(), std::ref(pred), std::ref(proj));
 }
 }

+ 6 - 1
include/stream/algorithm/equal.h

@@ -23,6 +23,10 @@ template <typename It1, typename S1, typename It2, typename S2,
                     detail::is_comparable_v<It2, S2>))>
 bool equal(It1 it1, S1 end1, It2 it2, S2 end2, Cmp cmp = {}, Proj1 proj1 = {},
            Proj2 proj2 = {}) {
+  if constexpr (detail::is_sized_sentinel_v<It1, S1> &&
+                detail::is_sized_sentinel_v<It2, S2>) {
+    if ((end1 - it1) != (end2 - it2)) { return false; }
+  }
   for (; it1 != end1 && it2 != end2; ++it1, ++it2) {
     if (!detail::invoke(cmp, *it1, *it2, proj1, proj2)) { return false; }
   }
@@ -33,7 +37,8 @@ template <typename R1, typename R2, typename Cmp = std::equal_to<>,
           typename Proj1 = detail::identity, typename Proj2 = detail::identity>
 bool equal(R1 const r1, R2 const & r2, Cmp cmp = {}, Proj1 proj1 = {},
            Proj2 proj2 = {}) {
-  return equal(r1.begin(), r1.end(), r2.begin(), r2.end(), cmp, proj1, proj2);
+  return equal(r1.begin(), r1.end(), r2.begin(), r2.end(), std::ref(cmp),
+               std::ref(proj1), std::ref(proj2));
 }
 
 }

+ 1 - 1
include/stream/algorithm/fold.h

@@ -34,7 +34,7 @@ auto fold_left(Stream && stream, T init, F reduce) {
 template <typename Stream, typename F>
 auto fold_left_with_first(Stream && stream, F reduce) {
   return fold_left(++stream.begin(), stream.end(), *stream.begin(),
-                   std::move(reduce));
+                   std::ref(reduce));
 }
 }
 

+ 1 - 2
include/stream/algorithm/for_each.h

@@ -23,8 +23,7 @@ auto for_each(It it, S end, F func, Proj proj = {}) {
 
 template <typename Stream, typename F, typename Proj = detail::identity>
 auto for_each(Stream && stream, F func, Proj proj = {}) {
-  return for_each(stream.begin(), stream.end(), std::move(func),
-                  std::move(proj));
+  return for_each(stream.begin(), stream.end(), std::ref(func), std::ref(proj));
 }
 }
 

+ 6 - 3
include/stream/algorithm/max.h

@@ -36,20 +36,23 @@ auto max_element(It it, S end, Comp comp = {}, Proj proj = {}) {
 template <typename Stream, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto max_element(Stream const & stream, Comp comp = {}, Proj proj = {}) {
-  return max_element(stream.begin(), stream.end(), comp, proj);
+  return max_element(stream.begin(), stream.end(), std::ref(comp),
+                     std::ref(proj));
 }
 
 template <typename T, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto max(std::initializer_list<T> const & stream, Comp comp = {},
          Proj proj = {}) {
-  return *max_element(stream.begin(), stream.end(), comp, proj);
+  return *max_element(stream.begin(), stream.end(), std::ref(comp),
+                      std::ref(proj));
 }
 
 template <typename Stream, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto max(Stream const & stream, Comp comp = {}, Proj proj = {}) {
-  return *max_element(stream.begin(), stream.end(), comp, proj);
+  return *max_element(stream.begin(), stream.end(), std::ref(comp),
+                      std::ref(proj));
 }
 }
 

+ 6 - 3
include/stream/algorithm/min.h

@@ -36,19 +36,22 @@ auto min_element(It it, S end, Comp comp = {}, Proj proj = {}) {
 template <typename Stream, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto min_element(Stream const & stream, Comp comp = {}, Proj proj = {}) {
-  return min_element(stream.begin(), stream.end(), comp, proj);
+  return min_element(stream.begin(), stream.end(), std::ref(comp),
+                     std::ref(proj));
 }
 
 template <typename T, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto min(std::initializer_list<T> stream, Comp comp = {}, Proj proj = {}) {
-  return *min_element(stream.begin(), stream.end(), comp, proj);
+  return *min_element(stream.begin(), stream.end(), std::ref(comp),
+                      std::ref(proj));
 }
 
 template <typename Stream, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto min(Stream const & stream, Comp comp = {}, Proj proj = {}) {
-  return *min_element(stream.begin(), stream.end(), comp, proj);
+  return *min_element(stream.begin(), stream.end(), std::ref(comp),
+                      std::ref(proj));
 }
 }
 

+ 6 - 3
include/stream/algorithm/minmax.h

@@ -43,20 +43,23 @@ auto minmax_element(It it, S end, Comp comp = {}, Proj proj = {}) {
 template <typename Stream, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto minmax_element(Stream const & stream, Comp comp = {}, Proj proj = {}) {
-  return minmax_element(stream.begin(), stream.end(), comp, proj);
+  return minmax_element(stream.begin(), stream.end(), std::ref(comp),
+                        std::ref(proj));
 }
 
 template <typename T, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto minmax(std::initializer_list<T> stream, Comp comp = {}, Proj proj = {}) {
-  auto result = minmax_element(stream.begin(), stream.end(), comp, proj);
+  auto result = minmax_element(stream.begin(), stream.end(), std::ref(comp),
+                               std::ref(proj));
   return detail::min_max_result(*result.min, *result.max);
 }
 
 template <typename Stream, typename Comp = std::less<>,
           typename Proj = detail::identity>
 auto minmax(Stream const & stream, Comp comp = {}, Proj proj = {}) {
-  auto result = minmax_element(stream.begin(), stream.end(), comp, proj);
+  auto result = minmax_element(stream.begin(), stream.end(), std::ref(comp),
+                               std::ref(proj));
   return detail::min_max_result(*result.min, *result.max);
 }
 }

+ 1 - 1
include/stream/algorithm/none_of.h

@@ -24,6 +24,6 @@ bool none_of(It it, S end, Pred pred, Proj proj = {}) {
 
 template <typename Stream, typename Pred, typename Proj = detail::identity>
 bool none_of(Stream const & stream, Pred pred, Proj proj = {}) {
-  return none_of(stream.begin(), stream.end(), pred, proj);
+  return none_of(stream.begin(), stream.end(), std::ref(pred), std::ref(proj));
 }
 }

+ 2 - 2
include/stream/algorithm/size.h

@@ -11,8 +11,8 @@
 
 namespace stream::ranges {
 template <typename It, typename S> std::ptrdiff_t distance(It it, S end) {
-  if constexpr (std::is_same_v<It, S>) {
-    return std::distance(it, end);
+  if constexpr (detail::is_sized_sentinel_v<It, S>) {
+    return end - it;
   } else {
     std::ptrdiff_t accum = 0;
     for (; it != end; ++it) {

+ 9 - 0
include/stream/detail/traits.h

@@ -41,6 +41,12 @@ struct is_comparable : std::false_type {};
 template <typename It, typename S>
 struct is_comparable<It, S, EXISTS(VAL(It) == VAL(S))> : std::true_type {};
 
+template <typename It, typename S, typename = void>
+struct is_sized_sentinel : std::false_type {};
+
+template <typename It, typename S>
+struct is_sized_sentinel<It, S, EXISTS(VAL(S) - VAL(It))> : std::true_type {};
+
 template <typename C> constexpr bool has_size_v = has_size<C>{};
 template <typename C> constexpr bool has_empty_v = has_empty<C>{};
 template <typename It, typename S>
@@ -48,6 +54,9 @@ constexpr bool is_comparable_v = is_comparable<It, S>{};
 
 template <typename S>
 constexpr bool is_sentinal_v = !std::is_same_v<begin_t<S>, end_t<S>>;
+
+template <typename It, typename S>
+constexpr bool is_sized_sentinel_v = is_sized_sentinel<It, S>{};
 }
 
 #include <iterator/detail/undef.h>