[Bf-blender-cvs] [5b9cad04c61] virtual-array-attributes: add virtual array for container
Jacques Lucke
noreply at git.blender.org
Mon Apr 12 18:27:52 CEST 2021
Commit: 5b9cad04c61585548512c461d17043e0d4d4d7e9
Author: Jacques Lucke
Date: Sat Apr 10 13:14:42 2021 +0200
Branches: virtual-array-attributes
https://developer.blender.org/rB5b9cad04c61585548512c461d17043e0d4d4d7e9
add virtual array for container
===================================================================
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 f9b0aaa7de6..371703d4038 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -145,35 +145,65 @@ template<typename T> class VArray {
};
/**
- * A virtual array implementation for a span. This class is final so that it can be devirtualized
- * by the compiler in some cases (e.g. when #devirtualize_varray is used).
+ * A virtual array implementation for a span. Methods in this class are final so that it can be
+ * devirtualized by the compiler in some cases (e.g. when #devirtualize_varray is used).
*/
-template<typename T> class VArrayForSpan final : public VArray<T> {
+template<typename T> class VArrayForSpan : public VArray<T> {
private:
- const T *data_;
+ const T *data_ = nullptr;
public:
VArrayForSpan(const Span<T> data) : VArray<T>(data.size()), data_(data.data())
{
}
+ /* When this constructor is used, the #set_data method has to be used as well. */
+ VArrayForSpan(const int64_t size) : VArray<T>(size)
+ {
+ }
+
protected:
- T get_impl(const int64_t index) const override
+ /* Can be used when the data pointer is not ready when the constructor is called. */
+ void set_data(const T *data)
+ {
+ data_ = data;
+ }
+
+ T get_impl(const int64_t index) const final
{
return data_[index];
}
- bool is_span_impl() const override
+ bool is_span_impl() const final
{
return true;
}
- Span<T> get_span_impl() const override
+ Span<T> get_span_impl() const final
{
return Span<T>(data_, this->size_);
}
};
+/**
+ * A variant of `VArrayForSpan` that owns the underlying data.
+ * The `Container` type has to implement a `size()` and `data()` method.
+ * The `data()` method has to return a pointer to the first element in the continuous array of
+ * elements.
+ */
+template<typename Container, typename T = typename Container::value_type>
+class VArrayForArrayContainer : public VArrayForSpan<T> {
+ private:
+ Container container_;
+
+ public:
+ VArrayForArrayContainer(Container container)
+ : VArrayForSpan<T>((int64_t)container.size()), container_(std::move(container))
+ {
+ this->set_data(container_.data());
+ }
+};
+
/**
* A virtual array implementation that returns the same value for every index. This class is final
* so that it can be devirtualized by the compiler in some cases (e.g. when #devirtualize_varray is
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index ac25229cd69..0f568f63d79 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -1,6 +1,9 @@
/* Apache License, Version 2.0 */
+#include "BLI_array.hh"
#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "BLI_vector_set.hh"
#include "BLI_virtual_array.hh"
#include "testing/testing.h"
@@ -28,4 +31,68 @@ TEST(virtual_array, ForSingle)
EXPECT_TRUE(varray.is_single());
}
+TEST(virtual_array, ForArray)
+{
+ Array<int> array = {1, 2, 3, 5, 8};
+ {
+ VArrayForArrayContainer varray{array};
+ EXPECT_EQ(varray.size(), 5);
+ EXPECT_EQ(varray[0], 1);
+ EXPECT_EQ(varray[2], 3);
+ EXPECT_EQ(varray[3], 5);
+ EXPECT_TRUE(varray.is_span());
+ }
+ {
+ VArrayForArrayContainer varray{std::move(array)};
+ EXPECT_EQ(varray.size(), 5);
+ EXPECT_EQ(varray[0], 1);
+ EXPECT_EQ(varray[2], 3);
+ EXPECT_EQ(varray[3], 5);
+ EXPECT_TRUE(varray.is_span());
+ }
+ {
+ VArrayForArrayContainer varray{array}; /* NOLINT: bugprone-use-after-move */
+ EXPECT_TRUE(varray.is_empty());
+ }
+}
+
+TEST(virtual_array, ForVector)
+{
+ Vector<int> vector = {9, 8, 7, 6};
+ VArrayForArrayContainer varray{std::move(vector)};
+ EXPECT_EQ(varray.size(), 4);
+ EXPECT_EQ(varray[0], 9);
+ EXPECT_EQ(varray[3], 6);
+}
+
+TEST(virtual_array, ForStdVector)
+{
+ std::vector<int> vector = {5, 6, 7, 8};
+ VArrayForArrayContainer varray{std::move(vector)};
+ EXPECT_EQ(varray.size(), 4);
+ EXPECT_EQ(varray[0], 5);
+ EXPECT_EQ(varray[1], 6);
+}
+
+TEST(virtual_array, ForStdArray)
+{
+ std::array<int, 4> array = {2, 3, 4, 5};
+ VArrayForArrayContainer varray{array};
+ EXPECT_EQ(varray.size(), 4);
+ EXPECT_EQ(varray[0], 2);
+ EXPECT_EQ(varray[1], 3);
+}
+
+TEST(virtual_array, ForVectorSet)
+{
+ VectorSet<int> vector_set = {5, 3, 7, 3, 3, 5, 1};
+ VArrayForArrayContainer varray{std::move(vector_set)};
+ EXPECT_TRUE(vector_set.is_empty()); /* NOLINT: bugprone-use-after-move. */
+ EXPECT_EQ(varray.size(), 4);
+ EXPECT_EQ(varray[0], 5);
+ EXPECT_EQ(varray[1], 3);
+ EXPECT_EQ(varray[2], 7);
+ EXPECT_EQ(varray[3], 1);
+}
+
} // namespace blender::tests
More information about the Bf-blender-cvs
mailing list