mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Cleanup: Split DynamicStackBuffer to its own header
This allows removing the MEM_guardedalloc.h include from BLI_memory_utils.hh, and arguably a more specific header is generally preferrable anyway. Pull Request: https://projects.blender.org/blender/blender/pulls/154483
This commit is contained in:
parent
ed859f3eac
commit
54fbc73c5f
6 changed files with 67 additions and 47 deletions
|
|
@ -10,6 +10,8 @@
|
|||
#include "BLI_path_utils.hh"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "utils.hh"
|
||||
|
||||
namespace blender::asset_system::utils {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
* pointers to virtual member functions.
|
||||
*/
|
||||
|
||||
#include "BLI_dynamic_stack_buffer.hh" // IWYU pragma: keep
|
||||
#include "BLI_enum_flags.hh"
|
||||
#include "BLI_hash.hh"
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
|
|
|
|||
62
source/blender/blenlib/BLI_dynamic_stack_buffer.hh
Normal file
62
source/blender/blenlib/BLI_dynamic_stack_buffer.hh
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
#include "BLI_assert.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/**
|
||||
* A dynamic stack buffer can be used instead of #alloca when one wants to allocate a dynamic
|
||||
* amount of memory on the stack. Using this class has some advantages:
|
||||
* - It falls back to heap allocation, when the size is too large.
|
||||
* - It can be used in loops safely.
|
||||
* - If the buffer is heap allocated, it is free automatically in the destructor.
|
||||
*/
|
||||
template<size_t ReservedSize = 64, size_t ReservedAlignment = 64>
|
||||
class alignas(ReservedAlignment) DynamicStackBuffer {
|
||||
private:
|
||||
/* Don't create an empty array. This causes problems with some compilers. */
|
||||
char reserved_buffer_[(ReservedSize > 0) ? ReservedSize : 1];
|
||||
void *buffer_;
|
||||
|
||||
public:
|
||||
DynamicStackBuffer(const int64_t size, const int64_t alignment)
|
||||
{
|
||||
BLI_assert(size >= 0);
|
||||
BLI_assert(alignment >= 0);
|
||||
if (size <= ReservedSize && alignment <= ReservedAlignment) {
|
||||
buffer_ = reserved_buffer_;
|
||||
}
|
||||
else {
|
||||
buffer_ = MEM_new_uninitialized_aligned(size, alignment, __func__);
|
||||
}
|
||||
}
|
||||
~DynamicStackBuffer()
|
||||
{
|
||||
if (buffer_ != reserved_buffer_) {
|
||||
MEM_delete_void(buffer_);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't allow any copying or moving of this type. */
|
||||
DynamicStackBuffer(const DynamicStackBuffer &other) = delete;
|
||||
DynamicStackBuffer(DynamicStackBuffer &&other) = delete;
|
||||
DynamicStackBuffer &operator=(const DynamicStackBuffer &other) = delete;
|
||||
DynamicStackBuffer &operator=(DynamicStackBuffer &&other) = delete;
|
||||
|
||||
void *buffer() const
|
||||
{
|
||||
return buffer_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/**
|
||||
|
|
@ -221,50 +219,6 @@ template<typename T, int64_t Size = 1> class TypedBuffer {
|
|||
}
|
||||
};
|
||||
|
||||
/* A dynamic stack buffer can be used instead of #alloca when wants to allocate a dynamic amount of
|
||||
* memory on the stack. Using this class has some advantages:
|
||||
* - It falls back to heap allocation, when the size is too large.
|
||||
* - It can be used in loops safely.
|
||||
* - If the buffer is heap allocated, it is free automatically in the destructor.
|
||||
*/
|
||||
template<size_t ReservedSize = 64, size_t ReservedAlignment = 64>
|
||||
class alignas(ReservedAlignment) DynamicStackBuffer {
|
||||
private:
|
||||
/* Don't create an empty array. This causes problems with some compilers. */
|
||||
char reserved_buffer_[(ReservedSize > 0) ? ReservedSize : 1];
|
||||
void *buffer_;
|
||||
|
||||
public:
|
||||
DynamicStackBuffer(const int64_t size, const int64_t alignment)
|
||||
{
|
||||
BLI_assert(size >= 0);
|
||||
BLI_assert(alignment >= 0);
|
||||
if (size <= ReservedSize && alignment <= ReservedAlignment) {
|
||||
buffer_ = reserved_buffer_;
|
||||
}
|
||||
else {
|
||||
buffer_ = MEM_new_uninitialized_aligned(size, alignment, __func__);
|
||||
}
|
||||
}
|
||||
~DynamicStackBuffer()
|
||||
{
|
||||
if (buffer_ != reserved_buffer_) {
|
||||
MEM_delete_void(buffer_);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't allow any copying or moving of this type. */
|
||||
DynamicStackBuffer(const DynamicStackBuffer &other) = delete;
|
||||
DynamicStackBuffer(DynamicStackBuffer &&other) = delete;
|
||||
DynamicStackBuffer &operator=(const DynamicStackBuffer &other) = delete;
|
||||
DynamicStackBuffer &operator=(DynamicStackBuffer &&other) = delete;
|
||||
|
||||
void *buffer() const
|
||||
{
|
||||
return buffer_;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This can be used by container constructors. A parameter of this type should be used to indicate
|
||||
* that the constructor does not construct the elements.
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ set(SRC
|
|||
BLI_disjoint_set.hh
|
||||
BLI_dot_export.hh
|
||||
BLI_dot_export_attribute_enums.hh
|
||||
BLI_dynamic_stack_buffer.hh
|
||||
BLI_dynstr.h
|
||||
BLI_easing.h
|
||||
BLI_endian_defines.h
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@
|
|||
#include "DNA_listBase.h"
|
||||
#include "DNA_sdna_type_ids.hh"
|
||||
|
||||
#include "BLI_dynamic_stack_buffer.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_implicit_sharing.hh"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_memory_utils.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue