|
|
@@ -17,24 +17,21 @@
|
|
|
|
|
|
namespace stream::detail {
|
|
|
template <typename T, typename Comp, typename Proj>
|
|
|
-bool compare(T const & l, T const & r, Comp comp, Proj proj) {
|
|
|
- return std::invoke(comp, std::invoke(proj, l), std::invoke(proj, r));
|
|
|
+bool compare(T const & l, T const & r, Comp && comp, Proj && proj) {
|
|
|
+ return std::invoke(FWD(comp), std::invoke(proj, l), std::invoke(proj, r));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
namespace stream::ranges {
|
|
|
|
|
|
template <typename It, typename S, typename Comp = std::less<>,
|
|
|
- typename Proj = detail::identity>
|
|
|
+ typename Proj = detail::identity,
|
|
|
+ typename = std::enable_if_t<traits::is_comparable_v<It, S>>>
|
|
|
auto minmax(It it, S end, Comp comp = {}, Proj proj = {}) {
|
|
|
detail::min_max_result v(*it, *it);
|
|
|
for (++it; it != end; ++it) {
|
|
|
- if (detail::compare(v.max, *it, std::ref(comp), std::ref(proj))) {
|
|
|
- v.max = *it;
|
|
|
- }
|
|
|
- if (detail::compare(*it, v.min, std::ref(comp), std::ref(proj))) {
|
|
|
- v.min = *it;
|
|
|
- }
|
|
|
+ if (detail::compare(v.max, *it, comp, proj)) { v.max = *it; }
|
|
|
+ if (detail::compare(*it, v.min, comp, proj)) { v.min = *it; }
|
|
|
}
|
|
|
return v;
|
|
|
}
|
|
|
@@ -46,11 +43,12 @@ auto minmax(Stream const & stream, Comp comp = {}, Proj proj = {}) {
|
|
|
}
|
|
|
|
|
|
template <typename It, typename S, typename Comp = std::less<>,
|
|
|
- typename Proj = detail::identity>
|
|
|
+ typename Proj = detail::identity,
|
|
|
+ typename = std::enable_if_t<traits::is_comparable_v<It, S>>>
|
|
|
auto min(It it, S end, Comp comp = {}, Proj proj = {}) {
|
|
|
auto v = *it;
|
|
|
for (++it; it != end; ++it) {
|
|
|
- if (detail::compare(*it, v, std::ref(comp), std::ref(proj))) { v = *it; }
|
|
|
+ if (detail::compare(*it, v, comp, proj)) { v = *it; }
|
|
|
}
|
|
|
return v;
|
|
|
}
|
|
|
@@ -62,11 +60,12 @@ auto min(Stream const & stream, Comp comp = {}, Proj proj = {}) {
|
|
|
}
|
|
|
|
|
|
template <typename It, typename S, typename Comp = std::less<>,
|
|
|
- typename Proj = detail::identity>
|
|
|
+ typename Proj = detail::identity,
|
|
|
+ typename = std::enable_if_t<traits::is_comparable_v<It, S>>>
|
|
|
auto max(It it, S end, Comp comp = {}, Proj proj = {}) {
|
|
|
auto v = *it;
|
|
|
for (++it; it != end; ++it) {
|
|
|
- if (detail::compare(v, *it, std::ref(comp), std::ref(proj))) { v = *it; }
|
|
|
+ if (detail::compare(v, *it, comp, proj)) { v = *it; }
|
|
|
}
|
|
|
return v;
|
|
|
}
|