summaryrefslogtreecommitdiff
path: root/lab02/container_of.h
diff options
context:
space:
mode:
Diffstat (limited to 'lab02/container_of.h')
-rw-r--r--lab02/container_of.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/lab02/container_of.h b/lab02/container_of.h
new file mode 100644
index 0000000..6383572
--- /dev/null
+++ b/lab02/container_of.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _CONTAINER_OF_H
+#define _CONTAINER_OF_H
+
+#include <stddef.h>
+
+#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+#define typeof_member(T, m) typeof(((T*)0)->m)
+
+
+#define container_of(ptr, type, member) ({ \
+ _Static_assert(__same_type(*(ptr), typeof_member(type, member)) || \
+ __same_type(*(ptr), void), \
+ "pointer type mismatch in container_of()"); \
+ (type *)((void *)(ptr) - offsetof(type, member)); })
+
+
+#define container_of_const(ptr, type, member) \
+ _Generic(ptr, \
+ const typeof(*(ptr)) *: ((const type *)container_of(ptr, type, member)),\
+ default: ((type *)container_of(ptr, type, member)) \
+ )
+
+#endif /* _CONTAINER_OF_H */