Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-11-26 16:47:02 +0300
committerJacques Lucke <jacques@blender.org>2021-11-26 16:47:15 +0300
commitf86331a0338dc2351e914b45ccbd743b6cccbb19 (patch)
treed67fb1d4baafd95e3b6fd97c9f707943b4d6746a /source/blender/blenlib
parentef88047a97a10283cca21a3fe75c8d69d8fc40eb (diff)
Geometry Nodes: deduplicate virtual array implementations
For some underlying data (e.g. spans) we had two virtual array implementations. One for the mutable and one for the immutable case. Now that most code does not deal with the virtual array implementations directly anymore (since rBrBd4c868da9f97a), we can get away with sharing one implementation for both cases. This means that we have to do a `const_cast` in a few places, but this is an implementation detail that does not leak into "user code" (only when explicitly casting a `VArrayImpl` to a `VMutableArrayImpl`, which should happen nowhere).
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_virtual_array.hh128
1 files changed, 24 insertions, 104 deletions
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index 33b3f82c0c2..2038abc0b77 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -223,69 +223,21 @@ template<typename T> class VMutableArrayImpl : public VArrayImpl<T> {
};
/**
- * 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).
+ * A virtual array implementation that references that wraps a span. This implementation is used by
+ * mutable and immutable spans to avoid code duplication.
*/
-template<typename T> class VArrayImpl_For_Span : public VArrayImpl<T> {
- protected:
- const T *data_ = nullptr;
-
- public:
- VArrayImpl_For_Span(const Span<T> data) : VArrayImpl<T>(data.size()), data_(data.data())
- {
- }
-
- protected:
- VArrayImpl_For_Span(const int64_t size) : VArrayImpl<T>(size)
- {
- }
-
- T get(const int64_t index) const final
- {
- return data_[index];
- }
-
- bool is_span() const final
- {
- return true;
- }
-
- Span<T> get_internal_span() const final
- {
- return Span<T>(data_, this->size_);
- }
-};
-
-/**
- * A version of #VArrayImpl_For_Span that can not be subclassed. This allows safely overwriting the
- * #may_have_ownership method.
- */
-template<typename T> class VArrayImpl_For_Span_final final : public VArrayImpl_For_Span<T> {
- public:
- using VArrayImpl_For_Span<T>::VArrayImpl_For_Span;
-
- private:
- bool may_have_ownership() const override
- {
- return false;
- }
-};
-
-/**
- * Like #VArrayImpl_For_Span but for mutable data.
- */
-template<typename T> class VMutableArrayImpl_For_MutableSpan : public VMutableArrayImpl<T> {
+template<typename T> class VArrayImpl_For_Span : public VMutableArrayImpl<T> {
protected:
T *data_ = nullptr;
public:
- VMutableArrayImpl_For_MutableSpan(const MutableSpan<T> data)
+ VArrayImpl_For_Span(const MutableSpan<T> data)
: VMutableArrayImpl<T>(data.size()), data_(data.data())
{
}
protected:
- VMutableArrayImpl_For_MutableSpan(const int64_t size) : VMutableArrayImpl<T>(size)
+ VArrayImpl_For_Span(const int64_t size) : VMutableArrayImpl<T>(size)
{
}
@@ -311,12 +263,12 @@ template<typename T> class VMutableArrayImpl_For_MutableSpan : public VMutableAr
};
/**
- * Like #VArrayImpl_For_Span_final but for mutable data.
+ * A version of #VArrayImpl_For_Span that can not be subclassed. This allows safely overwriting the
+ * #may_have_ownership method.
*/
-template<typename T>
-class VMutableArrayImpl_For_MutableSpan_final final : public VMutableArrayImpl_For_MutableSpan<T> {
+template<typename T> class VArrayImpl_For_Span_final final : public VArrayImpl_For_Span<T> {
public:
- using VMutableArrayImpl_For_MutableSpan<T>::VMutableArrayImpl_For_MutableSpan;
+ using VArrayImpl_For_Span<T>::VArrayImpl_For_Span;
private:
bool may_have_ownership() const override
@@ -340,7 +292,7 @@ class VArrayImpl_For_ArrayContainer : public VArrayImpl_For_Span<T> {
VArrayImpl_For_ArrayContainer(Container container)
: VArrayImpl_For_Span<T>((int64_t)container.size()), container_(std::move(container))
{
- this->data_ = container_.data();
+ this->data_ = const_cast<T *>(container_.data());
}
};
@@ -422,54 +374,16 @@ template<typename T, typename GetFunc> class VArrayImpl_For_Func final : public
/**
* \note: This is `final` so that #may_have_ownership can be implemented reliably.
*/
-template<typename StructT, typename ElemT, ElemT (*GetFunc)(const StructT &)>
-class VArrayImpl_For_DerivedSpan final : public VArrayImpl<ElemT> {
- private:
- const StructT *data_;
-
- public:
- VArrayImpl_For_DerivedSpan(const Span<StructT> data)
- : VArrayImpl<ElemT>(data.size()), data_(data.data())
- {
- }
-
- private:
- ElemT get(const int64_t index) const override
- {
- return GetFunc(data_[index]);
- }
-
- void materialize(IndexMask mask, MutableSpan<ElemT> r_span) const override
- {
- ElemT *dst = r_span.data();
- mask.foreach_index([&](const int64_t i) { dst[i] = GetFunc(data_[i]); });
- }
-
- void materialize_to_uninitialized(IndexMask mask, MutableSpan<ElemT> r_span) const override
- {
- ElemT *dst = r_span.data();
- mask.foreach_index([&](const int64_t i) { new (dst + i) ElemT(GetFunc(data_[i])); });
- }
-
- bool may_have_ownership() const override
- {
- return false;
- }
-};
-
-/**
- * \note: This is `final` so that #may_have_ownership can be implemented reliably.
- */
template<typename StructT,
typename ElemT,
ElemT (*GetFunc)(const StructT &),
- void (*SetFunc)(StructT &, ElemT)>
-class VMutableArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
+ void (*SetFunc)(StructT &, ElemT) = nullptr>
+class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
private:
StructT *data_;
public:
- VMutableArrayImpl_For_DerivedSpan(const MutableSpan<StructT> data)
+ VArrayImpl_For_DerivedSpan(const MutableSpan<StructT> data)
: VMutableArrayImpl<ElemT>(data.size()), data_(data.data())
{
}
@@ -482,6 +396,7 @@ class VMutableArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT>
void set(const int64_t index, ElemT value) override
{
+ BLI_assert(SetFunc != nullptr);
SetFunc(data_[index], std::move(value));
}
@@ -840,7 +755,10 @@ template<typename T> class VArray : public VArrayCommon<T> {
*/
static VArray ForSpan(Span<T> values)
{
- return VArray::For<VArrayImpl_For_Span_final<T>>(values);
+ /* Cast const away, because the virtual array implementation for const and non const spans is
+ * shared. */
+ MutableSpan<T> span{const_cast<T *>(values.data()), values.size()};
+ return VArray::For<VArrayImpl_For_Span_final<T>>(span);
}
/**
@@ -859,7 +777,10 @@ template<typename T> class VArray : public VArrayCommon<T> {
template<typename StructT, T (*GetFunc)(const StructT &)>
static VArray ForDerivedSpan(Span<StructT> values)
{
- return VArray::For<VArrayImpl_For_DerivedSpan<StructT, T, GetFunc>>(values);
+ /* Cast const away, because the virtual array implementation for const and non const derived
+ * spans is shared. */
+ MutableSpan<StructT> span{const_cast<StructT *>(values.data()), values.size()};
+ return VArray::For<VArrayImpl_For_DerivedSpan<StructT, T, GetFunc>>(span);
}
/**
@@ -919,7 +840,7 @@ template<typename T> class VMutableArray : public VArrayCommon<T> {
*/
static VMutableArray ForSpan(MutableSpan<T> values)
{
- return VMutableArray::For<VMutableArrayImpl_For_MutableSpan_final<T>>(values);
+ return VMutableArray::For<VArrayImpl_For_Span_final<T>>(values);
}
/**
@@ -929,8 +850,7 @@ template<typename T> class VMutableArray : public VArrayCommon<T> {
template<typename StructT, T (*GetFunc)(const StructT &), void (*SetFunc)(StructT &, T)>
static VMutableArray ForDerivedSpan(MutableSpan<StructT> values)
{
- return VMutableArray::For<VMutableArrayImpl_For_DerivedSpan<StructT, T, GetFunc, SetFunc>>(
- values);
+ return VMutableArray::For<VArrayImpl_For_DerivedSpan<StructT, T, GetFunc, SetFunc>>(values);
}
/** Convert to a #VArray by copying. */