diff options
author | Siddhartha Jejurkar <f20180617@goa.bits-pilani.ac.in> | 2021-11-19 21:34:44 +0300 |
---|---|---|
committer | Siddhartha Jejurkar <f20180617@goa.bits-pilani.ac.in> | 2021-11-19 21:34:44 +0300 |
commit | 99a2af76d10e05a18987be5d554ada197b1ca086 (patch) | |
tree | 9f9ceccccbd117c05a701b6769eb69055be6a28e /source/blender/functions/intern/generic_virtual_array.cc | |
parent | 139606bd370f96e0a8685547d515a2335591d5de (diff) | |
parent | 50ad0e15fe0adde7335c89c6fcfa0948c341a08a (diff) |
Merge branch 'master' into soc-2021-uv-edge-select-support
Diffstat (limited to 'source/blender/functions/intern/generic_virtual_array.cc')
-rw-r--r-- | source/blender/functions/intern/generic_virtual_array.cc | 642 |
1 files changed, 461 insertions, 181 deletions
diff --git a/source/blender/functions/intern/generic_virtual_array.cc b/source/blender/functions/intern/generic_virtual_array.cc index ea54f1e7c00..1fe1c2fc229 100644 --- a/source/blender/functions/intern/generic_virtual_array.cc +++ b/source/blender/functions/intern/generic_virtual_array.cc @@ -19,52 +19,10 @@ namespace blender::fn { /* -------------------------------------------------------------------- */ -/** \name #GVArray_For_ShallowCopy +/** \name #GVArrayImpl * \{ */ -class GVArray_For_ShallowCopy : public GVArray { - private: - const GVArray &varray_; - - public: - GVArray_For_ShallowCopy(const GVArray &varray) - : GVArray(varray.type(), varray.size()), varray_(varray) - { - } - - private: - void get_impl(const int64_t index, void *r_value) const override - { - varray_.get(index, r_value); - } - - void get_to_uninitialized_impl(const int64_t index, void *r_value) const override - { - varray_.get_to_uninitialized(index, r_value); - } - - void materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const override - { - varray_.materialize_to_uninitialized(mask, dst); - } -}; -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name #GVArray - * \{ */ - -void GVArray::materialize(void *dst) const -{ - this->materialize(IndexMask(size_), dst); -} - -void GVArray::materialize(const IndexMask mask, void *dst) const -{ - this->materialize_impl(mask, dst); -} - -void GVArray::materialize_impl(const IndexMask mask, void *dst) const +void GVArrayImpl::materialize(const IndexMask mask, void *dst) const { for (const int64_t i : mask) { void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); @@ -72,18 +30,7 @@ void GVArray::materialize_impl(const IndexMask mask, void *dst) const } } -void GVArray::materialize_to_uninitialized(void *dst) const -{ - this->materialize_to_uninitialized(IndexMask(size_), dst); -} - -void GVArray::materialize_to_uninitialized(const IndexMask mask, void *dst) const -{ - BLI_assert(mask.min_array_size() <= size_); - this->materialize_to_uninitialized_impl(mask, dst); -} - -void GVArray::materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const +void GVArrayImpl::materialize_to_uninitialized(const IndexMask mask, void *dst) const { for (const int64_t i : mask) { void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); @@ -91,83 +38,75 @@ void GVArray::materialize_to_uninitialized_impl(const IndexMask mask, void *dst) } } -void GVArray::get_impl(const int64_t index, void *r_value) const +void GVArrayImpl::get(const int64_t index, void *r_value) const { type_->destruct(r_value); - this->get_to_uninitialized_impl(index, r_value); + this->get_to_uninitialized(index, r_value); } -bool GVArray::is_span_impl() const +bool GVArrayImpl::is_span() const { return false; } -GSpan GVArray::get_internal_span_impl() const +GSpan GVArrayImpl::get_internal_span() const { BLI_assert(false); return GSpan(*type_); } -bool GVArray::is_single_impl() const +bool GVArrayImpl::is_single() const { return false; } -void GVArray::get_internal_single_impl(void *UNUSED(r_value)) const +void GVArrayImpl::get_internal_single(void *UNUSED(r_value)) const { BLI_assert(false); } -const void *GVArray::try_get_internal_varray_impl() const +bool GVArrayImpl::try_assign_VArray(void *UNUSED(varray)) const { - return nullptr; + return false; } -/** - * Creates a new `std::unique_ptr<GVArray>` based on this `GVArray`. - * The lifetime of the returned virtual array must not be longer than the lifetime of this virtual - * array. - */ -GVArrayPtr GVArray::shallow_copy() const +bool GVArrayImpl::may_have_ownership() const { - if (this->is_span()) { - return std::make_unique<GVArray_For_GSpan>(this->get_internal_span()); - } - if (this->is_single()) { - BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer); - this->get_internal_single(buffer); - std::unique_ptr new_varray = std::make_unique<GVArray_For_SingleValue>(*type_, size_, buffer); - type_->destruct(buffer); - return new_varray; - } - return std::make_unique<GVArray_For_ShallowCopy>(*this); + /* Use true as default to avoid accidentally creating subclasses that have this set to false but + * actually own data. Subclasses should set the to false instead. */ + return true; } /** \} */ /* -------------------------------------------------------------------- */ -/** \name #GVMutableArray +/** \name #GVMutableArrayImpl * \{ */ -void GVMutableArray::set_by_copy_impl(const int64_t index, const void *value) +GVMutableArrayImpl::GVMutableArrayImpl(const CPPType &type, const int64_t size) + : GVArrayImpl(type, size) +{ +} + +void GVMutableArrayImpl::set_by_copy(const int64_t index, const void *value) { BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer); type_->copy_construct(value, buffer); - this->set_by_move_impl(index, buffer); + this->set_by_move(index, buffer); type_->destruct(buffer); } -void GVMutableArray::set_by_relocate_impl(const int64_t index, void *value) +void GVMutableArrayImpl::set_by_relocate(const int64_t index, void *value) { - this->set_by_move_impl(index, value); + this->set_by_move(index, value); type_->destruct(value); } -void GVMutableArray::set_all_impl(const void *src) +void GVMutableArrayImpl::set_all(const void *src) { if (this->is_span()) { - const GMutableSpan span = this->get_internal_span(); - type_->copy_assign_n(src, span.data(), size_); + const GSpan span = this->get_internal_span(); + type_->copy_assign_n(src, const_cast<void *>(span.data()), size_); } else { for (int64_t i : IndexRange(size_)) { @@ -176,149 +115,224 @@ void GVMutableArray::set_all_impl(const void *src) } } -void *GVMutableArray::try_get_internal_mutable_varray_impl() -{ - return nullptr; -} - void GVMutableArray::fill(const void *value) { if (this->is_span()) { - const GMutableSpan span = this->get_internal_span(); - type_->fill_assign_n(value, span.data(), size_); + const GSpan span = this->get_internal_span(); + this->type().fill_assign_n(value, const_cast<void *>(span.data()), this->size()); } else { - for (int64_t i : IndexRange(size_)) { + for (int64_t i : IndexRange(this->size())) { this->set_by_copy(i, value); } } } +bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const +{ + return false; +} + /** \} */ /* -------------------------------------------------------------------- */ -/** \name #GVArray_For_GSpan +/** \name #GVArrayImpl_For_GSpan * \{ */ -void GVArray_For_GSpan::get_impl(const int64_t index, void *r_value) const +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 CPPType &type, const int64_t size) + : GVArrayImpl(type, size), element_size_(type.size()) +{ +} + +void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const { type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value); } -void GVArray_For_GSpan::get_to_uninitialized_impl(const int64_t index, void *r_value) const +void GVArrayImpl_For_GSpan::get_to_uninitialized(const int64_t index, void *r_value) const { type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value); } -bool GVArray_For_GSpan::is_span_impl() const +bool GVArrayImpl_For_GSpan::is_span() const { return true; } -GSpan GVArray_For_GSpan::get_internal_span_impl() const +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; + + private: + bool may_have_ownership() const override + { + return false; + } +}; + /** \} */ /* -------------------------------------------------------------------- */ -/** \name #GVMutableArray_For_GMutableSpan +/** \name #GVMutableArrayImpl_For_GMutableSpan * \{ */ -void GVMutableArray_For_GMutableSpan::get_impl(const int64_t index, void *r_value) const +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 GVMutableArray_For_GMutableSpan::get_to_uninitialized_impl(const int64_t index, - void *r_value) const +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 GVMutableArray_For_GMutableSpan::set_by_copy_impl(const int64_t index, const void *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 GVMutableArray_For_GMutableSpan::set_by_move_impl(const int64_t index, void *value) +void GVMutableArrayImpl_For_GMutableSpan::set_by_move(const int64_t index, void *value) { type_->move_construct(value, POINTER_OFFSET(data_, element_size_ * index)); } -void GVMutableArray_For_GMutableSpan::set_by_relocate_impl(const int64_t index, void *value) +void GVMutableArrayImpl_For_GMutableSpan::set_by_relocate(const int64_t index, void *value) { type_->relocate_assign(value, POINTER_OFFSET(data_, element_size_ * index)); } -bool GVMutableArray_For_GMutableSpan::is_span_impl() const +bool GVMutableArrayImpl_For_GMutableSpan::is_span() const { return true; } -GSpan GVMutableArray_For_GMutableSpan::get_internal_span_impl() const +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 #GVArray_For_SingleValueRef +/** \name #GVArrayImpl_For_SingleValueRef * \{ */ -void GVArray_For_SingleValueRef::get_impl(const int64_t UNUSED(index), void *r_value) const -{ - type_->copy_assign(value_, r_value); -} +/* Generic virtual array where each element has the same value. The value is not owned. */ +class GVArrayImpl_For_SingleValueRef : public GVArrayImpl { + protected: + const void *value_ = nullptr; -void GVArray_For_SingleValueRef::get_to_uninitialized_impl(const int64_t UNUSED(index), - void *r_value) const -{ - type_->copy_construct(value_, r_value); -} + public: + GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size, const void *value) + : GVArrayImpl(type, size), value_(value) + { + } -bool GVArray_For_SingleValueRef::is_span_impl() const -{ - return size_ == 1; -} + protected: + GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size) : GVArrayImpl(type, size) + { + } -GSpan GVArray_For_SingleValueRef::get_internal_span_impl() const -{ - return GSpan{*type_, value_, 1}; -} + void get(const int64_t UNUSED(index), void *r_value) const override + { + type_->copy_assign(value_, r_value); + } + void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override + { + type_->copy_construct(value_, r_value); + } -bool GVArray_For_SingleValueRef::is_single_impl() const -{ - return true; -} + bool is_span() const override + { + return size_ == 1; + } + GSpan get_internal_span() const override + { + return GSpan{*type_, value_, 1}; + } -void GVArray_For_SingleValueRef::get_internal_single_impl(void *r_value) const -{ - type_->copy_assign(value_, r_value); -} + bool is_single() const override + { + return true; + } + void get_internal_single(void *r_value) const override + { + type_->copy_assign(value_, r_value); + } +}; + +class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef { + public: + using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef; + + private: + bool may_have_ownership() const override + { + return false; + } +}; /** \} */ /* -------------------------------------------------------------------- */ -/** \name #GVArray_For_SingleValue +/** \name #GVArrayImpl_For_SingleValue * \{ */ -GVArray_For_SingleValue::GVArray_For_SingleValue(const CPPType &type, - const int64_t size, - const void *value) - : GVArray_For_SingleValueRef(type, size) -{ - value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__); - type.copy_construct(value, (void *)value_); -} +/* Same as GVArrayImpl_For_SingleValueRef, but the value is owned. */ +class GVArrayImpl_For_SingleValue : public GVArrayImpl_For_SingleValueRef, + NonCopyable, + NonMovable { + public: + GVArrayImpl_For_SingleValue(const CPPType &type, const int64_t size, const void *value) + : GVArrayImpl_For_SingleValueRef(type, size) + { + value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__); + type.copy_construct(value, (void *)value_); + } -GVArray_For_SingleValue::~GVArray_For_SingleValue() -{ - type_->destruct((void *)value_); - MEM_freeN((void *)value_); -} + ~GVArrayImpl_For_SingleValue() override + { + type_->destruct((void *)value_); + MEM_freeN((void *)value_); + } +}; /** \} */ @@ -326,7 +340,7 @@ GVArray_For_SingleValue::~GVArray_For_SingleValue() /** \name #GVArray_GSpan * \{ */ -GVArray_GSpan::GVArray_GSpan(const GVArray &varray) : GSpan(varray.type()), varray_(varray) +GVArray_GSpan::GVArray_GSpan(GVArray varray) : GSpan(varray.type()), varray_(std::move(varray)) { size_ = varray_.size(); if (varray_.is_span()) { @@ -353,8 +367,8 @@ GVArray_GSpan::~GVArray_GSpan() /** \name #GVMutableArray_GSpan * \{ */ -GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray &varray, const bool copy_values_to_span) - : GMutableSpan(varray.type()), varray_(varray) +GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray varray, const bool copy_values_to_span) + : GMutableSpan(varray.type()), varray_(std::move(varray)) { size_ = varray_.size(); if (varray_.is_span()) { @@ -405,48 +419,314 @@ void GVMutableArray_GSpan::disable_not_applied_warning() /** \} */ /* -------------------------------------------------------------------- */ -/** \name #GVArray_For_SlicedGVArray +/** \name #GVArrayImpl_For_SlicedGVArray * \{ */ -void GVArray_For_SlicedGVArray::get_impl(const int64_t index, void *r_value) const +class GVArrayImpl_For_SlicedGVArray : public GVArrayImpl { + protected: + GVArray varray_; + int64_t offset_; + + public: + GVArrayImpl_For_SlicedGVArray(GVArray varray, const IndexRange slice) + : GVArrayImpl(varray.type(), slice.size()), + varray_(std::move(varray)), + offset_(slice.start()) + { + BLI_assert(slice.one_after_last() <= varray_.size()); + } + + void get(const int64_t index, void *r_value) const override + { + varray_.get(index + offset_, r_value); + } + + void get_to_uninitialized(const int64_t index, void *r_value) const override + { + varray_.get_to_uninitialized(index + offset_, r_value); + } +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #GVArrayCommon + * \{ */ + +GVArrayCommon::GVArrayCommon() = default; + +GVArrayCommon::GVArrayCommon(const GVArrayCommon &other) : storage_(other.storage_) +{ + impl_ = this->impl_from_storage(); +} + +GVArrayCommon::GVArrayCommon(GVArrayCommon &&other) noexcept : storage_(std::move(other.storage_)) +{ + impl_ = this->impl_from_storage(); + other.storage_.reset(); + other.impl_ = nullptr; +} + +GVArrayCommon::GVArrayCommon(const GVArrayImpl *impl) : impl_(impl) +{ + storage_ = impl_; +} + +GVArrayCommon::GVArrayCommon(std::shared_ptr<const GVArrayImpl> impl) : impl_(impl.get()) +{ + if (impl) { + storage_ = std::move(impl); + } +} + +GVArrayCommon::~GVArrayCommon() = default; + +void GVArrayCommon::materialize(void *dst) const +{ + this->materialize(IndexMask(impl_->size()), dst); +} + +void GVArrayCommon::materialize(const IndexMask mask, void *dst) const +{ + impl_->materialize(mask, dst); +} + +void GVArrayCommon::materialize_to_uninitialized(void *dst) const +{ + this->materialize_to_uninitialized(IndexMask(impl_->size()), dst); +} + +void GVArrayCommon::materialize_to_uninitialized(const IndexMask mask, void *dst) const +{ + BLI_assert(mask.min_array_size() <= impl_->size()); + impl_->materialize_to_uninitialized(mask, dst); +} + +bool GVArrayCommon::may_have_ownership() const +{ + return impl_->may_have_ownership(); +} + +void GVArrayCommon::copy_from(const GVArrayCommon &other) +{ + if (this == &other) { + return; + } + storage_ = other.storage_; + impl_ = this->impl_from_storage(); +} + +void GVArrayCommon::move_from(GVArrayCommon &&other) noexcept +{ + if (this == &other) { + return; + } + storage_ = std::move(other.storage_); + impl_ = this->impl_from_storage(); + other.storage_.reset(); + other.impl_ = nullptr; +} + +/* Returns true when the virtual array is stored as a span internally. */ +bool GVArrayCommon::is_span() const +{ + if (this->is_empty()) { + return true; + } + return impl_->is_span(); +} + +/* Returns the internally used span of the virtual array. This invokes undefined behavior is the + * virtual array is not stored as a span internally. */ +GSpan GVArrayCommon::get_internal_span() const { - varray_.get(index + offset_, r_value); + BLI_assert(this->is_span()); + if (this->is_empty()) { + return GSpan(impl_->type()); + } + return impl_->get_internal_span(); } -void GVArray_For_SlicedGVArray::get_to_uninitialized_impl(const int64_t index, void *r_value) const +/* Returns true when the virtual array returns the same value for every index. */ +bool GVArrayCommon::is_single() const { - varray_.get_to_uninitialized(index + offset_, r_value); + if (impl_->size() == 1) { + return true; + } + return impl_->is_single(); +} + +/* Copies the value that is used for every element into `r_value`, which is expected to point to + * initialized memory. This invokes undefined behavior if the virtual array would not return the + * same value for every index. */ +void GVArrayCommon::get_internal_single(void *r_value) const +{ + BLI_assert(this->is_single()); + if (impl_->size() == 1) { + impl_->get(0, r_value); + return; + } + impl_->get_internal_single(r_value); +} + +/* Same as `get_internal_single`, but `r_value` points to initialized memory. */ +void GVArrayCommon::get_internal_single_to_uninitialized(void *r_value) const +{ + impl_->type().default_construct(r_value); + this->get_internal_single(r_value); +} + +const GVArrayImpl *GVArrayCommon::impl_from_storage() const +{ + return storage_.extra_info().get_varray(storage_.get()); +} + +IndexRange GVArrayCommon::index_range() const +{ + return IndexRange(this->size()); } /** \} */ /* -------------------------------------------------------------------- */ -/** \name #GVArray_Slice +/** \name #GVArray * \{ */ -GVArray_Slice::GVArray_Slice(const GVArray &varray, const IndexRange slice) +GVArray::GVArray(const GVArray &other) = default; + +GVArray::GVArray(GVArray &&other) noexcept = default; + +GVArray::GVArray(const GVArrayImpl *impl) : GVArrayCommon(impl) { - if (varray.is_span()) { - /* Create a new virtual for the sliced span. */ - const GSpan span = varray.get_internal_span(); - const GSpan sliced_span = span.slice(slice.start(), slice.size()); - varray_span_.emplace(sliced_span); - varray_ = &*varray_span_; - } - else if (varray.is_single()) { - /* Can just use the existing virtual array, because it's the same value for the indices in the - * slice anyway. */ - varray_ = &varray; - } - else { - /* Generic version when none of the above method works. - * We don't necessarily want to materialize the input varray because there might be - * large distances between the required indices. Then we would materialize many elements that - * are not accessed later on. - */ - varray_any_.emplace(varray, slice); - varray_ = &*varray_any_; +} + +GVArray::GVArray(std::shared_ptr<const GVArrayImpl> impl) : GVArrayCommon(std::move(impl)) +{ +} + +GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value) +{ + return GVArray::For<GVArrayImpl_For_SingleValue>(type, size, value); +} + +GVArray GVArray::ForSingleRef(const CPPType &type, const int64_t size, const void *value) +{ + return GVArray::For<GVArrayImpl_For_SingleValueRef_final>(type, size, value); +} + +GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size) +{ + return GVArray::ForSingleRef(type, size, type.default_value()); +} + +GVArray GVArray::ForSpan(GSpan span) +{ + return GVArray::For<GVArrayImpl_For_GSpan_final>(span); +} + +class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan { + protected: + GArray<> array_; + + public: + GVArrayImpl_For_GArray(GArray<> array) + : GVArrayImpl_For_GSpan(array.as_span()), array_(std::move(array)) + { } +}; + +GVArray GVArray::ForGArray(GArray<> array) +{ + return GVArray::For<GVArrayImpl_For_GArray>(array); +} + +GVArray GVArray::ForEmpty(const CPPType &type) +{ + return GVArray::ForSpan(GSpan(type)); +} + +GVArray GVArray::slice(IndexRange slice) const +{ + return GVArray::For<GVArrayImpl_For_SlicedGVArray>(*this, slice); +} + +GVArray &GVArray::operator=(const GVArray &other) +{ + this->copy_from(other); + return *this; +} + +GVArray &GVArray::operator=(GVArray &&other) noexcept +{ + this->move_from(std::move(other)); + return *this; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #GVMutableArray + * \{ */ + +GVMutableArray::GVMutableArray(const GVMutableArray &other) = default; +GVMutableArray::GVMutableArray(GVMutableArray &&other) noexcept = default; + +GVMutableArray::GVMutableArray(GVMutableArrayImpl *impl) : GVArrayCommon(impl) +{ +} + +GVMutableArray::GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl) + : GVArrayCommon(std::move(impl)) +{ +} + +GVMutableArray GVMutableArray::ForSpan(GMutableSpan span) +{ + return GVMutableArray::For<GVMutableArrayImpl_For_GMutableSpan_final>(span); +} + +GVMutableArray::operator GVArray() const & +{ + GVArray varray; + varray.copy_from(*this); + return varray; +} + +GVMutableArray::operator GVArray() &&noexcept +{ + GVArray varray; + varray.move_from(std::move(*this)); + return varray; +} + +GVMutableArray &GVMutableArray::operator=(const GVMutableArray &other) +{ + this->copy_from(other); + return *this; +} + +GVMutableArray &GVMutableArray::operator=(GVMutableArray &&other) noexcept +{ + this->move_from(std::move(other)); + return *this; +} + +GVMutableArrayImpl *GVMutableArray::get_implementation() const +{ + return this->get_impl(); +} + +/* Copy the values from the source buffer to all elements in the virtual array. */ +void GVMutableArray::set_all(const void *src) +{ + this->get_impl()->set_all(src); +} + +GMutableSpan GVMutableArray::get_internal_span() const +{ + BLI_assert(this->is_span()); + const GSpan span = impl_->get_internal_span(); + return GMutableSpan(span.type(), const_cast<void *>(span.data()), span.size()); } /** \} */ |