chiark / gitweb /
@@@ random mess
[mLib] / utils / macros.h
index 5b772252cc940a33be8b2b0e8c2baabdbfac63c6..b48e6f68fb13335e31ca8cbebbe0adfc112a4125 100644 (file)
@@ -92,7 +92,7 @@
        IGNORABLE extern char static_assert_failed[1 - 2*!(cond)]
 #endif
 
-/* --- @CHECK_TYPE@ ---
+/* --- @CHECK_TYPE@ --- *
  *
  * Arguments:  @expty@ = expected type of @x@
  *             @expty x@ = some object
 
 #define CHECK_TYPE(expty, x) (!sizeof(*(expty *)0 = (x)))
 
-/* --- @CONVERT_CAREFULLY@ ---
+/* --- @CONVERT_CAREFULLY@ --- *
  *
  * Arguments:  @newty@ = new type for the result
  *             @expty@ = expected type of @x@
 #define CONVERT_CAREFULLY(newty, expty, x)                             \
        (CHECK_TYPE(expty, x) + (/*unconst unvolatile*/ newty)(x))
 
+/* --- @CONTAINER@ --- *
+ *
+ * Arguments:  @type@ = the parent type, a structure or union
+ *             @mem@ = the name of the member we have a pointer to
+ *             @memty *p@ = pointer to @member@ within @type@
+ *
+ * Returns:    The address of the containing @ty@ object.
+ */
+
+#define CONTAINER(type, member, p)                                     \
+  (!sizeof((p) = &((type *)0)->mem) +                                  \
+   (type *)((unsigned char *)(p) - offsetof(type, mem)))
+
 /* --- @UNCONST@, @UNVOLATILE@, @UNQUALIFY@ --- *
  *
  * Arguments:  @type@ = a type name
 #  define LAUNDER(x)                                                   \
        ({ __typeof__(x) _y; __asm__("" : "=g"(_y) : "0"(x)); _y; })
 #  define ADMIRE(x)                                                    \
-       ({ __asm__("" : : "g"(x)); })
+       ({ __asm__("" :: "g"(x)); })
 #  define ADMIRE_BUF(p, sz)                                            \
-       ({ __asm__("" : : "g"(p), "g"(sz)); })
-#  define RELAX do __asm__ __volatile__("" ::: "memory"); while (0)
+       ({ __asm__("" :: "m"(*(unsigned char *)p), "g"(sz) : "memory"); })
+#  define RELAX do __asm__(""); while (0)
 #endif
 
 #if CLANG_VERSION_P(3, 3)