aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/comparator.hh
diff options
context:
space:
mode:
authorregnat <rg@regnat.ovh>2021-02-04 15:11:05 +0100
committerregnat <rg@regnat.ovh>2021-02-05 11:42:33 +0100
commitd2091af231ab97b729c2486b55e520c565e59dd3 (patch)
treeab66ac2880707700a4eb2b81d2ff2e49d210eb35 /src/libutil/comparator.hh
parent43d409f6690b79b5d4e1ab5e9780de93eb0f677a (diff)
Move the GENERATE_CMP macro to its own file
Despite being an ugly hack, it can probably be useful in a couple extra places
Diffstat (limited to 'src/libutil/comparator.hh')
-rw-r--r--src/libutil/comparator.hh30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/libutil/comparator.hh b/src/libutil/comparator.hh
new file mode 100644
index 000000000..0315dc506
--- /dev/null
+++ b/src/libutil/comparator.hh
@@ -0,0 +1,30 @@
+#pragma once
+
+/* Awfull hacky generation of the comparison operators by doing a lexicographic
+ * comparison between the choosen fields.
+ *
+ * ```
+ * GENERATE_CMP(ClassName, me->field1, me->field2, ...)
+ * ```
+ *
+ * will generate comparison operators semantically equivalent to:
+ *
+ * ```
+ * bool operator<(const ClassName& other) {
+ * return field1 < other.field1 && field2 < other.field2 && ...;
+ * }
+ * ```
+ */
+#define GENERATE_ONE_CMP(COMPARATOR, MY_TYPE, FIELDS...) \
+ bool operator COMPARATOR(const MY_TYPE& other) const { \
+ const MY_TYPE* me = this; \
+ auto fields1 = std::make_tuple( FIELDS ); \
+ me = &other; \
+ auto fields2 = std::make_tuple( FIELDS ); \
+ return fields1 COMPARATOR fields2; \
+ }
+#define GENERATE_EQUAL(args...) GENERATE_ONE_CMP(==, args)
+#define GENERATE_LEQ(args...) GENERATE_ONE_CMP(<, args)
+#define GENERATE_CMP(args...) \
+ GENERATE_EQUAL(args) \
+ GENERATE_LEQ(args)