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:
-rw-r--r--source/blender/blenlib/BLI_generic_span.hh64
-rw-r--r--source/blender/blenlib/BLI_generic_virtual_array.hh4
-rw-r--r--source/blender/blenlib/BLI_virtual_array.hh23
-rw-r--r--source/blender/blenlib/intern/generic_virtual_array.cc32
-rw-r--r--source/blender/blenlib/tests/BLI_virtual_array_test.cc33
5 files changed, 135 insertions, 21 deletions
diff --git a/source/blender/blenlib/BLI_generic_span.hh b/source/blender/blenlib/BLI_generic_span.hh
index 4c0bfc83ba8..0a40201634a 100644
--- a/source/blender/blenlib/BLI_generic_span.hh
+++ b/source/blender/blenlib/BLI_generic_span.hh
@@ -16,20 +16,30 @@ namespace blender {
*/
class GSpan {
protected:
- const CPPType *type_;
- const void *data_;
- int64_t size_;
+ const CPPType *type_ = nullptr;
+ const void *data_ = nullptr;
+ int64_t size_ = 0;
public:
- GSpan(const CPPType &type, const void *buffer, int64_t size)
- : type_(&type), data_(buffer), size_(size)
+ GSpan() = default;
+
+ GSpan(const CPPType *type, const void *buffer, int64_t size)
+ : type_(type), data_(buffer), size_(size)
{
BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
- BLI_assert(type.pointer_has_valid_alignment(buffer));
+ BLI_assert(type->pointer_has_valid_alignment(buffer));
+ }
+
+ GSpan(const CPPType &type, const void *buffer, int64_t size) : GSpan(&type, buffer, size)
+ {
+ }
+
+ GSpan(const CPPType &type) : type_(&type)
+ {
}
- GSpan(const CPPType &type) : GSpan(type, nullptr, 0)
+ GSpan(const CPPType *type) : type_(type)
{
}
@@ -41,9 +51,15 @@ class GSpan {
const CPPType &type() const
{
+ BLI_assert(type_ != nullptr);
return *type_;
}
+ const CPPType *type_ptr() const
+ {
+ return type_;
+ }
+
bool is_empty() const
{
return size_ == 0;
@@ -76,7 +92,7 @@ class GSpan {
BLI_assert(start >= 0);
BLI_assert(size >= 0);
const int64_t new_size = std::max<int64_t>(0, std::min(size, size_ - start));
- return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * start), new_size);
+ return GSpan(type_, POINTER_OFFSET(data_, type_->size() * start), new_size);
}
GSpan slice(const IndexRange range) const
@@ -91,20 +107,30 @@ class GSpan {
*/
class GMutableSpan {
protected:
- const CPPType *type_;
- void *data_;
- int64_t size_;
+ const CPPType *type_ = nullptr;
+ void *data_ = nullptr;
+ int64_t size_ = 0;
public:
- GMutableSpan(const CPPType &type, void *buffer, int64_t size)
- : type_(&type), data_(buffer), size_(size)
+ GMutableSpan() = default;
+
+ GMutableSpan(const CPPType *type, void *buffer, int64_t size)
+ : type_(type), data_(buffer), size_(size)
{
BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
- BLI_assert(type.pointer_has_valid_alignment(buffer));
+ BLI_assert(type->pointer_has_valid_alignment(buffer));
+ }
+
+ GMutableSpan(const CPPType &type, void *buffer, int64_t size) : GMutableSpan(&type, buffer, size)
+ {
+ }
+
+ GMutableSpan(const CPPType &type) : type_(&type)
+ {
}
- GMutableSpan(const CPPType &type) : GMutableSpan(type, nullptr, 0)
+ GMutableSpan(const CPPType *type) : type_(type)
{
}
@@ -116,14 +142,20 @@ class GMutableSpan {
operator GSpan() const
{
- return GSpan(*type_, data_, size_);
+ return GSpan(type_, data_, size_);
}
const CPPType &type() const
{
+ BLI_assert(type_ != nullptr);
return *type_;
}
+ const CPPType *type_ptr() const
+ {
+ return type_;
+ }
+
bool is_empty() const
{
return size_ == 0;
diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh
index 3526925c2e2..43ca16a894f 100644
--- a/source/blender/blenlib/BLI_generic_virtual_array.hh
+++ b/source/blender/blenlib/BLI_generic_virtual_array.hh
@@ -267,6 +267,7 @@ class GVArraySpan : public GSpan {
void *owned_data_ = nullptr;
public:
+ GVArraySpan();
GVArraySpan(GVArray varray);
GVArraySpan(GVArraySpan &&other);
~GVArraySpan();
@@ -282,11 +283,14 @@ class GMutableVArraySpan : public GMutableSpan, NonCopyable, NonMovable {
bool show_not_saved_warning_ = true;
public:
+ 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();
};
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index 84f6223580a..56b2f9f6c6f 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -1130,6 +1130,9 @@ template<typename T> class VArraySpan final : public Span<T> {
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) {
@@ -1146,6 +1149,9 @@ template<typename T> class VArraySpan final : public Span<T> {
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) {
@@ -1184,11 +1190,17 @@ template<typename T> class MutableVArraySpan 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. */
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) {
@@ -1212,10 +1224,14 @@ template<typename T> class MutableVArraySpan final : public MutableSpan<T> {
owned_data_(std::move(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_ = reinterpret_cast<T *>(info.data);
+ this->data_ = static_cast<T *>(const_cast<void *>(info.data));
}
else {
this->data_ = owned_data_.data();
@@ -1245,6 +1261,11 @@ template<typename T> class MutableVArraySpan final : public MutableSpan<T> {
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()
{
diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc
index 532c7b9b626..28bc66e8524 100644
--- a/source/blender/blenlib/intern/generic_virtual_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_array.cc
@@ -287,8 +287,15 @@ template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public
/** \name #GVArraySpan
* \{ */
-GVArraySpan::GVArraySpan(GVArray varray) : GSpan(varray.type()), varray_(std::move(varray))
+GVArraySpan::GVArraySpan() = default;
+
+GVArraySpan::GVArraySpan(GVArray varray)
+ : GSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
{
+ if (!varray_) {
+ return;
+ }
+
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -302,8 +309,12 @@ GVArraySpan::GVArraySpan(GVArray varray) : GSpan(varray.type()), varray_(std::mo
}
GVArraySpan::GVArraySpan(GVArraySpan &&other)
- : GSpan(other.type()), varray_(std::move(other.varray_)), owned_data_(other.owned_data_)
+ : GSpan(other.type_ptr()), varray_(std::move(other.varray_)), owned_data_(other.owned_data_)
{
+ if (!varray_) {
+ return;
+ }
+
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -340,9 +351,14 @@ GVArraySpan &GVArraySpan::operator=(GVArraySpan &&other)
/** \name #GMutableVArraySpan
* \{ */
+GMutableVArraySpan::GMutableVArraySpan() = default;
+
GMutableVArraySpan::GMutableVArraySpan(GVMutableArray varray, const bool copy_values_to_span)
- : GMutableSpan(varray.type()), varray_(std::move(varray))
+ : GMutableSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
{
+ if (!varray_) {
+ return;
+ }
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -361,11 +377,14 @@ GMutableVArraySpan::GMutableVArraySpan(GVMutableArray varray, const bool copy_va
}
GMutableVArraySpan::GMutableVArraySpan(GMutableVArraySpan &&other)
- : GMutableSpan(other.type()),
+ : GMutableSpan(other.type_ptr()),
varray_(std::move(other.varray_)),
owned_data_(other.owned_data_),
show_not_saved_warning_(other.show_not_saved_warning_)
{
+ if (!varray_) {
+ return;
+ }
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -417,6 +436,11 @@ void GMutableVArraySpan::disable_not_applied_warning()
show_not_saved_warning_ = false;
}
+const GVMutableArray &GMutableVArraySpan::varray() const
+{
+ return varray_;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index c3c6d84ea42..14f5480f751 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0 */
#include "BLI_array.hh"
+#include "BLI_generic_virtual_array.hh"
#include "BLI_strict_flags.h"
#include "BLI_vector.hh"
#include "BLI_vector_set.hh"
@@ -222,4 +223,36 @@ TEST(virtual_array, MaterializeCompressed)
}
}
+TEST(virtual_array, EmptySpanWrapper)
+{
+ {
+ VArray<int> varray;
+ VArraySpan<int> span1 = varray;
+ EXPECT_TRUE(span1.is_empty());
+ VArraySpan<int> span2 = std::move(span1);
+ EXPECT_TRUE(span2.is_empty());
+ }
+ {
+ VMutableArray<int> varray;
+ MutableVArraySpan<int> span1 = varray;
+ EXPECT_TRUE(span1.is_empty());
+ MutableVArraySpan<int> span2 = std::move(span1);
+ EXPECT_TRUE(span2.is_empty());
+ }
+ {
+ GVArray varray;
+ GVArraySpan span1 = varray;
+ EXPECT_TRUE(span1.is_empty());
+ GVArraySpan span2 = std::move(span1);
+ EXPECT_TRUE(span2.is_empty());
+ }
+ {
+ GVMutableArray varray;
+ GMutableVArraySpan span1 = varray;
+ EXPECT_TRUE(span1.is_empty());
+ GMutableVArraySpan span2 = std::move(span1);
+ EXPECT_TRUE(span2.is_empty());
+ }
+}
+
} // namespace blender::tests