Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/BLI_virtual_array.hh')
-rw-r--r--source/blender/blenlib/BLI_virtual_array.hh81
1 files changed, 67 insertions, 14 deletions
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index d0436bdc213..438fcc4b8f7 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,16 +1120,19 @@ template<typename T> static constexpr bool is_VMutableArray_v<VMutableArray<T>>
* from faster access.
* - An API is called, that does not accept virtual arrays, but only spans.
*/
-template<typename T> class VArray_Span final : public Span<T> {
+template<typename T> class VArraySpan final : public Span<T> {
private:
VArray<T> varray_;
Array<T> owned_data_;
public:
- VArray_Span() = default;
+ VArraySpan() = default;
- VArray_Span(VArray<T> varray) : Span<T>(), varray_(std::move(varray))
+ VArraySpan(VArray<T> varray) : Span<T>(), varray_(std::move(varray))
{
+ if (!varray_) {
+ return;
+ }
this->size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -1140,9 +1146,12 @@ template<typename T> class VArray_Span final : public Span<T> {
}
}
- VArray_Span(VArray_Span &&other)
+ VArraySpan(VArraySpan &&other)
: varray_(std::move(other.varray_)), owned_data_(std::move(other.owned_data_))
{
+ if (!varray_) {
+ return;
+ }
this->size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -1155,25 +1164,25 @@ template<typename T> class VArray_Span final : public Span<T> {
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<typename T> class VMutableArray_Span final : public MutableSpan<T> {
+template<typename T> class MutableVArraySpan final : public MutableSpan<T> {
private:
VMutableArray<T> varray_;
Array<T> owned_data_;
@@ -1181,11 +1190,17 @@ template<typename T> class VMutableArray_Span final : public MutableSpan<T> {
bool show_not_saved_warning_ = true;
public:
+ MutableVArraySpan() = default;
+
/* 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<T> varray, const bool copy_values_to_span = true)
+ MutableVArraySpan(VMutableArray<T> varray, const bool copy_values_to_span = true)
: MutableSpan<T>(), varray_(std::move(varray))
{
+ if (!varray_) {
+ return;
+ }
+
this->size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -1204,15 +1219,53 @@ template<typename T> class VMutableArray_Span final : public MutableSpan<T> {
}
}
- ~VMutableArray_Span()
+ MutableVArraySpan(MutableVArraySpan &&other)
+ : varray_(std::move(other.varray_)),
+ owned_data_(std::move(other.owned_data_)),
+ show_not_saved_warning_(other.show_not_saved_warning_)
+ {
+ if (!varray_) {
+ return;
+ }
+
+ this->size_ = varray_.size();
+ const CommonVArrayInfo info = varray_.common_info();
+ if (info.type == CommonVArrayInfo::Type::Span) {
+ this->data_ = static_cast<T *>(const_cast<void *>(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;
+ }
+
+ const VMutableArray<T> &varray() const
+ {
+ return varray_;
+ }
+
/* Write back all values from a temporary allocated array to the underlying virtual array. */
void save()
{