VTK  9.3.20240425
vtkBuffer.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
16#ifndef vtkBuffer_h
17#define vtkBuffer_h
18
19#include "vtkObject.h"
20#include "vtkObjectFactory.h" // New() implementation
21
22#include <algorithm> // for std::min and std::copy
23
24VTK_ABI_NAMESPACE_BEGIN
25template <class ScalarTypeT>
26class vtkBuffer : public vtkObject
27{
28public:
30 typedef ScalarTypeT ScalarType;
31
34
38 inline ScalarType* GetBuffer() { return this->Pointer; }
39 inline const ScalarType* GetBuffer() const { return this->Pointer; }
40
46 void SetBuffer(ScalarType* array, vtkIdType size);
47
51 void SetMallocFunction(vtkMallocingFunction mallocFunction = malloc);
52
56 void SetReallocFunction(vtkReallocingFunction reallocFunction = realloc);
57
64 void SetFreeFunction(bool noFreeFunction, vtkFreeingFunction deleteFunction = free);
65
69 inline vtkIdType GetSize() const { return this->Size; }
70
74 bool Allocate(vtkIdType size);
75
80 bool Reallocate(vtkIdType newsize);
81
82protected:
84 : Pointer(nullptr)
85 , Size(0)
86 {
90 }
91
92 ~vtkBuffer() override { this->SetBuffer(nullptr, 0); }
93
94 ScalarType* Pointer;
99
100private:
101 vtkBuffer(const vtkBuffer&) = delete;
102 void operator=(const vtkBuffer&) = delete;
103};
104
105template <class ScalarT>
107{
109}
110
111template <class ScalarT>
113{
114 auto mkhold = vtkMemkindRAII(true);
116}
117
118//------------------------------------------------------------------------------
119template <typename ScalarT>
121{
122 if (this->Pointer != array)
123 {
124 if (this->DeleteFunction)
125 {
126 this->DeleteFunction(this->Pointer);
127 }
128 this->Pointer = array;
129 }
130 this->Size = size;
131}
132//------------------------------------------------------------------------------
133template <typename ScalarT>
135{
136 this->MallocFunction = mallocFunction;
137}
138//------------------------------------------------------------------------------
139template <typename ScalarT>
141{
142 this->ReallocFunction = reallocFunction;
143}
144
145//------------------------------------------------------------------------------
146template <typename ScalarT>
147void vtkBuffer<ScalarT>::SetFreeFunction(bool noFreeFunction, vtkFreeingFunction deleteFunction)
148{
149 if (noFreeFunction)
150 {
151 this->DeleteFunction = nullptr;
152 }
153 else
154 {
155 this->DeleteFunction = deleteFunction;
156 }
157}
158
159//------------------------------------------------------------------------------
160template <typename ScalarT>
162{
163 // release old memory.
164 this->SetBuffer(nullptr, 0);
165 if (size > 0)
166 {
167 ScalarType* newArray;
168 if (this->MallocFunction)
169 {
170 newArray = static_cast<ScalarType*>(this->MallocFunction(size * sizeof(ScalarType)));
171 }
172 else
173 {
174 newArray = static_cast<ScalarType*>(malloc(size * sizeof(ScalarType)));
175 }
176 if (newArray)
177 {
178 this->SetBuffer(newArray, size);
179 if (!this->MallocFunction)
180 {
181 this->DeleteFunction = free;
182 }
183 return true;
184 }
185 return false;
186 }
187 return true; // size == 0
188}
189
190//------------------------------------------------------------------------------
191template <typename ScalarT>
193{
194 if (newsize == 0)
195 {
196 return this->Allocate(0);
197 }
198
199 if (this->Pointer && this->DeleteFunction != free)
200 {
201 ScalarType* newArray;
202 bool forceFreeFunction = false;
203 if (this->MallocFunction)
204 {
205 newArray = static_cast<ScalarType*>(this->MallocFunction(newsize * sizeof(ScalarType)));
206 if (this->MallocFunction == malloc)
207 {
208 // This must be done because the array passed in may have been
209 // allocated outside of the memory management of `vtkBuffer` and
210 // therefore have been registered with a `DeleteFunction` such as
211 // `delete` or `delete[]`. Since the memory is now allocated with
212 // `malloc` here, we must also reset `DeleteFunction` to something
213 // which matches.
214 forceFreeFunction = true;
215 }
216 }
217 else
218 {
219 newArray = static_cast<ScalarType*>(malloc(newsize * sizeof(ScalarType)));
220 }
221 if (!newArray)
222 {
223 return false;
224 }
225 std::copy(this->Pointer, this->Pointer + (std::min)(this->Size, newsize), newArray);
226 // now save the new array and release the old one too.
227 this->SetBuffer(newArray, newsize);
228 if (!this->MallocFunction || forceFreeFunction)
229 {
230 this->DeleteFunction = free;
231 }
232 }
233 else
234 {
235 // Try to reallocate with minimal memory usage and possibly avoid
236 // copying.
237 ScalarType* newArray = nullptr;
238 if (this->ReallocFunction)
239 {
240 newArray = static_cast<ScalarType*>(
241 this->ReallocFunction(this->Pointer, newsize * sizeof(ScalarType)));
242 }
243 else
244 {
245 newArray = static_cast<ScalarType*>(realloc(this->Pointer, newsize * sizeof(ScalarType)));
246 }
247 if (!newArray)
248 {
249 return false;
250 }
251 this->Pointer = newArray;
252 this->Size = newsize;
253 }
254 return true;
255}
256
257VTK_ABI_NAMESPACE_END
258#endif
259// VTK-HeaderTest-Exclude: vtkBuffer.h
internal storage class used by vtkSOADataArrayTemplate, vtkAOSDataArrayTemplate, and others.
Definition vtkBuffer.h:27
bool Reallocate(vtkIdType newsize)
Allocate a new buffer that holds newsize elements.
Definition vtkBuffer.h:192
ScalarType * Pointer
Definition vtkBuffer.h:94
ScalarType * GetBuffer()
Access the buffer as a scalar pointer.
Definition vtkBuffer.h:38
vtkFreeingFunction DeleteFunction
Definition vtkBuffer.h:98
vtkMallocingFunction MallocFunction
Definition vtkBuffer.h:96
const ScalarType * GetBuffer() const
Definition vtkBuffer.h:39
vtkIdType Size
Definition vtkBuffer.h:95
void SetReallocFunction(vtkReallocingFunction reallocFunction=realloc)
Set the realloc function to be used when allocating space inside this object.
Definition vtkBuffer.h:140
ScalarTypeT ScalarType
Definition vtkBuffer.h:30
static vtkBuffer< ScalarTypeT > * ExtendedNew()
Definition vtkBuffer.h:112
void SetMallocFunction(vtkMallocingFunction mallocFunction=malloc)
Set the malloc function to be used when allocating space inside this object.
Definition vtkBuffer.h:134
vtkIdType GetSize() const
Return the number of elements the current buffer can hold.
Definition vtkBuffer.h:69
~vtkBuffer() override
Definition vtkBuffer.h:92
vtkTemplateTypeMacro(vtkBuffer< ScalarTypeT >, vtkObject)
void SetFreeFunction(bool noFreeFunction, vtkFreeingFunction deleteFunction=free)
Set the free function to be used when releasing this object.
Definition vtkBuffer.h:147
vtkReallocingFunction ReallocFunction
Definition vtkBuffer.h:97
bool Allocate(vtkIdType size)
Allocate a new buffer that holds size elements.
Definition vtkBuffer.h:161
static vtkBuffer< ScalarTypeT > * New()
Definition vtkBuffer.h:106
void SetBuffer(ScalarType *array, vtkIdType size)
Set the memory buffer that this vtkBuffer object will manage.
Definition vtkBuffer.h:120
A class to help modify and restore the global UsingMemkind state, like SetUsingMemkind(newValue),...
static vtkFreeingFunction GetCurrentFreeFunction()
static vtkMallocingFunction GetCurrentMallocFunction()
static vtkReallocingFunction GetCurrentReallocFunction()
abstract base class for most VTK objects
Definition vtkObject.h:162
void *(* vtkMallocingFunction)(size_t)
void *(* vtkReallocingFunction)(void *, size_t)
void(* vtkFreeingFunction)(void *)
#define VTK_STANDARD_NEW_BODY(thisClass)
int vtkIdType
Definition vtkType.h:315