diff options
author | Julian Eisel <julian@blender.org> | 2022-07-20 18:25:31 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2022-07-20 18:25:31 +0300 |
commit | 9dbcefb10e53cc809eb2e99333376b2a881c0863 (patch) | |
tree | 9ea058c2877c472aba82650e24e5927e3f03eded /source/blender/blenlib/BLI_generic_virtual_array.hh | |
parent | e1ced645fa208b3b77e07c99cb289cf7fa659ad3 (diff) | |
parent | 85f0b2ef5d5bfb67c245da0a52aeec44e63445fa (diff) |
Merge branch 'asset-browser-grid-view' into file-browser-grid-view
Diffstat (limited to 'source/blender/blenlib/BLI_generic_virtual_array.hh')
-rw-r--r-- | source/blender/blenlib/BLI_generic_virtual_array.hh | 308 |
1 files changed, 150 insertions, 158 deletions
diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index d02760d9178..43ca16a894f 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -42,11 +42,7 @@ class GVArrayImpl { virtual void get(int64_t index, void *r_value) const; virtual void get_to_uninitialized(int64_t index, void *r_value) const = 0; - virtual bool is_span() const; - virtual GSpan get_internal_span() const; - - virtual bool is_single() const; - virtual void get_internal_single(void *UNUSED(r_value)) const; + virtual CommonVArrayInfo common_info() const; virtual void materialize(const IndexMask mask, void *dst) const; virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const; @@ -55,13 +51,14 @@ class GVArrayImpl { virtual void materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const; virtual bool try_assign_VArray(void *varray) const; - virtual bool may_have_ownership() const; }; /* A generic version of #VMutableArrayImpl. */ class GVMutableArrayImpl : public GVArrayImpl { public: - GVMutableArrayImpl(const CPPType &type, int64_t size); + GVMutableArrayImpl(const CPPType &type, int64_t size) : GVArrayImpl(type, size) + { + } virtual void set_by_copy(int64_t index, const void *value); virtual void set_by_relocate(int64_t index, void *value); @@ -105,7 +102,7 @@ class GVArrayCommon { Storage storage_; protected: - GVArrayCommon(); + GVArrayCommon() = default; GVArrayCommon(const GVArrayCommon &other); GVArrayCommon(GVArrayCommon &&other) noexcept; GVArrayCommon(const GVArrayImpl *impl); @@ -139,6 +136,8 @@ class GVArrayCommon { void materialize_compressed(IndexMask mask, void *dst) const; void materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const; + CommonVArrayInfo common_info() const; + /** * Returns true when the virtual array is stored as a span internally. */ @@ -186,6 +185,10 @@ class GVArray : public GVArrayCommon { GVArray(const GVArrayImpl *impl); GVArray(std::shared_ptr<const GVArrayImpl> impl); + GVArray(varray_tag::span /* tag */, GSpan span); + GVArray(varray_tag::single_ref /* tag */, const CPPType &type, int64_t size, const void *value); + GVArray(varray_tag::single /* tag */, const CPPType &type, int64_t size, const void *value); + template<typename T> GVArray(const VArray<T> &varray); template<typename T> VArray<T> typed() const; @@ -254,22 +257,25 @@ class GVMutableArray : public GVArrayCommon { /** \} */ /* -------------------------------------------------------------------- */ -/** \name #GVArray_GSpan and #GVMutableArray_GSpan. +/** \name #GVArraySpan and #GMutableVArraySpan. * \{ */ -/* A generic version of VArray_Span. */ -class GVArray_GSpan : public GSpan { +/* A generic version of VArraySpan. */ +class GVArraySpan : public GSpan { private: GVArray varray_; void *owned_data_ = nullptr; public: - GVArray_GSpan(GVArray varray); - ~GVArray_GSpan(); + GVArraySpan(); + GVArraySpan(GVArray varray); + GVArraySpan(GVArraySpan &&other); + ~GVArraySpan(); + GVArraySpan &operator=(GVArraySpan &&other); }; -/* A generic version of VMutableArray_Span. */ -class GVMutableArray_GSpan : public GMutableSpan { +/* A generic version of MutableVArraySpan. */ +class GMutableVArraySpan : public GMutableSpan, NonCopyable, NonMovable { private: GVMutableArray varray_; void *owned_data_ = nullptr; @@ -277,8 +283,13 @@ class GVMutableArray_GSpan : public GMutableSpan { bool show_not_saved_warning_ = true; public: - GVMutableArray_GSpan(GVMutableArray varray, bool copy_values_to_span = true); - ~GVMutableArray_GSpan(); + GMutableVArraySpan(); + GMutableVArraySpan(GVMutableArray varray, bool copy_values_to_span = true); + GMutableVArraySpan(GMutableVArraySpan &&other); + ~GMutableVArraySpan(); + GMutableVArraySpan &operator=(GMutableVArraySpan &&other); + + const GVMutableArray &varray() const; void save(); void disable_not_applied_warning(); @@ -312,26 +323,6 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl { new (r_value) T(varray_[index]); } - bool is_span() const override - { - return varray_.is_span(); - } - - GSpan get_internal_span() const override - { - return GSpan(varray_.get_internal_span()); - } - - bool is_single() const override - { - return varray_.is_single(); - } - - void get_internal_single(void *r_value) const override - { - *(T *)r_value = varray_.get_internal_single(); - } - void materialize(const IndexMask mask, void *dst) const override { varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size())); @@ -358,9 +349,9 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl { return true; } - bool may_have_ownership() const override + CommonVArrayInfo common_info() const override { - return varray_.may_have_ownership(); + return varray_.common_info(); } }; @@ -384,26 +375,9 @@ template<typename T> class VArrayImpl_For_GVArray : public VArrayImpl<T> { return value; } - bool is_span() const override - { - return varray_.is_span(); - } - - Span<T> get_internal_span() const override - { - return varray_.get_internal_span().template typed<T>(); - } - - bool is_single() const override + CommonVArrayInfo common_info() const override { - return varray_.is_single(); - } - - T get_internal_single() const override - { - T value; - varray_.get_internal_single(&value); - return value; + return varray_.common_info(); } bool try_assign_GVArray(GVArray &varray) const override @@ -412,11 +386,6 @@ template<typename T> class VArrayImpl_For_GVArray : public VArrayImpl<T> { return true; } - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } - void materialize(IndexMask mask, MutableSpan<T> r_span) const override { varray_.materialize(mask, r_span.data()); @@ -461,25 +430,9 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab new (r_value) T(varray_[index]); } - bool is_span() const override - { - return varray_.is_span(); - } - - GSpan get_internal_span() const override + CommonVArrayInfo common_info() const override { - Span<T> span = varray_.get_internal_span(); - return span; - } - - bool is_single() const override - { - return varray_.is_single(); - } - - void get_internal_single(void *r_value) const override - { - *(T *)r_value = varray_.get_internal_single(); + return varray_.common_info(); } void set_by_copy(const int64_t index, const void *value) override @@ -537,11 +490,6 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab *(VMutableArray<T> *)varray = varray_; return true; } - - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } }; /* Used to convert an generic mutable virtual array into a typed one. */ @@ -570,26 +518,9 @@ template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutabl varray_.set_by_relocate(index, &value); } - bool is_span() const override - { - return varray_.is_span(); - } - - Span<T> get_internal_span() const override - { - return varray_.get_internal_span().template typed<T>(); - } - - bool is_single() const override + CommonVArrayInfo common_info() const override { - return varray_.is_single(); - } - - T get_internal_single() const override - { - T value; - varray_.get_internal_single(&value); - return value; + return varray_.common_info(); } bool try_assign_GVArray(GVArray &varray) const override @@ -604,11 +535,6 @@ template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutabl return true; } - bool may_have_ownership() const override - { - return varray_.may_have_ownership(); - } - void materialize(IndexMask mask, MutableSpan<T> r_span) const override { varray_.materialize(mask, r_span.data()); @@ -643,10 +569,18 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { const int64_t element_size_; public: - GVArrayImpl_For_GSpan(const GMutableSpan span); + GVArrayImpl_For_GSpan(const GMutableSpan span) + : GVMutableArrayImpl(span.type(), span.size()), + data_(span.data()), + element_size_(span.type().size()) + { + } protected: - GVArrayImpl_For_GSpan(const CPPType &type, int64_t size); + GVArrayImpl_For_GSpan(const CPPType &type, int64_t size) + : GVMutableArrayImpl(type, size), element_size_(type.size()) + { + } public: void get(int64_t index, void *r_value) const override; @@ -656,8 +590,7 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { void set_by_move(int64_t index, void *value) override; void set_by_relocate(int64_t index, void *value) override; - bool is_span() const override; - GSpan get_internal_span() const override; + CommonVArrayInfo common_info() const override; virtual void materialize(const IndexMask mask, void *dst) const override; virtual void materialize_to_uninitialized(const IndexMask mask, void *dst) const override; @@ -667,6 +600,57 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { void *dst) const override; }; +class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { + public: + using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan; + + private: + CommonVArrayInfo common_info() const override; +}; + +template<> inline constexpr bool is_trivial_extended_v<GVArrayImpl_For_GSpan_final> = true; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #GVArrayImpl_For_SingleValueRef. + * \{ */ + +class GVArrayImpl_For_SingleValueRef : public GVArrayImpl { + protected: + const void *value_ = nullptr; + + public: + GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size, const void *value) + : GVArrayImpl(type, size), value_(value) + { + } + + protected: + GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size) : GVArrayImpl(type, 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; + CommonVArrayInfo common_info() const override; + void materialize(const IndexMask mask, void *dst) const override; + void materialize_to_uninitialized(const IndexMask mask, void *dst) const override; + void materialize_compressed(const IndexMask mask, void *dst) const override; + void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override; +}; + +class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef { + public: + using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef; + + private: + CommonVArrayInfo common_info() const override; +}; + +template<> +inline constexpr bool is_trivial_extended_v<GVArrayImpl_For_SingleValueRef_final> = true; + /** \} */ /* -------------------------------------------------------------------- */ @@ -790,6 +774,11 @@ inline GVArrayCommon::operator bool() const return impl_ != nullptr; } +inline CommonVArrayInfo GVArrayCommon::common_info() const +{ + return impl_->common_info(); +} + inline int64_t GVArrayCommon::size() const { if (impl_ == nullptr) { @@ -809,6 +798,22 @@ inline bool GVArrayCommon::is_empty() const /** \name Inline methods for #GVArray. * \{ */ +inline GVArray::GVArray(varray_tag::span /* tag */, const GSpan 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()}; + this->emplace<GVArrayImpl_For_GSpan_final>(mutable_span); +} + +inline GVArray::GVArray(varray_tag::single_ref /* tag */, + const CPPType &type, + const int64_t size, + const void *value) +{ + this->emplace<GVArrayImpl_For_SingleValueRef_final>(type, size, value); +} + namespace detail { template<typename StorageT> constexpr GVArrayAnyExtraInfo GVArrayAnyExtraInfo::get() { @@ -846,25 +851,20 @@ template<typename T> inline GVArray::GVArray(const VArray<T> &varray) if (!varray) { return; } - if (varray.try_assign_GVArray(*this)) { + const CommonVArrayInfo info = varray.common_info(); + if (info.type == CommonVArrayInfo::Type::Single) { + *this = GVArray::ForSingle(CPPType::get<T>(), varray.size(), info.data); return; } - /* Need to check this before the span/single special cases, because otherwise we might loose - * ownership to the referenced data when #varray goes out of scope. */ - if (varray.may_have_ownership()) { - *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); - } - else if (varray.is_single()) { - T value = varray.get_internal_single(); - *this = GVArray::ForSingle(CPPType::get<T>(), varray.size(), &value); - } - else if (varray.is_span()) { - Span<T> data = varray.get_internal_span(); - *this = GVArray::ForSpan(data); + /* Need to check for ownership, because otherwise the referenced data can be destructed when + * #this is destructed. */ + if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) { + *this = GVArray::ForSpan(GSpan(CPPType::get<T>(), info.data, varray.size())); } - else { - *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); + if (varray.try_assign_GVArray(*this)) { + return; } + *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); } template<typename T> inline VArray<T> GVArray::typed() const @@ -873,22 +873,19 @@ template<typename T> inline VArray<T> GVArray::typed() const return {}; } BLI_assert(impl_->type().is<T>()); + const CommonVArrayInfo info = this->common_info(); + if (info.type == CommonVArrayInfo::Type::Single) { + return VArray<T>::ForSingle(*static_cast<const T *>(info.data), this->size()); + } + /* Need to check for ownership, because otherwise the referenced data can be destructed when + * #this is destructed. */ + if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) { + return VArray<T>::ForSpan(Span<T>(static_cast<const T *>(info.data), this->size())); + } VArray<T> varray; if (this->try_assign_VArray(varray)) { return varray; } - if (this->may_have_ownership()) { - return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this); - } - if (this->is_single()) { - T value; - this->get_internal_single(&value); - return VArray<T>::ForSingle(value, this->size()); - } - if (this->is_span()) { - const Span<T> span = this->get_internal_span().typed<T>(); - return VArray<T>::ForSpan(span); - } return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this); } @@ -912,19 +909,16 @@ template<typename T> inline GVMutableArray::GVMutableArray(const VMutableArray<T if (!varray) { return; } - if (varray.try_assign_GVMutableArray(*this)) { + const CommonVArrayInfo info = varray.common_info(); + if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) { + *this = GVMutableArray::ForSpan( + GMutableSpan(CPPType::get<T>(), const_cast<void *>(info.data), varray.size())); return; } - if (varray.may_have_ownership()) { - *this = GVMutableArray::For<GVMutableArrayImpl_For_VMutableArray<T>>(varray); - } - else if (varray.is_span()) { - MutableSpan<T> data = varray.get_internal_span(); - *this = GVMutableArray::ForSpan(data); - } - else { - *this = GVMutableArray::For<GVMutableArrayImpl_For_VMutableArray<T>>(varray); + if (varray.try_assign_GVMutableArray(*this)) { + return; } + *this = GVMutableArray::For<GVMutableArrayImpl_For_VMutableArray<T>>(varray); } template<typename T> inline VMutableArray<T> GVMutableArray::typed() const @@ -933,17 +927,15 @@ template<typename T> inline VMutableArray<T> GVMutableArray::typed() const return {}; } BLI_assert(this->type().is<T>()); + const CommonVArrayInfo info = this->common_info(); + if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) { + return VMutableArray<T>::ForSpan( + MutableSpan<T>(const_cast<T *>(static_cast<const T *>(info.data)), this->size())); + } VMutableArray<T> varray; if (this->try_assign_VMutableArray(varray)) { return varray; } - if (this->may_have_ownership()) { - return VMutableArray<T>::template For<VMutableArrayImpl_For_GVMutableArray<T>>(*this); - } - if (this->is_span()) { - const MutableSpan<T> span = this->get_internal_span().typed<T>(); - return VMutableArray<T>::ForSpan(span); - } return VMutableArray<T>::template For<VMutableArrayImpl_For_GVMutableArray<T>>(*this); } |