Merge remote branch 'origin/master' into glsl2
[mesa.git] / src / glsl / list.h
index 7732d66d7a69607e751dadc1a8c7bf821265d83b..7348e323c1b3cfc6644b68d33f04af74afbd8521 100644 (file)
@@ -165,6 +165,17 @@ struct exec_node {
       this->prev->next = before;
       this->prev = before;
    }
+   /**
+    * Replace the current node with the given node.
+    */
+   void replace_with(exec_node *replacement)
+   {
+      replacement->prev = this->prev;
+      replacement->next = this->next;
+
+      this->prev->next = replacement;
+      this->next->prev = replacement;
+   }
 
    /**
     * Is this the sentinal at the tail of the list?
@@ -272,6 +283,25 @@ struct exec_list {
    struct exec_node *tail_pred;
 
 #ifdef __cplusplus
+   /* Callers of this talloc-based new need not call delete. It's
+    * easier to just talloc_free 'ctx' (or any of its ancestors). */
+   static void* operator new(size_t size, void *ctx)
+   {
+      void *node;
+
+      node = talloc_size(ctx, size);
+      assert(node != NULL);
+
+      return node;
+   }
+
+   /* If the user *does* call delete, that's OK, we will just
+    * talloc_free in that case. */
+   static void operator delete(void *node)
+   {
+      talloc_free(node);
+   }
+
    exec_list()
    {
       make_empty();
@@ -366,6 +396,30 @@ struct exec_list {
       }
    }
 
+   /**
+    * Append all nodes from the source list to the target list
+    */
+   void
+   append_list(exec_list *source)
+   {
+      if (source->is_empty())
+        return;
+
+      /* Link the first node of the source with the last node of the target list.
+       */
+      this->tail_pred->next = source->head;
+      source->head->prev = this->tail_pred;
+
+      /* Make the tail of the source list be the tail of the target list.
+       */
+      this->tail_pred = source->tail_pred;
+      this->tail_pred->next = (exec_node *) &this->tail;
+
+      /* Make the source list empty for good measure.
+       */
+      source->make_empty();
+   }
+
    exec_list_iterator iterator()
    {
       return exec_list_iterator(head);
@@ -378,6 +432,14 @@ struct exec_list {
 #endif
 };
 
+/**
+ * This version is safe even if the current node is removed.
+ */ 
+#define foreach_list_safe(__node, __list)                           \
+   for (exec_node * __node = (__list)->head, * __next = __node->next \
+       ; __next != NULL                                             \
+       ; __node = __next, __next = __next->next)
+
 #define foreach_list(__node, __list)                   \
    for (exec_node * __node = (__list)->head            \
        ; (__node)->next != NULL                        \