]> git.ipfire.org Git - thirdparty/libbsd.git/commitdiff
Add __offsetof, __rangeof and __containerof to sys/cdefs.h
authorGuillem Jover <guillem@hadrons.org>
Fri, 31 Oct 2014 23:21:30 +0000 (00:21 +0100)
committerGuillem Jover <guillem@hadrons.org>
Wed, 23 Sep 2015 05:59:27 +0000 (07:59 +0200)
Import and adapt from FreeBSD.

include/bsd/sys/cdefs.h

index c1567be42faf79f0cf62a9c6926b6c5904c1c199..4b1063acb015e1fda200f350431c1883e3d5fd03 100644 (file)
 # define __bounded__(x, y, z)
 #endif
 
+/*
+ * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
+ * require it.
+ */
+#ifndef __offsetof
+# if LIBBSD_GCC_VERSION >= 0x0401
+#  define __offsetof(type, field)      __builtin_offsetof(type, field)
+# else
+#  ifndef __cplusplus
+#   define __offsetof(type, field) \
+           ((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field))
+#  else
+#   define __offsetof(type, field) \
+       (__offsetof__ (reinterpret_cast <__size_t> \
+                      (&reinterpret_cast <const volatile char &> \
+                       (static_cast<type *> (0)->field))))
+#  endif
+# endif
+#endif
+
+#define __rangeof(type, start, end) \
+        (__offsetof(type, end) - __offsetof(type, start))
+
+/*
+ * Given the pointer x to the member m of the struct s, return
+ * a pointer to the containing structure.  When using GCC, we first
+ * assign pointer x to a local variable, to check that its type is
+ * compatible with member m.
+ */
+#ifndef __containerof
+# if LIBBSD_GCC_VERSION >= 0x0301
+#  define __containerof(x, s, m) ({ \
+       const volatile __typeof(((s *)0)->m) *__x = (x); \
+       __DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m)); \
+})
+# else
+#  define __containerof(x, s, m) \
+          __DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
+# endif
+#endif
+
 #ifndef __RCSID
 # define __RCSID(x)
 #endif