AGX Dynamics 2.42.1.1
Loading...
Searching...
No Matches
agxData/Vector.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17
18#ifndef AGXDATA_VECTOR_H
19#define AGXDATA_VECTOR_H
20
21#include <agxData/Array.h>
22#include <agxData/Buffer.h>
23
24namespace agxData
25{
26 template <typename T>
27 class Vector : public Array<T>
28 {
29 public:
30 typedef T Type;
31 typedef T value_type;
32 typedef T* pointer;
33 typedef const T* const_pointer;
34 typedef T& reference;
35 typedef const T& const_reference;
36 typedef size_t size_type;
37 typedef T* iterator;
38 typedef const T* const_iterator;
39 typedef std::random_access_iterator_tag iterator_category;
40 typedef ptrdiff_t difference_type;
41
42 public:
43 explicit Vector();
44 explicit Vector(agxData::Buffer* buffer);
45 ~Vector();
46
50 void commit();
51
55 void resize(size_t size, const T& value = T());
56
60 void reserve(size_t size);
61
65 T* increment(size_t numElements = 1, const T& value = T());
66 void decrement(size_t numElements = 1);
67
68
72 template <typename T2>
73 void push_back(const T2& value);
74
78 void pop_back();
79
80
84 iterator erase(iterator position);
86
90 void erase(size_t index);
91 void erase(size_t start, size_t end);
92
97 void eraseFast(size_t index);
98
102 void clear();
103
110 template <typename T2>
111 bool findAndErase(const T2& element, bool searchMultiple = false);
112
113 iterator insert(iterator position, const T& value);
114 void insert(size_t index, const T& value);
115
116 template <typename InputIterator>
117 void insert(iterator it, InputIterator first, InputIterator last);
118
119 private:
120 void reallocate(size_t size);
121 };
122
124
125
126
127 /* Implementation */
128
129 template <typename T>
131 {
132 }
133
134 template <typename T>
136 {
138 }
139
140 template <typename T>
142 {
143 this->commit();
144 }
145
146 template <typename T>
148 {
149 agxAssert(this->buffer());
150 size_t size = this->buffer()->size();
151 size_t oldSize = this->buffer()->sizeParameter->get();
152
153 if (oldSize != size)
154 {
155 this->buffer()->sizeParameter->updateEvent.removeCallback(&this->buffer()->m_resizeCallback);
156 this->buffer()->sizeParameter->set(size);
157 this->buffer()->sizeParameter->updateEvent.addCallbackFirst(&this->buffer()->m_resizeCallback);
158
159 this->buffer()->m_eventDispatch.triggerResizeEvent(this->buffer(), (agx::Index)size, (agx::Index)oldSize);
160 }
161 }
162
163
164 template <typename T>
165 AGX_FORCE_INLINE void Vector<T>::resize(size_t size, const T& value)
166 {
167 agxAssert(this->buffer());
168
169 if (size > this->buffer()->m_size)
170 {
171 this->increment(size - this->buffer()->m_size, value);
172 }
173 else
174 {
175 if (size < (size_t)((double)this->buffer()->m_capacity * AGX_VECTOR_SHRINK_THRESHOLD))
176 this->reallocate(size);
177
178 this->destroyElements(size, this->buffer()->m_size);
179 }
180 }
181
182 template <typename T>
184 {
185 this->buffer()->reserve(std::max((size_t)4, size));
186 this->sync();
187 }
188
189
190 template <typename T>
192 {
193 agxAssert(this->buffer());
194 this->reallocate(size);
195 }
196
197 template <typename T>
198 AGX_FORCE_INLINE T* Vector<T>::increment(size_t numElements, const T& value)
199 {
200 agxAssert(this->buffer());
201
202 size_t currentSize = this->buffer()->m_size;
203 size_t newSize = currentSize + numElements;
204 if (newSize > this->buffer()->m_capacity)
205 this->reallocate((size_t)((agx::Real)newSize * Buffer::CAPACITY_MULTIPLIER));
206
207 this->buffer()->m_size = newSize;
208 this->range().end() = newSize;
209
210 for(size_t i = currentSize; i < newSize; ++i)
211 ::new((void *)(this->ptr() + i)) T(value);
212
213 return this->ptr() + currentSize;
214 }
215
216 template <typename T>
217 AGX_FORCE_INLINE void Vector<T>::decrement(size_t numElements)
218 {
219 agxAssert(this->buffer());
220 agxAssert(this->buffer()->size() >= numElements);
221
222 size_t newSize = this->buffer()->m_size - numElements;
223 for (size_t i = newSize; i < this->buffer()->m_size; ++i)
224 this->ptr()[i].~T();
225
226 this->range().end() = newSize;
227 this->buffer()->m_size = newSize;
228 }
229
230 template <typename T> template <typename T2>
232 {
233 agxAssert(this->buffer());
234
235 if (this->buffer()->m_size == this->buffer()->m_capacity)
236 this->reallocate((size_t)((agx::Real)this->buffer()->m_size * Buffer::CAPACITY_MULTIPLIER));
237
238 this->buffer()->m_size++;
239 this->range().end()++;
240 ::new((void *)&this->back()) T(value);
241 }
242
243 template <typename T>
245 {
246 agxAssert(this->buffer());
247 agxAssert(!this->buffer()->empty());
248
249 this->back().~T();
250 this->range().end()--;
251 this->buffer()->m_size--;
252 }
253
254 template <typename T>
256 {
257 agxAssert(this->buffer());
258
259 size_t index = position - this->begin();
260 this->erase(index);
261 return this->begin() + index;
262 }
263
264 template <typename T>
266 {
267 agxAssert(this->buffer());
268
269 size_t startIndex = start - this->begin();
270 size_t endIndex = end - this->begin();
271 this->erase(startIndex, endIndex);
272
273 return this->begin() + endIndex;
274 }
275
276 template <typename T>
278 {
279 agxAssert(this->buffer());
280
281 for (size_t i = index + 1; i < this->buffer()->m_size; i++)
282 this->ptr()[i-1] = this->ptr()[i];
283
284 /* Run destructor on trailing elements */
285 this->ptr()[this->buffer()->m_size - 1].~T();
286
287 this->buffer()->m_size--;
288 }
289
290 template <typename T>
291 AGX_FORCE_INLINE void Vector<T>::erase(size_t start, size_t end)
292 {
293 agxAssert(this->buffer());
294
295 agxAssert1(start < end && end <= this->buffer()->m_size, "Erase bounds are not with array bounds!");
296 size_t numElements = end - start;
297
298 // TODO We should first run destructor and constructor on element before copying? Again we assume copy operator semantics to be 'proper'
299 for (size_t i = end; i < this->buffer()->m_size; i++)
300 this->ptr()[i-numElements] = this->ptr()[i];
301
302 /* Run destructor on trailing elements */
303 for(size_t i = this->buffer()->m_size - numElements; i < this->buffer()->m_size; ++i)
304 this->ptr()[i].~T();
305
306 this->buffer()->m_size -= numElements;
307 }
308
309 template <typename T>
311 {
312 agxAssert(this->buffer());
313
314 size_t index = position - this->begin();
315 this->eraseFast(index);
316 return this->begin() + index;
317 }
318
319 template <typename T>
321 {
322 agxAssert(this->buffer());
323 agxAssertN(index < this->buffer()->m_size, "Array index %llu is out of bounds, current size is %llu", (long long unsigned)index, (long long unsigned)this->buffer()->m_size);
324
325 this->ptr()[index] = this->ptr()[this->buffer()->m_size-1];
326 this->ptr()[this->buffer()->m_size - 1].~T();
327 this->buffer()->m_size--;
328 }
329
330 template <typename T>
332 {
333 agxAssert(this->buffer());
334 this->decrement(this->buffer()->m_size);
335 }
336
337 template <typename T> template <typename T2>
338 AGX_FORCE_INLINE bool Vector<T>::findAndErase(const T2& element, bool searchMultiple)
339 {
340 agxAssert(this->buffer());
341
342 bool found = false;
343
344 for (size_t i = 0; i < this->buffer()->m_size; i++)
345 {
346 if (this->ptr()[i] == element)
347 {
348 found = true;
349 this->erase(i);
350
351 if (!searchMultiple)
352 return true;
353
354 i--;
355 }
356 }
357
358 return found;
359 }
360
361 template <typename T>
363 {
364 agxAssert(this->buffer());
365
366 size_t index = position - this->begin();
367 this->insert(index, value);
368 return this->begin() + index;
369 }
370
371 template <typename T>
372 AGX_FORCE_INLINE void Vector<T>::insert(size_t index, const T& value)
373 {
374 agxAssert(this->buffer());
375
376 agxAssertN(index <= this->buffer()->m_size, "Insert with invalid index %llu, size is %llu", (long long unsigned)index, (long long unsigned)this->buffer()->m_size);
377
378 if (this->buffer()->m_size == this->buffer()->m_capacity)
379 this->reallocate((size_t)((agx::Real)this->buffer()->m_size * Buffer::CAPACITY_MULTIPLIER));
380
381 for (size_t i = this->buffer()->m_size; i > index; i--) {
382 ::new((void *)&this->ptr()[i]) T(this->ptr()[i-1]);
383 this->ptr()[i-1].~T();
384 }
385
386 ::new((void *)&this->ptr()[index]) T(value);
387 this->buffer()->m_size++;
388 }
389
390 template <typename T> template <typename InputIterator>
391 AGX_FORCE_INLINE void Vector<T>::insert(iterator it, InputIterator first, InputIterator last)
392 {
393 agxAssert(this->buffer());
394
395 size_t numElements = std::distance( first, last );
396
397 if (numElements == 0)
398 return;
399
400 size_t index = it - this->begin();
401
402 if (this->buffer()->m_size + numElements > this->buffer()->m_capacity)
403 this->reallocate((size_t)((agx::Real)(this->buffer()->m_size + numElements) * Buffer::CAPACITY_MULTIPLIER));
404
405 for (size_t i = this->buffer()->m_size; i > index; i--) {
406 ::new((void *)&this->ptr()[i + numElements - 1]) T(this->ptr()[i-1]);
407 this->ptr()[i-1].~T();
408 }
409
410 for (; first != last; first++)
411 ::new((void *)&this->ptr()[index++]) T(*first);
412
413 this->buffer()->m_size += numElements;
414 }
415}
416
418
419#endif /* AGXDATA_VECTOR_H */
#define AGX_TEMPLATED_TYPE_BINDING(_Type, _Name)
Definition: Type.h:192
#define m_size
Definition: agx/Vector.h:429
#define m_capacity
Definition: agx/Vector.h:430
#define AGX_VECTOR_SHRINK_THRESHOLD
Definition: agx/Vector.h:425
const agxData::Buffer * buffer() const
Definition: Buffer.h:720
size_t size() const
Definition: Buffer.h:708
Type-specific Array used for fast access into the data held by a Buffer.
Definition: Array.h:107
iterator end()
Definition: Buffer.h:894
Abstract representation of a data buffer.
Definition: Buffer.h:56
agxData::EntityStorage * getStorage()
Definition: Buffer.h:468
static agx::Real CAPACITY_MULTIPLIER
Definition: Buffer.h:65
std::random_access_iterator_tag iterator_category
iterator erase(iterator position)
STL erase functionality.
void resize(size_t size, const T &value=T())
Resize the vector, which then enables direct addressing using the bracket '[]' operator.
void push_back(const T2 &value)
Append a new data element to the vector.
iterator eraseFast(const_iterator position)
Fast erase, replacing the erased element with the last element.
T * increment(size_t numElements=1, const T &value=T())
Resize using a increment.
ptrdiff_t difference_type
void clear()
Remove all elements, optionally with maintained buffer allocation.
bool findAndErase(const T2 &element, bool searchMultiple=false)
Find and erase an element.
void pop_back()
Remove the back element.
const T * const_pointer
void reserve(size_t size)
Reserve capacity in the vector.
const T & const_reference
iterator insert(iterator position, const T &value)
void commit()
Commit all changes.
const T * const_iterator
void decrement(size_t numElements=1)
#define agxAssert1(expr, msg)
Definition: debug.h:144
#define agxVerify(expr)
Definition: debug.h:131
#define agxAssertN(expr, format,...)
Definition: debug.h:145
#define agxAssert(expr)
Definition: debug.h:143
#define AGX_FORCE_INLINE
Definition: macros.h:58
Contains classes for low level data storage for AGX.
Definition: Container.h:23
Vector< agx::UInt32 > GenericVector
double Real
Definition: Real.h:41
UInt32 Index
Definition: Integer.h:44