[Bf-blender-cvs] [649916f0983] master: BLI: make it harder to forget to destruct a value

Jacques Lucke noreply at git.blender.org
Sun Mar 7 14:25:09 CET 2021


Commit: 649916f0983e4c59201672e6e28dcc7ae1f655b2
Author: Jacques Lucke
Date:   Sun Mar 7 14:24:52 2021 +0100
Branches: master
https://developer.blender.org/rB649916f0983e4c59201672e6e28dcc7ae1f655b2

BLI: make it harder to forget to destruct a value

Instead of returning a raw pointer, `LinearAllocator.construct(...)` now returns
a `destruct_ptr`, which is similar to `unique_ptr`, but does not deallocate
the memory and only calls the destructor instead.

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

M	source/blender/blenlib/BLI_linear_allocator.hh
M	source/blender/blenlib/BLI_resource_collector.hh
M	source/blender/blenlib/tests/BLI_linear_allocator_test.cc
M	source/blender/functions/intern/multi_function_network_evaluation.cc
M	source/blender/modifiers/intern/MOD_nodes.cc

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

diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh
index 11022a03d69..0bf4ad194e1 100644
--- a/source/blender/blenlib/BLI_linear_allocator.hh
+++ b/source/blender/blenlib/BLI_linear_allocator.hh
@@ -118,14 +118,14 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
    *
    * Arguments passed to this method will be forwarded to the constructor of T.
    *
-   * You must not call `delete` on the returned pointer.
-   * Instead, the destruct has to be called explicitly.
+   * You must not call `delete` on the returned value.
+   * Instead, only the destructor has to be called.
    */
