]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fundamental: add ABS_DIFF macro
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Sat, 11 Apr 2026 11:06:56 +0000 (13:06 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Sat, 11 Apr 2026 12:58:34 +0000 (14:58 +0200)
Sometimes we want need to diff two unsigned numbers, which is awkward
because we need to cast them to something with a sign first, if we want
to use abs(). Let's add a helper that avoids the function call
altogether.

Also drop unnecessary parens arounds args which are delimited by commas.

src/fundamental/macro-fundamental.h
src/test/test-macro.c

index a5300d591ae203c7b640812ea2b4b4efeaa4b99d..6ed6cf2f8a0a11e5be48b846c7b2dad3c45dd9b8 100644 (file)
 #define U64_GB (UINT64_C(1024) * U64_MB)
 
 #undef MAX
-#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
+#define MAX(a, b) __MAX(UNIQ, a, UNIQ, b)
 #define __MAX(aq, a, bq, b)                             \
         ({                                              \
                 const typeof(a) UNIQ_T(A, aq) = (a);    \
@@ -234,7 +234,7 @@ assert_cc(sizeof(long long) == sizeof(intmax_t));
         })
 
 #undef MIN
-#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
+#define MIN(a, b) __MIN(UNIQ, a, UNIQ, b)
 #define __MIN(aq, a, bq, b)                             \
         ({                                              \
                 const typeof(a) UNIQ_T(A, aq) = (a);    \
@@ -242,6 +242,14 @@ assert_cc(sizeof(long long) == sizeof(intmax_t));
                 UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
         })
 
+#define ABS_DIFF(a, b) __ABS_DIFF(UNIQ, a, UNIQ, b)
+#define __ABS_DIFF(aq, a, bq, b)                        \
+        ({                                              \
+                const typeof(a) UNIQ_T(A, aq) = (a);    \
+                const typeof(b) UNIQ_T(B, bq) = (b);    \
+                UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(B, bq) - UNIQ_T(A, aq) : UNIQ_T(A, aq) - UNIQ_T(B, bq); \
+        })
+
 /* evaluates to (void) if _A or _B are not constant or of different types */
 #define CONST_MIN(_A, _B) \
         (__builtin_choose_expr(                                         \
@@ -312,7 +320,7 @@ assert_cc(sizeof(long long) == sizeof(intmax_t));
         })
 
 #undef CLAMP
-#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
+#define CLAMP(x, low, high) __CLAMP(UNIQ, x, UNIQ, low, UNIQ, high)
 #define __CLAMP(xq, x, lowq, low, highq, high)                          \
         ({                                                              \
                 const typeof(x) UNIQ_T(X, xq) = (x);                    \
@@ -329,7 +337,7 @@ assert_cc(sizeof(long long) == sizeof(intmax_t));
  * computation should be possible in the given type. Therefore, we use
  * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
  * quotient and the remainder, so both should be equally fast. */
-#define DIV_ROUND_UP(x, y) __DIV_ROUND_UP(UNIQ, (x), UNIQ, (y))
+#define DIV_ROUND_UP(x, y) __DIV_ROUND_UP(UNIQ, x, UNIQ, y)
 #define __DIV_ROUND_UP(xq, x, yq, y)                                    \
         ({                                                              \
                 const typeof(x) UNIQ_T(X, xq) = (x);                    \
@@ -341,11 +349,11 @@ assert_cc(sizeof(long long) == sizeof(intmax_t));
 #define __ROUND_UP(q, x, y)                                             \
         ({                                                              \
                 const typeof(y) UNIQ_T(A, q) = (y);                     \
-                const typeof(x) UNIQ_T(B, q) = DIV_ROUND_UP((x), UNIQ_T(A, q)); \
+                const typeof(x) UNIQ_T(B, q) = DIV_ROUND_UP(x, UNIQ_T(A, q)); \
                 typeof(x) UNIQ_T(C, q);                                 \
                 MUL_SAFE(&UNIQ_T(C, q), UNIQ_T(B, q), UNIQ_T(A, q)) ? UNIQ_T(C, q) : (typeof(x)) -1; \
         })
-#define ROUND_UP(x, y) __ROUND_UP(UNIQ, (x), (y))
+#define ROUND_UP(x, y) __ROUND_UP(UNIQ, x, y)
 
 #define  CASE_F_1(X)      case X:
 #define  CASE_F_2(X, ...) case X:  CASE_F_1( __VA_ARGS__)
index 7f7bf1ce8dbda80b7933aaeaaed9846d5df9b03d..9a9a1fa2dac7fd79e176517a37be3df42ef45beb 100644 (file)
@@ -130,6 +130,13 @@ TEST(MAX) {
         assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
 }
 
+TEST(ABS_DIFF) {
+        ASSERT_EQ(ABS_DIFF(5, 3), 2);
+        ASSERT_EQ(ABS_DIFF(3, 5), 2);
+        ASSERT_EQ(ABS_DIFF(5llu, 2llu), 3llu);
+        ASSERT_EQ(ABS_DIFF(3llu, 5llu), 2llu);
+}
+
 #pragma GCC diagnostic push
 #ifdef __clang__
 #  pragma GCC diagnostic ignored "-Waddress-of-packed-member"