Iros
 
Loading...
Searching...
No Matches
minmax_element.h
Go to the documentation of this file.
1#pragma once
2
7
8namespace di::container {
9namespace detail {
11 template<concepts::ForwardIterator It, concepts::SentinelFor<It> Sent, typename Proj = function::Identity,
12 concepts::IndirectStrictWeakOrder<meta::Projected<It, Proj>> Comp = function::Compare>
13 constexpr auto operator()(It first, Sent last, Comp comp = {}, Proj proj = {}) const -> MinMaxResult<It> {
14 if (first == last) {
15 return { first, first };
16 }
17
18 auto min_iter = first;
19 auto max_iter = first;
20 for (auto it = ++first; it != last; ++it) {
21 // Perform fancy algorithm to only do 3*N/2 - 2 comparisons, instead of 2*N comparisons.
22 // The idea is to consider pairs of elements in a row, and first compare them. Based on that
23 // result, we know whether to compare each element with the min or max element.
24
25 auto jt = container::next(it);
26 // Base case: only 1 element remains.
27 if (jt == last) {
28 auto compare_with_max =
30 if (compare_with_max >= 0) {
31 max_iter = it;
32 } else if (function::invoke(comp, function::invoke(proj, *it), function::invoke(proj, *min_iter)) <
33 0) {
34 min_iter = it;
35 }
36 } else {
37 auto it_jt_result =
39 if (it_jt_result < 0) {
40 // Compare it to min, jt to max.
41 if (function::invoke(comp, function::invoke(proj, *it), function::invoke(proj, *min_iter)) <
42 0) {
43 min_iter = it;
44 }
45 if (function::invoke(comp, function::invoke(proj, *jt), function::invoke(proj, *max_iter)) >=
46 0) {
47 max_iter = jt;
48 }
49 } else {
50 // Compare it to max, jt to min.
51 if (function::invoke(comp, function::invoke(proj, *it), function::invoke(proj, *min_iter)) >=
52 0) {
53 max_iter = it;
54 }
55 if (function::invoke(comp, function::invoke(proj, *jt), function::invoke(proj, *max_iter)) <
56 0) {
57 min_iter = jt;
58 }
59 }
60 ++it;
61 }
62 }
63 return { util::move(min_iter), util::move(max_iter) };
64 }
65
66 template<concepts::ForwardContainer Con, typename Proj = function::Identity,
67 concepts::IndirectStrictWeakOrder<meta::Projected<meta::ContainerIterator<Con>, Proj>> Comp =
68 function::Compare>
69 constexpr auto operator()(Con&& container, Comp comp = {}, Proj proj = {}) const
72 }
73 };
74}
75
77}
78
79namespace di {
81}
Definition sequence.h:13
Definition sequence.h:12
constexpr auto next
Definition next.h:35
constexpr auto end
Definition end.h:47
constexpr auto begin
Definition begin.h:44
constexpr auto minmax_element
Definition minmax_element.h:76
constexpr auto invoke
Definition invoke.h:100
Conditional< concepts::BorrowedContainer< Con >, ContainerIterator< Con >, container::Dangling > BorrowedIterator
Definition borrowed_iterator.h:11
constexpr auto ref
Definition reference_wrapper.h:98
Definition zstring_parser.h:9
constexpr auto proj
Definition proj.h:59
Definition min_max_result.h:8
Definition minmax_element.h:10
constexpr auto operator()(It first, Sent last, Comp comp={}, Proj proj={}) const -> MinMaxResult< It >
Definition minmax_element.h:13
constexpr auto operator()(Con &&container, Comp comp={}, Proj proj={}) const -> MinMaxResult< meta::BorrowedIterator< Con > >
Definition minmax_element.h:69