[Bf-blender-cvs] [d4e3b8c3561] virtual-array-attributes: derived span

Jacques Lucke noreply at git.blender.org
Mon Apr 12 18:27:53 CEST 2021


Commit: d4e3b8c35611972960aabd1f2ef5536e5c1d4f9b
Author: Jacques Lucke
Date:   Sat Apr 10 16:34:31 2021 +0200
Branches: virtual-array-attributes
https://developer.blender.org/rBd4e3b8c35611972960aabd1f2ef5536e5c1d4f9b

derived span

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

M	source/blender/blenlib/BLI_virtual_array.hh
M	source/blender/blenlib/tests/BLI_virtual_array_test.cc

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

diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index b585f4e808d..b43fa3e386d 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -493,12 +493,55 @@ template<typename T, typename GetFunc> class VArrayForFunc final : public VArray
   }
 
  private:
-  virtual T get_impl(const int64_t index) const
+  T get_impl(const int64_t index) const override
   {
     return get_func_(index);
   }
 };
 
+template<typename StructT, typename ElemT, ElemT (*GetFunc)(const StructT &)>
+class VArrayForDerivedSpan : public VArray<ElemT> {
+ private:
+  const StructT *data_;
+
+ public:
+  VArrayForDerivedSpan(const Span<StructT> data) : VArray<ElemT>(data.size()), data_(data.data())
+  {
+  }
+
+ private:
+  ElemT get_impl(const int64_t index) const override
+  {
+    return GetFunc(data_[index]);
+  }
+};
+
+template<typename StructT,
+         typename ElemT,
+         ElemT (*GetFunc)(const StructT &),
+         void (*SetFunc)(StructT &, ElemT)>
+class VMutableArrayForDerivedSpan : public VMutableArray<ElemT> {
+ private:
+  StructT *data_;
+
+ public:
+  VMutableArrayForDerivedSpan(const MutableSpan<StructT> data)
+      : VMutableArray<ElemT>(data.size()), data_(data.data())
+  {
+  }
+
+ private:
+  ElemT get_impl(const int64_t index) const override
+  {
+    return GetFunc(data_[index]);
+  }
+
+  void set_impl(const int64_t index, ElemT value) override
+  {
+    SetFunc(data_[index], std::move(value));
+  }
+};
+
 /**
  * Generate multiple versions of the given function optimized for different virtual arrays.
  * One has to be careful with nesting multiple devirtualizations, because that results in an
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index c438ff90040..8e375fd3d19 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -118,4 +118,37 @@ TEST(virtual_array, AsSpan)
   EXPECT_EQ(span[6], 60);
 }
 
+static int get_x(const std::array<int, 3> &item)
+{
+  return item[0];
+}
+
+static void set_x(std::array<int, 3> &item, int value)
+{
+  item[0] = value;
+}
+
+TEST(virtual_array, ForDerivedSpan)
+{
+  Vector<std::array<int, 3>> vector;
+  vector.append({3, 4, 5});
+  vector.append({1, 1, 1});
+  {
+    VArrayForDerivedSpan<std::array<int, 3>, int, get_x> varray{vector};
+    EXPECT_EQ(varray.size(), 2);
+    EXPECT_EQ(varray[0], 3);
+    EXPECT_EQ(varray[1], 1);
+  }
+  {
+    VMutableArrayForDerivedSpan<std::array<int, 3>, int, get_x, set_x> varray{vector};
+    EXPECT_EQ(varray.size(), 2);
+    EXPECT_EQ(varray[0], 3);
+    EXPECT_EQ(varray[1], 1);
+    varray.set(0, 10);
+    varray.set(1, 20);
+    EXPECT_EQ(vector[0][0], 10);
+    EXPECT_EQ(vector[1][0], 20);
+  }
+}
+
 }  // namespace blender::tests



More information about the Bf-blender-cvs mailing list