diff --git a/core/lib/include/macros/utils.h b/core/lib/include/macros/utils.h index 2b6b6f728209..d3ec5027ac88 100644 --- a/core/lib/include/macros/utils.h +++ b/core/lib/include/macros/utils.h @@ -63,6 +63,32 @@ extern "C" { #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif +#ifndef ABS +/** + * @brief Returns the absolute value of @p x + * + * @note This is the trivial implementation that does evaluate the arguments + * more than once + */ +#define ABS(x) ((x) > 0 ? (x) : -(x)) +#endif + +/** + * @brief Limit a value to an inclusive range + * + * If @p val is > @p high, @p high is returned. If @p val is < @p low, @p low + * is returned. Otherwise, @p val is returned. + * + * @note This macro evaluate its arguments more than once. + * + * @param[in] val value to limit + * @param[in] low minimum limit + * @param[in] high maximum limit + * + * @return range limited value + */ +#define LIMIT(val, low, high) ((val < low) ? low : (val > high) ? high : val) + #ifdef __cplusplus } #endif diff --git a/tests/unittests/tests-core/tests-core-macros.c b/tests/unittests/tests-core/tests-core-macros.c index 76b5b4554f98..bd77d0e87c15 100644 --- a/tests/unittests/tests-core/tests-core-macros.c +++ b/tests/unittests/tests-core/tests-core-macros.c @@ -12,6 +12,46 @@ #include "embUnit.h" #include "tests-core.h" #include "macros/math.h" +#include "macros/utils.h" + +static void test_max(void) +{ + TEST_ASSERT_EQUAL_INT(10, MAX(5, 10)); + TEST_ASSERT_EQUAL_INT(10, MAX(10, 5)); + + // prove it works with non-integer types + TEST_ASSERT(22.1 == MAX(22.1, 5.5)); +} + +static void test_min(void) +{ + TEST_ASSERT_EQUAL_INT(5, MIN(5, 10)); + TEST_ASSERT_EQUAL_INT(5, MIN(10, 5)); + + // prove it works with non-integer types + TEST_ASSERT(5.5 == MIN(22.1, 5.5)); +} + +static void test_abs(void) +{ + TEST_ASSERT_EQUAL_INT(22, ABS(22)); + TEST_ASSERT_EQUAL_INT(22, ABS(-22)); + + // prove it works with non-integer types + TEST_ASSERT(300.7 == ABS(-300.7)); +} + +static void test_limit(void) +{ + TEST_ASSERT_EQUAL_INT(5, LIMIT(5, -10, 10)); + TEST_ASSERT_EQUAL_INT(10, LIMIT(10, -10, 10)); + TEST_ASSERT_EQUAL_INT(10, LIMIT(22, -10, 10)); + TEST_ASSERT_EQUAL_INT(-10, LIMIT(-10, -10, 10)); + TEST_ASSERT_EQUAL_INT(-10, LIMIT(-22, -10, 10)); + + // prove it works with non-integer types + TEST_ASSERT(10.2 == LIMIT(22.2, -10.1, 10.2)); +} static void test_math_signof(void) { @@ -81,6 +121,10 @@ static void test_math_div_round_inf(void) Test *tests_core_macros_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_max), + new_TestFixture(test_min), + new_TestFixture(test_abs), + new_TestFixture(test_limit), new_TestFixture(test_math_signof), new_TestFixture(test_math_div_round), new_TestFixture(test_math_div_round_up),