summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-05-10 11:16:24 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-05-10 11:16:24 -0700
commit43bfc2b6b5477b24d831f49a6ab2123ce95ba747 (patch)
treeabdfbdecd74004518b1b50933a02d6c5342d55af
parent4f9d72fa9e2a4ff1a2aca6de8ee4fa93639c75f1 (diff)
exec_list: Add macros to get ptr to structure containing a node
This has some ugly hackery to work-around C++ fail. I have emperically determined that it works in all the cases that matter.
-rw-r--r--list.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/list.h b/list.h
index afa32f1ed9..26941746b4 100644
--- a/list.h
+++ b/list.h
@@ -64,6 +64,9 @@
#ifndef LIST_CONTAINER_H
#define LIST_CONTAINER_H
+#ifndef __cplusplus
+#include <stddef.h>
+#endif
#include <assert.h>
struct exec_node {
@@ -140,6 +143,30 @@ struct exec_node {
#endif
};
+
+#ifdef __cplusplus
+/* This macro will not work correctly if `t' uses virtual inheritance. If you
+ * are using virtual inheritance, you deserve a slow and painful death. Enjoy!
+ */
+#define exec_list_offsetof(t, f, p) \
+ (((char *) &((t *) p)->f) - ((char *) p))
+#else
+#define exec_list_offsetof(t, f, p) offsetof(t, f)
+#endif
+
+/**
+ * Get a pointer to the structure containing an exec_node
+ *
+ * Given a pointer to an \c exec_node embedded in a structure, get a pointer to
+ * the containing structure.
+ *
+ * \param type Base type of the structure containing the node
+ * \param node Pointer to the \c exec_node
+ * \param field Name of the field in \c type that is the embedded \c exec_node
+ */
+#define exec_node_data(type, node, field) \
+ ((type *) (((char *) node) - exec_list_offsetof(type, field, node)))
+
#ifdef __cplusplus
struct exec_node;