[Bf-blender-cvs] [3d95f774c8e] soc-2021-adaptive-cloth: bli: generational_arena: fix: begin() points to `EntryNoExist`

ishbosamiya noreply at git.blender.org
Mon Jul 12 08:23:47 CEST 2021


Commit: 3d95f774c8efb78e5aa1ab6c0470d3efb415afb1
Author: ishbosamiya
Date:   Wed Jul 7 17:40:41 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB3d95f774c8efb78e5aa1ab6c0470d3efb415afb1

bli: generational_arena: fix: begin() points to `EntryNoExist`

When the first element of `Arena::data` is `EntryNoExist`, must iterate over the vector until the first `EntryExist` is found.

For `Arena::end()` this shouldn't be necessary because it should point to the last element + 1 anyway, so the `operator*` on this is meaningless.

===================================================================

M	source/blender/blenlib/BLI_generational_arena.hh
M	source/blender/blenlib/tests/BLI_generational_arena_test.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_generational_arena.hh b/source/blender/blenlib/BLI_generational_arena.hh
index 127916bc6f0..9a5864c4220 100644
--- a/source/blender/blenlib/BLI_generational_arena.hh
+++ b/source/blender/blenlib/BLI_generational_arena.hh
@@ -435,22 +435,56 @@ class Arena {
 
   Iterator begin()
   {
-    return Iterator(this->data.begin(), this->data.begin(), this->data.end());
+    auto *ptr = this->data.begin();
+    auto *begin = this->data.begin();
+    auto *end = this->data.end();
+    while (true) {
+      if (ptr == end) {
+        break;
+      }
+
+      if (auto val = std::get_if<EntryExist>(ptr)) {
+        break;
+      }
+
+      ptr++;
+    }
+    return Iterator(ptr, begin, end);
   }
 
   ConstIterator begin() const
   {
-    return ConstIterator(this->data.begin(), this->data.begin(), this->data.end());
+    auto *ptr = this->data.begin();
+    auto *begin = this->data.begin();
+    auto *end = this->data.end();
+    while (true) {
+      if (ptr == end) {
+        break;
+      }
+
+      if (auto val = std::get_if<EntryExist>(ptr)) {
+        break;
+      }
+
+      ptr++;
+    }
+    return ConstIterator(ptr, begin, end);
   }
 
   Iterator end()
   {
-    return Iterator(this->data.end(), this->data.begin(), this->data.end());
+    auto *ptr = this->data.end();
+    auto *begin = this->data.begin();
+    auto *end = this->data.end();
+    return Iterator(ptr, begin, end);
   }
 
   ConstIterator end() const
   {
-    return ConstIterator(this->data.end(), this->data.begin(), this->data.end());
+    auto *ptr = this->data.end();
+    auto *begin = this->data.begin();
+    auto *end = this->data.end();
+    return ConstIterator(ptr, begin, end);
   }
 
   class Iterator {
diff --git a/source/blender/blenlib/tests/BLI_generational_arena_test.cc b/source/blender/blenlib/tests/BLI_generational_arena_test.cc
index a13ccc83cda..b59c09db1dd 100644
--- a/source/blender/blenlib/tests/BLI_generational_arena_test.cc
+++ b/source/blender/blenlib/tests/BLI_generational_arena_test.cc
@@ -204,6 +204,21 @@ TEST(generational_arena, Iter3)
   }
 }
 
+TEST(generational_arena, Iter4)
+{
+  Arena<int> arena;
+  auto i0 = arena.insert(0);
+  auto i1 = arena.insert(1);
+  auto i2 = arena.insert(2);
+  arena.remove(i0);
+
+  auto iter = arena.begin();
+  std::cout << *iter << std::endl;
+  EXPECT_EQ(arena.get(i0), std::nullopt);
+  EXPECT_EQ(arena.get(i1), 1);
+  EXPECT_EQ(arena.get(i2), 2);
+}
+
 TEST(generational_arena, IterIncrement)
 {
   Arena<int> arena;



More information about the Bf-blender-cvs mailing list