min.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //
  2. // min.h
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 4/2/23.
  6. //
  7. #pragma once
  8. #include <stream/forward.h>
  9. #include <stream/detail/identity.h>
  10. #include <stream/detail/invoke.h>
  11. #include <stream/detail/traits.h>
  12. #include <stream/detail/macro.h>
  13. namespace stream::ranges {
  14. template <typename T, typename Comp = std::less<>,
  15. typename Proj = detail::identity>
  16. T const & min(T const & l, T const & r, Comp comp = {}, Proj proj = {}) {
  17. return detail::invoke(comp, l, r, proj, proj) ? l : r;
  18. }
  19. template <typename It, typename S, typename Comp = std::less<>,
  20. typename Proj = detail::identity,
  21. REQUIRES((detail::is_comparable_v<It, S>))>
  22. auto min_element(It it, S end, Comp comp = {}, Proj proj = {}) {
  23. auto rval = it;
  24. for (++it; it != end; ++it) {
  25. if (detail::invoke(comp, *it, *rval, proj, proj)) { rval = it; }
  26. }
  27. return rval;
  28. }
  29. template <typename Stream, typename Comp = std::less<>,
  30. typename Proj = detail::identity>
  31. auto min_element(Stream const & stream, Comp comp = {}, Proj proj = {}) {
  32. return min_element(stream.begin(), stream.end(), std::ref(comp),
  33. std::ref(proj));
  34. }
  35. template <typename T, typename Comp = std::less<>,
  36. typename Proj = detail::identity>
  37. auto min(std::initializer_list<T> stream, Comp comp = {}, Proj proj = {}) {
  38. return *min_element(stream.begin(), stream.end(), std::ref(comp),
  39. std::ref(proj));
  40. }
  41. template <typename Stream, typename Comp = std::less<>,
  42. typename Proj = detail::identity>
  43. auto min(Stream const & stream, Comp comp = {}, Proj proj = {}) {
  44. return *min_element(stream.begin(), stream.end(), std::ref(comp),
  45. std::ref(proj));
  46. }
  47. }
  48. #include <stream/detail/undef.h>