-  template<typename T, typename... Args> T *construct(Args &&... args)
+  template<typename T, typename... Args> destruct_ptr<T> construct(Args &&... args)
   {
     void *buffer = this->allocate(sizeof(T), alignof(T));
     T *value = new (buffer) T(std::forward<Args>(args)...);
-    return value;
+    return destruct_ptr<T>(value);
   }
 
   /**
diff --git a/source/blender/blenlib/BLI_resource_collector.hh b/source/blender/blenlib/BLI_resource_collector.hh
index ecae9b8c682..70804ceb1f1 100644
--- a/source/blender/blenlib/BLI_resource_collector.hh
+++ b/source/blender/blenlib/BLI_resource_collector.hh
@@ -130,9 +130,10 @@ class ResourceCollector : NonCopyable, NonMovable {
    */
   template<typename T, typename... Args> T &construct(const char *name, Args &&... args)
   {
-    T *value = m_allocator.construct<T>(std::forward<Args>(args)...);
-    this->add(destruct_ptr<T>(value), name);
-    return *value;
+    destruct_ptr<T> value_ptr = m_allocator.construct<T>(std::forward<Args>(args)...);
+    T &value_ref = *value_ptr;
+    this->add(std::move(value_ptr), name);
+    return value_ref;
   }
 
   /**
diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
index 95156ae5c0c..977e5dba497 100644
--- a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
+++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
@@ -79,7 +79,7 @@ TEST(linear_allocator, Construct)
   LinearAllocator<> allocator;
 
   std::array<int, 5> values = {1, 2, 3, 4, 5};
-  Vector<int> *vector = allocator.construct<Vector<int>>(values);
+  Vector<int> *vector = allocator.construct<Vector<int>>(values).release();
   EXPECT_EQ(vector->size(), 5);
   EXPECT_EQ((*vector)[3], 4);
   vector->~Vector();
diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc
index c543d86ad34..5a37a45908f 100644
--- a/source/blender/functions/intern/multi_function_network_evaluation.cc
+++ b/source/blender/functions/intern/multi_function_network_evaluation.cc
@@ -663,7 +663,7 @@ void MFNetworkEvaluationStorage::add_single_input_from_caller(const MFOutputSock
   BLI_assert(value_per_output_id_[socket.id()] == nullptr);
   BLI_assert(virtual_span.size() >= min_array_size_);
 
-  auto *value = allocator_.construct<InputSingleValue>(virtual_span);
+  auto *value = allocator_.construct<InputSingleValue>(virtual_span).release();
   value_per_output_id_[socket.id()] = value;
 }
 
@@ -673,7 +673,7 @@ void MFNetworkEvaluationStorage::add_vector_input_from_caller(const MFOutputSock
   BLI_assert(value_per_output_id_[socket.id()] == nullptr);
   BLI_assert(virtual_array_span.size() >= min_array_size_);
 
-  auto *value = allocator_.construct<InputVectorValue>(virtual_array_span);
+  auto *value = allocator_.construct<InputVectorValue>(virtual_array_span).release();
   value_per_output_id_[socket.id()] = value;
 }
 
@@ -683,7 +683,7 @@ void MFNetworkEvaluationStorage::add_single_output_from_caller(const MFOutputSoc
   BLI_assert(value_per_output_id_[socket.id()] == nullptr);
   BLI_assert(span.size() >= min_array_size_);
 
-  auto *value = allocator_.construct<OutputSingleValue>(span);
+  auto *value = allocator_.construct<OutputSingleValue>(span).release();
   value_per_output_id_[socket.id()] = value;
 }
 
@@ -693,7 +693,7 @@ void MFNetworkEvaluationStorage::add_vector_output_from_caller(const MFOutputSoc
   BLI_assert(value_per_output_id_[socket.id()] == nullptr);
   BLI_assert(vector_array.size() >= min_array_size_);
 
-  auto *value = allocator_.construct<OutputVectorValue>(vector_array);
+  auto *value = allocator_.construct<OutputVectorValue>(vector_array).release();
   value_per_output_id_[socket.id()] = value;
 }
 
@@ -705,7 +705,8 @@ GMutableSpan MFNetworkEvaluationStorage::get_single_output__full(const MFOutputS
     void *buffer = MEM_mallocN_aligned(min_array_size_ * type.size(), type.alignment(), AT);
     GMutableSpan span(type, buffer, min_array_size_);
 
-    auto *value = allocator_.construct<OwnSingleValue>(span, socket.targets().size(), false);
+    auto *value =
+        allocator_.construct<OwnSingleValue>(span, socket.targets().size(), false).release();
     value_per_output_id_[socket.id()] = value;
 
     return span;
@@ -723,7 +724,8 @@ GMutableSpan MFNetworkEvaluationStorage::get_single_output__single(const MFOutpu
     void *buffer = allocator_.allocate(type.size(), type.alignment());
     GMutableSpan span(type, buffer, 1);
 
-    auto *value = allocator_.construct<OwnSingleValue>(span, socket.targets().size(), true);
+    auto *value =
+        allocator_.construct<OwnSingleValue>(span, socket.targets().size(), true).release();
     value_per_output_id_[socket.id()] = value;
 
     return value->span;
@@ -742,7 +744,8 @@ GVectorArray &MFNetworkEvaluationStorage::get_vector_output__full(const MFOutput
     const CPPType &type = socket.data_type().vector_base_type();
     GVectorArray *vector_array = new GVectorArray(type, min_array_size_);
 
-    auto *value = allocator_.construct<OwnVectorValue>(*vector_array, socket.targets().size());
+    auto *value =
+        allocator_.construct<OwnVectorValue>(*vector_array, socket.targets().size()).release();
     value_per_output_id_[socket.id()] = value;
 
     return *value->vector_array;
@@ -759,7 +762,8 @@ GVectorArray &MFNetworkEvaluationStorage::get_vector_output__single(const MFOutp
     const CPPType &type = socket.data_type().vector_base_type();
     GVectorArray *vector_array = new GVectorArray(type, 1);
 
-    auto *value = allocator_.construct<OwnVectorValue>(*vector_array, socket.targets().size());
+    auto *value =
+        allocator_.construct<OwnVectorValue>(*vector_array, socket.targets().size()).release();
     value_per_output_id_[socket.id()] = value;
 
     return *value->vector_array;
@@ -806,8 +810,8 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputS
   GMutableSpan new_array_ref(type, new_buffer, min_array_size_);
   virtual_span.materialize_to_uninitialized(mask_, new_array_ref.data());
 
-  OwnSingleValue *new_value = allocator_.construct<OwnSingleValue>(
-      new_array_ref, to.targets().size(), false);
+  OwnSingleValue *new_value =
+      allocator_.construct<OwnSingleValue>(new_array_ref, to.targets().size(), false).release();
   value_per_output_id_[to.id()] = new_value;
   return new_array_ref;
 }
@@ -850,8 +854,8 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__single(const MFInpu
   type.copy_to_uninitialized(virtual_span.as_single_element(), new_buffer);
   GMutableSpan new_array_ref(type, new_buffer, 1);
 
-  OwnSingleValue *new_value = allocator_.construct<OwnSingleValue>(
-      new_array_ref, to.targets().size(), true);
+  OwnSingleValue *new_value =
+      allocator_.construct<OwnSingleValue>(new_array_ref, to.targets().size(), true).release();
   value_per_output_id_[to.id()] = new_value;
   return new_array_ref;
 }
@@ -891,8 +895,8 @@ GVectorArray &MFNetworkEvaluationStorage::get_mutable_vector__full(const MFInput
   GVectorArray *new_vector_array = new GVectorArray(base_type, min_array_size_);
   new_vector_array->extend(mask_, virtual_array_span);
 
-  OwnVectorValue *new_value = allocator_.construct<OwnVectorValue>(*new_vector_array,
-                                                                   to.targets().size());
+  OwnVectorValue *new_value =
+      allocator_.construct<OwnVectorValue>(*new_vector_array, to.targets().size()).release();
   value_per_output_id_[to.id()] = new_value;
 
   return *new_vector_array;
@@ -934,8 +938,8 @@ GVectorArray &MFNetworkEvaluationStorage::get_mutable_vector__single(const MFInp
   GVectorArray *new_vector_array = new GVectorArray(base_type, 1);
   new_vector_array->extend(0, virtual_array_span[0]);
 
-  OwnVectorValue *new_value = allocator_.construct<OwnVectorValue>(*new_vector_array,
-                                                                   to.targets().size());
+  OwnVectorValue *new_value =
+      allocator_.construct<OwnVectorValue>(*new_vector_array, to.targets().size()).release();
   value_per_output_id_[to.id()] = new_value;
   return *new_vector_array;
 }
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 4d1823b8951..50c07578173 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -1045,8 +1045,8 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
      * modifier. */
     const OutputSocketRef *first_input_socket = group_input_sockets[0];
     if (first_input_socket->bsocket()->type == SOCK_GEOMETRY) {
-      GeometrySet *geometry_set_in = allocator.construct<GeometrySet>(
-          std::move(input_geometry_set));
+      GeometrySet *geometry_set_in =
+          allocator.construct<GeometrySet>(std::move(input_geometry_set)).release();
       group_inputs.add_new({root_context, first_input_socket}, geometry_set_in);
       remaining_input_sockets = remaining_input_sockets.drop_front(1);
     }



More information about the Bf-blender-cvs mailing list