Add a virtual clone() method to ir_instruction.
[mesa.git] / list.h
diff --git a/list.h b/list.h
index afa32f1ed9715d9eaf372d9055097f07f942eff0..0b91647be4f69c240da55169c8ba5b7bf4eb214a 100644 (file)
--- 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 {
@@ -137,9 +140,49 @@ struct exec_node {
       this->prev->next = before;
       this->prev = before;
    }
+
+   /**
+    * Is this the sentinal at the tail of the list?
+    */
+   bool is_tail_sentinal() const
+   {
+      return this->next == NULL;
+   }
+
+   /**
+    * Is this the sentinal at the head of the list?
+    */
+   bool is_head_sentinal() const
+   {
+      return this->prev == NULL;
+   }
 #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;
 
@@ -310,4 +353,26 @@ struct exec_list {
 #endif
 };
 
+#define foreach_list(__node, __list)                   \
+   for (exec_node * __node = (__list)->head            \
+       ; (__node)->next != NULL                        \
+       ; (__node) = (__node)->next)
+
+#define foreach_list_const(__node, __list)             \
+   for (const exec_node * __node = (__list)->head      \
+       ; (__node)->next != NULL                        \
+       ; (__node) = (__node)->next)
+
+#define foreach_list_typed(__type, __node, __field, __list)            \
+   for (__type * __node =                                              \
+          exec_node_data(__type, (__list)->head, __field);             \
+       (__node)->__field.next != NULL;                                 \
+       (__node) = exec_node_data(__type, (__node)->__field.next, __field))
+
+#define foreach_list_typed_const(__type, __node, __field, __list)      \
+   for (const __type * __node =                                                \
+          exec_node_data(__type, (__list)->head, __field);             \
+       (__node)->__field.next != NULL;                                 \
+       (__node) = exec_node_data(__type, (__node)->__field.next, __field))
+
 #endif /* LIST_CONTAINER_H */