@@ -402,6 +402,127 @@ extern "C" {
402
402
#define MIN (a , b ) (((a) < (b)) ? (a) : (b))
403
403
#endif
404
404
405
+ #ifndef MAX_FROM_LIST
406
+ /**
407
+ * @brief Returns the maximum of a single value (base case).
408
+ * @param a The value.
409
+ * @returns The value `a`.
410
+ */
411
+ #define Z_MAX_1 (a ) a
412
+
413
+ /**
414
+ * @brief Returns the maximum of two values.
415
+ *
416
+ * @note Arguments are evaluated multiple times.
417
+ *
418
+ * @param a First value.
419
+ * @param b Second value.
420
+ * @returns Maximum value of @p a and @p b.
421
+ */
422
+ #define Z_MAX_2 (a , b ) ((a) > (b) ? (a) : (b))
423
+
424
+ /**
425
+ * @brief Returns the maximum of three values.
426
+ * @note Arguments may be evaluated multiple times.
427
+ * @param a First value.
428
+ * @param b Second value.
429
+ * @param c Third value.
430
+ * @returns Maximum value of @p a, @p b, and @p c.
431
+ */
432
+ #define Z_MAX_3 (a , b , c ) Z_MAX_2(a, Z_MAX_2(b, c))
433
+
434
+ /**
435
+ * @brief Returns the maximum of four values.
436
+ * @note Arguments may be evaluated multiple times.
437
+ * @param a First value.
438
+ * @param b Second value.
439
+ * @param c Third value.
440
+ * @param d Fourth value.
441
+ * @returns Maximum value of @p a, @p b, @p c, and @p d.
442
+ */
443
+ #define Z_MAX_4 (a , b , c , d ) Z_MAX_2(Z_MAX_2(a, b), Z_MAX_2(c, d))
444
+
445
+ /**
446
+ * @brief Returns the maximum of five values.
447
+ * @note Arguments may be evaluated multiple times.
448
+ */
449
+ #define Z_MAX_5 (a , b , c , d , e ) Z_MAX_2(Z_MAX_4(a, b, c, d), e)
450
+
451
+ /**
452
+ * @brief Returns the maximum of six values.
453
+ * @note Arguments may be evaluated multiple times.
454
+ */
455
+ #define Z_MAX_6 (a , b , c , d , e , f ) Z_MAX_2(Z_MAX_5(a, b, c, d, e), f)
456
+
457
+ /**
458
+ * @brief Returns the maximum of seven values.
459
+ * @note Arguments may be evaluated multiple times.
460
+ */
461
+ #define Z_MAX_7 (a , b , c , d , e , f , g ) Z_MAX_2(Z_MAX_6(a, b, c, d, e, f), g)
462
+
463
+ /**
464
+ * @brief Returns the maximum of eight values.
465
+ * @note Arguments may be evaluated multiple times.
466
+ */
467
+ #define Z_MAX_8 (a , b , c , d , e , f , g , h ) Z_MAX_2(Z_MAX_7(a, b, c, d, e, f, g), h)
468
+
469
+ /**
470
+ * @brief Returns the maximum of nine values.
471
+ * @note Arguments may be evaluated multiple times.
472
+ */
473
+ #define Z_MAX_9 (a , b , c , d , e , f , g , h , i ) Z_MAX_2(Z_MAX_8(a, b, c, d, e, f, g, h), i)
474
+
475
+ /**
476
+ * @brief Returns the maximum of ten values.
477
+ * @note Arguments may be evaluated multiple times.
478
+ */
479
+ #define Z_MAX_10 (a , b , c , d , e , f , g , h , i , j ) Z_MAX_2(Z_MAX_9(a, b, c, d, e, f, g, h, i), j)
480
+
481
+ /**
482
+ * @brief Helper macro to select the correct MAX_N macro.
483
+ *
484
+ * This macro uses the argument-counting trick to pick the correct
485
+ * `Z_MAX_N` macro name from the arguments provided to `MAX_FROM_LIST`.
486
+ * The 10th argument (or 11th including `NAME`) effectively becomes the
487
+ * macro name to use.
488
+ *
489
+ * @param _1 Positional argument 1.
490
+ * @param _2 Positional argument 2.
491
+ * @param _3 Positional argument 3.
492
+ * @param _4 Positional argument 4.
493
+ * @param _5 Positional argument 5.
494
+ * @param _6 Positional argument 6.
495
+ * @param _7 Positional argument 7.
496
+ * @param _8 Positional argument 8.
497
+ * @param _9 Positional argument 9.
498
+ * @param _10 Positional argument 10.
499
+ * @param NAME The macro name to be selected.
500
+ * @param ... Additional arguments.
501
+ * @returns The selected macro name `NAME`.
502
+ */
503
+ #define Z_GET_MAX_MACRO (_1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 , _9 , _10 , NAME , ...) NAME
504
+
505
+ /**
506
+ * @brief Finds the maximum value from a list of 1 to 10 arguments.
507
+ *
508
+ * Dispatches to the appropriate internal `Z_MAX_N` macro based on the number of
509
+ * arguments provided.
510
+ *
511
+ * Example Usage:
512
+ * MAX_FROM_LIST(1, 5, 2)
513
+ * MAX_FROM_LIST(10)
514
+ *
515
+ * @note Arguments may be evaluated multiple times by the underlying
516
+ * `Z_MAX_N` macros. Avoid expressions with side effects.
517
+ *
518
+ * @param ... A list of 1 to 10 values to compare.
519
+ * @returns The maximum value among the arguments.
520
+ */
521
+ #define MAX_FROM_LIST (...) \
522
+ Z_GET_MAX_MACRO(__VA_ARGS__, Z_MAX_10, Z_MAX_9, Z_MAX_8, Z_MAX_7, Z_MAX_6, Z_MAX_5, \
523
+ Z_MAX_4, Z_MAX_3, Z_MAX_2, Z_MAX_1)(__VA_ARGS__)
524
+ #endif
525
+
405
526
#ifndef CLAMP
406
527
/**
407
528
* @brief Clamp a value to a given range.
0 commit comments