| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- //
- // minmax.h
- // stream
- //
- // Created by Sam Jaffe on 3/30/23.
- //
- #pragma once
- #include <optional>
- #include <stream/detail/identity.h>
- #include <stream/detail/named_pair.h>
- #include <stream/detail/traits.h>
- #define FWD(x) std::forward<decltype(x)>(x)
- 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));
- }
- }
- namespace stream::ranges {
- template <typename It, typename S, typename Comp = std::less<>,
- typename Proj = detail::identity>
- 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;
- }
- }
- return v;
- }
- template <typename Stream, typename Comp = std::less<>,
- typename Proj = detail::identity>
- auto minmax(Stream const & stream, Comp comp = {}, Proj proj = {}) {
- return minmax(stream.begin(), stream.end(), std::move(comp), std::move(proj));
- }
- template <typename It, typename S, typename Comp = std::less<>,
- typename Proj = detail::identity>
- 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; }
- }
- return v;
- }
- template <typename Stream, typename Comp = std::less<>,
- typename Proj = detail::identity>
- auto min(Stream const & stream, Comp comp = {}, Proj proj = {}) {
- return min(stream.begin(), stream.end(), std::move(comp), std::move(proj));
- }
- template <typename It, typename S, typename Comp = std::less<>,
- typename Proj = detail::identity>
- 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; }
- }
- return v;
- }
- template <typename Stream, typename Comp = std::less<>,
- typename Proj = detail::identity>
- auto max(Stream const & stream, Comp comp = {}, Proj proj = {}) {
- return max(stream.begin(), stream.end(), std::move(comp), std::move(proj));
- }
- }
- #undef FWD
|