diff options
author | Jacques Lucke <jacques@blender.org> | 2021-10-30 20:31:19 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-10-30 20:31:19 +0300 |
commit | 3d0abb3be9f685584759209eda0070a214f2a716 (patch) | |
tree | 7ac4eec3a3f7edb59665c1b0ef3adc984b3640a0 /source | |
parent | 9b6c13e66c20af705812ad4bcdd107743d03fae5 (diff) |
progress
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/functions/FN_generic_virtual_array.hh | 205 | ||||
-rw-r--r-- | source/blender/functions/intern/generic_virtual_array.cc | 24 |
2 files changed, 131 insertions, 98 deletions
diff --git a/source/blender/functions/FN_generic_virtual_array.hh b/source/blender/functions/FN_generic_virtual_array.hh index 8bff9d5cb22..59a5937ff93 100644 --- a/source/blender/functions/FN_generic_virtual_array.hh +++ b/source/blender/functions/FN_generic_virtual_array.hh @@ -135,24 +135,98 @@ struct GVArrayAnyExtraInfo { class GVMutableArray; -class GVArray { - private: +class GVArrayCommon { + protected: using ExtraInfo = detail::GVArrayAnyExtraInfo; using Storage = Any<ExtraInfo, 32, 8>; - using Impl = GVArrayImpl; - const Impl *impl_ = nullptr; + const GVArrayImpl *impl_ = nullptr; Storage storage_; + protected: + GVArrayCommon() = default; + + GVArrayCommon(const GVArrayCommon &other) : storage_(other.storage_) + { + impl_ = this->impl_from_storage(); + } + + GVArrayCommon(GVArrayCommon &&other) : storage_(std::move(other.storage_)) + { + impl_ = this->impl_from_storage(); + other.storage_.reset(); + other.impl_ = nullptr; + } + + GVArrayCommon(const GVArrayImpl *impl) : impl_(impl) + { + storage_ = impl_; + } + + GVArrayCommon(std::shared_ptr<const GVArrayImpl> impl) : impl_(impl.get()) + { + if (impl) { + storage_ = std::move(impl); + } + } + + template<typename ImplT, typename... Args> void emplace(Args &&...args) + { + static_assert(std::is_base_of_v<GVArrayImpl, ImplT>); + if constexpr (std::is_copy_constructible_v<ImplT> && Storage::template is_inline_v<ImplT>) { + impl_ = &storage_.template emplace<ImplT>(std::forward<Args>(args)...); + } + else { + std::shared_ptr<const GVArrayImpl> ptr = std::make_shared<ImplT>( + std::forward<Args>(args)...); + impl_ = &*ptr; + storage_ = std::move(ptr); + } + } + + void copy_from(const GVArrayCommon &other) + { + if (this == &other) { + return; + } + storage_ = other.storage_; + impl_ = this->impl_from_storage(); + } + + void move_from(GVArrayCommon &&other) + { + if (this == &other) { + return; + } + storage_ = std::move(other.storage_); + impl_ = this->impl_from_storage(); + other.storage_.reset(); + other.impl_ = nullptr; + } + + const GVArrayImpl *impl_from_storage() const + { + return storage_.extra_info().get_varray(storage_.get()); + } + + public: + operator bool() const + { + return impl_ != nullptr; + } +}; + +class GVArray : public GVArrayCommon { + private: friend GVMutableArray; public: GVArray() = default; - /* TODO: Add move constructor? */ GVArray(const GVArray &other); - GVArray(const Impl *impl); - GVArray(std::shared_ptr<const Impl> impl); + GVArray(GVArray &&other); + GVArray(const GVArrayImpl *impl); + GVArray(std::shared_ptr<const GVArrayImpl> impl); template<typename T> GVArray(const VArray<T> &varray); template<typename T> VArray<T> typed() const; @@ -171,26 +245,17 @@ class GVArray { GVArray &operator=(const GVArray &other); GVArray &operator=(GVArray &&other); - operator bool() const; - const Impl *operator->() const; - const Impl &operator*() const; + const GVArrayImpl *operator->() const; + const GVArrayImpl &operator*() const; }; -class GVMutableArray { - private: - using ExtraInfo = detail::GVArrayAnyExtraInfo; - using Storage = Any<ExtraInfo, 32, 8>; - using Impl = GVMutableArrayImpl; - - Impl *impl_ = nullptr; - Storage storage_; - +class GVMutableArray : public GVArrayCommon { public: - /* TODO: Add move constructor? */ GVMutableArray() = default; GVMutableArray(const GVMutableArray &other); - GVMutableArray(Impl *impl); - GVMutableArray(std::shared_ptr<Impl> impl); + GVMutableArray(GVMutableArray &&other); + GVMutableArray(GVMutableArrayImpl *impl); + GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl); template<typename T> GVMutableArray(const VMutableArray<T> &varray); template<typename T> VMutableArray<T> typed() const; @@ -204,9 +269,14 @@ class GVMutableArray { GVMutableArray &operator=(const GVMutableArray &other); GVMutableArray &operator=(GVMutableArray &&other); - operator bool() const; - Impl *operator->() const; - Impl &operator*() const; + GVMutableArrayImpl *operator->() const; + GVMutableArrayImpl &operator*() const; + + private: + GVMutableArrayImpl *get_impl() const + { + return (GVMutableArrayImpl *)impl_; + } }; /** \} */ @@ -756,48 +826,37 @@ template<typename StorageT> inline GVArrayAnyExtraInfo GVArrayAnyExtraInfo::get( } } // namespace detail -inline GVArray::GVArray(const GVArray &other) : storage_(other.storage_) +inline GVArray::GVArray(const GVArray &other) : GVArrayCommon(other) { - impl_ = storage_.extra_info().get_varray(storage_.get()); } -inline GVArray::GVArray(const Impl *impl) : impl_(impl) +inline GVArray::GVArray(GVArray &&other) : GVArrayCommon(std::move(other)) { - storage_ = impl; } -inline GVArray::GVArray(std::shared_ptr<const Impl> impl) : impl_(impl.get()) +inline GVArray::GVArray(const GVArrayImpl *impl) : GVArrayCommon(impl) { - if (impl) { - storage_ = std::move(impl); - } } -template<typename ImplT, typename... Args> inline GVArray GVArray::For(Args &&...args) +inline GVArray::GVArray(std::shared_ptr<const GVArrayImpl> impl) : GVArrayCommon(std::move(impl)) { - static_assert(std::is_base_of_v<Impl, ImplT>); - if constexpr (std::is_copy_constructible_v<ImplT> && Storage::template is_inline_v<ImplT>) { - GVArray varray; - varray.impl_ = &varray.storage_.template emplace<ImplT>(std::forward<Args>(args)...); - return varray; - } - else { - return GVArray(std::make_shared<ImplT>(std::forward<Args>(args)...)); - } } -inline GVArray::operator bool() const +template<typename ImplT, typename... Args> inline GVArray GVArray::For(Args &&...args) { - return impl_ != nullptr; + static_assert(std::is_base_of_v<GVArrayImpl, ImplT>); + GVArray varray; + varray.template emplace<ImplT>(std::forward<Args>(args)...); + return varray; } -inline const GVArray::Impl *GVArray::operator->() const +inline const GVArrayImpl *GVArray::operator->() const { BLI_assert(*this); return impl_; } -inline const GVArray::Impl &GVArray::operator*() const +inline const GVArrayImpl &GVArray::operator*() const { BLI_assert(*this); return *impl_; @@ -858,53 +917,42 @@ template<typename T> inline VArray<T> GVArray::typed() const /** \name Inline methods for #GVMutableArray. * \{ */ -inline GVMutableArray::GVMutableArray(const GVMutableArray &other) : storage_(other.storage_) +inline GVMutableArray::GVMutableArray(const GVMutableArray &other) : GVArrayCommon(other) { - impl_ = const_cast<Impl *>( - static_cast<const Impl *>(storage_.extra_info().get_varray(storage_.get()))); } -inline GVMutableArray::GVMutableArray(Impl *impl) : impl_(impl) +inline GVMutableArray::GVMutableArray(GVMutableArray &&other) : GVArrayCommon(std::move(other)) { - storage_ = static_cast<const GVArrayImpl *>(impl); } -inline GVMutableArray::GVMutableArray(std::shared_ptr<Impl> impl) : impl_(impl.get()) +inline GVMutableArray::GVMutableArray(GVMutableArrayImpl *impl) : GVArrayCommon(impl) { - if (impl) { - storage_ = std::shared_ptr<const GVArrayImpl>(std::move(impl)); - } } -template<typename ImplT, typename... Args> -inline GVMutableArray GVMutableArray::For(Args &&...args) +inline GVMutableArray::GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl) + : GVArrayCommon(std::move(impl)) { - static_assert(std::is_base_of_v<Impl, ImplT>); - if constexpr (std::is_copy_constructible_v<ImplT> && Storage::template is_inline_v<ImplT>) { - GVMutableArray varray; - varray.impl_ = &varray.storage_.template emplace<ImplT>(std::forward<Args>(args)...); - return varray; - } - else { - return GVMutableArray(std::make_shared<ImplT>(std::forward<Args>(args)...)); - } } -inline GVMutableArray::operator bool() const +template<typename ImplT, typename... Args> +inline GVMutableArray GVMutableArray::For(Args &&...args) { - return impl_ != nullptr; + static_assert(std::is_base_of_v<GVMutableArrayImpl, ImplT>); + GVMutableArray varray; + varray.emplace<ImplT>(std::forward<Args>(args)...); + return varray; } -inline GVMutableArray::Impl *GVMutableArray::operator->() const +inline GVMutableArrayImpl *GVMutableArray::operator->() const { BLI_assert(*this); - return impl_; + return this->get_impl(); } -inline GVMutableArray::Impl &GVMutableArray::operator*() const +inline GVMutableArrayImpl &GVMutableArray::operator*() const { BLI_assert(*this); - return *impl_; + return *this->get_impl(); } template<typename T> inline GVMutableArray::GVMutableArray(const VMutableArray<T> &varray) @@ -932,16 +980,17 @@ template<typename T> inline VMutableArray<T> GVMutableArray::typed() const if (!*this) { return {}; } - BLI_assert(impl_->type().is<T>()); + GVMutableArrayImpl *impl = this->get_impl(); + BLI_assert(impl->type().is<T>()); VMutableArray<T> varray; - if (impl_->try_assign_VMutableArray(varray)) { + if (impl->try_assign_VMutableArray(varray)) { return varray; } - if (impl_->has_ownership()) { + if (impl->has_ownership()) { return VMutableArray<T>::template For<VMutableArrayImpl_For_GVMutableArray<T>>(*this); } - if (impl_->is_span()) { - const MutableSpan<T> span = impl_->get_internal_span().typed<T>(); + if (impl->is_span()) { + const MutableSpan<T> span = impl->get_internal_span().typed<T>(); return VMutableArray<T>::ForSpan(span); } return VMutableArray<T>::template For<VMutableArrayImpl_For_GVMutableArray<T>>(*this); diff --git a/source/blender/functions/intern/generic_virtual_array.cc b/source/blender/functions/intern/generic_virtual_array.cc index 18ac92ea2ec..47ea1522636 100644 --- a/source/blender/functions/intern/generic_virtual_array.cc +++ b/source/blender/functions/intern/generic_virtual_array.cc @@ -520,21 +520,13 @@ GVArray GVArray::slice(IndexRange slice) const GVArray &GVArray::operator=(const GVArray &other) { - if (this == &other) { - return *this; - } - this->~GVArray(); - new (this) GVArray(other); + this->copy_from(other); return *this; } GVArray &GVArray::operator=(GVArray &&other) { - if (this == &other) { - return *this; - } - this->~GVArray(); - new (this) GVArray(std::move(other)); + this->move_from(std::move(other)); return *this; } @@ -559,21 +551,13 @@ GVMutableArray::operator GVArray() const GVMutableArray &GVMutableArray::operator=(const GVMutableArray &other) { - if (this == &other) { - return *this; - } - this->~GVMutableArray(); - new (this) GVMutableArray(other); + this->copy_from(other); return *this; } GVMutableArray &GVMutableArray::operator=(GVMutableArray &&other) { - if (this == &other) { - return *this; - } - this->~GVMutableArray(); - new (this) GVMutableArray(std::move(other)); + this->move_from(std::move(other)); return *this; } |