AGX Dynamics 2.41.2.0
Loading...
Searching...
No Matches
agx/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#ifndef AGX_VECTOR_H
18#define AGX_VECTOR_H
19
20#include <type_traits>
21
22#include <agx/agx.h>
23// #include <agx/Referenced.h>
24#include <agx/Allocator.h>
25#include <agx/Container.h>
26#include <ostream>
27#include <cstring>
28#include <iterator>
29
30#ifdef __linux__
31#include <cstddef>
32#endif
33
34#define AGX_DECLARE_VECTOR_TYPES(type) \
35typedef agx::Vector<type ## Ref> type ## RefVector; \
36typedef agx::Vector<type ## Observer> type ## ObserverVector; \
37typedef agx::VectorPOD<type *> type ## PtrVector
38
39#ifdef _MSC_VER
40#pragma warning (push)
41# pragma warning( disable: 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
42#endif
43
44
45
46namespace agx
47{
51 template<typename T, typename Allocator = ByteAllocator >
52 class Vector : public Container
53 {
54 public:
55 typedef T Type;
56 typedef T value_type;
57 typedef T* pointer;
58 typedef const T* const_pointer;
59 typedef T& reference;
60 typedef const T& const_reference;
61 typedef size_t size_type;
62 typedef T* iterator;
63 typedef const T* const_iterator;
64 typedef std::random_access_iterator_tag iterator_category;
65 typedef ptrdiff_t difference_type;
66
67 public:
68 explicit Vector(const Allocator& allocator = Allocator());
69 explicit Vector(size_t size, const T& value = T(), const Allocator& allocator = Allocator());
71 Vector(std::initializer_list<T> values, const Allocator& allocator = Allocator());
72
75
77
79
80
84 bool operator == ( const Vector<T, Allocator>& other ) const;
85 bool operator != ( const Vector<T, Allocator>& other ) const;
86
87
91 void resize(size_t size);
92 void resize(size_t size, const T& value);
93
94
99
103 void reserve(size_t size);
104
105
109 void reserveAtLeast(size_t size);
110
111
115 T* increment(size_t numElements = 1);
116
120 T* ptr();
121 const T* ptr() const;
122
123 T& operator[] (size_t i) const;
124 T& at(size_t index) const;
125 T& front() const;
126 T& back() const;
127
128 template <typename T2>
129 void push_back(const T2& value);
130
131 void push_back(const T& value);
132
133 void push_back(T&& value);
134
135 void pop_back();
136
137 typedef std::reverse_iterator<iterator> reverse_iterator;
138 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
139
144
149
155
159 void erase(size_t index);
160 void erase(size_t start, size_t end);
161
166 void eraseFast(size_t index);
167
172
176 template <typename T2>
177 bool contains(const T2& element) const;
178
179 bool contains(const T& element) const;
180
181
185 template <typename T2>
186 size_t find(const T2& element) const;
187
194 template <typename T2>
195 bool findAndErase(const T2& element, bool searchMultiple = false);
196
197 iterator insert(iterator position, const T& value);
198 void insert(size_t index, const T& value);
199
200 template <typename InputIterator>
201 void insert(const_iterator it, InputIterator first, InputIterator last);
202
203 void insert(const_iterator it, std::initializer_list<T> ilist);
204
205 void swap(Vector& other);
206
207
209 const Allocator& allocator() const;
210
212 size_t getNumActiveElements() const;
214
215 private:
216 void reallocate(size_t size);
217 void constructElements(size_t startIndex, size_t endIndex);
218 void constructElements(size_t startIndex, size_t endIndex, const T& value);
219 void destroyElements(size_t startIndex, size_t endIndex);
220
221 Allocator m_allocator;
222 Real32 m_smoothingAverage;
223 };
224
225 template<typename T, typename A>
226 typename Vector<T, A>::iterator begin(Vector<T, A>& v);
227
228 template<typename T, typename A>
229 typename Vector<T, A>::const_iterator begin(const Vector<T, A>& v);
230
231 template<typename T, typename A>
232 typename Vector<T, A>::iterator end(Vector<T, A>& v);
233
234 template<typename T, typename A>
235 typename Vector<T, A>::const_iterator end(const Vector<T, A>& v);
236
237
238
244 template<typename T, typename Allocator = ByteAllocator>
245 class VectorPOD : public Container
246 {
247 public:
248 typedef T Type;
249 typedef T value_type;
250 typedef T* pointer;
251 typedef const T* const_pointer;
252 typedef T& reference;
253 typedef const T& const_reference;
254 typedef size_t size_type;
255 typedef T* iterator;
256 typedef const T* const_iterator;
257 typedef ptrdiff_t difference_type;
258
259
260
261 public:
263 explicit VectorPOD(size_t size, const T& value = T(), const Allocator& allocator = Allocator());
265 VectorPOD(std::initializer_list<T> values, const Allocator& allocator = Allocator());
266
269
271
273
274
278 bool operator == ( const VectorPOD<T, Allocator>& other ) const;
279 bool operator != ( const VectorPOD<T, Allocator>& other ) const;
280
284 void resize(size_t size);
285 void resize(size_t size, const T& value);
286
291
295 void reserve(size_t size);
296
300 void reserveAtLeast(size_t size);
301
305 T* increment(size_t numElements = 1);
306
310 T* ptr();
311 const T* ptr() const;
312
313 T& operator[] (size_t i) const;
314 T& at(size_t index) const;
315 T& front() const;
316 T& back() const;
317
318 void push_back(const T& value);
319 void push_back(T&& value);
320 void pop_back();
321
322 typedef std::reverse_iterator<iterator> reverse_iterator;
323 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
324
329
334
340
344 void erase(size_t index);
345 void erase(size_t start, size_t end);
346
351 void eraseFast(size_t index);
352
353
358
362 template <typename T2>
363 bool contains(const T2& element) const;
364
365 bool contains(const T& element) const;
366
370 template <typename T2>
371 size_t find(const T2& element) const;
372
379 bool findAndErase(const T& element, bool searchMultiple = false);
380
381 iterator insert(iterator position, const T& value);
382 void insert(size_t index, const T& value);
383
384 template <typename InputIterator>
385 void insert(const_iterator it, InputIterator first, InputIterator last);
386
387 void insert(const_iterator it, std::initializer_list<T> ilist);
388
389 void swap(VectorPOD& other);
390
392 const Allocator& allocator() const;
393
395 size_t getNumActiveElements() const;
397
398 private:
399 void reallocate(size_t size);
400 void constructElements(size_t startIndex, size_t endIndex);
401 void constructElements(size_t startIndex, size_t endIndex, const T& value);
402
403 static T s_initializer;
404
405 Allocator m_allocator;
406 Real32 m_smoothingAverage;
407 };
408
409 template<typename T, typename A>
410 typename VectorPOD<T, A>::iterator begin(VectorPOD<T, A>& v);
411
412 template<typename T, typename A>
413 typename VectorPOD<T, A>::const_iterator begin(const VectorPOD<T, A>& v);
414
415 template<typename T, typename A>
416 typename VectorPOD<T, A>::iterator end(VectorPOD<T, A>& v);
417
418 template<typename T, typename A>
419 typename VectorPOD<T, A>::const_iterator end(const VectorPOD<T, A>& v);
420
421
422 /* Implementation */
423 #define AGX_VECTOR_RESIZE_FACTOR 2.0f
424 #define AGX_VECTOR_SMOOTHING_FACTOR 0.8f
425 #define AGX_VECTOR_SHRINK_THRESHOLD 0.25f
426 #define AGX_VECTOR_MIN_SIZE 4
427
428 #define m_elements static_cast<T *>(this->m_buffer)
429 #define m_size this->m_size
430 #define m_capacity this->m_capacity
431
432
433 template<class T>
435
436 template<class T>
438
439
440 template <typename T, typename A>
441 Vector<T, A>::Vector(const A& allocator) : m_allocator(allocator), m_smoothingAverage(0.0)
442 {
443 m_allocator.setContainer(this);
444 }
445
446 template <typename T, typename A>
447 Vector<T, A>::Vector(size_t size, const T& value, const A& allocator) : m_allocator(allocator), m_smoothingAverage(0.0)
448 {
449 m_allocator.setContainer(this);
450 this->resize(size, value);
451 }
452
453 template <typename T, typename A>
454 Vector<T, A>::Vector(const Vector<T, A>& other) : m_smoothingAverage(0.0)
455 {
456 *this = other;
457 }
458
459 template <typename T, typename Allocator>
461 :Container(std::move(other)), m_smoothingAverage(0.0)
462 {
463 // Move values
464 m_allocator = other.m_allocator;
465 m_allocator.setContainer(this),
466 m_smoothingAverage = other.m_smoothingAverage;
467
468 // Assign default values to the rvalue reference.
469 other.m_allocator = Allocator();
470 other.m_smoothingAverage = Real32(0.0);
471 }
472
473 template <typename T, typename A>
474 Vector<T, A>::Vector(const_iterator first, const_iterator end, const A& allocator) : m_allocator(allocator), m_smoothingAverage(0.0)
475 {
476 m_allocator.setContainer(this);
477 this->insert(this->begin(), first, end);
478 }
479
480 template <typename T, typename A>
481 Vector<T, A>::Vector(std::initializer_list<T> values, const A& allocator)
482 : m_allocator(allocator), m_smoothingAverage(0.0)
483 {
484 m_allocator.setContainer(this);
485 using std::begin;
486 using std::end;
487 this->insert(begin(*this), begin(values), end(values));
488 }
489
490 template <typename T, typename A>
492 {
493 if (this->empty())
494 return;
495
496 this->destroyElements(0, m_size);
497
498 if (policy == MAINTAIN_BUFFER)
499 {
500 m_size = 0;
501 }
502 else if (policy == SHRINK_BUFFER)
503 {
504 m_allocator.deallocateBytes(m_buffer, m_capacity * sizeof(T));
505 m_buffer = nullptr;
506 m_size = 0;
507 m_capacity = 0;
508 m_smoothingAverage = 0.0;
509 }
510 else // SHRINK_BUFFER_AVERAGED
511 {
512 /* Smoothing average is never less than current size */
513 if ((Real32)m_size > m_smoothingAverage)
514 m_smoothingAverage = (Real32)m_size;
515
516 /* Update smoothing average */
517 m_smoothingAverage = (Real32)(AGX_VECTOR_SMOOTHING_FACTOR * m_smoothingAverage + (1.0f-AGX_VECTOR_SMOOTHING_FACTOR) * (float)m_size);
518
519 /* Clear size before reallocate so it does not copy elements from old buffer. */
520 m_size = 0;
521
522 /* Reallocate buffer if the smoothing average is sufficiently below the current capacity */
523 if (m_smoothingAverage/(Real32)m_capacity < AGX_VECTOR_SHRINK_THRESHOLD)
524 this->reallocate((size_t)m_smoothingAverage);
525 }
526 }
527
528
529
530 template <typename T, typename A>
532 {
533 if (m_capacity > m_size )
534 {
535 this->reallocate(m_size);
536 }
537 }
538
539 template <typename T, typename A>
541 {
542 if (size > m_size)
543 {
544 if (size > m_capacity)
545 this->reallocate(size);
546
547 this->constructElements(m_size, size);
548 }
549 else
550 {
551 if (size < (size_t)((double)m_capacity * AGX_VECTOR_SHRINK_THRESHOLD))
552 this->reallocate(size);
553
554 this->destroyElements(size, m_size);
555 }
556
557 m_size = size;
558 }
559
560
561 template <typename T, typename A>
562 AGX_FORCE_INLINE void Vector<T, A>::resize(size_t size, const T& value)
563 {
564 if (size > m_size)
565 {
566 if (size > m_capacity)
567 this->reallocate(size);
568
569 this->constructElements(m_size, size, value);
570 }
571 else
572 {
573 if (size < (size_t)((double)m_capacity * AGX_VECTOR_SHRINK_THRESHOLD))
574 this->reallocate(size);
575
576 this->destroyElements(size, m_size);
577 }
578
579 m_size = size;
580 }
581
582 template <typename T, typename A>
584 {
585 if (size > m_capacity)
586 this->reallocate(size);
587 }
588
589
590
591 template <typename T, typename A>
593 {
594 if (size > m_capacity) {
595 size_t newCapacity = std::max(m_capacity, size_t(AGX_VECTOR_MIN_SIZE));
596 while (size > newCapacity)
597 newCapacity = size_t((double)newCapacity * AGX_VECTOR_RESIZE_FACTOR);
598 this->reallocate(newCapacity);
599 }
600 }
601
602
603
604 template <typename T, typename A>
606 {
607 size_t newSize = m_size + numElements;
608 if (newSize > m_capacity)
609 this->reallocate((size_t)((double)newSize * AGX_VECTOR_RESIZE_FACTOR));
610
611 this->constructElements(m_size, newSize);
612 m_size = newSize;
613 return m_elements + m_size - numElements;
614 }
615
616
617
618 template <typename T, typename A>
620 {
621 if (m_size != other.size())
622 return false;
623
624 for (size_t i = 0; i < m_size; i++)
625 if (m_elements[i] != other[i])
626 return false;
627
628 return true;
629 }
630
631 template <typename T, typename A>
633 {
634 if (m_size != other.size())
635 return true;
636
637 for (size_t i = 0; i < m_size; i++)
638 if (m_elements[i] != other[i])
639 return true;
640
641 return false;
642 }
643
644
645 template <typename T, typename A>
647 {
648 if (this == &other)
649 return *this;
650
651 this->clear(MAINTAIN_BUFFER);
652 m_allocator = other.m_allocator;
653 m_allocator.setContainer(this);
654
655 // this->reserve(other.capacity());
656 // this->resize(other.size());
657 this->reallocate(other.capacity());
658
659 /* Copy elements from other buffer */
660 for (size_t i = 0; i < other.size(); i++)
661 ::new((void *)&m_elements[i]) T(other[i]);
662
663 m_size = other.size();
664
665 return *this;
666 }
667
668 template <typename T, typename A>
670 {
671 this->destroyElements(0, m_size);
672 m_allocator.deallocateBytes(m_elements, m_capacity * sizeof(T));
673 }
674
675
676 template <typename T, typename A>
678
679 template <typename T, typename A>
680 AGX_FORCE_INLINE const T* Vector<T, A>::ptr() const { return m_elements; }
681
682
683 template <typename T, typename A>
685 {
686 agxAssertN(i < m_size, "Array index %llu is out of bounds, current size is %llu", (long long unsigned)i, (long long unsigned)m_size);
687 return m_elements[i];
688 }
689
690 template <typename T, typename A>
691 AGX_FORCE_INLINE T& Vector<T, A>::at(size_t index) const
692 {
693 agxVerifyN(index < m_size, "Array index %llu is out of bounds, current size is %llu", (long long unsigned)index, (long long unsigned)m_size);
694 return m_elements[index];
695 }
696
697
698 template <typename T, typename A>
700 {
701 agxAssert1(m_size > 0, "Can not take front element of an empty vector!");
702 return m_elements[0];
703 }
704
705
706 template <typename T, typename A>
708 {
709 agxAssert1(m_size > 0, "Can not take back element of an empty vector!");
710 return m_elements[m_size-1];
711 }
712
713
714 template <typename T, typename A> template <typename T2>
716 {
717 if (m_size == m_capacity)
718 this->reallocate(std::max((size_t)AGX_VECTOR_MIN_SIZE, (size_t)((float)m_size * AGX_VECTOR_RESIZE_FACTOR)));
719
720
721 ::new((void *)&m_elements[m_size]) T(value); // removed unnecessary loop by replacing line below by this one
722 // this->_constructElements(m_size, m_size+1, value);
723 m_size++;
724 }
725
726 template <typename T, typename A>
728 {
729 if (m_size == m_capacity)
730 this->reallocate(std::max((size_t)AGX_VECTOR_MIN_SIZE, (size_t)((float)m_size * AGX_VECTOR_RESIZE_FACTOR)));
731
732
733 ::new((void *)&m_elements[m_size]) T(value); // removed unnecessary loop by replacing line below by this one
734 // this->_constructElements(m_size, m_size+1, value);
735 m_size++;
736 }
737
738
739
740 template <typename T, typename A>
742 {
743 if (m_size == m_capacity)
744 {
745 this->reallocate(std::max((size_t)AGX_VECTOR_MIN_SIZE, (size_t)((float)m_size * AGX_VECTOR_RESIZE_FACTOR)));
746 }
747
748 ::new((void*)&m_elements[m_size]) T(std::move(value));
749 m_size++;
750 }
751
752
753 template <typename T, typename A>
755 {
756 agxAssert( m_size );
757 m_elements[m_size-1].~T();
758 m_size--;
759
760// if (m_size < m_capacity * AGX_VECTOR_SHRINK_THRESHOLD)
761// this->reallocate((size_t)(m_size * AGX_VECTOR_RESIZE_FACTOR));
762 }
763
764 template <typename T, typename A>
766 {
767 size_t index = position - this->begin();
768 this->erase(index);
769 return this->begin() + index;
770 }
771
772 template <typename T, typename A>
774 {
775 size_t startIndex = start - this->begin();
776 size_t endIndex = end - this->begin();
777 this->erase(startIndex, endIndex);
778
779 return this->begin() + endIndex;
780 }
781
782
783 template <typename T, typename A>
785 {
786 agxAssert( m_size );
787
788 // removed unnecessary loop by replacing line below by this block
789 {
790 // TODO We should first run destructor and constructor on element before copying? Again we assume copy operator semantics to be 'proper'
791 for (size_t i = index + 1; i < m_size; i++)
792 m_elements[i-1] = m_elements[i];
793
794 /* Run destructor on trailing elements */
795 m_elements[m_size - 1].~T();
796
797 m_size--;
798
799 // if (m_size < m_capacity * AGX_VECTOR_SHRINK_THRESHOLD)
800 // this->reallocate((size_t)(m_size * AGX_VECTOR_RESIZE_FACTOR));
801 }
802 // this->erase(index, index+1);
803 }
804
805 template <typename T, typename A>
806 AGX_FORCE_INLINE void Vector<T, A>::erase(size_t start, size_t end)
807 {
808 agxAssert1(start < end && end <= m_size, "Erase bounds are not with array bounds!");
809 size_t numElements = end - start;
810
811 // TODO We should first run destructor and constructor on element before copying? Again we assume copy operator semantics to be 'proper'
812 for (size_t i = end; i < m_size; i++)
813 m_elements[i-numElements] = m_elements[i];
814
815 /* Run destructor on trailing elements */
816 this->destroyElements(m_size-numElements, m_size);
817
818 m_size -= numElements;
819
820 // if (m_size < m_capacity * AGX_VECTOR_SHRINK_THRESHOLD)
821 // this->reallocate((size_t)(m_size * AGX_VECTOR_RESIZE_FACTOR));
822 }
823
824 template <typename T, typename A>
826 {
827 size_t index = position - this->begin();
828 this->eraseFast(index);
829 return this->begin() + index;
830 }
831
832 template <typename T, typename A>
834 {
835 agxAssertN(index < m_size, "Array index %llu is out of bounds, current size is %llu", (long long unsigned)index, (long long unsigned)m_size);
836 m_elements[index] = m_elements[m_size-1];
837 m_elements[m_size - 1].~T(); // removed unnecessary loop by replacing line below by this one
838 // this->_destroyElements(m_size-1, m_size);
839 m_size--;
840 }
841
842 template <typename T, typename A> template <typename T2>
843 AGX_FORCE_INLINE bool Vector<T, A>::contains(const T2& element) const
844 {
845 return this->find(element) != m_size;
846 }
847
848 template <typename T, typename A> //template <typename T2>
849 AGX_FORCE_INLINE bool Vector<T, A>::contains(const T& element) const
850 {
851 return this->find(element) != m_size;
852 }
853
854
855 template <typename T, typename A> template <typename T2>
856 AGX_FORCE_INLINE size_t Vector<T, A>::find(const T2& element) const
857 {
858 for (size_t i = 0; i < m_size; i++)
859 {
860 if (m_elements[i] == element)
861 return i;
862 }
863
864 return m_size;
865 }
866
867 template <typename T, typename A> template <typename T2>
868 AGX_FORCE_INLINE bool Vector<T, A>::findAndErase(const T2& element, bool searchMultiple)
869 {
870 bool found = false;
871
872 for (size_t i = 0; i < m_size; i++)
873 {
874 if (m_elements[i] == element)
875 {
876 found = true;
877 this->erase(i);
878
879 if (!searchMultiple)
880 return true;
881
882 i--;
883 }
884 }
885
886 return found;
887 }
888
889
890 template <typename T, typename A>
892 {
893 size_t index = position - this->begin();
894 this->insert(index, value);
895 return this->begin() + index;
896 }
897
898 template <typename T, typename A> template <typename InputIterator>
899 AGX_FORCE_INLINE void Vector<T, A>::insert(const_iterator it, InputIterator first, InputIterator last)
900 {
901 // TODO Difference between iterators is always number of elements between them??
902 size_t numElements = std::distance( first, last );
903
904 if (numElements == 0)
905 return;
906
907 size_t index = it - this->begin();
908
909 if (m_size + numElements > m_capacity)
910 this->reallocate((size_t)((float)(m_size + numElements) * AGX_VECTOR_RESIZE_FACTOR));
911
912 for (size_t i = m_size; i > index; i--) {
913 ::new((void *)&m_elements[i + numElements - 1]) T(m_elements[i-1]);
914 m_elements[i-1].~T();
915 }
916
917 for (; first != last; first++)
918 ::new((void *)&m_elements[index++]) T(*first);
919
920 m_size += numElements;
921 }
922
923 template <typename T, typename A>
924 AGX_FORCE_INLINE void agx::Vector<T, A>::insert(const_iterator it, std::initializer_list<T> ilist)
925 {
926 this->insert(it, ilist.begin(), ilist.end());
927 }
928
929 template <typename T, typename A>
930 AGX_FORCE_INLINE void Vector<T, A>::insert(size_t index, const T& value)
931 {
932 agxAssertN(index <= m_size, "Insert with invalid index %llu, size is %llu", (long long unsigned)index, (long long unsigned)m_size);
933
934 if (m_size == m_capacity)
935 this->reallocate(std::max((size_t)AGX_VECTOR_MIN_SIZE, (size_t)((double)m_size * AGX_VECTOR_RESIZE_FACTOR)));
936
937 for (size_t i = m_size; i > index; i--) {
938 ::new((void *)&m_elements[i]) T(m_elements[i-1]);
939 m_elements[i-1].~T();
940 }
941
942 ::new((void *)&m_elements[index]) T(value);
943 m_size++;
944 }
945
946 template <typename T, typename A>
948 {
949 /* Check if new size is less than current size, which will remove trailing elements */
950 if (size < m_size)
951 {
952 this->destroyElements(size, m_size);
953 m_size = size;
954 }
955
956
957 /* Create new buffer */
958 size = std::max(size, (size_t)AGX_VECTOR_MIN_SIZE);
959 T *newBuf = reinterpret_cast<T*>(m_allocator.allocateBytes(size * sizeof(T)));
960
961 /* Initialize elements with old values. NOTE This only works as long as the copy constructor
962 has the same semantics as the assignment operator, which we will assume. Otherwise this has to
963 be done in two passes, first running default constructors, then assigning old values. */
964 for (size_t i = 0; i < m_size; i++)
965 ::new((void *)&newBuf[i]) T(m_elements[i]);
966
967
968 /* Destroy old elements and free buffer */
969 this->destroyElements(0, m_size);
970 m_allocator.deallocateBytes(m_elements, m_capacity * sizeof(T));
971
972 m_buffer = (void *)newBuf;
973 m_capacity = size;
974 }
975
976
977 template <typename T, typename A>
978 AGX_FORCE_INLINE void Vector<T, A>::constructElements(size_t startIndex, size_t endIndex)
979 {
980 for (size_t i = startIndex; i < endIndex; i++)
981 ::new((void *)&m_elements[i]) T();
982 }
983
984 template <typename T, typename A>
985 AGX_FORCE_INLINE void Vector<T, A>::constructElements(size_t startIndex, size_t endIndex, const T& value)
986 {
987 for (size_t i = startIndex; i < endIndex; i++)
988 ::new((void *)&m_elements[i]) T(value);
989 }
990
991 template <typename T, typename A>
992 AGX_FORCE_INLINE void Vector<T, A>::destroyElements(size_t startIndex, size_t endIndex)
993 {
994 for (size_t i = startIndex; i < endIndex; i++)
995 m_elements[i].~T();
996 }
997
998
999
1000 template <typename T, typename A>
1001 AGX_FORCE_INLINE A& Vector<T, A>::allocator() { return m_allocator; }
1002
1003 template <typename T, typename A>
1004 AGX_FORCE_INLINE const A& Vector<T, A>::allocator() const { return m_allocator; }
1005
1007 template <typename T, typename A>
1008 AGX_FORCE_INLINE size_t Vector<T, A>::getNumActiveElements() const { return m_size; }
1010
1011 template <typename VectorT>
1012 std::ostream& printVector( std::ostream& output, const VectorT& vec)
1013 {
1014 for (size_t i = 0; i < vec.size(); i++)
1015 {
1016 output << vec[i];
1017
1018 if (i < vec.size()-1)
1019 output << ", ";
1020 }
1021
1022 return output;
1023 }
1024
1025 template <typename T, typename A>
1026 std::ostream& operator << ( std::ostream& output, const Vector<T, A>& vec)
1027 {
1028 return printVector(output, vec);
1029 }
1030
1031
1032 template <typename T, typename A>
1033 std::ostream& operator << ( std::ostream& output, const VectorPOD<T, A>& vec)
1034 {
1035 return printVector(output, vec);
1036 }
1037
1038
1039 /* Iterators */
1040 template <typename T, typename A>
1042
1043 template <typename T, typename A>
1045
1046 template <typename T, typename A>
1048
1049 template <typename T, typename A>
1051
1052 template <typename T, typename A>
1054
1055 template <typename T, typename A>
1057
1058 template <typename T, typename A>
1060
1061 template <typename T, typename A>
1063
1064
1065
1066
1067 template<typename T, typename A>
1068 typename Vector<T, A>::iterator begin(Vector<T, A>& v) { return v.begin(); }
1069
1070 template<typename T, typename A>
1071 typename Vector<T, A>::const_iterator begin(const Vector<T, A>& v) { return v.begin(); }
1072
1073
1074 template <typename T, typename A>
1075 typename Vector<T, A>::iterator end(Vector<T, A>& v) { return v.end(); }
1076
1077 template <typename T, typename A>
1078 typename Vector<T, A>::const_iterator end(const Vector<T, A>& v) { return v.end(); }
1079
1080
1081
1082
1083
1084
1085
1086 //-----------------------------------------------------------------------------------------------------
1087 //--------------- VectorPOD ---------------------------------------------------------------------------
1088 //-----------------------------------------------------------------------------------------------------
1089
1090
1091
1092 template <typename T, typename A>
1093 VectorPOD<T, A>::VectorPOD(const A& allocator) : m_allocator(allocator), m_smoothingAverage(0.0)
1094 {
1095 static_assert( std::is_trivially_destructible<T>::value, "Non-POD type used in VectorPOD");
1096 m_allocator.setContainer(this);
1097 }
1098
1099 template <typename T, typename A>
1100 VectorPOD<T, A>::VectorPOD(size_t size, const T& value, const A& allocator) : m_allocator(allocator), m_smoothingAverage(0.0)
1101 {
1102 m_allocator.setContainer(this);
1103 this->resize(size, value);
1104 }
1105
1106 template <typename T, typename A>
1107 VectorPOD<T, A>::VectorPOD(const VectorPOD<T, A>& other) : m_smoothingAverage(0.0)
1108 {
1109 *this = other;
1110 }
1111
1112
1113
1114 template <typename T, typename A>
1115 VectorPOD<T, A>::VectorPOD(VectorPOD<T, A>&& other)
1116 : Container(std::move(other)), m_smoothingAverage(0.0)
1117 {
1118 // Move values
1119 m_allocator = std::move(other.m_allocator);
1120 m_allocator.setContainer(this);
1121 m_smoothingAverage = other.m_smoothingAverage;
1122
1123 // Assign default values to rvalue reference
1124 other.m_allocator = A();
1125 other.m_smoothingAverage = Real32(0);
1126 }
1127
1128
1129
1130 template <typename T, typename A>
1131 VectorPOD<T, A>::VectorPOD(const_iterator first, const_iterator end, const A& allocator) : m_allocator(allocator), m_smoothingAverage(0.0)
1132 {
1133 m_allocator.setContainer(this);
1134 this->insert(this->begin(), first, end);
1135 }
1136
1137 template <typename T, typename A>
1138 VectorPOD<T, A>::VectorPOD(std::initializer_list<T> values, const A& allocator)
1139 : m_allocator(allocator), m_smoothingAverage(0.0)
1140 {
1141 m_allocator.setContainer(this);
1142 using std::begin;
1143 using std::end;
1144 this->insert(begin(*this), begin(values), end(values));
1145 }
1146
1147
1148 template <typename T, typename A>
1150 {
1151 if (this->empty())
1152 return;
1153
1154 if (policy == MAINTAIN_BUFFER)
1155 {
1156 m_size = 0;
1157 }
1158 else if (policy == SHRINK_BUFFER)
1159 {
1160 m_allocator.deallocateBytes(m_buffer, m_capacity * sizeof(T));
1161 m_buffer = nullptr;
1162 m_size = 0;
1163 m_capacity = 0;
1164 m_smoothingAverage = 0.0;
1165 }
1166 else // SHRINK_BUFFER_AVERAGED
1167 {
1168 /* Smoothing average is never less than current size */
1169 if ((Real32)m_size > m_smoothingAverage)
1170 m_smoothingAverage = (Real32)m_size;
1171
1172 /* Update smoothing average */
1173 m_smoothingAverage = (Real32)(AGX_VECTOR_SMOOTHING_FACTOR * m_smoothingAverage + (1.0-AGX_VECTOR_SMOOTHING_FACTOR) * (float)m_size);
1174
1175 /* Clear size before reallocate so it does not copy elements from old buffer. */
1176 m_size = 0;
1177
1178 /* Reallocate buffer if the smoothing average is sufficiently below the current capacity */
1179 if (m_smoothingAverage/(Real32)m_capacity < AGX_VECTOR_SHRINK_THRESHOLD)
1180 this->reallocate((size_t)m_smoothingAverage);
1181 }
1182 }
1183
1184
1185 template <typename T, typename A>
1187 {
1188 if (m_capacity > m_size)
1189 {
1190 this->reallocate(m_size);
1191 }
1192 }
1193
1194
1195 template <typename T, typename A>
1197 {
1198 if (size > m_size)
1199 {
1200 if (size > m_capacity)
1201 this->reallocate(size);
1202
1203 this->constructElements(m_size, size);
1204 }
1205 else
1206 {
1207 if (size < (size_t)((double)m_capacity * AGX_VECTOR_SHRINK_THRESHOLD))
1208 this->reallocate(size);
1209 }
1210
1211 m_size = size;
1212 }
1213
1214
1215 template <typename T, typename A>
1216 AGX_FORCE_INLINE void VectorPOD<T, A>::resize(size_t size, const T& value)
1217 {
1218 if (size > m_size)
1219 {
1220 if (size > m_capacity)
1221 this->reallocate(size);
1222
1223 this->constructElements(m_size, size, value);
1224 }
1225 else
1226 {
1228 this->reallocate(size);
1229 }
1230
1231 m_size = size;
1232 }
1233
1234 template <typename T, typename A>
1236 {
1237 if (size > m_capacity)
1238 this->reallocate(size);
1239 }
1240
1241
1242 template <typename T, typename A>
1244 {
1245 if (size > m_capacity) {
1246 size_t newCapacity = std::max(m_capacity, size_t(AGX_VECTOR_MIN_SIZE));
1247 while (size > newCapacity)
1248 newCapacity = size_t((float)newCapacity * AGX_VECTOR_RESIZE_FACTOR);
1249 this->reallocate(newCapacity);
1250 }
1251 }
1252
1253
1254 template <typename T, typename A>
1256 {
1257 size_t newSize = m_size + numElements;
1258 if (newSize > m_capacity)
1259 this->reallocate((size_t)((float)newSize * AGX_VECTOR_RESIZE_FACTOR));
1260
1261 this->constructElements(m_size, newSize);
1262 m_size = newSize;
1263 return m_elements + m_size - numElements;
1264 }
1265
1266
1267
1268 template <typename T, typename A>
1270 {
1271 if (m_size != other.size())
1272 return false;
1273
1274 for (size_t i = 0; i < m_size; i++)
1275 if (m_elements[i] != other[i])
1276 return false;
1277
1278 return true;
1279 }
1280
1281 template <typename T, typename A>
1283 {
1284 if (m_size != other.size())
1285 return true;
1286
1287 for (size_t i = 0; i < m_size; i++)
1288 if (m_elements[i] != other[i])
1289 return true;
1290
1291 return false;
1292 }
1293
1294
1295 template <typename T, typename A>
1297 {
1298 if (this == &other)
1299 return *this;
1300
1301 m_allocator = other.m_allocator;
1302 m_allocator.setContainer(this);
1303
1304 if (other.size() > m_capacity || other.size() < (size_t)((double)m_capacity * AGX_VECTOR_SHRINK_THRESHOLD))
1305 this->reallocate(other.size());
1306
1307 if (other.size() > 0) {
1308 memcpy(m_elements, other.ptr(), other.size() * sizeof(T));
1309 }
1310
1311 m_size = other.size();
1312
1313 return *this;
1314 }
1315
1316 template <typename T, typename A>
1318 {
1319 m_allocator.deallocateBytes(m_elements, m_capacity * sizeof(T));
1320 }
1321
1322
1323 template <typename T, typename A>
1325
1326 template <typename T, typename A>
1328
1329 template <typename T, typename A>
1331 {
1332 agxAssertN(i < m_size, "Array index %llu is out of bounds, current size is %llu", (long long unsigned)i, (long long unsigned)m_size);
1333 return m_elements[i];
1334 }
1335
1336
1337 template <typename T, typename A>
1339 {
1340 agxVerifyN(index < m_size, "Array index %llu is out of bounds, current size is %llu", (long long unsigned)index, (long long unsigned)m_size);
1341 return m_elements[index];
1342 }
1343
1344
1345 template <typename T, typename A>
1347 {
1348 agxAssert1(m_size > 0, "Can not take front element of an empty vector!");
1349 return m_elements[0];
1350 }
1351
1352
1353 template <typename T, typename A>
1355 {
1356 agxAssert1(m_size > 0, "Can not take back element of an empty vector!");
1357 return m_elements[m_size-1];
1358 }
1359
1360
1361 template <typename T, typename A>
1363 {
1364 if (m_size == m_capacity)
1365 this->reallocate(std::max((size_t)AGX_VECTOR_MIN_SIZE, (size_t)( (float)m_size * AGX_VECTOR_RESIZE_FACTOR)));
1366
1367 m_elements[m_size] = value;
1368 m_size++;
1369 }
1370
1371
1372
1373 template <typename T, typename A>
1375 {
1376 if (m_size == m_capacity)
1377 this->reallocate(std::max((size_t)AGX_VECTOR_MIN_SIZE, (size_t)( (float)m_size * AGX_VECTOR_RESIZE_FACTOR)));
1378
1379 m_elements[m_size] = std::move(value);
1380 m_size++;
1381 }
1382
1383
1384
1385 template <typename T, typename A>
1387 {
1388 m_size--;
1389
1390// if (m_size < m_capacity * AGX_VECTOR_SHRINK_THRESHOLD)
1391// this->reallocate((size_t)(m_size * AGX_VECTOR_RESIZE_FACTOR));
1392 }
1393
1394 template <typename T, typename A>
1396 {
1397 size_t index = position - this->begin();
1398 this->erase(index);
1399 return this->begin() + index;
1400 }
1401
1402 template <typename T, typename A>
1404 {
1405 size_t startIndex = start - this->begin();
1406 size_t endIndex = end - this->begin();
1407 this->erase(startIndex, endIndex);
1408
1409 return this->begin() + endIndex;
1410 }
1411
1412
1413 template <typename T, typename A>
1415 {
1416 this->erase(index, index+1);
1417 }
1418
1419 template <typename T, typename A>
1420 AGX_FORCE_INLINE void VectorPOD<T, A>::erase(size_t start, size_t end)
1421 {
1422 agxAssert1(start < end && end <= m_size, "Erase bounds are not with array bounds!");
1423 size_t numElements = end - start;
1424
1425 // TODO We should first run destructor and constructor on element before copying? Again we assume copy operator semantics to be 'proper'
1426 for (size_t i = end; i < m_size; i++)
1427 m_elements[i-numElements] = m_elements[i];
1428
1429 m_size -= numElements;
1430
1431 // if (m_size < m_capacity * AGX_VECTOR_SHRINK_THRESHOLD)
1432 // this->reallocate((size_t)(m_size * AGX_VECTOR_RESIZE_FACTOR));
1433 }
1434
1435 template <typename T, typename A>
1437 {
1438 size_t index = position - this->begin();
1439 this->eraseFast(index);
1440 return this->begin() + index;
1441 }
1442
1443 template <typename T, typename A>
1445 {
1446 agxAssertN(index < m_size, "Array index %llu is out of bounds, current size is %llu", (long long unsigned)index, (long long unsigned)m_size);
1447 m_elements[index] = m_elements[m_size-1];
1448 m_size--;
1449 }
1450
1451 template <typename T, typename A> template <typename T2>
1452 AGX_FORCE_INLINE bool VectorPOD<T, A>::contains(const T2& element) const
1453 {
1454 return this->find(element) != m_size;
1455 }
1456
1457 template <typename T, typename A> //template <typename T2>
1458 AGX_FORCE_INLINE bool VectorPOD<T, A>::contains(const T& element) const
1459 {
1460 return this->find(element) != m_size;
1461 }
1462
1463
1464 template <typename T, typename A> template <typename T2>
1465 AGX_FORCE_INLINE size_t VectorPOD<T, A>::find(const T2& element) const
1466 {
1467 for (size_t i = 0; i < m_size; i++)
1468 {
1469 if (m_elements[i] == element)
1470 return i;
1471 }
1472
1473 return m_size;
1474 }
1475
1476
1477 template <typename T, typename A>
1478 AGX_FORCE_INLINE bool VectorPOD<T, A>::findAndErase(const T& element, bool searchMultiple)
1479 {
1480 bool found = false;
1481
1482 for (size_t i = 0; i < m_size; i++)
1483 {
1484 if (m_elements[i] == element)
1485 {
1486 found = true;
1487 this->erase(i);
1488
1489 if (!searchMultiple)
1490 return true;
1491
1492 i--;
1493 }
1494 }
1495
1496 return found;
1497 }
1498
1499
1500 template <typename T, typename A>
1502 {
1503 agxAssert( position >= begin() );
1504 size_t index = position - this->begin();
1505 this->insert(index, value);
1506 return this->begin() + index;
1507 }
1508
1509
1510 template <typename T, typename A>
1511 AGX_FORCE_INLINE void VectorPOD<T, A>::insert(const_iterator it, std::initializer_list<T> ilist)
1512 {
1513 this->insert(it, ilist.begin(), ilist.end());
1514 }
1515
1516 template <typename T, typename A> template <typename InputIterator>
1517 AGX_FORCE_INLINE void VectorPOD<T, A>::insert(const_iterator it, InputIterator first, InputIterator last)
1518 {
1519 // TODO Difference between iterators is always number of elements between them??
1520 size_t numElements = std::distance( first, last );
1521 if (numElements == 0)
1522 return;
1523
1524 size_t index = it - this->begin();
1525
1526 if (m_size + numElements > m_capacity)
1527 this->reallocate((size_t)((float)(m_size + numElements) * AGX_VECTOR_RESIZE_FACTOR));
1528
1529 for (size_t i = m_size; i > index; i--)
1530 memcpy(&m_elements[i + numElements - 1], &m_elements[i-1], sizeof(T));
1531
1532 for (; first != last; first++)
1533 memcpy(&m_elements[index++], &(*first), sizeof(T));
1534
1535 m_size += numElements;
1536 }
1537
1538 template <typename T, typename A>
1539 AGX_FORCE_INLINE void VectorPOD<T, A>::insert(size_t index, const T& value)
1540 {
1541 if (m_size == m_capacity)
1542 this->reallocate(std::max((size_t)AGX_VECTOR_MIN_SIZE, (size_t)((double)m_size * AGX_VECTOR_RESIZE_FACTOR)));
1543
1544 for (size_t i = m_size; i > index; i--)
1545 memcpy(&m_elements[i], &m_elements[i-1], sizeof(T));
1546
1547 memcpy(&m_elements[index], &value, sizeof(T));
1548 m_size++;
1549 }
1550
1551
1552
1553 template <typename T, typename A>
1555 {
1556 /* Check if new size is less than current size, which will remove trailing elements */
1557 if (size < m_size)
1558 m_size = size;
1559
1560 /* Create new buffer */
1561 size = std::max(size, (size_t)AGX_VECTOR_MIN_SIZE);
1562 void *newBuf = m_allocator.allocateBytes(size * sizeof(T));
1563 void *oldBuf = m_elements;
1564
1565 if (m_size > 0) {
1566 memcpy(newBuf, oldBuf, m_size * sizeof(T));
1567 }
1568
1569 m_buffer = newBuf;
1570
1571 /* Free old buffer */
1572 m_allocator.deallocateBytes(oldBuf, m_capacity * sizeof(T));
1573 m_capacity = size;
1574 }
1575
1576
1577 template <typename T, typename A>
1578 AGX_FORCE_INLINE void VectorPOD<T, A>::constructElements(size_t startIndex, size_t endIndex)
1579 {
1580 for (size_t i = startIndex; i < endIndex; i++)
1581 memcpy(&m_elements[i], &s_initializer, sizeof(T));
1582 }
1583
1584 template <typename T, typename A>
1585 AGX_FORCE_INLINE void VectorPOD<T, A>::constructElements(size_t startIndex, size_t endIndex, const T& value)
1586 {
1587 for (size_t i = startIndex; i < endIndex; i++)
1588 memcpy((void*)&m_elements[i], (void*)&value, sizeof(T));
1589 }
1590
1591
1592 template <typename T, typename A>
1594
1595 template <typename T, typename A>
1596 AGX_FORCE_INLINE const A& VectorPOD<T, A>::allocator() const { return m_allocator; }
1597
1599 template <typename T, typename A>
1600 AGX_FORCE_INLINE size_t VectorPOD<T, A>::getNumActiveElements() const { return m_size; }
1602
1603 /* Initializer instance */
1604 template <typename T, typename A>
1605 T VectorPOD<T, A>::s_initializer;
1606
1607 /* Iterators */
1608 template <typename T, typename A>
1609 AGX_FORCE_INLINE typename VectorPOD<T, A>::iterator VectorPOD<T, A>::begin() { return m_elements; }
1610
1611 template <typename T, typename A>
1613
1614 template <typename T, typename A>
1616
1617 template <typename T, typename A>
1619
1620 template <typename T, typename A>
1622
1623 template <typename T, typename A>
1625
1626 template <typename T, typename A>
1628
1629 template <typename T, typename A>
1631
1632
1633 template<typename T, typename A>
1635
1636 template<typename T, typename A>
1638
1639 template <typename T, typename A>
1641
1642 template <typename T, typename A>
1643 typename VectorPOD<T, A>::const_iterator end(const VectorPOD<T, A>& v) { return v.end(); }
1644
1645 #undef m_elements
1646 #undef m_size
1647 #undef m_capacity
1648
1649
1650 template <typename T, typename A>
1652 {
1653 std::swap(this->m_buffer, other.m_buffer);
1654 std::swap(this->m_size, other.m_size);
1655 std::swap(this->m_capacity, other.m_capacity);
1656 std::swap(this->m_smoothingAverage, other.m_smoothingAverage);
1657 }
1658
1659 template <typename T, typename A>
1661 {
1662 std::swap(this->m_buffer, other.m_buffer);
1663 std::swap(this->m_size, other.m_size);
1664 std::swap(this->m_capacity, other.m_capacity);
1665 std::swap(this->m_smoothingAverage, other.m_smoothingAverage);
1666 }
1667
1668}
1669
1670#ifdef _MSC_VER
1671#pragma warning (pop)
1672#endif
1673
1674#endif /* _AGX_VECTOR_H_ */
#define m_size
Definition: agx/Vector.h:429
#define AGX_VECTOR_SMOOTHING_FACTOR
Definition: agx/Vector.h:424
#define m_capacity
Definition: agx/Vector.h:430
#define m_elements
Definition: agx/Vector.h:428
#define AGX_VECTOR_SHRINK_THRESHOLD
Definition: agx/Vector.h:425
#define AGX_VECTOR_RESIZE_FACTOR
Definition: agx/Vector.h:423
#define AGX_VECTOR_MIN_SIZE
Definition: agx/Vector.h:426
Templated allocator.
Definition: Allocator.h:107
Byte allocator.
Definition: Allocator.h:55
void setContainer(class Container *)
Definition: Allocator.h:71
void deallocateBytes(void *buffer, size_t numBytes)
Deallocate a section previously allocated using allocateBytes method.
void * allocateBytes(size_t numBytes, size_t alignment=16)
Allocate a memory section of specified alignment.
The Container is the base class for several of the container classes proided by AGX,...
Definition: Container.h:35
size_t m_size
Definition: Container.h:94
size_t m_capacity
Definition: Container.h:95
ClearPolicy
agxData::Values from this enumeration is passed to the subclasses' 'clear' method in order to control...
Definition: Container.h:43
@ SHRINK_BUFFER_AVERAGED
Buffer is shrunk if a smoothing average (which is updated each clear call) goes below a threshold.
Definition: Container.h:45
size_t capacity() const
Returns the size of the memory are used by the container to store its elements.
Definition: Container.h:135
void * m_buffer
Definition: Container.h:96
size_t size() const
Definition: Container.h:134
Vector containing 'raw' data.
Definition: agx/Vector.h:246
size_t size_type
Definition: agx/Vector.h:254
VectorPOD(size_t size, const T &value=T(), const Allocator &allocator=Allocator())
void resize(size_t size)
Resize the vector, which then enables direct addressing using the bracket '[]' operator.
Definition: agx/Vector.h:1196
const_iterator begin() const
Definition: agx/Vector.h:1615
iterator insert(iterator position, const T &value)
Definition: agx/Vector.h:1501
void push_back(const T &value)
Definition: agx/Vector.h:1362
reverse_iterator rbegin()
Definition: agx/Vector.h:1621
const_iterator end() const
Definition: agx/Vector.h:1618
std::reverse_iterator< iterator > reverse_iterator
Definition: agx/Vector.h:322
reverse_iterator rend()
Definition: agx/Vector.h:1624
const_reverse_iterator rend() const
Definition: agx/Vector.h:1630
Allocator & allocator()
Definition: agx/Vector.h:1593
bool contains(const T2 &element) const
Test if the vector contains a certain element.
Definition: agx/Vector.h:1452
VectorPOD(const_iterator first, const_iterator end, const Allocator &allocator=Allocator())
VectorPOD(std::initializer_list< T > values, const Allocator &allocator=Allocator())
iterator begin()
Definition: agx/Vector.h:1609
iterator eraseFast(const_iterator position)
Fast erase, replacing the erased element with the last element.
Definition: agx/Vector.h:1436
T & at(size_t index) const
Definition: agx/Vector.h:1338
ptrdiff_t difference_type
Definition: agx/Vector.h:257
void shrink_to_fit()
Reduce the capacity of the vector to the actual size (number of elements)
Definition: agx/Vector.h:1186
VectorPOD(VectorPOD< T, Allocator > &&other)
T * ptr()
Get access to the internal data buffer.
Definition: agx/Vector.h:1324
VectorPOD(const VectorPOD< T, Allocator > &other)
const_reverse_iterator rbegin() const
Definition: agx/Vector.h:1627
bool findAndErase(const T &element, bool searchMultiple=false)
Find and erase an element.
Definition: agx/Vector.h:1478
const T * const_iterator
Definition: agx/Vector.h:256
void erase(size_t start, size_t end)
Definition: agx/Vector.h:1420
size_t find(const T2 &element) const
Find the index to a matching element, return size() if not found.
Definition: agx/Vector.h:1465
const T & const_reference
Definition: agx/Vector.h:253
void insert(size_t index, const T &value)
Definition: agx/Vector.h:1539
void erase(size_t index)
Erase elements using indices instead of iterators.
Definition: agx/Vector.h:1414
void reserveAtLeast(size_t size)
Reserve capacity in the vector.
Definition: agx/Vector.h:1243
void eraseFast(size_t index)
Definition: agx/Vector.h:1444
T & back() const
Definition: agx/Vector.h:1354
void insert(const_iterator it, InputIterator first, InputIterator last)
Definition: agx/Vector.h:1517
void reserve(size_t size)
Reserve capacity in the vector.
Definition: agx/Vector.h:1235
const T * ptr() const
Definition: agx/Vector.h:1327
void swap(VectorPOD &other)
Definition: agx/Vector.h:1660
const T * const_pointer
Definition: agx/Vector.h:251
void clear(ClearPolicy policy=SHRINK_BUFFER_AVERAGED)
Remove all elements, optionally with maintained buffer allocation.
Definition: agx/Vector.h:1149
bool contains(const T &element) const
Definition: agx/Vector.h:1458
iterator end()
Definition: agx/Vector.h:1612
const Allocator & allocator() const
Definition: agx/Vector.h:1596
void insert(const_iterator it, std::initializer_list< T > ilist)
Definition: agx/Vector.h:1511
iterator erase(iterator start, iterator end)
Definition: agx/Vector.h:1403
VectorPOD(const Allocator &allocator=Allocator())
void resize(size_t size, const T &value)
Definition: agx/Vector.h:1216
void push_back(T &&value)
Definition: agx/Vector.h:1374
T * increment(size_t numElements=1)
Resize using a increment.
Definition: agx/Vector.h:1255
iterator erase(iterator position)
STL erase functionality.
Definition: agx/Vector.h:1395
T & front() const
Definition: agx/Vector.h:1346
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: agx/Vector.h:323
Templated vector class.
Definition: agx/Vector.h:53
void clear(ClearPolicy policy=SHRINK_BUFFER_AVERAGED)
Remove all elements, optionally with maintained buffer allocation.
Definition: agx/Vector.h:491
size_t size_type
Definition: agx/Vector.h:61
reverse_iterator rbegin()
Definition: agx/Vector.h:1053
size_t find(const T2 &element) const
Find the index to a matching element, return size() if not found.
Definition: agx/Vector.h:856
iterator end()
Definition: agx/Vector.h:1044
const T & const_reference
Definition: agx/Vector.h:60
std::random_access_iterator_tag iterator_category
Definition: agx/Vector.h:64
Vector(const Vector< T, Allocator > &other)
void insert(const_iterator it, InputIterator first, InputIterator last)
Definition: agx/Vector.h:899
Allocator & allocator()
Definition: agx/Vector.h:1001
void reserveAtLeast(size_t size)
Reserve capacity in the vector.
Definition: agx/Vector.h:592
void push_back(T &&value)
Definition: agx/Vector.h:741
void insert(size_t index, const T &value)
Definition: agx/Vector.h:930
const Allocator & allocator() const
Definition: agx/Vector.h:1004
Vector(Vector< T, Allocator > &&other)
Definition: agx/Vector.h:460
void insert(const_iterator it, std::initializer_list< T > ilist)
Definition: agx/Vector.h:924
Vector(std::initializer_list< T > values, const Allocator &allocator=Allocator())
void swap(Vector &other)
Definition: agx/Vector.h:1651
void push_back(const T &value)
Definition: agx/Vector.h:727
iterator erase(iterator start, iterator end)
Definition: agx/Vector.h:773
const_reverse_iterator rbegin() const
Definition: agx/Vector.h:1059
bool operator==(const Vector< T, Allocator > &other) const
Compare with other vector, return true if same size and all pairs are equal.
Definition: agx/Vector.h:619
T * ptr()
Get access to the internal data buffer.
Definition: agx/Vector.h:677
bool findAndErase(const T2 &element, bool searchMultiple=false)
Find and erase an element.
Definition: agx/Vector.h:868
bool contains(const T &element) const
Definition: agx/Vector.h:849
ptrdiff_t difference_type
Definition: agx/Vector.h:65
void resize(size_t size)
Resize the vector, which then enables direct addressing using the bracket '[]' operator.
Definition: agx/Vector.h:540
T & at(size_t index) const
Definition: agx/Vector.h:691
void eraseFast(size_t index)
Definition: agx/Vector.h:833
const_reverse_iterator rend() const
Definition: agx/Vector.h:1062
const T * const_iterator
Definition: agx/Vector.h:63
bool operator!=(const Vector< T, Allocator > &other) const
Definition: agx/Vector.h:632
T & front() const
Definition: agx/Vector.h:699
Vector(size_t size, const T &value=T(), const Allocator &allocator=Allocator())
void shrink_to_fit()
Reduce the capacity of the vector to the actual size (number of elements)
Definition: agx/Vector.h:531
iterator begin()
Definition: agx/Vector.h:1041
Vector(const_iterator first, const_iterator end, const Allocator &allocator=Allocator())
T & back() const
Definition: agx/Vector.h:707
void reserve(size_t size)
Reserve capacity in the vector.
Definition: agx/Vector.h:583
const T * ptr() const
Definition: agx/Vector.h:680
T * iterator
Definition: agx/Vector.h:62
void erase(size_t index)
Erase elements using indices instead of iterators.
Definition: agx/Vector.h:784
void pop_back()
Definition: agx/Vector.h:754
void push_back(const T2 &value)
Definition: agx/Vector.h:715
iterator eraseFast(const_iterator position)
Fast erase, replacing the erased element with the last element.
Definition: agx/Vector.h:825
T & operator[](size_t i) const
Definition: agx/Vector.h:684
void erase(size_t start, size_t end)
Definition: agx/Vector.h:806
iterator erase(iterator position)
STL erase functionality.
Definition: agx/Vector.h:765
Vector(const Allocator &allocator=Allocator())
const T * const_pointer
Definition: agx/Vector.h:58
iterator insert(iterator position, const T &value)
Definition: agx/Vector.h:891
Vector< T, Allocator > & operator=(const Vector< T, Allocator > &other)
Definition: agx/Vector.h:646
std::reverse_iterator< iterator > reverse_iterator
Definition: agx/Vector.h:137
const_iterator begin() const
Definition: agx/Vector.h:1047
const_iterator end() const
Definition: agx/Vector.h:1050
bool contains(const T2 &element) const
Test if the vector contains a certain element.
Definition: agx/Vector.h:843
T & reference
Definition: agx/Vector.h:59
T * increment(size_t numElements=1)
Resize using a increment.
Definition: agx/Vector.h:605
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: agx/Vector.h:138
reverse_iterator rend()
Definition: agx/Vector.h:1056
void resize(size_t size, const T &value)
Definition: agx/Vector.h:562
#define agxAssert1(expr, msg)
Definition: debug.h:144
#define agxAssertN(expr, format,...)
Definition: debug.h:145
#define agxVerifyN(expr, format,...)
Definition: debug.h:133
#define agxAssert(expr)
Definition: debug.h:143
#define DOXYGEN_END_INTERNAL_BLOCK()
Definition: macros.h:89
#define DOXYGEN_START_INTERNAL_BLOCK()
Definition: macros.h:88
#define AGX_FORCE_INLINE
Definition: macros.h:58
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
std::ostream & printVector(std::ostream &output, const VectorT &vec)
Definition: agx/Vector.h:1012
LinearProbingHashSetImplementation< KeyT, HashT >::iterator end(LinearProbingHashSetImplementation< KeyT, HashT > &set)
std::ostream & operator<<(std::ostream &os, const agx::AddedMassInteraction::Matrix6x6 &m)
float Real32
Definition: Real.h:44
LinearProbingHashSetImplementation< KeyT, HashT >::iterator begin(LinearProbingHashSetImplementation< KeyT, HashT > &set)
STL namespace.
void swap(agx::Name &lhs, agx::Name &rhs)
Definition: Name.h:323
Data type to bind an index and ranges associated with it.
Definition: SparseTypes.h:30