Thanks: Eric Blake
---
common/include/minmax.h | 21 +++++++++++++--------
common/include/test-minmax.c | 14 ++++++++++++++
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/common/include/minmax.h b/common/include/minmax.h
index d3e667ea..8d1fbf19 100644
--- a/common/include/minmax.h
+++ b/common/include/minmax.h
@@ -44,16 +44,23 @@
* is required.
*/
+#include "unique-name.h"
+
+#undef MIN
+#define MIN(x, y) \
+ MIN_1((x), (y), NBDKIT_UNIQUE_NAME(_x), NBDKIT_UNIQUE_NAME(_y))
+#undef MAX
+#define MAX(x, y) \
+ MAX_1((x), (y), NBDKIT_UNIQUE_NAME(_x), NBDKIT_UNIQUE_NAME(_y))
+
#ifdef HAVE_AUTO_TYPE
-#undef MIN
-#define MIN(x, y) ({ \
+#define MIN_1(x, y, _x, _y) ({ \
__auto_type _x = (x); \
__auto_type _y = (y); \
_x < _y ? _x : _y; \
})
-#undef MAX
-#define MAX(x, y) ({ \
+#define MAX_1(x, y, _x, _y) ({ \
__auto_type _x = (x); \
__auto_type _y = (y); \
_x > _y ? _x : _y; \
@@ -61,14 +68,12 @@
#else
-#undef MIN
-#define MIN(x, y) ({ \
+#define MIN_1(x, y, _x, _y) ({ \
typeof (x) _x = (x); \
typeof (y) _y = (y); \
_x < _y ? _x : _y; \
})
-#undef MAX
-#define MAX(x, y) ({ \
+#define MAX_1(x, y, _x, _y) ({ \
typeof (x) _x = (x); \
typeof (y) _y = (y); \
_x > _y ? _x : _y; \
diff --git a/common/include/test-minmax.c b/common/include/test-minmax.c
index 7584ab27..32bc8a11 100644
--- a/common/include/test-minmax.c
+++ b/common/include/test-minmax.c
@@ -154,5 +154,19 @@ main (void)
SIGNED_TEST (f, -FLT_MAX, FLT_MAX);
SIGNED_TEST (d, -DBL_MAX, DBL_MAX);
+ /* Test that MIN and MAX can be nested. This is really a compile
+ * test, but we do check the answer.
+ */
+ assert (MIN (MIN (1, 2), 3) == 1);
+ assert (MAX (MIN (1, 2), 3) == 3);
+ assert (MIN (MAX (1, 2), 3) == 2);
+ assert (MAX (MAX (1, 4), 3) == 4);
+ assert (MIN (3, MIN (1, 2)) == 1);
+ assert (MAX (3, MIN (1, 2)) == 3);
+ assert (MIN (3, MAX (1, 2)) == 2);
+ assert (MAX (3, MAX (1, 4)) == 4);
+ assert (MIN (MIN (1, MIN (2, 3)), 4) == 1);
+ assert (MAX (MAX (1, MAX (2, 3)), 4) == 4);
+
exit (EXIT_SUCCESS);
}
--
2.35.1