[Bf-blender-cvs] [0620fbbb94e] soc-2021-adaptive-cloth: bli: generational_arena: tests, size(), capacity(), fix some errors

ishbosamiya noreply at git.blender.org
Fri Jun 18 11:22:44 CEST 2021


Commit: 0620fbbb94e7224e975e244a553f0f741901f9fa
Author: ishbosamiya
Date:   Wed Jun 16 12:45:39 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB0620fbbb94e7224e975e244a553f0f741901f9fa

bli: generational_arena: tests, size(), capacity(), fix some errors

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

M	source/blender/blenlib/BLI_generational_arena.hh
M	source/blender/blenlib/CMakeLists.txt
A	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 8cec19ca76e..05ca740a06e 100644
--- a/source/blender/blenlib/BLI_generational_arena.hh
+++ b/source/blender/blenlib/BLI_generational_arena.hh
@@ -69,6 +69,9 @@ template<typename... Ts> struct overloaded : Ts... {
 template<typename... Ts> overloaded(Ts...) -> overloaded<Ts...>;
 } /* namespace extra */
 
+class Index;
+template<typename, int64_t, typename> class Arena;
+
 class Index {
   using usize = uint64_t;
 
@@ -82,10 +85,17 @@ class Index {
     this->generation = generation;
   }
 
+  static inline Index invalid()
+  {
+    return Index(std::numeric_limits<usize>::max(), std::numeric_limits<usize>::max());
+  }
+
   std::tuple<usize, usize> get_raw() const
   {
     return std::make_tuple(this->index, this->generation);
   }
+
+  template<typename, int64_t, typename> friend class Arena;
 };
 
 template<
@@ -152,7 +162,13 @@ class Arena {
 
  public:
   /* default constructor */
-  Arena() = default;
+  Arena()
+  {
+    this->data = Vector<Entry>();
+    this->next_free_head = std::nullopt;
+    this->generation = 0;
+    this->length = 0;
+  }
   /* other constructors */
   Arena(const usize size) : Arena()
   {
@@ -197,19 +213,18 @@ class Arena {
   std::optional<Index> try_insert(T value)
   {
     if (this->next_free_head) {
-      auto loc = this->next_free_head;
-      std::visit(extra::overloaded{[this, value](EntryNoExist &data) {
-                                     this->next_free_head = data.next_free;
-                                     data = EntryExist(value, this->generation);
-                                   },
-                                   [](EntryExist &data) {
-                                     /* The linked list created to
-                                      * know where to insert next is
-                                      * corrupted.
-                                      * `this->next_free_head` is corrupted */
-                                     BLI_assert_unreachable();
-                                   }},
-                 this->data[loc]);
+      auto loc = *this->next_free_head;
+      if (auto entry = std::get_if<EntryNoExist>(&this->data[loc])) {
+        this->next_free_head = entry->next_free;
+        this->data[loc] = EntryExist(value, this->generation);
+      }
+      else {
+        /* The linked list created to
+         * know where to insert next is
+         * corrupted.
+         * `this->next_free_head` is corrupted */
+        BLI_assert_unreachable();
+      }
       this->length += 1;
       return Index(loc, this->generation);
     }
@@ -219,7 +234,7 @@ class Arena {
   Index insert(T value)
   {
     if (auto index = this->try_insert(value)) {
-      return index;
+      return *index;
     }
     else {
       /* couldn't insert the value within reserved memory space  */
@@ -227,11 +242,12 @@ class Arena {
        * needs a special case for that */
       this->reserve(this->data.size() * 2);
       if (auto index = this->try_insert(value)) {
-        return index;
+        return *index;
       }
       else {
         /* now that more memory has been reserved, it shouldn't fail */
         BLI_assert_unreachable();
+        return Index::invalid();
       }
     }
   }
@@ -243,11 +259,17 @@ class Arena {
       return std::nullopt;
     }
 
-    if (index.generation != this->data[index.index]) {
+    if (auto entry = std::get_if<EntryExist>(&this->data[index.index])) {
+      if (index.generation != entry->generation) {
+        return std::nullopt;
+      }
+      else {
+        return std::cref(entry->value);
+      }
+    }
+    else {
       return std::nullopt;
     }
-
-    return std::cref(this->data[index.index]);
   }
 
   std::optional<std::reference_wrapper<T>> get(Index index)
@@ -257,11 +279,17 @@ class Arena {
       return std::nullopt;
     }
 
-    if (index.generation != this->data[index.index]) {
+    if (auto entry = std::get_if<EntryExist>(&this->data[index.index])) {
+      if (index.generation != entry->generation) {
+        return std::nullopt;
+      }
+      else {
+        return std::ref(entry->value);
+      }
+    }
+    else {
       return std::nullopt;
     }
-
-    return std::ref(this->data[index.index]);
   }
 
   std::optional<std::reference_wrapper<const T>> get_no_gen(usize index) const
@@ -300,6 +328,16 @@ class Arena {
     return res;
   }
 
+  isize capacity() const
+  {
+    return static_cast<isize>(this->data.size());
+  }
+
+  isize size() const
+  {
+    return static_cast<isize>(this->length);
+  }
+
  protected:
   /* all protected static methods */
   /* all protected non-static methods */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 18f207c62be..0268c7c0cba 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -397,6 +397,7 @@ if(WITH_GTESTS)
     tests/BLI_edgehash_test.cc
     tests/BLI_expr_pylike_eval_test.cc
     tests/BLI_function_ref_test.cc
+    tests/BLI_generational_arena_test.cc
     tests/BLI_ghash_test.cc
     tests/BLI_hash_mm2a_test.cc
     tests/BLI_heap_simple_test.cc
diff --git a/source/blender/blenlib/tests/BLI_generational_arena_test.cc b/source/blender/blenlib/tests/BLI_generational_arena_test.cc
new file mode 100644
index 00000000000..0e5730046f8
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_generational_arena_test.cc
@@ -0,0 +1,40 @@
+#include "BLI_generational_arena.hh"
+
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+using namespace blender::generational_arena;
+
+TEST(generational_arena, DefaultConstructor)
+{
+  Arena<int> arena;
+  EXPECT_EQ(arena.capacity(), 0);
+}
+
+TEST(generational_arena, SizeConstructor)
+{
+  Arena<int> arena(5);
+  EXPECT_EQ(arena.capacity(), 5);
+}
+
+TEST(generational_arena, Insert)
+{
+  Arena<int> arena(3);
+  EXPECT_EQ(arena.capacity(), 3);
+  auto i1 = arena.insert(1);
+  auto i2 = arena.insert(2);
+  auto i3 = arena.insert(3);
+  auto i4 = arena.insert(4);
+  auto i5 = arena.insert(5);
+
+  EXPECT_EQ(arena.capacity(), 6);
+  EXPECT_EQ(arena.size(), 5);
+  EXPECT_EQ(arena.get(i1), 1);
+  EXPECT_EQ(arena.get(i2), 2);
+  EXPECT_EQ(arena.get(i3), 3);
+  EXPECT_EQ(arena.get(i4), 4);
+  EXPECT_EQ(arena.get(i5), 5);
+}
+
+} /* namespace blender::tests */



More information about the Bf-blender-cvs mailing list