Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenlib / intern / listbase.c
index 3bf0dfa09faff55f852684f8c6c986addac22a27..abc4a77332823596b741b4c24901c6d953d447f7 100644 (file)
@@ -370,6 +370,40 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
        }
 }
 
+
+/**
+ * Insert a link in place of another, without changing it's position in the list.
+ *
+ * Puts `vnewlink` in the position of `vreplacelink`, removing `vreplacelink`.
+ * - `vreplacelink` *must* be in the list.
+ * - `vnewlink` *must not* be in the list.
+ */
+void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
+{
+       Link *l_old = vreplacelink;
+       Link *l_new = vnewlink;
+
+       /* update adjacent links */
+       if (l_old->next != NULL) {
+               l_old->next->prev = l_new;
+       }
+       if (l_old->prev != NULL) {
+               l_old->prev->next = l_new;
+       }
+
+       /* set direct links */
+       l_new->next = l_old->next;
+       l_new->prev = l_old->prev;
+
+        /* update list */
+       if (listbase->first == l_old) {
+               listbase->first = l_new;
+       }
+       if (listbase->last == l_old) {
+               listbase->last = l_new;
+       }
+}
+
 /**
  * Reinsert \a vlink relative to its current position but offset by \a step. Doesn't move
  * item if new position would exceed list (could optionally move to head/tail).