std::ranges::minmax
Defined in header <algorithm>
|
||
template< class T, class Proj = std::identity, std::indirect_strict_weak_order< |
(1) | (since C++20) |
template< class T, class Proj = std::identity, std::indirect_strict_weak_order< |
(2) | (since C++20) |
template< ranges::input_range R, class Proj = std::identity, std::indirect_strict_weak_order< |
(3) | (since C++20) |
template< class T > using ranges::minmax_result = min_max_result<T>; |
(4) | (since C++20) |
Returns the smaller of the given projected values.
a
and b
.r
.r
.The function-like entities described on this page are niebloids, that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
In practice, they may be implemented as function objects, or with special compiler extensions.
Contents |
Parameters
a, b | - | the values to compare |
r | - | a non-empty range of values to compare |
comp | - | comparison to apply to the projected elements |
proj | - | projection to apply to the elements |
Return value
b
is smaller than a
; otherwise it returns {a, b}.s
and l
are respectively the smallest and largest values in r
, according to their respective projections. If several values are equivalent to the smallest and largest, returns the leftmost smallest value, and the rightmost largest value.Complexity
3 / 2 * ranges::distance(r)
comparisons and twice as many applications of the projectionPossible implementation
struct minmax_fn { template<class T, class Proj = std::identity, std::indirect_strict_weak_order< std::projected<const T*, Proj>> Comp = ranges::less> constexpr ranges::minmax_result<const T&> operator()( const T& a, const T& b, Comp comp = {}, Proj proj = {}) const { if (std::invoke(comp, std::invoke(proj, b), std::invoke(proj, a))) { return {b, a}; } return {a, b}; } template<class T, class Proj = std::identity, std::indirect_strict_weak_order< std::projected<const T*, Proj>> Comp = ranges::less> constexpr ranges::minmax_result<const T&> operator()( std::initializer_list<T> r, Comp comp = {}, Proj proj = {}) const { auto result = ranges::minmax_element(r, std::ref(comp), std::ref(proj)); return {std::move(*result.min), std::move(*result.max)}; } template<ranges::input_range R, class Proj = std::identity, std::indirect_strict_weak_order< std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less> requires std::indirectly_copyable_storable<ranges::iterator_t<R>, ranges::range_value_t<R>*> constexpr ranges::minmax_result<ranges::range_value_t<R>> operator()( R&& r, Comp comp = {}, Proj proj = {}) const { auto result = ranges::minmax_element(r, std::ref(comp), std::ref(proj)); return {std::move(*result.min), std::move(*result.max)}; } }; inline constexpr minmax_fn minmax; |
Notes
For overloads (1,2), if one of the parameters is an rvalue, the reference returned becomes a dangling reference at the end of the full expression that contains the call to minmax
:
int n = 1; auto p = ranges::minmax(n, n+1); int m = p.first; // ok int x = p.second; // undefined behavior
Example
#include <algorithm> #include <iostream> #include <random> #include <vector> int main() { std::vector<int> v{3, 1, 4, 9, 1, 5, 9, 2, 6}; std::mt19937_64 generator; std::uniform_int_distribution<> distribution(0, ranges::distance(v)); namespace ranges = std::ranges; auto bounds = ranges::minmax(distribution(generator), distribution(generator)); std::cout << "v[" << bounds.min << ":" << bounds.max << "]: "; for (int i = bounds.min; i < bounds.max; ++i) { std::cout << v[i] << ' '; } std::cout << '\n'; auto [min, max] = ranges::minmax(v); std::cout << "smallest: " << min << '\n' << "largest: " << max << '\n'; }
Possible output:
v[2:7]: 4 9 1 5 9 smallest: 1 largest: 9
See also
(C++20) |
returns the smaller of the given values (niebloid) |
(C++20) |
returns the greater of the given values (niebloid) |
ranges::minmax (C++20) |
returns the smaller and larger of two elements (niebloid) |
(C++20) |
returns the smallest and the largest elements in a range (niebloid) |
(C++20) |
clamps a value between a pair of boundary values (niebloid) |
(C++11) |
returns the smaller and larger of two elements (function template) |