// // min.h // stream // // Created by Sam Jaffe on 4/2/23. // #pragma once #include #include #include #include #include namespace stream::ranges { template , typename Proj = detail::identity> T const & min(T const & l, T const & r, Comp comp = {}, Proj proj = {}) { return detail::invoke(comp, l, r, proj, proj) ? l : r; } template , typename Proj = detail::identity, REQUIRES((detail::is_comparable_v))> auto min_element(It it, S end, Comp comp = {}, Proj proj = {}) { auto rval = it; for (++it; it != end; ++it) { if (detail::invoke(comp, *it, *rval, proj, proj)) { rval = it; } } return rval; } template , typename Proj = detail::identity> auto min_element(Stream const & stream, Comp comp = {}, Proj proj = {}) { return min_element(stream.begin(), stream.end(), std::ref(comp), std::ref(proj)); } template , typename Proj = detail::identity> auto min(std::initializer_list stream, Comp comp = {}, Proj proj = {}) { return *min_element(stream.begin(), stream.end(), std::ref(comp), std::ref(proj)); } template , typename Proj = detail::identity> auto min(Stream const & stream, Comp comp = {}, Proj proj = {}) { return *min_element(stream.begin(), stream.end(), std::ref(comp), std::ref(proj)); } } #include