[Bf-blender-cvs] [9c14039a8f4] master: BLI ListBase: Add new 'SplitAfter' given link util.
Bastien Montagne
noreply at git.blender.org
Mon Feb 6 17:58:51 CET 2023
Commit: 9c14039a8f4b5f00d84caf41b83175d8b4deda2d
Author: Bastien Montagne
Date: Mon Feb 6 17:54:18 2023 +0100
Branches: master
https://developer.blender.org/rB9c14039a8f4b5f00d84caf41b83175d8b4deda2d
BLI ListBase: Add new 'SplitAfter' given link util.
Allows to easily split a ListBase by moving the part after given link
into a new ListBase.
===================================================================
M source/blender/blenlib/BLI_listbase.h
M source/blender/blenlib/intern/listbase.cc
M source/blender/blenlib/tests/BLI_listbase_test.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 6a41fce27b3..f819413c7ce 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -243,6 +243,16 @@ void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL
* Moves the entire contents of \a src at the beginning of \a dst.
*/
void BLI_movelisttolist_reverse(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2);
+/**
+ * Split `original_listbase` after given `vlink`, putting the remaining of the list into given
+ * `split_listbase`.
+ *
+ * \note If `vlink` is nullptr, it is considered as 'the item before the first item', so the whole
+ * list is moved from `original_listbase` to `split_listbase`.
+ */
+void BLI_listbase_split_after(struct ListBase *original_listbase,
+ struct ListBase *split_listbase,
+ void *vlink) ATTR_NONNULL(1, 2);
/**
* Sets dst to a duplicate of the entire contents of src. dst may be the same as src.
*/
diff --git a/source/blender/blenlib/intern/listbase.cc b/source/blender/blenlib/intern/listbase.cc
index 6812a12c9f0..3b549cf68c4 100644
--- a/source/blender/blenlib/intern/listbase.cc
+++ b/source/blender/blenlib/intern/listbase.cc
@@ -57,6 +57,35 @@ void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src)
src->first = src->last = nullptr;
}
+void BLI_listbase_split_after(ListBase *original_listbase, ListBase *split_listbase, void *vlink)
+{
+ BLI_assert(BLI_listbase_is_empty(split_listbase));
+ BLI_assert(vlink == nullptr || BLI_findindex(original_listbase, vlink) >= 0);
+
+ if (vlink == original_listbase->last) {
+ /* Nothing to split, and `split_listbase` is assumed already empty (see assert above). */
+ return;
+ }
+
+ if (vlink == nullptr) {
+ /* Move everything into `split_listbase`. */
+ SWAP(ListBase, *original_listbase, *split_listbase);
+ return;
+ }
+
+ Link *link = static_cast<Link *>(vlink);
+ Link *next_link = link->next;
+ BLI_assert(next_link != nullptr);
+ Link *last_link = static_cast<Link *>(original_listbase->last);
+
+ original_listbase->last = link;
+ split_listbase->first = next_link;
+ split_listbase->last = last_link;
+
+ link->next = nullptr;
+ next_link->prev = nullptr;
+}
+
void BLI_addhead(ListBase *listbase, void *vlink)
{
Link *link = static_cast<Link *>(vlink);
diff --git a/source/blender/blenlib/tests/BLI_listbase_test.cc b/source/blender/blenlib/tests/BLI_listbase_test.cc
index abdd4f90221..c5a2904505c 100644
--- a/source/blender/blenlib/tests/BLI_listbase_test.cc
+++ b/source/blender/blenlib/tests/BLI_listbase_test.cc
@@ -187,6 +187,77 @@ TEST(listbase, FromLink)
BLI_freelistN(&lb);
}
+TEST(listbase, SplitAfter)
+{
+ ListBase lb;
+ ListBase split_after_lb;
+ void *link1 = MEM_callocN(sizeof(Link), "link1");
+ void *link2 = MEM_callocN(sizeof(Link), "link2");
+
+ /* Empty list */
+ BLI_listbase_clear(&lb);
+ BLI_listbase_clear(&split_after_lb);
+
+ BLI_listbase_split_after(&lb, &split_after_lb, nullptr);
+ EXPECT_EQ(BLI_listbase_is_empty(&split_after_lb), true);
+ EXPECT_BLI_ASSERT(BLI_listbase_split_after(&lb, &split_after_lb, link1), "");
+
+ /* One link */
+ BLI_listbase_clear(&lb);
+ BLI_listbase_clear(&split_after_lb);
+ BLI_addtail(&lb, link1);
+
+ BLI_listbase_split_after(&lb, &split_after_lb, nullptr);
+ EXPECT_EQ(BLI_listbase_is_empty(&lb), true);
+ EXPECT_EQ(BLI_listbase_count(&split_after_lb), 1);
+ EXPECT_EQ(BLI_findindex(&split_after_lb, link1), 0);
+ EXPECT_EQ(split_after_lb.first, link1);
+ EXPECT_EQ(split_after_lb.last, link1);
+
+ BLI_listbase_clear(&lb);
+ BLI_listbase_clear(&split_after_lb);
+ BLI_addtail(&lb, link1);
+
+ BLI_listbase_split_after(&lb, &split_after_lb, link1);
+ EXPECT_EQ(BLI_listbase_count(&lb), 1);
+ EXPECT_EQ(BLI_findindex(&lb, link1), 0);
+ EXPECT_EQ(lb.first, link1);
+ EXPECT_EQ(lb.last, link1);
+ EXPECT_EQ(BLI_listbase_is_empty(&split_after_lb), true);
+
+ /* Two links */
+ BLI_listbase_clear(&lb);
+ BLI_listbase_clear(&split_after_lb);
+ BLI_addtail(&lb, link1);
+ BLI_addtail(&lb, link2);
+
+ BLI_listbase_split_after(&lb, &split_after_lb, nullptr);
+ EXPECT_EQ(BLI_listbase_is_empty(&lb), true);
+ EXPECT_EQ(BLI_listbase_count(&split_after_lb), 2);
+ EXPECT_EQ(BLI_findindex(&split_after_lb, link1), 0);
+ EXPECT_EQ(BLI_findindex(&split_after_lb, link2), 1);
+ EXPECT_EQ(split_after_lb.first, link1);
+ EXPECT_EQ(split_after_lb.last, link2);
+
+ BLI_listbase_clear(&lb);
+ BLI_listbase_clear(&split_after_lb);
+ BLI_addtail(&lb, link1);
+ BLI_addtail(&lb, link2);
+
+ BLI_listbase_split_after(&lb, &split_after_lb, link1);
+ EXPECT_EQ(BLI_listbase_count(&lb), 1);
+ EXPECT_EQ(BLI_findindex(&lb, link1), 0);
+ EXPECT_EQ(lb.first, link1);
+ EXPECT_EQ(lb.last, link1);
+ EXPECT_EQ(BLI_listbase_count(&split_after_lb), 1);
+ EXPECT_EQ(BLI_findindex(&split_after_lb, link2), 0);
+ EXPECT_EQ(split_after_lb.first, link2);
+ EXPECT_EQ(split_after_lb.last, link2);
+
+ BLI_freelistN(&lb);
+ BLI_freelistN(&split_after_lb);
+}
+
/* -------------------------------------------------------------------- */
/* Sort utilities & test */
More information about the Bf-blender-cvs
mailing list