[Bf-blender-cvs] [ba62e20af67] master: BLI: make some spans default constructible

Jacques Lucke noreply at git.blender.org
Thu Jul 7 19:19:38 CEST 2022


Commit: ba62e20af67e1de25f781456df7175fa1b31db67
Author: Jacques Lucke
Date:   Thu Jul 7 19:19:01 2022 +0200
Branches: master
https://developer.blender.org/rBba62e20af67e1de25f781456df7175fa1b31db67

BLI: make some spans default constructible

`GSpan` and spans based on virtual arrays were not default constructible
before, which made them hard to use sometimes. It's generally fine for
spans to be empty.

The main thing the keep in mind is that the type pointer in `GSpan` may
be null now. Generally, code receiving spans as input can assume that
the type is not-null, but sometimes that may be valid. The old #type() method
that returned a reference to the type still exists. It asserts when the
type is null.

===================================================================

M	source/blender/blenlib/BLI_generic_span.hh
M	source/blender/blenlib/BLI_generic_virtual_array.hh
M	source/blender/blenlib/BLI_virtual_array.hh
M	source/blender/blenlib/intern/generic_virtual_array.cc
M	source/blender/blenlib/tests/BLI_virtual_array_test.cc

===================================================================

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)
   }
 }
 
+TES

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list