Ocean
StaticVector.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_STATIC_VECTOR_H
9 #define META_OCEAN_BASE_STATIC_VECTOR_H
10 
11 #include "ocean/base/Base.h"
13 
14 namespace Ocean
15 {
16 
17 /**
18  * This class implements a static vector that has a fixed capacity.
19  * @tparam T Data type of the elements that will be stored
20  * @tparam tCapacity Number of elements that can be stored, with range [1, infinity)
21  * @ingroup base
22  */
23 template <typename T, size_t tCapacity>
24 class StaticVector : public StaticBuffer<T, tCapacity>
25 {
26  public:
27 
28  /**
29  * Creates a new vector object.
30  */
31  StaticVector() = default;
32 
33  /**
34  * Creates a new vector object.
35  * @param value The value that will be set as first element
36  */
37  explicit inline StaticVector(const T& value);
38 
39  /**
40  * Creates a new vector object.
41  * @param value The value that will be set as first element
42  */
43  explicit inline StaticVector(T&& value);
44 
45  /**
46  * Creates a new vector object.
47  * @param number The number of elements to be created
48  * @param value The value that will be created in the first 'number' elements of this vector
49  */
50  inline StaticVector(const size_t number, const T& value);
51 
52  /**
53  * Creates a new vector object.
54  * @param values The values to be copied into this vector object, can be nullptr if 'size == 0'
55  * @param size The number of values to copy, with range [0, tCapacity]
56  */
57  inline StaticVector(const T* values, const size_t size);
58 
59  /**
60  * Creates a new vector object.
61  * This constructor converts a stl vector object to a static vector object.<br>
62  * Only the first tCapacity elements of the given vector are copied.
63  * @param values The values that will be used as first elements
64  */
65  explicit inline StaticVector(const std::vector<T>& values);
66 
67  /**
68  * Creates a new vector object.
69  * This constructor converts a stl vector object to a static vector object.<br>
70  * Only the first tCapacity elements of the given vector are copied.
71  * @param values The values that will be used as first elements
72  */
73  explicit inline StaticVector(std::vector<T>&& values);
74 
75  /**
76  * Returns the size of this vector.
77  * @return Vector size
78  */
79  inline size_t size() const;
80 
81  /**
82  * Returns whether no free space is left.
83  * @return True, if capacity() - size() == 0
84  */
85  inline bool occupied() const;
86 
87  /**
88  * Adds a new element to this vector.
89  * Beware: No range check is applied.
90  * @param value The value to be added
91  * @see securePushBack().
92  */
93  inline void pushBack(const T& value);
94 
95  /**
96  * Adds a new element to this vector.
97  * Beware: No range check is applied.
98  * @param value The value to be added
99  * @see securePushBack().
100  */
101  inline void pushBack(T&& value);
102 
103  /**
104  * Adds a new element to this vector if this vector has free elements left, otherwise nothing happens
105  * @param value The value to be added
106  * @return True, if succeeded
107  * @see pushBack().
108  */
109  inline bool securePushBack(const T& value);
110 
111  /**
112  * Adds a new element to this vector if this vector has free elements left, otherwise nothing happens
113  * @param value The value to be added
114  * @return True, if succeeded
115  * @see pushBack().
116  */
117  inline bool securePushBack(T&& value);
118 
119  /**
120  * Adds a new elements to this vector.
121  * This function avoids a memory overflow.<br>
122  * @param value Values to be added
123  * @tparam tCapacity2 Capacity of the second vector
124  */
125  template <size_t tCapacity2>
126  inline void pushBack(const StaticVector<T, tCapacity2>& value);
127 
128  /**
129  * Adds a new elements to this vector.
130  * This function avoids a memory overflow.<br>
131  * @param value Values to be added
132  */
133  inline void pushBack(const std::vector<T>& value);
134 
135  /**
136  * Removes the last element from this vector.
137  * Beware: No range check is applied.
138  * Thus: Check that this vector holds at least one element!<br>
139  * @see weakPopBack(), pushBack().
140  */
141  inline void popBack();
142 
143  /**
144  * Removes the last element from this vector.
145  * If this vector holds no element, nothing is happen.<br>
146  * @see weakPopBack(), pushBack().
147  */
148  inline void securePopBack();
149 
150  /**
151  * Removes the last element from this vector.
152  * This function simply decreases the element counter, the last element is untouched.<br>
153  * Beware: No range check is applied.
154  * Thus: Check that this vector holds at least one element!<br>
155  * @see popBack().
156  */
157  inline void weakPopBack();
158 
159  /**
160  * Removes the last element from this vector.
161  * This function simply decreases the element counter, the last element is untouched.<br>
162  * If this vector holds no element, nothing is happen.<br>
163  * @see popBack().
164  */
165  inline void secureWeakPopBack();
166 
167  /**
168  * Erases one element of this vector.
169  * @param index The index of the element that will be removed, with range [0, size())
170  * @see unstableErase().
171  */
172  inline void erase(const size_t index);
173 
174  /**
175  * Erases one element from this vector.
176  * The free element is replace by the last element in the vector, thus the previous order of the elements inside this vector is lost.<br>
177  * This erase function is faster than the standard erase function.
178  * @param index The index of the element that will be removed, with range [0, size())
179  * @see erase().
180  */
181  inline void unstableErase(const size_t index);
182 
183  /**
184  * Resizes this vector.
185  * @param size The size to be applied, with range [0, tCapacity]
186  * @see weakResize().
187  */
188  inline void resize(const size_t size);
189 
190  /**
191  * Resizes this vector.
192  * This function simply sets the element counter.<br>
193  * @param size The size to be applied, with range [0, tCapacity]
194  * @see resize().
195  */
196  inline void weakResize(const size_t size);
197 
198  /**
199  * Clears all elements of this vector.
200  * @see weakClear().
201  */
202  inline void clear();
203 
204  /**
205  * Clears all elements of this vector by setting the internal index to zero (all stored elements are untouched).
206  * @see clear().
207  */
208  inline void weakClear();
209 
210  /**
211  * Returns the first elements of this vector.
212  * @return First element
213  */
214  inline const T& front() const;
215 
216  /**
217  * Returns the first elements of this vector.
218  * @return First element
219  */
220  inline T& front();
221 
222  /**
223  * Returns the last elements of this vector.
224  * @return Last element
225  */
226  inline const T& back() const;
227 
228  /**
229  * Returns the last elements of this vector.
230  * @return Last element
231  */
232  inline T& back();
233 
234  /**
235  * Returns whether this vector hold no element.
236  * @return True, if so
237  */
238  inline bool empty() const;
239 
240  /**
241  * Returns one element of this vector.
242  * Beware: No range check is done.
243  * @param index The index of the element that will be returned, with range [0, size())
244  * @return Vector element
245  */
246  inline const T& operator[](const size_t index) const;
247 
248  /**
249  * Returns one element of this vector.
250  * Beware: No range check is done.
251  * @param index The index of the element that will be returned, with range [0, size())
252  * @return Vector element
253  */
254  inline T& operator[](const size_t index);
255 
256  /**
257  * Returns whether two vectors are identical.
258  * @param second The second vector object
259  * @return True, if so
260  */
261  inline bool operator==(const StaticVector<T, tCapacity>& second) const;
262 
263  /**
264  * Returns whether two vectors are not identical.
265  * @param second The second vector object
266  * @return True, if so
267  */
268  inline bool operator!=(const StaticVector<T, tCapacity>& second) const;
269 
270  /**
271  * Returns whether this vector holds at least one element.
272  * @return True, if so
273  */
274  explicit inline operator bool() const;
275 
276  protected:
277 
278  /// The current number of stored elements, with range [0, tCapacity]
279  size_t size_ = 0;
280 };
281 
282 template <typename T, size_t tCapacity>
284  StaticBuffer<T, tCapacity>(value),
285  size_(1)
286 {
287  static_assert(tCapacity > 0, "Invalid vector capacity!");
288 }
289 
290 template <typename T, size_t tCapacity>
292  StaticBuffer<T, tCapacity>(std::move(value)),
293  size_(1)
294 {
295  static_assert(tCapacity > 0, "Invalid vector capacity!");
296 }
297 
298 template <typename T, size_t tCapacity>
299 inline StaticVector<T, tCapacity>::StaticVector(const size_t number, const T& value) :
300  StaticBuffer<T, tCapacity>(number, value),
301  size_(number)
302 {
303  static_assert(tCapacity > 0, "Invalid vector capacity!");
304 
305  ocean_assert(number <= tCapacity);
306 }
307 
308 template <typename T, size_t tCapacity>
309 inline StaticVector<T, tCapacity>::StaticVector(const T* values, const size_t size)
310 {
311  static_assert(tCapacity > 0, "Invalid vector capacity!");
312 
313  ocean_assert(size <= tCapacity);
314 
315  for (size_t n = 0; n < std::min(size, tCapacity); ++n)
316  {
317  this->elements_[n] = values[n];
318  }
319 
320  size_ = size;
321 }
322 
323 template <typename T, size_t tCapacity>
324 inline StaticVector<T, tCapacity>::StaticVector(const std::vector<T>& values) :
325  StaticBuffer<T, tCapacity>(values),
326  size_(min(tCapacity, values.size()))
327 {
328  static_assert(tCapacity > 0, "Invalid vector capacity!");
329 }
330 
331 template <typename T, size_t tCapacity>
332 inline StaticVector<T, tCapacity>::StaticVector(std::vector<T>&& values) :
333  StaticBuffer<T, tCapacity>(std::move(values)),
334  size_(min(tCapacity, values.size()))
335 {
336  static_assert(tCapacity > 0, "Invalid vector capacity!");
337 }
338 
339 template <typename T, size_t tCapacity>
340 inline size_t StaticVector<T, tCapacity>::size() const
341 {
342  return size_;
343 }
344 
345 template <typename T, size_t tCapacity>
347 {
348  return size_ == tCapacity;
349 }
350 
351 template <typename T, size_t tCapacity>
352 inline void StaticVector<T, tCapacity>::pushBack(const T& value)
353 {
354  ocean_assert(size_ < tCapacity);
355 
356  this->elements_[size_++] = value;
357 }
358 
359 template <typename T, size_t tCapacity>
361 {
362  ocean_assert(size_ < tCapacity);
363 
364  this->elements_[size_++] = std::move(value);
365 }
366 
367 template <typename T, size_t tCapacity>
369 {
370  if (size_ >= tCapacity)
371  {
372  return false;
373  }
374 
375  this->elements_[size_++] = value;
376 
377  return true;
378 }
379 
380 template <typename T, size_t tCapacity>
382 {
383  if (size_ >= tCapacity)
384  {
385  return false;
386  }
387 
388  this->elements_[size_++] = std::move(value);
389 
390  return true;
391 }
392 
393 template <typename T, size_t tCapacity>
394 template <size_t tCapacity2>
396 {
397  size_t elements = min(value.size(), tCapacity - size_);
398 
399  for (size_t n = 0; n < elements; ++n)
400  {
401  this->elements_[n + size_] = value.elements_[n];
402  }
403 
404  size_ += elements;
405 }
406 
407 template <typename T, size_t tCapacity>
408 inline void StaticVector<T, tCapacity>::pushBack(const std::vector<T>& value)
409 {
410  size_t elements = min(value.size(), tCapacity - size_);
411 
412  for (size_t n = 0; n < elements; ++n)
413  {
414  this->elements_[n + size_] = value.elements_[n];
415  }
416 
417  size_ += elements;
418 }
419 
420 template <typename T, size_t tCapacity>
422 {
423  ocean_assert(size_ > 0);
424 
425  this->elements_[--size_] = T();
426 }
427 
428 template <typename T, size_t tCapacity>
430 {
431  if (size_ > 0)
432  {
433  this->elements_[--size_] = T();
434  }
435 }
436 
437 template <typename T, size_t tCapacity>
439 {
440  ocean_assert(size_ > 0);
441 
442  --size_;
443 }
444 
445 template <typename T, size_t tCapacity>
447 {
448  if (size_ > 0)
449  {
450  --size_;
451  }
452 }
453 
454 template <typename T, size_t tCapacity>
455 inline const T& StaticVector<T, tCapacity>::front() const
456 {
457  ocean_assert(!empty());
458 
459  return this->elements_[0];
460 }
461 
462 template <typename T, size_t tCapacity>
464 {
465  ocean_assert(!empty());
466 
467  return this->elements_[0];
468 }
469 
470 template <typename T, size_t tCapacity>
471 inline const T& StaticVector<T, tCapacity>::back() const
472 {
473  ocean_assert(!empty());
474 
475  return this->elements_[size_ - 1];
476 }
477 
478 template <typename T, size_t tCapacity>
480 {
481  ocean_assert(!empty());
482 
483  return this->elements_[size_ - 1];
484 }
485 
486 template <typename T, size_t tCapacity>
488 {
489  return size_ == 0;
490 }
491 
492 template <typename T, size_t tCapacity>
493 inline void StaticVector<T, tCapacity>::erase(const size_t index)
494 {
495  ocean_assert(index < size_);
496 
497  for (size_t n = index + 1; n < size_; ++n)
498  {
499  this->elements_[n - 1] = std::move(this->elements_[n]);
500  }
501 
502  this->elements_[--size_] = T();
503 }
504 
505 template <typename T, size_t tCapacity>
506 inline void StaticVector<T, tCapacity>::unstableErase(const size_t index)
507 {
508  ocean_assert(index < size_);
509 
510  --size_;
511 
512  if (index < size_)
513  {
514  this->elements_[index] = std::move(this->elements_[size_]);
515  }
516 
517  this->elements_[size_] = T();
518 }
519 
520 template <typename T, size_t tCapacity>
521 inline void StaticVector<T, tCapacity>::resize(const size_t size)
522 {
523  ocean_assert(size <= tCapacity);
524 
525  for (size_t n = size; n < size_; ++n)
526  {
527  this->elements_[n] = T();
528  }
529 
530  size_ = size;
531 }
532 
533 template <typename T, size_t tCapacity>
534 inline void StaticVector<T, tCapacity>::weakResize(const size_t size)
535 {
536  ocean_assert(size <= tCapacity);
537 
538  size_ = size;
539 }
540 
541 template <typename T, size_t tCapacity>
543 {
544  for (size_t n = 0; n < size_; ++n)
545  {
546  this->elements_[n] = T();
547  }
548 
549  size_ = 0;
550 }
551 
552 template <typename T, size_t tCapacity>
554 {
555  size_ = 0;
556 }
557 
558 template <typename T, size_t tCapacity>
559 inline const T& StaticVector<T, tCapacity>::operator[](const size_t index) const
560 {
561  ocean_assert(index < size_);
562 
563  return this->elements_[index];
564 }
565 
566 template <typename T, size_t tCapacity>
567 inline T& StaticVector<T, tCapacity>::operator[](const size_t index)
568 {
569  ocean_assert(index < size_);
570 
571  return this->elements_[index];
572 }
573 
574 template <typename T, size_t tCapacity>
576 {
577  if (size_ != second.size_)
578  {
579  return false;
580  }
581 
582  for (size_t n = 0; n < size_; ++n)
583  {
584  if (this->elements_[n] != second.elements_[n])
585  {
586  return false;
587  }
588  }
589 
590  return true;
591 }
592 
593 template <typename T, size_t tCapacity>
595 {
596  return !(*this == second);
597 }
598 
599 template <typename T, size_t tCapacity>
601 {
602  return size_ > 0;
603 }
604 
605 }
606 
607 #endif // META_OCEAN_BASE_STATIC_VECTOR_H
This class implements a static buffer that has a fixed capacity.
Definition: StaticBuffer.h:24
T elements_[tCapacity > size_t(0) ? tCapacity :size_t(1)]
Elements of this buffer (with at least one entry).
Definition: StaticBuffer.h:160
This class implements a static vector that has a fixed capacity.
Definition: StaticVector.h:25
size_t size_
The current number of stored elements, with range [0, tCapacity].
Definition: StaticVector.h:279
bool securePushBack(T &&value)
Adds a new element to this vector if this vector has free elements left, otherwise nothing happens.
Definition: StaticVector.h:381
StaticVector(const T *values, const size_t size)
Creates a new vector object.
Definition: StaticVector.h:309
StaticVector(const size_t number, const T &value)
Creates a new vector object.
Definition: StaticVector.h:299
const T & front() const
Returns the first elements of this vector.
Definition: StaticVector.h:455
void pushBack(const std::vector< T > &value)
Adds a new elements to this vector.
Definition: StaticVector.h:408
void secureWeakPopBack()
Removes the last element from this vector.
Definition: StaticVector.h:446
size_t size() const
Returns the size of this vector.
Definition: StaticVector.h:340
bool occupied() const
Returns whether no free space is left.
Definition: StaticVector.h:346
T & back()
Returns the last elements of this vector.
Definition: StaticVector.h:479
void popBack()
Removes the last element from this vector.
Definition: StaticVector.h:421
void erase(const size_t index)
Erases one element of this vector.
Definition: StaticVector.h:493
T & operator[](const size_t index)
Returns one element of this vector.
Definition: StaticVector.h:567
void clear()
Clears all elements of this vector.
Definition: StaticVector.h:542
void pushBack(T &&value)
Adds a new element to this vector.
Definition: StaticVector.h:360
void securePopBack()
Removes the last element from this vector.
Definition: StaticVector.h:429
StaticVector()=default
Creates a new vector object.
StaticVector(std::vector< T > &&values)
Creates a new vector object.
Definition: StaticVector.h:332
void weakClear()
Clears all elements of this vector by setting the internal index to zero (all stored elements are unt...
Definition: StaticVector.h:553
StaticVector(const T &value)
Creates a new vector object.
Definition: StaticVector.h:283
void resize(const size_t size)
Resizes this vector.
Definition: StaticVector.h:521
void unstableErase(const size_t index)
Erases one element from this vector.
Definition: StaticVector.h:506
StaticVector(T &&value)
Creates a new vector object.
Definition: StaticVector.h:291
void pushBack(const StaticVector< T, tCapacity2 > &value)
Adds a new elements to this vector.
Definition: StaticVector.h:395
bool operator!=(const StaticVector< T, tCapacity > &second) const
Returns whether two vectors are not identical.
Definition: StaticVector.h:594
StaticVector(const std::vector< T > &values)
Creates a new vector object.
Definition: StaticVector.h:324
void weakResize(const size_t size)
Resizes this vector.
Definition: StaticVector.h:534
void weakPopBack()
Removes the last element from this vector.
Definition: StaticVector.h:438
T & front()
Returns the first elements of this vector.
Definition: StaticVector.h:463
bool empty() const
Returns whether this vector hold no element.
Definition: StaticVector.h:487
void pushBack(const T &value)
Adds a new element to this vector.
Definition: StaticVector.h:352
bool securePushBack(const T &value)
Adds a new element to this vector if this vector has free elements left, otherwise nothing happens.
Definition: StaticVector.h:368
const T & operator[](const size_t index) const
Returns one element of this vector.
Definition: StaticVector.h:559
const T & back() const
Returns the last elements of this vector.
Definition: StaticVector.h:471
bool operator==(const StaticVector< T, tCapacity > &second) const
Returns whether two vectors are identical.
Definition: StaticVector.h:575
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15