Ocean
Loading...
Searching...
No Matches
StackHeapVector.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_STACK_HEAP_VECTOR_H
9#define META_OCEAN_BASE_STACK_HEAP_VECTOR_H
10
11#include "ocean/base/Base.h"
13
14namespace Ocean
15{
16
17/**
18 * Vector like data structure combining stack and heap memory.
19 * This class implements a vector-like data structure which stores the first `tStackCapacity` elements on the stack, and any additional elements on the heap.<br>
20 * This approach can optimize performance and memory usage when the number of elements is often within the `tStackCapacity` but can occasionally exceed it.
21 * @tparam T Data type of the elements that will be stored
22 * @tparam tStackCapacity Number of elements that can be stored on the stack, with range [1, infinity)
23 * @ingroup base
24 */
25template <typename T, size_t tStackCapacity>
27{
28 static_assert(tStackCapacity >= 1, "Invalid stack capacity!");
29
30 public:
31
32 /**
33 * Definition of an iterator allowing to iterate through the vector.
34 * The iterator allows to modified the element to which the iterator is pointing.
35 */
37 {
38 friend class StackHeapVector;
39
40 public:
41
42 /**
43 * (Pre-) increments this iterator.
44 * @return Reference to the incremented iterator
45 */
46 Iterator& operator++();
47
48 /**
49 * (Post-) increments this iterator.
50 * @return The current (not yet) incremented iterator.
51 */
52 Iterator operator++(int);
53
54 /**
55 * De-references the iterator and provides access to the underlying element in the vector.
56 * @return The vector element to which this iterator points
57 */
59
60 /**
61 * Compares two iterators and returns whether both iterators point to the same vector element.
62 * @return True, if so
63 */
64 bool operator==(const Iterator& iterator) const;
65
66 /**
67 * Compares two iterators and returns whether both iterators do not point to the same vector element.
68 * @return True, if so
69 */
70 bool operator!=(const Iterator& iterator) const;
71
72 protected:
73
74 /**
75 * Creates a new iterator pointing to a specified elements in the vector.
76 * @param vector The vector owning this iterator
77 * @param index The index of the element to which the iterator points
78 */
79 Iterator(StackHeapVector& vector, const size_t index);
80
81 protected:
82
83 /// The vector owning this iterator.
85
86 /// The index of the element within the vector to which the iterator points.
87 size_t index_ = size_t(-1);
88 };
89
90 /**
91 * Definition of an iterator allowing to iterate through the vector.
92 * The iterator does ont allow to modified the element to which the iterator is pointing.
93 */
95 {
96 friend class StackHeapVector;
97
98 public:
99
100 /**
101 * (Pre-) increments this iterator.
102 * @return Reference to the incremented iterator
103 */
104 ConstIterator& operator++();
105
106 /**
107 * (Post-) increments this iterator.
108 * @return The current (not yet) incremented iterator.
109 */
110 ConstIterator operator++(int);
111
112 /**
113 * De-references the iterator and provides access to the underlying element in the vector.
114 * @return The vector element to which this iterator points
115 */
116 const T& operator*() const;
117
118 /**
119 * Compares two iterators and returns whether both iterators point to the same vector element.
120 * @return True, if so
121 */
122 bool operator==(const ConstIterator& iterator) const;
123
124 /**
125 * Compares two iterators and returns whether both iterators do not point to the same vector element.
126 * @return True, if so
127 */
128 bool operator!=(const ConstIterator& iterator) const;
129
130 protected:
131
132 /**
133 * Creates a new iterator pointing to a specified elements in the vector.
134 * @param vector The vector owning this iterator
135 * @param index The index of the element to which the iterator points
136 */
137 ConstIterator(const StackHeapVector& vector, const size_t index);
138
139 protected:
140
141 /// The vector owning this iterator.
143
144 /// The index of the element within the vector to which the iterator points.
145 size_t index_ = size_t(-1);
146 };
147
148 public:
149
150 /**
151 * Creates a new vector object.
152 */
154
155 /**
156 * Creates a new vector object.
157 * @param size The number of elements to be created
158 * @param element The value that will be created in the first 'number' elements of this vector
159 */
160 StackHeapVector(const size_t size, const T& element);
161
162 /**
163 * Pushes a new element to the end of this vector.
164 * @param element The new element to be pushed
165 */
166 void pushBack(T&& element);
167
168 /**
169 * Pushes a new element to the end of this vector.
170 * @param element The new element to be pushed
171 */
172 void pushBack(const T& element);
173
174 /**
175 * Emplaces a new element to the end of this vector.
176 * @param args The arguments of the new element
177 * @tparam TArgs The data types of the arguments
178 */
179 template <typename... TArgs>
180 T& emplaceBack(TArgs&&... args);
181
182 /**
183 * Removed the last elements from the vector.
184 * The vector must not be empty.
185 */
186 void popBack();
187
188 /**
189 * Resizes the vector.
190 * @param size The new size of the vector
191 */
192 void resize(const size_t size);
193
194 /**
195 * Replaces the content of the vector with 'size' copies of the provided element.
196 * @param size The new size of the vector, with range [0, infinity)
197 * @param element The element which will be copied into all places of the resized vector
198 */
199 void assign(const size_t size, const T& element);
200
201 /**
202 * Returns the number of elements of this vector.
203 * @return The vector's number of elements, with range [0, infinity)
204 */
205 inline size_t size() const;
206
207 /**
208 * Returns the overall capacity of this vector (including the capacity on the stack and on the heap).
209 * @return The vector's capacity, with range [size(), infinity)
210 */
211 inline size_t capacity() const;
212
213 /**
214 * Returns whether this vector is empty.
215 * @return True, if so
216 */
217 inline bool isEmpty() const;
218
219 /**
220 * Clears this vector.
221 * All stack elements will be overwritten with default values.
222 */
223 void clear();
224
225 /**
226 * Sets the capacity of this vector to a specified number of elements.
227 * In case the specified capacity is smaller than the current capacity or is smaller than the number of elements in this vector, nothing happens.
228 * @param capacity The capacity to set, with range [0, infinity)
229 */
230 void setCapacity(const size_t capacity);
231
232 /**
233 * Returns the first element of this vector.
234 * Ensure that the vector is not empty before calling this function.
235 * @return The vector's first element
236 */
237 const T& front() const;
238
239 /**
240 * Returns the first element of this vector.
241 * Ensure that the vector is not empty before calling this function.
242 * @return The vector's first element
243 */
244 T& front();
245
246 /**
247 * Returns the last element of this vector.
248 * Ensure that the vector is not empty before calling this function.
249 * @return The vector's last element
250 */
251 const T& back() const;
252
253 /**
254 * Returns the last element of this vector.
255 * Ensure that the vector is not empty before calling this function.
256 * @return The vector's last element
257 */
258 T& back();
259
260 /**
261 * Returns an iterator to the first element in this vector.
262 * @return The vector's iterator to the first element
263 */
264 Iterator begin();
265
266 /**
267 * Returns an iterator to the element following the last element in this vector.
268 * @return The vector's iterator to the element following the last element
269 */
270 Iterator end();
271
272 /**
273 * Returns a const iterator to the first element in this vector.
274 * @return The vector's iterator to the first element
275 */
276 ConstIterator begin() const;
277
278 /**
279 * Returns an iterator to the element following the last element in this vector.
280 * @return The vector's iterator to the element following the last element
281 */
282 ConstIterator end() const;
283
284 /**
285 * Elements access operator.
286 * @param index The index of the element to access, with range [0, size() - 1]
287 * @return The element with specified index
288 */
289 inline const T& operator[](const size_t index) const;
290
291 /**
292 * Elements access operator.
293 * @param index The index of the element to access, with range [0, size() - 1]
294 * @return The element with specified index
295 */
296 inline T& operator[](const size_t index);
297
298 protected:
299
300 /// The elements located on the stack.
301 T stackElements_[tStackCapacity];
302
303 /// The remaining elements located on the heap.
304 std::vector<T> heapElements_;
305
306 /// The number of elements in this vector.
307 size_t size_ = 0;
308};
309
310template <typename T, size_t tStackCapacity>
312 vector_(vector),
313 index_(index)
314{
315 ocean_assert(index <= vector_.size_);
316}
317
318template <typename T, size_t tStackCapacity>
325
326template <typename T, size_t tStackCapacity>
328{
329 Iterator iterator(*this);
330
331 ++index_;
332
333 return iterator;
334}
335
336template <typename T, size_t tStackCapacity>
338{
339 return vector_[index_];
340}
341
342template <typename T, size_t tStackCapacity>
344{
345 ocean_assert(&vector_ == &iterator.vector_);
346
347 return &vector_ == &iterator.vector_ && index_ == iterator.index_;
348}
349
350template <typename T, size_t tStackCapacity>
352{
353 return !(*this == iterator);
354}
355
356template <typename T, size_t tStackCapacity>
358 vector_(vector),
359 index_(index)
360{
361 ocean_assert(index <= vector_.size_);
362}
363
364template <typename T, size_t tStackCapacity>
371
372template <typename T, size_t tStackCapacity>
374{
375 Iterator iterator(*this);
376
377 ++index_;
378
379 return iterator;
380}
381
382template <typename T, size_t tStackCapacity>
384{
385 return vector_[index_];
386}
387
388template <typename T, size_t tStackCapacity>
390{
391 ocean_assert(&vector_ == &iterator.vector_);
392
393 return &vector_ == &iterator.vector_ && index_ == iterator.index_;
394}
395
396template <typename T, size_t tStackCapacity>
398{
399 return !(*this == iterator);
400}
401
402template <typename T, size_t tStackCapacity>
404{
405 // nothing to do here
406}
407
408template <typename T, size_t tStackCapacity>
410{
412
413 for (size_t n = 0; n < size; ++n)
414 {
415 pushBack(element);
416 }
417}
418
419template <typename T, size_t tStackCapacity>
421{
422 if (size_ < tStackCapacity)
423 {
424 stackElements_[size_] = std::move(element);
425 }
426 else
427 {
428 heapElements_.emplace_back(std::move(element));
429 }
430
431 ++size_;
432}
433
434template <typename T, size_t tStackCapacity>
436{
437 if (size_ < tStackCapacity)
438 {
439 stackElements_[size_] = element;
440 }
441 else
442 {
443 heapElements_.push_back(element);
444 }
445
446 ++size_;
447}
448
449template <typename T, size_t tStackCapacity>
450template <typename... TArgs>
452{
453 const size_t index = size_;
454
455 ++size_;
456
457 if (index < tStackCapacity)
458 {
459 stackElements_[index] = T(std::forward<TArgs>(args)...);
460
461 return stackElements_[index];
462 }
463 else
464 {
465 return heapElements_.emplace_back(std::forward<TArgs>(args)...);
466 }
467}
468
469template <typename T, size_t tStackCapacity>
471{
472 ocean_assert(size_ >= 1);
473
474 --size_;
475
476 if (size_ >= tStackCapacity)
477 {
478 heapElements_.pop_back();
479 }
480 else
481 {
482 stackElements_[size_] = T();
483 }
484}
485
486template <typename T, size_t tStackCapacity>
488{
489 if (size == size_)
490 {
491 return;
492 }
493
494 if (size < size_)
495 {
496 // we have to remove elements
497
498 for (size_t n = size; n < tStackCapacity; ++n) // in case size >= tStackCapacity, nothing happens
499 {
500 stackElements_[n] = T();
501 }
502
503 if (size_ > tStackCapacity)
504 {
505 if (size < tStackCapacity)
506 {
507 heapElements_.clear();
508 }
509 else
510 {
511 heapElements_.resize(size - tStackCapacity);
512 }
513 }
514 }
515 else
516 {
517 ocean_assert(size > size_);
518
519 if (size > tStackCapacity)
520 {
521 heapElements_.resize(size - tStackCapacity);
522 }
523 }
524
525 size_ = size;
526}
527
528template <typename T, size_t tStackCapacity>
529void StackHeapVector<T, tStackCapacity>::assign(const size_t size, const T& element)
530{
531 for (size_t n = 0; n < std::min(size, tStackCapacity); ++n) // we assign as many elements in the stack
532 {
533 stackElements_[n] = element;
534 }
535
536 for (size_t n = size; n < std::min(tStackCapacity, size_); ++n) // if necessary (if the new size is smaller than the previous size), we overwrite stack elements with default values
537 {
538 stackElements_[n] = T();
539 }
540
541 if (size < tStackCapacity)
542 {
543 heapElements_.clear();
544 }
545 else
546 {
547 const size_t newHeapSize = size - tStackCapacity;
548
549 heapElements_.assign(newHeapSize, element);
550 }
551
552 size_ = size;
553}
554
555template <typename T, size_t tStackCapacity>
557{
558 ocean_assert(size_ <= tStackCapacity || size_ == tStackCapacity + heapElements_.size());
559
560 return size_;
561}
562
563template <typename T, size_t tStackCapacity>
565{
566 return tStackCapacity + heapElements_.capacity();
567}
568
569template <typename T, size_t tStackCapacity>
571{
572 return size() == 0;
573}
574
575template <typename T, size_t tStackCapacity>
577{
578 for (size_t nStack = 0; nStack < std::min(size_, tStackCapacity); ++nStack)
579 {
580 stackElements_[nStack] = T();
581 }
582
583 heapElements_.clear();
584
585 size_ = 0;
586}
587
588template <typename T, size_t tStackCapacity>
590{
591 if (capacity > size_)
592 {
593 if (capacity > tStackCapacity)
594 {
595 heapElements_.reserve(capacity - tStackCapacity);
596 }
597 }
598}
599
600template <typename T, size_t tStackCapacity>
602{
603 ocean_assert(!isEmpty());
604
605 return stackElements_[0];
606}
607
608template <typename T, size_t tStackCapacity>
610{
611 ocean_assert(!isEmpty());
612
613 return stackElements_[0];
614}
615
616template <typename T, size_t tStackCapacity>
618{
619 ocean_assert(!isEmpty());
620
621 if (size_ <= tStackCapacity)
622 {
623 return stackElements_[size_ - 1];
624 }
625 else
626 {
627 return heapElements_.back();
628 }
629}
630
631template <typename T, size_t tStackCapacity>
633{
634 ocean_assert(!isEmpty());
635
636 if (size_ <= tStackCapacity)
637 {
638 return stackElements_[size_ - 1];
639 }
640 else
641 {
642 return heapElements_.back();
643 }
644}
645
646template <typename T, size_t tStackCapacity>
651
652template <typename T, size_t tStackCapacity>
657
658template <typename T, size_t tStackCapacity>
663
664template <typename T, size_t tStackCapacity>
669
670template <typename T, size_t tStackCapacity>
671inline const T& StackHeapVector<T, tStackCapacity>::operator[](const size_t index) const
672{
673 ocean_assert(index < size());
674
675 if (index < tStackCapacity)
676 {
677 return stackElements_[index];
678 }
679
680 return heapElements_[index - tStackCapacity];
681}
682
683template <typename T, size_t tStackCapacity>
685{
686 ocean_assert(index < size());
687
688 if (index < tStackCapacity)
689 {
690 return stackElements_[index];
691 }
692
693 return heapElements_[index - tStackCapacity];
694}
695
696}
697
698#endif // META_OCEAN_BASE_STACK_HEAP_VECTOR_H
Definition of an iterator allowing to iterate through the vector.
Definition StackHeapVector.h:95
const StackHeapVector & vector_
The vector owning this iterator.
Definition StackHeapVector.h:142
ConstIterator(const StackHeapVector &vector, const size_t index)
Creates a new iterator pointing to a specified elements in the vector.
Definition StackHeapVector.h:357
bool operator==(const ConstIterator &iterator) const
Compares two iterators and returns whether both iterators point to the same vector element.
Definition StackHeapVector.h:389
size_t index_
The index of the element within the vector to which the iterator points.
Definition StackHeapVector.h:145
bool operator!=(const ConstIterator &iterator) const
Compares two iterators and returns whether both iterators do not point to the same vector element.
Definition StackHeapVector.h:397
const T & operator*() const
De-references the iterator and provides access to the underlying element in the vector.
Definition StackHeapVector.h:383
ConstIterator & operator++()
(Pre-) increments this iterator.
Definition StackHeapVector.h:365
Definition of an iterator allowing to iterate through the vector.
Definition StackHeapVector.h:37
size_t index_
The index of the element within the vector to which the iterator points.
Definition StackHeapVector.h:87
bool operator==(const Iterator &iterator) const
Compares two iterators and returns whether both iterators point to the same vector element.
Definition StackHeapVector.h:343
bool operator!=(const Iterator &iterator) const
Compares two iterators and returns whether both iterators do not point to the same vector element.
Definition StackHeapVector.h:351
Iterator(StackHeapVector &vector, const size_t index)
Creates a new iterator pointing to a specified elements in the vector.
Definition StackHeapVector.h:311
StackHeapVector & vector_
The vector owning this iterator.
Definition StackHeapVector.h:84
T & operator*()
De-references the iterator and provides access to the underlying element in the vector.
Definition StackHeapVector.h:337
Iterator & operator++()
(Pre-) increments this iterator.
Definition StackHeapVector.h:319
Vector like data structure combining stack and heap memory.
Definition StackHeapVector.h:27
size_t size_
The number of elements in this vector.
Definition StackHeapVector.h:307
StackHeapVector(const size_t size, const T &element)
Creates a new vector object.
Definition StackHeapVector.h:409
Iterator begin()
Returns an iterator to the first element in this vector.
Definition StackHeapVector.h:647
void setCapacity(const size_t capacity)
Sets the capacity of this vector to a specified number of elements.
Definition StackHeapVector.h:589
std::vector< T > heapElements_
The remaining elements located on the heap.
Definition StackHeapVector.h:304
StackHeapVector()
Creates a new vector object.
Definition StackHeapVector.h:403
const T & operator[](const size_t index) const
Elements access operator.
Definition StackHeapVector.h:671
T stackElements_[tStackCapacity]
The elements located on the stack.
Definition StackHeapVector.h:301
void assign(const size_t size, const T &element)
Replaces the content of the vector with 'size' copies of the provided element.
Definition StackHeapVector.h:529
const T & back() const
Returns the last element of this vector.
Definition StackHeapVector.h:617
T & emplaceBack(TArgs &&... args)
Emplaces a new element to the end of this vector.
Definition StackHeapVector.h:451
Iterator end()
Returns an iterator to the element following the last element in this vector.
Definition StackHeapVector.h:653
size_t capacity() const
Returns the overall capacity of this vector (including the capacity on the stack and on the heap).
Definition StackHeapVector.h:564
const T & front() const
Returns the first element of this vector.
Definition StackHeapVector.h:601
void pushBack(T &&element)
Pushes a new element to the end of this vector.
Definition StackHeapVector.h:420
void resize(const size_t size)
Resizes the vector.
Definition StackHeapVector.h:487
ConstIterator begin() const
Returns a const iterator to the first element in this vector.
Definition StackHeapVector.h:659
T & operator[](const size_t index)
Elements access operator.
Definition StackHeapVector.h:684
void clear()
Clears this vector.
Definition StackHeapVector.h:576
T & back()
Returns the last element of this vector.
Definition StackHeapVector.h:632
T & front()
Returns the first element of this vector.
Definition StackHeapVector.h:609
ConstIterator end() const
Returns an iterator to the element following the last element in this vector.
Definition StackHeapVector.h:665
void pushBack(const T &element)
Pushes a new element to the end of this vector.
Definition StackHeapVector.h:435
bool isEmpty() const
Returns whether this vector is empty.
Definition StackHeapVector.h:570
void popBack()
Removed the last elements from the vector.
Definition StackHeapVector.h:470
size_t size() const
Returns the number of elements of this vector.
Definition StackHeapVector.h:556
The namespace covering the entire Ocean framework.
Definition Accessor.h:15