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).
This commit is contained in:
2021-11-26 14:47:02 +01:00
parent ef88047a97
commit f86331a033
6 changed files with 139 additions and 387 deletions

View File

@@ -555,37 +555,19 @@ template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutabl
/** \} */
/* -------------------------------------------------------------------- */
/** \name #GVArrayImpl_For_GSpan and #GVMutableArrayImpl_For_GMutableSpan.
/** \name #GVArrayImpl_For_GSpan.
* \{ */
class GVArrayImpl_For_GSpan : public GVArrayImpl {
protected:
const void *data_ = nullptr;
const int64_t element_size_;
public:
GVArrayImpl_For_GSpan(const GSpan span);
protected:
GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size);
void get(const int64_t index, void *r_value) const override;
void get_to_uninitialized(const int64_t index, void *r_value) const override;
bool is_span() const override;
GSpan get_internal_span() const override;
};
class GVMutableArrayImpl_For_GMutableSpan : public GVMutableArrayImpl {
class GVArrayImpl_For_GSpan : public GVMutableArrayImpl {
protected:
void *data_ = nullptr;
const int64_t element_size_;
public:
GVMutableArrayImpl_For_GMutableSpan(const GMutableSpan span);
GVArrayImpl_For_GSpan(const GMutableSpan span);
protected:
GVMutableArrayImpl_For_GMutableSpan(const CPPType &type, const int64_t size);
GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size);
public:
void get(const int64_t index, void *r_value) const override;

View File

@@ -139,13 +139,15 @@ bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const
/** \name #GVArrayImpl_For_GSpan
* \{ */
GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const GSpan span)
: GVArrayImpl(span.type(), span.size()), data_(span.data()), element_size_(span.type().size())
GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const GMutableSpan span)
: GVMutableArrayImpl(span.type(), span.size()),
data_(span.data()),
element_size_(span.type().size())
{
}
GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size)
: GVArrayImpl(type, size), element_size_(type.size())
: GVMutableArrayImpl(type, size), element_size_(type.size())
{
}
@@ -159,6 +161,21 @@ void GVArrayImpl_For_GSpan::get_to_uninitialized(const int64_t index, void *r_va
type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value);
}
void GVArrayImpl_For_GSpan::set_by_copy(const int64_t index, const void *value)
{
type_->copy_assign(value, POINTER_OFFSET(data_, element_size_ * index));
}
void GVArrayImpl_For_GSpan::set_by_move(const int64_t index, void *value)
{
type_->move_construct(value, POINTER_OFFSET(data_, element_size_ * index));
}
void GVArrayImpl_For_GSpan::set_by_relocate(const int64_t index, void *value)
{
type_->relocate_assign(value, POINTER_OFFSET(data_, element_size_ * index));
}
bool GVArrayImpl_For_GSpan::is_span() const
{
return true;
@@ -169,7 +186,6 @@ GSpan GVArrayImpl_For_GSpan::get_internal_span() const
return GSpan(*type_, data_, size_);
}
/** See #VArrayImpl_For_Span_final. */
class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan {
public:
using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan;
@@ -183,73 +199,6 @@ class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan {
/** \} */
/* -------------------------------------------------------------------- */
/** \name #GVMutableArrayImpl_For_GMutableSpan
* \{ */
GVMutableArrayImpl_For_GMutableSpan::GVMutableArrayImpl_For_GMutableSpan(const GMutableSpan span)
: GVMutableArrayImpl(span.type(), span.size()),
data_(span.data()),
element_size_(span.type().size())
{
}
GVMutableArrayImpl_For_GMutableSpan::GVMutableArrayImpl_For_GMutableSpan(const CPPType &type,
const int64_t size)
: GVMutableArrayImpl(type, size), element_size_(type.size())
{
}
void GVMutableArrayImpl_For_GMutableSpan::get(const int64_t index, void *r_value) const
{
type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
}
void GVMutableArrayImpl_For_GMutableSpan::get_to_uninitialized(const int64_t index,
void *r_value) const
{
type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value);
}
void GVMutableArrayImpl_For_GMutableSpan::set_by_copy(const int64_t index, const void *value)
{
type_->copy_assign(value, POINTER_OFFSET(data_, element_size_ * index));
}
void GVMutableArrayImpl_For_GMutableSpan::set_by_move(const int64_t index, void *value)
{
type_->move_construct(value, POINTER_OFFSET(data_, element_size_ * index));
}
void GVMutableArrayImpl_For_GMutableSpan::set_by_relocate(const int64_t index, void *value)
{
type_->relocate_assign(value, POINTER_OFFSET(data_, element_size_ * index));
}
bool GVMutableArrayImpl_For_GMutableSpan::is_span() const
{
return true;
}
GSpan GVMutableArrayImpl_For_GMutableSpan::get_internal_span() const
{
return GSpan(*type_, data_, size_);
}
class GVMutableArrayImpl_For_GMutableSpan_final final
: public GVMutableArrayImpl_For_GMutableSpan {
public:
using GVMutableArrayImpl_For_GMutableSpan::GVMutableArrayImpl_For_GMutableSpan;
private:
bool may_have_ownership() const override
{
return false;
}
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name #GVArrayImpl_For_SingleValueRef
* \{ */
@@ -682,7 +631,10 @@ GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size)
GVArray GVArray::ForSpan(GSpan span)
{
return GVArray::For<GVArrayImpl_For_GSpan_final>(span);
/* Use const-cast because the underlying virtual array implementation is shared between const
* and non const data. */
GMutableSpan mutable_span{span.type(), const_cast<void *>(span.data()), span.size()};
return GVArray::For<GVArrayImpl_For_GSpan_final>(mutable_span);
}
class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan {
@@ -691,7 +643,7 @@ class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan {
public:
GVArrayImpl_For_GArray(GArray<> array)
: GVArrayImpl_For_GSpan(array.as_span()), array_(std::move(array))
: GVArrayImpl_For_GSpan(array.as_mutable_span()), array_(std::move(array))
{
}
};
@@ -743,7 +695,7 @@ GVMutableArray::GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl)
GVMutableArray GVMutableArray::ForSpan(GMutableSpan span)
{
return GVMutableArray::For<GVMutableArrayImpl_For_GMutableSpan_final>(span);
return GVMutableArray::For<GVArrayImpl_For_GSpan_final>(span);
}
GVMutableArray::operator GVArray() const &