aboutsummaryrefslogtreecommitdiff
path: root/utils.h
diff options
context:
space:
mode:
authorYaroslav de la Peña Smirnov <yps@yaroslavps.com>2023-07-22 03:03:09 +0300
committerYaroslav de la Peña Smirnov <yps@yaroslavps.com>2023-07-22 03:03:09 +0300
commitcb1a40859029f33184355475e51fec95afb79a73 (patch)
tree5aea859d3a3e10ddd058beac9d6734d17979d560 /utils.h
downloadc-wares-cb1a40859029f33184355475e51fec95afb79a73.tar.gz
c-wares-cb1a40859029f33184355475e51fec95afb79a73.zip
init
Just some C wares; hmap, list, optional, unit tests.
Diffstat (limited to 'utils.h')
-rw-r--r--utils.h35
1 files changed, 35 insertions, 0 deletions
diff --git a/utils.h b/utils.h
new file mode 100644
index 0000000..cb7d795
--- /dev/null
+++ b/utils.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: MIT */
+/**
+ * utils.h - useful macros for compile-time magic
+ *
+ * Inspired by similar macros in the Linux Kernel.
+ *
+ * Copyright (c) 2023 - Yaroslav de la Peña Smirnov
+ */
+#ifndef CWARE_UTILS_H
+#define CWARE_UTILS_H
+
+#include <stddef.h>
+
+#ifndef static_assert
+#define static_assert(exp, msg) _Static_assert(exp, msg)
+#endif
+
+#define same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+
+#define container_of(ptr, T, member) \
+ ({ \
+ static_assert(same_type(*(ptr), ((T *)0)->member) \
+ || same_type(*(ptr), void), \
+ "type mismatch in container_of()"); \
+ (T *)((void *)(ptr)-offsetof(T, member)); \
+ })
+
+#define ARRAY_SIZE(arr) \
+ ({ \
+ static_assert(!same_type((arr), &(arr)[0]), \
+ "variable is not an array"); \
+ sizeof(arr) / sizeof(*arr); \
+ })
+
+#endif