Ocean
Loading...
Searching...
No Matches
ShiftVector.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_SHIFT_VECTOR_H
9#define META_OCEAN_BASE_SHIFT_VECTOR_H
10
11#include "ocean/base/Base.h"
12
13#include <deque>
14
15namespace Ocean
16{
17
18/**
19 * This class implements a vector with shifted elements.
20 * The elements are shifted by a shift offset index so that the elements can be accessed by adding this shift offset to the normal element index.<br>
21 * The shift offset can either be positive or negative.
22 * @tparam T Data type of the elements that are stored
23 * @ingroup base
24 */
25template <typename T>
27{
28 public:
29
30 /**
31 * Definition of the data type of each element of this object.
32 */
33 typedef T Type;
34
35 /**
36 * Definition of an element index.
37 */
38 typedef std::ptrdiff_t Index;
39
40 /**
41 * Definition of a data iterator.
42 */
43 typedef typename std::deque<T>::iterator Iterator;
44
45 /**
46 * Definition of a const data iterator.
47 */
48 typedef typename std::deque<T>::const_iterator ConstIterator;
49
50 public:
51
52 /**
53 * Creates a new shift vector object.
54 */
55 ShiftVector() = default;
56
57 /**
58 * Copy constructor.
59 * @param object Vector object to be copied
60 */
62
63 /**
64 * Move constructor.
65 * @param object Vector object to be moved
66 */
67 ShiftVector(ShiftVector<T>&& object) noexcept;
68
69 /**
70 * Creates a new shift vector object.
71 * @param firstIndex The index of the first element of this vector
72 */
73 explicit ShiftVector(const Index firstIndex);
74
75 /**
76 * Creates a new shift vector object.
77 * @param firstIndex The index of the first element of this vector
78 * @param size Number of elements to be created
79 */
80 ShiftVector(const Index firstIndex, const size_t size);
81
82 /**
83 * Creates a new shift vector object.
84 * @param firstIndex The index of the first element of this vector
85 * @param size Number of elements to be created
86 * @param element Pattern element that will be copied as often as requested
87 */
88 ShiftVector(const Index firstIndex, const size_t size, const T& element);
89
90 /**
91 * Creates a new shift vector object and copies a specified number of elements.
92 * @param firstIndex The index of the first element of this vector
93 * @param elements The elements to be copied
94 * @param size Number of elements to be copied
95 */
96 ShiftVector(const Index firstIndex, const T* elements, const size_t size);
97
98 /**
99 * Returns the index of the first element of this object.
100 * @return Index of first element
101 */
102 inline Index firstIndex() const;
103
104 /**
105 * Returns the index of the last (including) element of this object.
106 * @return Index of last element
107 * @see endIndex().
108 */
109 inline Index lastIndex() const;
110
111 /**
112 * Returns the index of the element behind the last (excluding) element of this object.
113 * Thus, there does not exist an element with the returning index.<br>
114 * @return Index of ending element
115 * @see lastIndex()
116 */
117 inline Index endIndex() const;
118
119 /**
120 * Sets the index of the first element of this vector.
121 * The elements of this vector will be untouched, however the individual elements receive a new index due to the new shift offset.
122 * @param index The index of the first element
123 */
124 inline void setFirstIndex(const Index index);
125
126 /**
127 * Returns the element located at the first index.
128 * Beware: Ensure that this object holds at least one element before accessing the element.
129 * @return The first element
130 * @see firstIndex().
131 */
132 inline const T& front() const;
133
134 /**
135 * Returns the element located at the first index.
136 * Beware: Ensure that this object holds at least one element before accessing the element.
137 * @return The first element
138 * @see firstIndex().
139 */
140 inline T& front();
141
142 /**
143 * Returns the element located at the last (including) index.
144 * Beware: Ensure that this object holds at least one element before accessing the element.
145 * @return The last element
146 * @see lastIndex().
147 */
148 inline const T& back() const;
149
150 /**
151 * Returns the element located at the last (including) index.
152 * Beware: Ensure that this object holds at least one element before accessing the element.
153 * @return The first element
154 * @see lastIndex().
155 */
156 inline T& back();
157
158 /**
159 * Returns the number of elements that are stored by this object.
160 * @return Number of elements
161 */
162 inline size_t size() const;
163
164 /**
165 * Changes the number of elements of this vector.
166 * If the new size is greater than the current size, than new elements are inserted with default initialization of the data type handled by this vector.
167 * @param size New element number
168 */
169 inline void resize(const size_t size);
170
171 /**
172 * Changes the number of elements of this vector.
173 * If the new size is greater than the current size, than new elements are inserted and initialized as copies of the given pattern element.<br>
174 * @param size New element number
175 * @param element The pattern element that is copied to each new internal element if necessary
176 */
177 inline void resize(const size_t size, const T& element);
178
179 /**
180 * Adds a new element to the end of this vector.
181 * The internal shift offset is untouched.<br>
182 * @param element New element to be added
183 */
184 inline void pushBack(const T& element);
185
186 /**
187 * Adds a new element to the end of this vector.
188 * The internal shift offset is untouched.<br>
189 * @param element New element to be added
190 */
191 inline void pushBack(T&& element);
192
193 /**
194 * Adds a new element to the front of this vector.
195 * The internal shift offset will be decremented by 1 so that the indices of the existing elements remain unchanged.<br>
196 * @param element New element to be added
197 */
198 inline void pushFront(const T& element);
199
200 /**
201 * Adds a new element to the front of this vector.
202 * The internal shift offset will be decremented by 1 so that the indices of the existing elements remain unchanged.<br>
203 * @param element New element to be added
204 */
205 inline void pushFront(T&& element);
206
207 /**
208 * Removes an element from the end of this vector.
209 * The internal shift offset is untouched.<br>
210 */
211 inline void popBack();
212
213 /**
214 * Removes an element form the front of this vector.
215 * The internal shift offset will be incremented by 1 so that the indices of the remaining elements remain unchanged.<br>
216 */
217 inline void popFront();
218
219 /**
220 * Inserts (or overwrites) an element at a specific position of this vector.
221 * If the position is outside the current range of the vector (in negative or positive direction) than this vector will be extended accordingly.<br>
222 * Whenever the vector will be extended, all intermediate elements (elements at new indices not equal to the given index) are initialized with the default constructor of the data type of this vector.<br>
223 * Beware: If elements have to be added at the front, than the index of the first element will also be adjusted.<br>
224 * @param index The index of the element
225 * @param element The element to be inserted at the given index
226 */
227 inline void insert(const Index index, const T& element);
228
229 /**
230 * Inserts (or overwrites) an element at a specific position of this vector.
231 * If the position is outside the current range of the vector (in negative or positive direction) than this vector will be extended accordingly.<br>
232 * Whenever the vector will be extended, all intermediate elements (elements at new indices not equal to the given index) are initialized with the given intermediate element instance.<br>
233 * Beware: If elements have to be added at the front, than the index of the first element will also be adjusted.<br>
234 * @param index The index of the element
235 * @param element The element to be inserted at the given index
236 * @param intermediateElement The element that is copied to all intermediate elements (elements at new indices not equal to the given index)
237 */
238 inline void insert(const Index index, const T& element, const T& intermediateElement);
239
240 /**
241 * Inserts (or overwrites) an element at a specific position of this vector.
242 * If the position is outside the current range of the vector (in negative or positive direction) than this vector will be extended accordingly.<br>
243 * Whenever the vector will be extended, all intermediate elements (elements at new indices not equal to the given index) are initialized with the default constructor of the data type of this vector.<br>
244 * Beware: If elements have to be added at the front, than the index of the first element will also be adjusted.<br>
245 * @param index The index of the element
246 * @param element The element to be inserted at the given index
247 */
248 inline void insert(const Index index, T&& element);
249
250 /**
251 * Inserts (or overwrites) an element at a specific position of this vector.
252 * If the position is outside the current range of the vector (in negative or positive direction) than this vector will be extended accordingly.<br>
253 * Whenever the vector will be extended, all intermediate elements (elements at new indices not equal to the given index) are initialized with the given intermediate element instance.<br>
254 * Beware: If elements have to be added at the front, than the index of the first element will also be adjusted.<br>
255 * @param index The index of the element
256 * @param element The element to be inserted at the given index
257 * @param intermediateElement The element that is copied to all intermediate elements (elements at new indices not equal to the given index)
258 */
259 inline void insert(const Index index, T&& element, const T& intermediateElement);
260
261 /**
262 * Returns whether a specific index is valid for this vector and matches to the current offset layout.
263 * @param index The index to be checked
264 * @return True, if succeeded
265 */
266 inline bool isValidIndex(const Index index) const;
267
268 /**
269 * Returns whether this object holds no element.
270 * @return True, if so
271 */
272 inline bool isEmpty() const;
273
274 /**
275 * Clears this object, the specified index shift will be untouched.
276 */
277 inline void clear();
278
279 /**
280 * Returns a vector storing the elements.
281 * @return Vector holding the elements
282 */
283 std::vector<T> data() const;
284
285 /**
286 * Returns the iterator for the first data element.
287 * @return Iterator for the first data element
288 */
289 inline Iterator begin();
290
291 /**
292 * Returns the iterator for the first data element.
293 * @return Iterator for the first data element
294 */
295 inline ConstIterator begin() const;
296
297 /**
298 * Returns the end iterator.
299 * @return Iterator for the end
300 */
301 inline Iterator end();
302
303 /**
304 * Returns the end iterator.
305 * @return Iterator for the end
306 */
307 inline ConstIterator end() const;
308
309 /**
310 * Assign operator.
311 * @param object Vector object to be copied
312 * @return Reference to this object
313 */
315
316 /**
317 * Move operator.
318 * @param object Vector object to be moved
319 * @return Reference to this object
320 */
322
323 /**
324 * Returns one element of this object.
325 * @param index The index of the element to be returned, with range [firstIndex(), lastIndex()]
326 * @return Requested element
327 */
328 inline const T& operator[](const Index index) const;
329
330 /**
331 * Returns one element of this object.
332 * @param index The index of the element to be returned, with range [firstIndex(), lastIndex()]
333 * @return Requested element
334 */
335 inline T& operator[](const Index index);
336
337 /**
338 * Returns whether this object holds at least one element.
339 * @return True, if so
340 */
341 explicit inline operator bool() const;
342
343 /**
344 * Compares two shift vector objects whether they are equal.
345 * Two shift vector object are equal if they have the same firstIndex() parameter, if they have the same size and if all elements are equal.<br>
346 * @param object Second shift vector object to be compared
347 * @return True, if so
348 */
349 bool operator==(const ShiftVector<T>& object) const;
350
351 /**
352 * Compares two shift vector object whether they are not equal.
353 * @param object Second shift vector object to be compared
354 * @return True, if so
355 */
356 inline bool operator!=(const ShiftVector<T>& object) const;
357
358 protected:
359
360 /// The index of the first element.
362
363 /// Elements of this object.
364 std::deque<T> elements_;
365};
366
367template <typename T>
369 firstIndex_(object.firstIndex_),
370 elements_(object.elements_)
371{
372 // nothing to do here
373}
374
375template <typename T>
377{
378 *this = std::move(object);
379}
380
381template <typename T>
383 firstIndex_(firstIndex)
384{
385 // nothing to do here
386}
387
388template <typename T>
389ShiftVector<T>::ShiftVector(const Index firstIndex, const size_t size) :
390 firstIndex_(firstIndex),
391 elements_(size)
392{
393 // nothing to do here
394}
395
396template <typename T>
397ShiftVector<T>::ShiftVector(const Index firstIndex, const size_t size, const T& element) :
398 firstIndex_(firstIndex),
399 elements_(size, element)
400{
401 // nothing to do here
402}
403
404template <typename T>
405ShiftVector<T>::ShiftVector(const Index firstIndex, const T* elements, const size_t size) :
406 firstIndex_(firstIndex),
407 elements_(size)
408{
409 for (size_t n = 0; n < size; ++n)
410 {
411 elements_[n] = elements[n];
412 }
413}
414
415template <typename T>
417{
418 return firstIndex_;
419}
420
421template <typename T>
423{
424 ocean_assert(!elements_.empty());
425
426 if (elements_.empty())
427 {
428 return firstIndex_ - 1;
429 }
430
431 return firstIndex_ + Index(elements_.size()) - 1;
432}
433
434template <typename T>
436{
437 ocean_assert(!elements_.empty());
438
439 if (elements_.empty())
440 {
441 return firstIndex_;
442 }
443
444 return firstIndex_ + Index(elements_.size());
445}
446
447template <typename T>
448inline void ShiftVector<T>::setFirstIndex(const Index index)
449{
450 firstIndex_ = index;
451}
452
453template <typename T>
454inline const T& ShiftVector<T>::front() const
455{
456 ocean_assert(!elements_.empty());
457 ocean_assert((*this)[firstIndex()] == elements_.front());
458
459 return elements_.front();
460}
461
462template <typename T>
464{
465 ocean_assert(!elements_.empty());
466 ocean_assert((*this)[firstIndex()] == elements_.front());
467
468 return elements_.front();
469}
470
471template <typename T>
472inline const T& ShiftVector<T>::back() const
473{
474 ocean_assert(!elements_.empty());
475 ocean_assert((*this)[lastIndex()] == elements_.back());
476
477 return elements_.back();
478}
479
480template <typename T>
482{
483 ocean_assert(!elements_.empty());
484 ocean_assert((*this)[lastIndex()] == elements_.back());
485
486 return elements_.back();
487}
488
489template <typename T>
490inline size_t ShiftVector<T>::size() const
491{
492 return elements_.size();
493}
494
495template <typename T>
496inline void ShiftVector<T>::resize(const size_t size)
497{
498 elements_.resize(size);
499}
500
501template <typename T>
502inline void ShiftVector<T>::resize(const size_t size, const T& element)
503{
504 elements_.resize(size, element);
505}
506
507template <typename T>
508inline void ShiftVector<T>::pushBack(const T& element)
509{
510 elements_.push_back(element);
511}
512
513template <typename T>
514inline void ShiftVector<T>::pushBack(T&& element)
515{
516 elements_.push_back(element);
517}
518
519template <typename T>
520inline void ShiftVector<T>::pushFront(const T& element)
521{
522 elements_.push_front(element);
523 firstIndex_--;
524}
525
526template <typename T>
527inline void ShiftVector<T>::pushFront(T&& element)
528{
529 elements_.push_front(element);
530 firstIndex_--;
531}
532
533template <typename T>
535{
536 ocean_assert(!elements_.empty());
537 elements_.pop_back();
538}
539
540template <typename T>
542{
543 ocean_assert(!elements_.empty());
544 elements_.pop_front();
545 firstIndex_++;
546}
547
548template <typename T>
549inline void ShiftVector<T>::insert(const Index index, const T& element)
550{
551 if (index < firstIndex_)
552 {
553 // add default objects
554 while (index + 1 < firstIndex_)
555 {
556 pushFront(T());
557 }
558
559 pushFront(element);
560 }
561 else
562 {
563 if (index >= (Index)(firstIndex_ + elements_.size()))
564 {
565 elements_.resize(index - firstIndex_ + 1);
566 }
567
568 elements_[index - firstIndex_] = element;
569 }
570}
571
572template <typename T>
573inline void ShiftVector<T>::insert(const Index index, const T& element, const T& intermediateElement)
574{
575 if (index < firstIndex_)
576 {
577 // add default objects
578 while (index + 1 < firstIndex_)
579 {
580 pushFront(intermediateElement);
581 }
582
583 pushFront(element);
584 }
585 else
586 {
587 if (index >= (Index)(firstIndex_ + elements_.size()))
588 {
589 elements_.resize(index - firstIndex_ + 1, intermediateElement);
590 }
591
592 elements_[index - firstIndex_] = element;
593 }
594}
595
596
597template <typename T>
598inline void ShiftVector<T>::insert(const Index index, T&& element)
599{
600 if (index < firstIndex_)
601 {
602 // add default objects
603 while (index + 1 < firstIndex_)
604 {
605 pushFront(T());
606 }
607
608 pushFront(element);
609 }
610 else
611 {
612 if (index >= (Index)(firstIndex_ + elements_.size()))
613 {
614 elements_.resize(index - firstIndex_ + 1);
615 }
616
617 elements_[index - firstIndex_] = std::move(element);
618 }
619}
620
621template <typename T>
622inline void ShiftVector<T>::insert(const Index index, T&& element, const T& intermediateElement)
623{
624 if (index < firstIndex_)
625 {
626 // add default objects
627 while (index + 1 < firstIndex_)
628 {
629 pushFront(intermediateElement);
630 }
631
632 pushFront(element);
633 }
634 else
635 {
636 if (index >= (Index)(firstIndex_ + elements_.size()))
637 {
638 elements_.resize(index - firstIndex_ + 1, intermediateElement);
639 }
640
641 elements_[index - firstIndex_] = element;
642 }
643}
644
645template <typename T>
646inline bool ShiftVector<T>::isValidIndex(const Index index) const
647{
648 return index >= firstIndex_ && index < Index(firstIndex_ + elements_.size());
649}
650
651template <typename T>
652inline bool ShiftVector<T>::isEmpty() const
653{
654 return elements_.empty();
655}
656
657template <typename T>
659{
660 elements_.clear();
661}
662
663template <typename T>
664std::vector<T> ShiftVector<T>::data() const
665{
666 return std::vector<T>(elements_.begin(), elements_.end());
667}
668
669template <typename T>
671{
672 return elements_.begin();
673}
674
675template <typename T>
677{
678 return elements_.begin();
679}
680
681template <typename T>
683{
684 return elements_.end();
685}
686
687template <typename T>
689{
690 return elements_.end();
691}
692
693template <typename T>
695{
696 firstIndex_ = object.firstIndex_;
697 elements_ = object.elements_;
698
699 return *this;
700}
701
702template <typename T>
704{
705 if (this != &object)
706 {
707 firstIndex_ = object.firstIndex_;
708 object.firstIndex_ = 0;
709
710 elements_ = std::move(object.elements_);
711 }
712
713 return *this;
714}
715
716template <typename T>
717inline const T& ShiftVector<T>::operator[](const Index index) const
718{
719 ocean_assert(!isEmpty());
720 ocean_assert(isValidIndex(index));
721 ocean_assert(index >= firstIndex() && index <= lastIndex());
722
723 return elements_[index - firstIndex_];
724}
725
726template <typename T>
727inline T& ShiftVector<T>::operator[](const Index index)
728{
729 ocean_assert(!isEmpty());
730 ocean_assert(isValidIndex(index));
731 ocean_assert(index >= firstIndex() && index <= lastIndex());
732
733 return elements_[index - firstIndex_];
734}
735
736template <typename T>
737inline ShiftVector<T>::operator bool() const
738{
739 return !elements_.empty();
740}
741
742template <typename T>
744{
745 return firstIndex_ == object.firstIndex_ && elements_ == object.elements_;
746}
747
748template <typename T>
749inline bool ShiftVector<T>::operator!=(const ShiftVector<T>& object) const
750{
751 return !(*this == object);
752}
753
754}
755
756#endif // META_OCEAN_BASE_SHIFT_VECTOR_H
This class implements a vector with shifted elements.
Definition ShiftVector.h:27
T Type
Definition of the data type of each element of this object.
Definition ShiftVector.h:33
ShiftVector(const Index firstIndex)
Creates a new shift vector object.
Definition ShiftVector.h:382
void resize(const size_t size, const T &element)
Changes the number of elements of this vector.
Definition ShiftVector.h:502
bool isValidIndex(const Index index) const
Returns whether a specific index is valid for this vector and matches to the current offset layout.
Definition ShiftVector.h:646
const T & operator[](const Index index) const
Returns one element of this object.
Definition ShiftVector.h:717
ShiftVector< T > & operator=(ShiftVector< T > &&object) noexcept
Move operator.
Definition ShiftVector.h:703
ShiftVector(ShiftVector< T > &&object) noexcept
Move constructor.
Definition ShiftVector.h:376
T & operator[](const Index index)
Returns one element of this object.
Definition ShiftVector.h:727
void insert(const Index index, T &&element, const T &intermediateElement)
Inserts (or overwrites) an element at a specific position of this vector.
Definition ShiftVector.h:622
const T & back() const
Returns the element located at the last (including) index.
Definition ShiftVector.h:472
bool operator==(const ShiftVector< T > &object) const
Compares two shift vector objects whether they are equal.
Definition ShiftVector.h:743
size_t size() const
Returns the number of elements that are stored by this object.
Definition ShiftVector.h:490
ShiftVector(const Index firstIndex, const T *elements, const size_t size)
Creates a new shift vector object and copies a specified number of elements.
Definition ShiftVector.h:405
Index endIndex() const
Returns the index of the element behind the last (excluding) element of this object.
Definition ShiftVector.h:435
void resize(const size_t size)
Changes the number of elements of this vector.
Definition ShiftVector.h:496
void insert(const Index index, T &&element)
Inserts (or overwrites) an element at a specific position of this vector.
Definition ShiftVector.h:598
ShiftVector(const ShiftVector< T > &object)
Copy constructor.
Definition ShiftVector.h:368
ShiftVector(const Index firstIndex, const size_t size, const T &element)
Creates a new shift vector object.
Definition ShiftVector.h:397
void pushBack(const T &element)
Adds a new element to the end of this vector.
Definition ShiftVector.h:508
std::deque< T > elements_
Elements of this object.
Definition ShiftVector.h:364
ConstIterator begin() const
Returns the iterator for the first data element.
Definition ShiftVector.h:676
T & front()
Returns the element located at the first index.
Definition ShiftVector.h:463
void pushFront(T &&element)
Adds a new element to the front of this vector.
Definition ShiftVector.h:527
void popFront()
Removes an element form the front of this vector.
Definition ShiftVector.h:541
bool operator!=(const ShiftVector< T > &object) const
Compares two shift vector object whether they are not equal.
Definition ShiftVector.h:749
void pushFront(const T &element)
Adds a new element to the front of this vector.
Definition ShiftVector.h:520
ShiftVector()=default
Creates a new shift vector object.
void clear()
Clears this object, the specified index shift will be untouched.
Definition ShiftVector.h:658
Index firstIndex_
The index of the first element.
Definition ShiftVector.h:361
bool isEmpty() const
Returns whether this object holds no element.
Definition ShiftVector.h:652
ConstIterator end() const
Returns the end iterator.
Definition ShiftVector.h:688
std::ptrdiff_t Index
Definition of an element index.
Definition ShiftVector.h:38
std::deque< T >::const_iterator ConstIterator
Definition of a const data iterator.
Definition ShiftVector.h:48
void setFirstIndex(const Index index)
Sets the index of the first element of this vector.
Definition ShiftVector.h:448
Iterator begin()
Returns the iterator for the first data element.
Definition ShiftVector.h:670
std::deque< T >::iterator Iterator
Definition of a data iterator.
Definition ShiftVector.h:43
void popBack()
Removes an element from the end of this vector.
Definition ShiftVector.h:534
Index lastIndex() const
Returns the index of the last (including) element of this object.
Definition ShiftVector.h:422
ShiftVector< T > & operator=(const ShiftVector< T > &object)
Assign operator.
Definition ShiftVector.h:694
Iterator end()
Returns the end iterator.
Definition ShiftVector.h:682
T & back()
Returns the element located at the last (including) index.
Definition ShiftVector.h:481
void insert(const Index index, const T &element)
Inserts (or overwrites) an element at a specific position of this vector.
Definition ShiftVector.h:549
ShiftVector(const Index firstIndex, const size_t size)
Creates a new shift vector object.
Definition ShiftVector.h:389
std::vector< T > data() const
Returns a vector storing the elements.
Definition ShiftVector.h:664
void insert(const Index index, const T &element, const T &intermediateElement)
Inserts (or overwrites) an element at a specific position of this vector.
Definition ShiftVector.h:573
void pushBack(T &&element)
Adds a new element to the end of this vector.
Definition ShiftVector.h:514
const T & front() const
Returns the element located at the first index.
Definition ShiftVector.h:454
Index firstIndex() const
Returns the index of the first element of this object.
Definition ShiftVector.h:416
The namespace covering the entire Ocean framework.
Definition Accessor.h:15