Skip to content

Commit 7e0d8f9

Browse files
fabiobaltiericfriedt
authored andcommitted
sys: util: add min3 and max3 single evaluation macros
Add three argument variants of the single evaluation min and max, seems like there's few of these in the code we may as well have them. Signed-off-by: Fabio Baltieri <[email protected]>
1 parent c576b09 commit 7e0d8f9

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

include/zephyr/sys/util.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,19 @@ extern "C" {
383383

384384
#define _minmax_cnt(op, a, b, cnt) \
385385
_minmax_unique(op, a, b, UTIL_CAT(_value_a_, cnt), UTIL_CAT(_value_b_, cnt))
386+
387+
#define _minmax3_unique(op, a, b, c, ua, ub, uc) ({ \
388+
__typeof__(a) ua = (a); \
389+
__typeof__(b) ub = (b); \
390+
__typeof__(c) uc = (c); \
391+
op(ua, op(ub, uc)); \
392+
})
393+
394+
#define _minmax3_cnt(op, a, b, c, cnt) \
395+
_minmax3_unique(op, a, b, c, \
396+
UTIL_CAT(_value_a_, cnt), \
397+
UTIL_CAT(_value_b_, cnt), \
398+
UTIL_CAT(_value_c_, cnt))
386399
/**
387400
* @endcond
388401
*/
@@ -415,6 +428,13 @@ extern "C" {
415428
#define max(a, b) _minmax_cnt(MAX, a, b, __COUNTER__)
416429
#endif
417430

431+
/** @brief Return larger value of three provided expressions.
432+
*
433+
* Macro ensures that expressions are evaluated only once. See @ref max for
434+
* macro limitations.
435+
*/
436+
#define max3(a, b, c) _minmax3_cnt(MAX, a, b, c, __COUNTER__)
437+
418438
#ifndef MIN
419439
/**
420440
* @brief Obtain the minimum of two values.
@@ -439,6 +459,14 @@ extern "C" {
439459
#define min(a, b) _minmax_cnt(MIN, a, b, __COUNTER__)
440460
#endif
441461

462+
/** @brief Return smaller value of three provided expressions.
463+
*
464+
* Macro ensures that expressions are evaluated only once. See @ref max for
465+
* macro limitations.
466+
*/
467+
#define min3(a, b, c) _minmax3_cnt(MIN, a, b, c, __COUNTER__)
468+
469+
442470
#ifndef MAX_FROM_LIST
443471
/**
444472
* @brief Returns the maximum of a single value (base case).

tests/unit/util/main.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,26 @@ ZTEST(util, test_max_min_clamp) {
279279
#endif
280280
}
281281

282+
ZTEST(util, test_max3_min3) {
283+
/* check for single call */
284+
zassert_equal(max3(inc_func(true), 0, 0), 1, "Unexpected macro result");
285+
zassert_equal(inc_func(false), 2, "Unexpected return value");
286+
287+
zassert_equal(min3(inc_func(false), 9, 10), 3, "Unexpected macro result");
288+
zassert_equal(inc_func(false), 4, "Unexpected return value");
289+
290+
/* test the general functionality */
291+
zassert_equal(max3(1, 2, 3), 3, "Unexpected macro result");
292+
zassert_equal(max3(3, 1, 2), 3, "Unexpected macro result");
293+
zassert_equal(max3(2, 3, 1), 3, "Unexpected macro result");
294+
zassert_equal(max3(-1, 0, 1), 1, "Unexpected macro result");
295+
296+
zassert_equal(min3(1, 2, 3), 1, "Unexpected macro result");
297+
zassert_equal(min3(3, 1, 2), 1, "Unexpected macro result");
298+
zassert_equal(min3(2, 3, 1), 1, "Unexpected macro result");
299+
zassert_equal(min3(-1, 0, 1), -1, "Unexpected macro result");
300+
}
301+
282302
ZTEST(util, test_max_from_list_macro) {
283303
/* Test with one argument */
284304
zassert_equal(MAX_FROM_LIST(10), 10, "Should return the single value.");

0 commit comments

Comments
 (0)