[Bf-blender-cvs] [b9fa792e081] soc-2021-adaptive-cloth: bli: generational_arena: ConstIterator

ishbosamiya noreply at git.blender.org
Mon Jun 28 08:28:23 CEST 2021


Commit: b9fa792e081d5d717a93a323364a99c29b9c11eb
Author: ishbosamiya
Date:   Thu Jun 24 11:01:54 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rBb9fa792e081d5d717a93a323364a99c29b9c11eb

bli: generational_arena: ConstIterator

ConstIterator is an iterator where the Iterator cannot change the value stored by the iterator.

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

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 84c2b391445..94738881404 100644
--- a/source/blender/blenlib/BLI_generational_arena.hh
+++ b/source/blender/blenlib/BLI_generational_arena.hh
@@ -130,6 +130,7 @@ template<
 class Arena {
  public:
   class Iterator;
+  class ConstIterator;
 
  private:
   struct EntryNoExist;
@@ -418,11 +419,21 @@ class Arena {
     return Iterator(this->data.begin(), this->data.begin(), this->data.end());
   }
 
+  ConstIterator begin() const
+  {
+    return ConstIterator(this->data.begin(), this->data.begin(), this->data.end());
+  }
+
   Iterator end()
   {
     return Iterator(this->data.end(), this->data.begin(), this->data.end());
   }
 
+  ConstIterator end() const
+  {
+    return ConstIterator(this->data.end(), this->data.begin(), this->data.end());
+  }
+
   class Iterator {
    public:
     using iterator_category = std::bidirectional_iterator_tag;
@@ -519,6 +530,107 @@ class Arena {
     }
   };
 
+  class ConstIterator {
+   public:
+    using iterator_category = std::bidirectional_iterator_tag;
+    using difference_type = std::ptrdiff_t;
+    using value_type = T;
+    using pointer = value_type *;
+    using const_pointer = const value_type *;
+    using reference = value_type &;
+    using const_reference = const value_type &;
+
+   private:
+    const Entry *ptr;   /* points to current position */
+    const Entry *start; /* points to first element in the
+                         * Arena::data, aka Arena::data.begin() */
+    const Entry *end;   /* points to last+1 element in the Arena::data, aka Arena::data.end()*/
+
+   public:
+    ConstIterator(const Entry *ptr, const Entry *start, const Entry *end)
+    {
+      this->ptr = ptr;
+      this->start = start;
+      this->end = end;
+    }
+
+    const_reference operator*() const
+    {
+      if (auto val = std::get_if<EntryExist>(this->ptr)) {
+        return val->value;
+      }
+
+      BLI_assert_unreachable();
+
+      return std::get<EntryExist>(*this->ptr).value;
+    }
+
+    const_pointer operator->()
+    {
+      return this->ptr;
+    }
+
+    /* pre fix */
+    ConstIterator &operator++()
+    {
+      BLI_assert(this->ptr != this->end);
+      while (true) {
+        this->ptr++;
+
+        if (this->ptr == this->end) {
+          break;
+        }
+
+        if (auto val = std::get_if<EntryExist>(this->ptr)) {
+          break;
+        }
+      }
+      return *this;
+    }
+
+    ConstIterator &operator--()
+    {
+      BLI_assert(this->ptr != this->start);
+      while (true) {
+        this->ptr--;
+
+        if (this->ptr == this->start) {
+          break;
+        }
+
+        if (auto val = std::get_if<EntryExist>(this->ptr)) {
+          break;
+        }
+      }
+      return *this;
+    }
+
+    /* post fix */
+    ConstIterator operator++(int)
+    {
+      ConstIterator temp = *this;
+      ++(*this);
+      return temp;
+    }
+
+    ConstIterator operator--(int)
+    {
+      ConstIterator temp = *this;
+      --(*this);
+      return temp;
+    }
+
+    friend bool operator==(const ConstIterator &a, const ConstIterator &b)
+    {
+      return a.start == b.start && a.end == b.end && a.ptr == b.ptr;
+    }
+
+    friend bool operator!=(const ConstIterator &a, const ConstIterator &b)
+    {
+      return a.start != b.start || a.end != b.end || a.ptr != b.ptr;
+    }
+  };
+
  protected:
   /* all protected static methods */
   /* all protected non-static methods */
diff --git a/source/blender/blenlib/tests/BLI_generational_arena_test.cc b/source/blender/blenlib/tests/BLI_generational_arena_test.cc
index 279480dbb44..a13ccc83cda 100644
--- a/source/blender/blenlib/tests/BLI_generational_arena_test.cc
+++ b/source/blender/blenlib/tests/BLI_generational_arena_test.cc
@@ -181,6 +181,29 @@ TEST(generational_arena, Iter2)
   EXPECT_NE(std::find(it, arena.end(), 4), arena.end());
 }
 
+TEST(generational_arena, Iter3)
+{
+  struct Foo {
+    int a;
+    int b;
+    Foo(int a, int b) : a(a), b(b)
+    {
+    }
+  };
+  Arena<Foo> arena;
+  arena.insert(Foo(0, 0));
+  arena.insert(Foo(1, 0));
+  arena.insert(Foo(2, 0));
+  arena.insert(Foo(3, 0));
+  arena.insert(Foo(4, 0));
+
+  const Arena<Foo> &arena_ref = arena;
+
+  for (const auto &i : arena_ref) {
+    EXPECT_EQ(i.b, 0);
+  }
+}
+
 TEST(generational_arena, IterIncrement)
 {
   Arena<int> arena;



More information about the Bf-blender-cvs mailing list