diff options
author | Jacques Lucke <jacques@blender.org> | 2021-03-07 16:24:52 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-03-07 16:24:52 +0300 |
commit | 649916f0983e4c59201672e6e28dcc7ae1f655b2 (patch) | |
tree | f8caa573963f0af1897b25cbda1352c5ea7474a1 /source/blender | |
parent | 456d3cc85e9f408341b12eb0d4f2c3a925855e8c (diff) |
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.
Diffstat (limited to 'source/blender')
5 files changed, 31 insertions, 26 deletions
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); } |