[Bf-blender-cvs] [98721c85431] master: BLI: improve support for generic algorithms with c++ containers

Jacques Lucke noreply at git.blender.org
Sat Mar 20 15:47:40 CET 2021


Commit: 98721c85431d223c895a25d63dafb9e6637d34c4
Author: Jacques Lucke
Date:   Sat Mar 20 15:42:35 2021 +0100
Branches: master
https://developer.blender.org/rB98721c85431d223c895a25d63dafb9e6637d34c4

BLI: improve support for generic algorithms with c++ containers

Some generic algorithms from the standard library like `std::any_of`
did not work with all container and iterator types. To improve the
situation, this patch adds various type members to containers
and iterators.

Custom iterators for Set, Map and IndexRange now have an iterator
category, which soe algorithms require. IndexRange could become
a random access iterator, but adding all the missing methods can
be done when it is necessary.

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

M	source/blender/blenlib/BLI_array.hh
M	source/blender/blenlib/BLI_index_range.hh
M	source/blender/blenlib/BLI_map.hh
M	source/blender/blenlib/BLI_multi_value_map.hh
M	source/blender/blenlib/BLI_set.hh
M	source/blender/blenlib/BLI_span.hh
M	source/blender/blenlib/BLI_stack.hh
M	source/blender/blenlib/BLI_vector.hh
M	source/blender/blenlib/BLI_vector_set.hh
M	source/blender/blenlib/tests/BLI_index_range_test.cc
M	source/blender/blenlib/tests/BLI_map_test.cc
M	source/blender/blenlib/tests/BLI_set_test.cc

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

diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh
index 284d62fb876..fc8fc615feb 100644
--- a/source/blender/blenlib/BLI_array.hh
+++ b/source/blender/blenlib/BLI_array.hh
@@ -60,6 +60,16 @@ template<
      */
     typename Allocator = GuardedAllocator>
 class Array {
+ public:
+  using value_type = T;
+  using pointer = T *;
+  using const_pointer = const T *;
+  using reference = T &;
+  using const_reference = const T &;
+  using iterator = T *;
+  using const_iterator = const T *;
+  using size_type = int64_t;
+
  private:
   /** The beginning of the array. It might point into the inline buffer. */
   T *data_;
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh
index 61a8088edea..665f44468db 100644
--- a/source/blender/blenlib/BLI_index_range.hh
+++ b/source/blender/blenlib/BLI_index_range.hh
@@ -82,11 +82,18 @@ class IndexRange {
   }
 
   class Iterator {
+   public:
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = int64_t;
+    using pointer = const int64_t *;
+    using reference = const int64_t &;
+    using difference_type = std::ptrdiff_t;
+
    private:
     int64_t current_;
 
    public:
-    constexpr Iterator(int64_t current) : current_(current)
+    constexpr explicit Iterator(int64_t current) : current_(current)
     {
     }
 
@@ -96,9 +103,21 @@ class IndexRange {
       return *this;
     }
 
-    constexpr bool operator!=(const Iterator &iterator) const
+    constexpr Iterator operator++(int) const
+    {
+      Iterator copied_iterator = *this;
+      ++copied_iterator;
+      return copied_iterator;
+    }
+
+    constexpr friend bool operator!=(const Iterator &a, const Iterator &b)
+    {
+      return a.current_ != b.current_;
+    }
+
+    constexpr friend bool operator==(const Iterator &a, const Iterator &b)
     {
-      return current_ != iterator.current_;
+      return a.current_ == b.current_;
     }
 
     constexpr int64_t operator*() const
diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 9480af89107..9fa69853e44 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -120,6 +120,9 @@ template<
      */
     typename Allocator = GuardedAllocator>
 class Map {
+ public:
+  using size_type = int64_t;
+
  private:
   /**
    * Slots are either empty, occupied or removed. The number of occupied slots can be computed by
@@ -623,6 +626,9 @@ class Map {
    * This uses the "curiously recurring template pattern" (CRTP).
    */
   template<typename SubIterator> struct BaseIterator {
+    using iterator_category = std::forward_iterator_tag;
+    using difference_type = std::ptrdiff_t;
+
     Slot *slots_;
     int64_t total_slots_;
     int64_t current_slot_;
@@ -642,6 +648,13 @@ class Map {
       return *this;
     }
 
+    BaseIterator operator++(int) const
+    {
+      BaseIterator copied_iterator = *this;
+      ++copied_iterator;
+      return copied_iterator;
+    }
+
     friend bool operator!=(const BaseIterator &a, const BaseIterator &b)
     {
       BLI_assert(a.slots_ == b.slots_);
@@ -649,6 +662,11 @@ class Map {
       return a.current_slot_ != b.current_slot_;
     }
 
+    friend bool operator==(const BaseIterator &a, const BaseIterator &b)
+    {
+      return !(a != b);
+    }
+
     SubIterator begin() const
     {
       for (int64_t i = 0; i < total_slots_; i++) {
@@ -672,6 +690,10 @@ class Map {
 
   class KeyIterator final : public BaseIterator<KeyIterator> {
    public:
+    using value_type = Key;
+    using pointer = const Key *;
+    using reference = const Key &;
+
     KeyIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
         : BaseIterator<KeyIterator>(slots, total_slots, current_slot)
     {
@@ -685,6 +707,10 @@ class Map {
 
   class ValueIterator final : public BaseIterator<ValueIterator> {
    public:
+    using value_type = Value;
+    using pointer = const Value *;
+    using reference = const Value &;
+
     ValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
         : BaseIterator<ValueIterator>(slots, total_slots, current_slot)
     {
@@ -698,6 +724,10 @@ class Map {
 
   class MutableValueIterator final : public BaseIterator<MutableValueIterator> {
    public:
+    using value_type = Value;
+    using pointer = Value *;
+    using reference = Value &;
+
     MutableValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
         : BaseIterator<MutableValueIterator>(slots, total_slots, current_slot)
     {
@@ -726,6 +756,10 @@ class Map {
 
   class ItemIterator final : public BaseIterator<ItemIterator> {
    public:
+    using value_type = Item;
+    using pointer = Item *;
+    using reference = Item &;
+
     ItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
         : BaseIterator<ItemIterator>(slots, total_slots, current_slot)
     {
@@ -740,6 +774,10 @@ class Map {
 
   class MutableItemIterator final : public BaseIterator<MutableItemIterator> {
    public:
+    using value_type = MutableItem;
+    using pointer = MutableItem *;
+    using reference = MutableItem &;
+
     MutableItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
         : BaseIterator<MutableItemIterator>(slots, total_slots, current_slot)
     {
diff --git a/source/blender/blenlib/BLI_multi_value_map.hh b/source/blender/blenlib/BLI_multi_value_map.hh
index 4113085a1e3..98b55067a5c 100644
--- a/source/blender/blenlib/BLI_multi_value_map.hh
+++ b/source/blender/blenlib/BLI_multi_value_map.hh
@@ -38,6 +38,9 @@
 namespace blender {
 
 template<typename Key, typename Value> class MultiValueMap {
+ public:
+  using size_type = int64_t;
+
  private:
   using MapType = Map<Key, Vector<Value>>;
   MapType map_;
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index 06b56c3f8e5..fef657b2d8f 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -119,6 +119,16 @@ template<
      */
     typename Allocator = GuardedAllocator>
 class Set {
+ public:
+  class Iterator;
+  using value_type = Key;
+  using pointer = Key *;
+  using const_pointer = const Key *;
+  using reference = Key &;
+  using const_reference = const Key &;
+  using iterator = Iterator;
+  using size_type = int64_t;
+
  private:
   /**
    * Slots are either empty, occupied or removed. The number of occupied slots can be computed by
@@ -401,6 +411,13 @@ class Set {
    * also change their hash.
    */
   class Iterator {
+   public:
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = Key;
+    using pointer = const Key *;
+    using reference = const Key &;
+    using difference_type = std::ptrdiff_t;
+
    private:
     const Slot *slots_;
     int64_t total_slots_;
@@ -422,17 +439,34 @@ class Set {
       return *this;
     }
 
+    Iterator operator++(int) const
+    {
+      Iterator copied_iterator = *this;
+      ++copied_iterator;
+      return copied_iterator;
+    }
+
     const Key &operator*() const
     {
       return *slots_[current_slot_].key();
     }
 
+    const Key *operator->() const
+    {
+      return slots_[current_slot_].key();
+    }
+
     friend bool operator!=(const Iterator &a, const Iterator &b)
     {
       BLI_assert(a.slots_ == b.slots_);
       BLI_assert(a.total_slots_ == b.total_slots_);
       return a.current_slot_ != b.current_slot_;
     }
+
+    friend bool operator==(const Iterator &a, const Iterator &b)
+    {
+      return !(a != b);
+    }
   };
 
   Iterator begin() const
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index fcc6d6f754b..fe511793c46 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -85,6 +85,15 @@ namespace blender {
  * modified.
  */
 template<typename T> class Span {
+ public:
+  using value_type = T;
+  using pointer = T *;
+  using const_pointer = const T *;
+  using reference = T &;
+  using const_reference = const T &;
+  using iterator = const T *;
+  using size_type = int64_t;
+
  private:
   const T *data_ = nullptr;
   int64_t size_ = 0;
@@ -459,6 +468,15 @@ template<typename T> class Span {
  * MutableSpan.
  */
 template<typename T> class MutableSpan {
+ public:
+  using value_type = T;
+  using pointer = T *;
+  using const_pointer = const T *;
+  using reference = T &;
+  using const_reference = const T &;
+  using iterator = T *;
+  using size_type = int64_t;
+
  private:
   T *data_;
   int64_t size_;
diff --git a/source/blender/blenlib/BLI_stack.hh b/source/blender/blenlib/BLI_stack.hh
index a463ac102f1..19f77078c5b 100644
--- a/source/blender/blenlib/BLI_stack.hh
+++ b/source/blender/blenlib/BLI_stack.hh
@@ -80,6 +80,14 @@ template<
      */
     typename Allocator = GuardedAllocator>
 class Stack {
+ public:
+  using value_type = T;
+  using pointer = T *;
+  using const_pointer = const T *;
+  using reference = T &;
+  using const_reference = const T &;
+  using size_type = int64_t;
+
  private:
   using Chunk = StackChunk<T>;
 
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index eefacd5d64f..328d623787b 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -76,6 +76,16 @@ template<
      */
     typename Allocator = GuardedAllocator>
 class Vector {
+ public:
+  using value_type = T;
+  using pointer = T *;
+  using const_pointer = const T *;
+  using reference = T &;
+  using const_reference = const T &;
+  using iterator = T *;
+  using const_iterator = const T *;
+  using size_type = int64_t;
+
  private:
   /**
    * Use pointers instead of storing the size explicitly. This reduces the number of instructions
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index c9773dc599d..14b38d564cb 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -100,6 +100,16 @@ template<
      */
     typename Allocator = GuardedAllocator>
 class VectorSet {
+ public:
+  using value_type = Key;
+  using pointer = Key *;
+  

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list