From 5d9ade27de54b6910ed32f92d20d8f692959603c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 2 Jul 2022 11:45:57 +0200 Subject: BLI: improve span access to virtual arrays * Make the class names more consistent. * Implement missing move-constructors and assignment-operators. --- source/blender/blenlib/BLI_virtual_array.hh | 60 ++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 14 deletions(-) (limited to 'source/blender/blenlib/BLI_virtual_array.hh') diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index d0436bdc213..84f6223580a 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -51,7 +51,10 @@ struct CommonVArrayInfo { /** True when the #data becomes a dangling pointer when the virtual array is destructed. */ bool may_have_ownership = true; - /** Points either to nothing, a single value or array of values, depending on #type. */ + /** + * Points either to nothing, a single value or array of values, depending on #type. + * If this is a span of a mutable virtual array, it is safe to cast away const. + */ const void *data; CommonVArrayInfo() = default; @@ -1117,15 +1120,15 @@ template static constexpr bool is_VMutableArray_v> * from faster access. * - An API is called, that does not accept virtual arrays, but only spans. */ -template class VArray_Span final : public Span { +template class VArraySpan final : public Span { private: VArray varray_; Array owned_data_; public: - VArray_Span() = default; + VArraySpan() = default; - VArray_Span(VArray varray) : Span(), varray_(std::move(varray)) + VArraySpan(VArray varray) : Span(), varray_(std::move(varray)) { this->size_ = varray_.size(); const CommonVArrayInfo info = varray_.common_info(); @@ -1140,7 +1143,7 @@ template class VArray_Span final : public Span { } } - VArray_Span(VArray_Span &&other) + VArraySpan(VArraySpan &&other) : varray_(std::move(other.varray_)), owned_data_(std::move(other.owned_data_)) { this->size_ = varray_.size(); @@ -1155,25 +1158,25 @@ template class VArray_Span final : public Span { other.size_ = 0; } - VArray_Span &operator=(VArray_Span &&other) + VArraySpan &operator=(VArraySpan &&other) { if (this == &other) { return *this; } std::destroy_at(this); - new (this) VArray_Span(std::move(other)); + new (this) VArraySpan(std::move(other)); return *this; } }; /** - * Same as #VArray_Span, but for a mutable span. + * Same as #VArraySpan, but for a mutable span. * The important thing to note is that when changing this span, the results might not be * immediately reflected in the underlying virtual array (only when the virtual array is a span * internally). The #save method can be used to write all changes to the underlying virtual array, * if necessary. */ -template class VMutableArray_Span final : public MutableSpan { +template class MutableVArraySpan final : public MutableSpan { private: VMutableArray varray_; Array owned_data_; @@ -1183,7 +1186,7 @@ template class VMutableArray_Span final : public MutableSpan { public: /* Create a span for any virtual array. This is cheap when the virtual array is a span itself. If * not, a new array has to be allocated as a wrapper for the underlying virtual array. */ - VMutableArray_Span(VMutableArray varray, const bool copy_values_to_span = true) + MutableVArraySpan(VMutableArray varray, const bool copy_values_to_span = true) : MutableSpan(), varray_(std::move(varray)) { this->size_ = varray_.size(); @@ -1204,15 +1207,44 @@ template class VMutableArray_Span final : public MutableSpan { } } - ~VMutableArray_Span() + MutableVArraySpan(MutableVArraySpan &&other) + : varray_(std::move(other.varray_)), + owned_data_(std::move(owned_data_)), + show_not_saved_warning_(other.show_not_saved_warning_) + { + this->size_ = varray_.size(); + const CommonVArrayInfo info = varray_.common_info(); + if (info.type == CommonVArrayInfo::Type::Span) { + this->data_ = reinterpret_cast(info.data); + } + else { + this->data_ = owned_data_.data(); + } + other.data_ = nullptr; + other.size_ = 0; + } + + ~MutableVArraySpan() { - if (show_not_saved_warning_) { - if (!save_has_been_called_) { - std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n"; + if (varray_) { + if (show_not_saved_warning_) { + if (!save_has_been_called_) { + std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n"; + } } } } + MutableVArraySpan &operator=(MutableVArraySpan &&other) + { + if (this == &other) { + return *this; + } + std::destroy_at(this); + new (this) MutableVArraySpan(std::move(other)); + return *this; + } + /* Write back all values from a temporary allocated array to the underlying virtual array. */ void save() { -- cgit v1.2.3