Horizon
Loading...
Searching...
No Matches
minmax_element.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2014-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13// Implementation based on the code in libc++
14// http://http://libcxx.llvm.org/
15
16#ifndef RANGES_V3_ALGORITHM_MINMAX_ELEMENT_HPP
17#define RANGES_V3_ALGORITHM_MINMAX_ELEMENT_HPP
18
20
21#include <range/v3/algorithm/result_types.hpp>
31#include <range/v3/utility/static_const.hpp>
32
33#include <range/v3/detail/prologue.hpp>
34
35namespace ranges
36{
39 template<typename I>
40 using minmax_element_result = detail::min_max_result<I, I>;
41
42 RANGES_FUNC_BEGIN(minmax_element)
43
44
45 template(typename I, typename S, typename C = less, typename P = identity)(
46 requires forward_iterator<I> AND sentinel_for<S, I> AND
47 indirect_strict_weak_order<C, projected<I, P>>)
48 constexpr minmax_element_result<I> //
49 RANGES_FUNC(minmax_element)(I first, S last, C pred = C{}, P proj = P{}) //
50 {
51 minmax_element_result<I> result{first, first};
52 if(first == last || ++first == last)
53 return result;
54 if(invoke(pred, invoke(proj, *first), invoke(proj, *result.min)))
55 result.min = first;
56 else
57 result.max = first;
58 while(++first != last)
59 {
60 I tmp = first;
61 if(++first == last)
62 {
63 if(invoke(pred, invoke(proj, *tmp), invoke(proj, *result.min)))
64 result.min = tmp;
65 else if(!invoke(pred, invoke(proj, *tmp), invoke(proj, *result.max)))
66 result.max = tmp;
67 break;
68 }
69 else
70 {
71 if(invoke(pred, invoke(proj, *first), invoke(proj, *tmp)))
72 {
73 if(invoke(pred, invoke(proj, *first), invoke(proj, *result.min)))
74 result.min = first;
75 if(!invoke(pred, invoke(proj, *tmp), invoke(proj, *result.max)))
76 result.max = tmp;
77 }
78 else
79 {
80 if(invoke(pred, invoke(proj, *tmp), invoke(proj, *result.min)))
81 result.min = tmp;
82 if(!invoke(pred, invoke(proj, *first), invoke(proj, *result.max)))
83 result.max = first;
84 }
85 }
86 }
87 return result;
88 }
89
91 template(typename Rng, typename C = less, typename P = identity)(
92 requires forward_range<Rng> AND
93 indirect_strict_weak_order<C, projected<iterator_t<Rng>, P>>)
94 constexpr minmax_element_result<borrowed_iterator_t<Rng>> //
95 RANGES_FUNC(minmax_element)(Rng && rng, C pred = C{}, P proj = P{}) //
96 {
97 return (*this)(begin(rng), end(rng), std::move(pred), std::move(proj));
98 }
99
100 RANGES_FUNC_END(minmax_element)
101
102 namespace cpp20
103 {
104 using ranges::minmax_element;
105 using ranges::minmax_element_result;
106 } // namespace cpp20
108} // namespace ranges
109
110#include <range/v3/detail/epilogue.hpp>
111
112#endif
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition meta.hpp:541
front< Pair > first
Retrieve the first element of the pair Pair.
Definition meta.hpp:2251
bool_<(T::type::value< U::type::value)> less
A Boolean integral constant wrapper around true if T::type::value is less than U::type::value; false,...
Definition meta.hpp:255