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