| 36 | typename Projection = std::identity, |
| 37 | std::indirect_strict_weak_order<std::projected<Iterator, Projection>> Comparison = std::ranges::less> |
| 38 | Iterator find_optimum(Iterator begin, Sentinel end, Comparison compare = {}, Projection projection = {}) |
| 39 | { |
| 40 | if (begin == end) return begin; // Do not return end as before... |
| 41 | |
| 42 | Iterator optimum{ begin }; |
| 43 | for (auto iter{ ++begin }; iter != end; ++iter) |
| 44 | { |
| 45 | // Note 1: std::invoke() is required to support comparison and projection through member pointers |
| 46 | // Note 2: this re-invokes projection(*optimum) for each comparison, same as std::max_element() |
| 47 | if (std::invoke(compare, std::invoke(projection, *iter), std::invoke(projection, *optimum))) |
| 48 | optimum = iter; |
| 49 | } |
| 50 | return optimum; |
| 51 | } |
| 52 | |
| 53 | /* A simple Box class to exercise our member-based comparison and projection facilities. |
| 54 | It lacks an operator<(), so with classical algorithms you'd need lambdas to compare these Boxes... |