max.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //
  2. // max.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 & max(T const & l, T const & r, Comp comp = {}, Proj proj = {}) {
  17. return detail::invoke(comp, r, l, 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 max_element(It it, S end, Comp comp = {}, Proj proj = {}) {
  23. auto rval = it;
  24. for (++it; it != end; ++it) {
  25. if (detail::invoke(comp, *rval, *it, proj, proj)) { rval = *it; }
  26. }
  27. return rval;
  28. }
  29. template <typename Stream, typename Comp = std::less<>,
  30. typename Proj = detail::identity>
  31. auto max_element(Stream const & stream, Comp comp = {}, Proj proj = {}) {
  32. return max_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 max(std::initializer_list<T> const & stream, Comp comp = {},
  38. Proj proj = {}) {
  39. return *max_element(stream.begin(), stream.end(), std::ref(comp),
  40. std::ref(proj));
  41. }
  42. template <typename Stream, typename Comp = std::less<>,
  43. typename Proj = detail::identity>
  44. auto max(Stream const & stream, Comp comp = {}, Proj proj = {}) {
  45. return *max_element(stream.begin(), stream.end(), std::ref(comp),
  46. std::ref(proj));
  47. }
  48. }
  49. #include <stream/detail/undef.h>