GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/algorithm/minmax.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 28 28 100.0%
Functions: 116 116 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //======================================================================================================================
2 /*
3 KUMI - Compact Tuple Tools
4 Copyright : KUMI Project Contributors
5 SPDX-License-Identifier: BSL-1.0
6 */
7 //======================================================================================================================
8 #pragma once
9
10 namespace kumi
11 {
12 namespace _
13 {
14 struct minmax_case_t
15 {
16 188 template<typename V, typename F, typename C> KUMI_HIDDEN_ABI constexpr auto operator()(V&& v, F f, C c) const
17 {
18 28 if constexpr (kumi::concepts::product_type<V>) return c(KUMI_FWD(v), f);
19 160 else return kumi::invoke(f, KUMI_FWD(v));
20 }
21 };
22
23 KUMI_VARIABLE_ABI constexpr minmax_case_t minmax_case{};
24
25 template<typename F, typename T, typename V, std::size_t... I>
26 66 KUMI_HIDDEN_ABI constexpr auto minmax_(kumi::_::adl_tag_t, F f, T&& t, V v, std::index_sequence<I...>)
27 {
28 690 return (kumi::function::foldable{v} >> ... >> kumi::bind_back(f, get<I + 1>(KUMI_FWD(t))))();
29 }
30
31 template<typename M, typename F, typename T, typename V, std::size_t... I>
32 62 KUMI_HIDDEN_ABI constexpr auto map_minmax_(kumi::_::adl_tag_t, M m, F f, T&& t, V v, std::index_sequence<I...>)
33 {
34 300 return (kumi::function::foldable{kumi::invoke(m, v)} >> ... >>
35 776 kumi::bind_back(f, kumi::invoke(m, get<I + 1>(KUMI_FWD(t)))))();
36 }
37
38 template<typename T, typename V, typename F, typename S, std::size_t... I>
39 56 KUMI_HIDDEN_ABI constexpr auto minmax_flat_(
40 kumi::_::adl_tag_t, T&& t, V visitor, F f, S self, std::index_sequence<I...>) noexcept
41 {
42 244 return kumi::make_tuple(visitor(get<I>(KUMI_FWD(t)), f, self)...);
43 }
44 }
45
46 struct max_t
47 {
48 template<kumi::concepts::product_type T> [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t) const noexcept
49 {
50 3 if constexpr (kumi::concepts::record_type<T>) return (*this)(kumi::values_of(KUMI_FWD(t)));
51 else if constexpr (kumi::concepts::sized_product_type<T, 1>) return get<0>(KUMI_FWD(t));
52 else
53 {
54 20 return minmax_(kumi::_::adl_tag, kumi::function::max, KUMI_FWD(t), get<0>(KUMI_FWD(t)),
55 20 std::make_index_sequence<kumi::size_v<T> - 1>{});
56 }
57 }
58
59 template<kumi::concepts::product_type T, typename F>
60 [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t, F f) const noexcept
61 {
62 7 if constexpr (kumi::concepts::record_type<T>) return (*this)(kumi::values_of(KUMI_FWD(t)), f);
63 else if constexpr (kumi::concepts::sized_product_type<T, 1>) return invoke(f, get<0>(KUMI_FWD(t)));
64 else
65 {
66 15 return map_minmax_(kumi::_::adl_tag, f, kumi::function::max, KUMI_FWD(t), get<0>(KUMI_FWD(t)),
67 15 std::make_index_sequence<kumi::size_v<T> - 1>{});
68 }
69 }
70 };
71
72 struct max_flat_t : private kumi::max_t
73 {
74 template<kumi::concepts::product_type T, typename F>
75 [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t, F f) const noexcept
76 {
77 if constexpr (kumi::concepts::empty_product_type<T>) return 0;
78 6 else if constexpr (kumi::concepts::record_type<T>) return (*this)(kumi::values_of(KUMI_FWD(t)), f);
79 else
80 28 return this->max_t::operator()(minmax_flat_(kumi::_::adl_tag, KUMI_FWD(t), kumi::_::minmax_case, f, (*this),
81 28 kumi::function::indexes_for<T>{}));
82 }
83 };
84
85 struct min_t
86 {
87 template<kumi::concepts::product_type T> [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t) const noexcept
88 {
89 2 if constexpr (kumi::concepts::record_type<T>) return (*this)(kumi::values_of(KUMI_FWD(t)));
90 else if constexpr (kumi::concepts::sized_product_type<T, 1>) return get<0>(KUMI_FWD(t));
91 else
92 {
93 18 return minmax_(kumi::_::adl_tag, kumi::function::min, KUMI_FWD(t), get<0>(KUMI_FWD(t)),
94 18 std::make_index_sequence<kumi::size_v<T> - 1>{});
95 }
96 }
97
98 template<kumi::concepts::product_type T, typename F>
99 [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t, F f) const noexcept
100 {
101 8 if constexpr (kumi::concepts::record_type<T>) return (*this)(kumi::values_of(KUMI_FWD(t)), f);
102 else if constexpr (kumi::concepts::sized_product_type<T, 1>) return kumi::invoke(f, get<0>(KUMI_FWD(t)));
103 else
104 {
105 17 return map_minmax_(kumi::_::adl_tag, f, kumi::function::min, KUMI_FWD(t), get<0>(KUMI_FWD(t)),
106 17 std::make_index_sequence<kumi::size_v<T> - 1>{});
107 }
108 }
109 };
110
111 struct min_flat_t : private kumi::min_t
112 {
113 template<kumi::concepts::product_type T, typename F>
114 [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t, F f) const noexcept
115 {
116 if constexpr (kumi::concepts::empty_product_type<T>) return 0;
117 6 else if constexpr (kumi::concepts::record_type<T>) return (*this)(kumi::values_of(KUMI_FWD(t)), f);
118 else
119 28 return this->min_t::operator()(minmax_flat_(kumi::_::adl_tag, KUMI_FWD(t), kumi::_::minmax_case, f, (*this),
120 28 kumi::function::indexes_for<T>{}));
121 }
122 };
123
124 //====================================================================================================================
125 /**
126 @ingroup kumi_reductions
127
128 @var max
129 @brief Callable object computing the maximum value of all elements of `t`.
130
131 @qualifier nodiscard
132 @qualifier inline
133 @qualifier constexpr
134 @qualifier noexcept
135
136 @groupheader{Header file}
137 @code
138 #include <kumi/algorithm/minmax.hpp>
139 @endcode
140
141 @groupheader{Call Signature}
142
143 @code
144 template<product_type T>
145 constexpr auto max(T && t) noexcept;
146 @endcode
147
148 @code
149 template<product_type T, typename Function>
150 constexpr auto max(T && t, Function f) noexcept;
151 @endcode
152
153 @subgroupheader{Parameters}
154
155 - `t`: Product Type to inspect
156 - `f`: Unary callable object to be invoked
157
158 @subgroupheader{Return value}
159
160 - The maximum value of `f` over all elements of a flattened version of `t`
161
162 @groupheader{Helper type}
163
164 @snippet include/kumi/algorithm/minmax.hpp max_t
165
166 Computes the return type of a call to kumi::max
167
168 @groupheader{Examples}
169
170 @tab_begin
171
172 @tab{Tuple}
173 @godbolt{doc/tuple/algo/max.cpp}
174
175 @tab{Record}
176 @godbolt{doc/record/algo/max.cpp}
177
178 @tab_end
179 **/
180 //====================================================================================================================
181 KUMI_VARIABLE_ABI constexpr max_t max{};
182
183 //====================================================================================================================
184 /**
185 @ingroup kumi_reductions
186
187 @var max_flat
188 @brief Callable object computing the maximum value of applications of `f` to all elements of kumi::flatten_all(t).
189
190 @qualifier nodiscard
191 @qualifier inline
192 @qualifier constexpr
193 @qualifier noexcept
194
195 @groupheader{Header file}
196 @code
197 #include <kumi/algorithm/minmax.hpp>
198 @endcode
199
200 @groupheader{Call Signature}
201
202 @code
203 template<product_type T, typename Function>
204 constexpr auto max_flat(T && t, Function f) noexcept;
205 @endcode
206
207 @subgroupheader{Parameters}
208
209 - `t`: Product Type to inspect
210 - `f`: Unary callable object to be invoked
211
212 @subgroupheader{Return value}
213
214 - The minimum value of `f` over all elements of a flattened version of `t`
215
216 @groupheader{Helper type}
217
218 @snippet include/kumi/algorithm/minmax.hpp max_flat_t
219
220 Computes the return type of a call to kumi::max_flat
221
222 @groupheader{Examples}
223
224 @tab_begin
225
226 @tab{Tuple}
227 @godbolt{doc/tuple/algo/max_flat.cpp}
228
229 @tab{Record}
230 @godbolt{doc/record/algo/max_flat.cpp}
231
232 @tab_end
233 **/
234 //====================================================================================================================
235 KUMI_VARIABLE_ABI constexpr max_flat_t max_flat{};
236
237 //====================================================================================================================
238 /**
239 @ingroup kumi_reductions
240
241 @var min
242 @brief Callable object computing the minimum value of all elements of `t`.
243
244 @qualifier nodiscard
245 @qualifier inline
246 @qualifier constexpr
247 @qualifier noexcept
248
249 @groupheader{Header file}
250 @code
251 #include <kumi/algorithm/minmax.hpp>
252 @endcode
253
254 @groupheader{Call Signature}
255
256 @code
257 template<product_type T>
258 constexpr auto min(T && t) noexcept;
259 @endcode
260
261 @code
262 template<product_type T, typename Function>
263 constexpr auto min(T && t, Function f) noexcept;
264 @endcode
265
266 @subgroupheader{Parameters}
267
268 - `t`: Product Type to inspect
269 - `f`: Unary callable object to be invoked
270
271 @subgroupheader{Return value}
272
273 - The minimum value of all elements of `t`
274
275 @groupheader{Helper type}
276
277 @snippet include/kumi/algorithm/minmax.hpp min_t
278
279 Computes the return type of a call to kumi::min
280
281 @groupheader{Examples}
282
283 @tab_begin
284
285 @tab{Tuple}
286 @godbolt{doc/tuple/algo/min.cpp}
287
288 @tab{Record}
289 @godbolt{doc/record/algo/min.cpp}
290
291 @tab_end
292 **/
293 //====================================================================================================================
294 KUMI_VARIABLE_ABI constexpr min_t min{};
295
296 //====================================================================================================================
297 /**
298 @ingroup kumi_reductions
299
300 @var min_flat
301 @brief Callable object computing the minimum value of applications of `f` to all elements of kumi::flatten_all(t).
302
303 @qualifier nodiscard
304 @qualifier inline
305 @qualifier constexpr
306 @qualifier noexcept
307
308 @groupheader{Header file}
309 @code
310 #include <kumi/algorithm/minmax.hpp>
311 @endcode
312
313 @groupheader{Call Signature}
314
315 @code
316 template<product_type T, typename Function>
317 constexpr auto min_flat(T && t, Function f) noexcept;
318 @endcode
319
320 @subgroupheader{Parameters}
321
322 - `t`: Product Type to inspect
323 - `f`: Unary callable object to be invoked
324
325 @subgroupheader{Return value}
326
327 - The minimum value of `f` over all elements of a flattened version of `t`
328
329 @groupheader{Helper type}
330
331 @snippet include/kumi/algorithm/minmax.hpp min_flat_t
332
333 Computes the return type of a call to kumi::min_flat
334
335 @groupheader{Examples}
336
337 @tab_begin
338
339 @tab{Tuple}
340 @godbolt{doc/tuple/algo/min_flat.cpp}
341
342 @tab{Record}
343 @godbolt{doc/record/algo/min_flat.cpp}
344
345 @tab_end
346 **/
347 //====================================================================================================================
348 KUMI_VARIABLE_ABI constexpr min_flat_t min_flat{};
349
350 namespace result
351 {
352 //! [max_t]
353 template<typename T, typename... F>
354 requires((sizeof...(F) == 0) || (sizeof...(F) == 1))
355 using max_t = decltype(kumi::max(std::declval<T>(), std::declval<F>()...));
356
357 template<typename T, typename... F>
358 requires((sizeof...(F) == 0) || (sizeof...(F) == 1))
359 struct max
360 {
361 using type = kumi::result::max_t<T, F...>;
362 };
363
364 //! [max_t]
365
366 //! [max_flat_t]
367 //
368 template<typename T, typename F> using max_flat_t = decltype(kumi::max_flat(std::declval<T>(), std::declval<F>()));
369
370 template<typename T, typename F> struct max_flat
371 {
372 using type = kumi::result::max_flat_t<T, F>;
373 };
374
375 //! [max_flat_t]
376
377 //! [min_t]
378 template<typename T, typename... F>
379 requires((sizeof...(F) == 0) || (sizeof...(F) == 1))
380 using min_t = decltype(kumi::min(std::declval<T>(), std::declval<F>()...));
381
382 template<typename T, typename... F>
383 requires((sizeof...(F) == 0) || (sizeof...(F) == 1))
384 struct min
385 {
386 using type = kumi::result::min_t<T, F...>;
387 };
388
389 //! [min_t]
390
391 //! [min_flat_t]
392 template<typename T, typename F> using min_flat_t = decltype(kumi::min_flat(std::declval<T>(), std::declval<F>()));
393
394 template<typename T, typename F> struct min_flat
395 {
396 using type = kumi::result::min_flat_t<T, F>;
397 };
398
399 //! [min_flat_t]
400 }
401 }
402