casacore
Loading...
Searching...
No Matches
uvector.h
Go to the documentation of this file.
1#ifndef AOCOMMON_UVECTOR_H_
2#define AOCOMMON_UVECTOR_H_
3
4#include <algorithm>
5#include <cstring>
6#include <iterator>
7#include <memory>
8#include <stdexcept>
9#include <utility>
10
17
18namespace aocommon {
19
24
76template <typename Tp, typename Alloc = std::allocator<Tp>>
77class UVector : private Alloc {
78 static_assert(std::is_standard_layout<Tp>(),
79 "A UVector can only hold classes with standard layout");
80
81 public:
83 typedef Tp value_type;
85 typedef Alloc allocator_type;
87 typedef Tp& reference;
89 typedef const Tp& const_reference;
91 typedef Tp* pointer;
93 typedef const Tp* const_pointer;
95 typedef Tp* iterator;
97 typedef const Tp* const_iterator;
99 typedef std::reverse_iterator<iterator> reverse_iterator;
101 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
103 typedef std::ptrdiff_t difference_type;
105 typedef std::size_t size_t;
107 typedef std::size_t size_type;
108
109 private:
110#if __cplusplus > 201402L
111 typedef typename std::allocator_traits<allocator_type>::is_always_equal allocator_is_always_equal;
112#else
113 typedef std::false_type allocator_is_always_equal;
114#endif
116
117 public:
121 explicit UVector(const allocator_type& allocator = Alloc()) noexcept
122 : Alloc(allocator), _begin(nullptr), _end(nullptr), _endOfStorage(nullptr) {}
123
131 explicit UVector(size_t n) : _begin(allocate(n)), _end(_begin + n), _endOfStorage(_end) {}
132
140 UVector(size_t n, const value_type& val, const allocator_type& allocator = Alloc())
141 : Alloc(allocator), _begin(allocate(n)), _end(_begin + n), _endOfStorage(_end) {
142 std::uninitialized_fill_n<Tp*, size_t>(_begin, n, val);
143 }
144
150 template <class InputIterator>
151 UVector(InputIterator first, InputIterator last, const allocator_type& allocator = Alloc())
152 : Alloc(allocator) {
153 construct_from_range<InputIterator>(first, last, std::is_integral<InputIterator>());
154 }
155
163 : Alloc(std::allocator_traits<Alloc>::select_on_container_copy_construction(
164 static_cast<allocator_type>(other))),
165 _begin(allocate(other.size())),
166 _end(_begin + other.size()),
168 std::copy(other._begin, other._end, _begin);
169 }
170
175 UVector(const UVector<Tp, Alloc>& other, const allocator_type& allocator)
176 : Alloc(allocator),
177 _begin(allocate(other.size())),
178 _end(_begin + other.size()),
180 std::copy(other._begin, other._end, _begin);
181 }
182
186 UVector(UVector<Tp, Alloc>&& other) noexcept
187 : Alloc(std::move(other)),
188 _begin(other._begin),
189 _end(other._end),
190 _endOfStorage(other._endOfStorage) {
191 other._begin = nullptr;
192 other._end = nullptr;
193 other._endOfStorage = nullptr;
194 }
195
200 UVector(UVector<Tp, Alloc>&& other, const allocator_type& allocator) noexcept
201 : Alloc(allocator),
202 _begin(other._begin),
203 _end(other._end),
204 _endOfStorage(other._endOfStorage) {
205 other._begin = nullptr;
206 other._end = nullptr;
207 other._endOfStorage = nullptr;
208 }
209
214 UVector(std::initializer_list<Tp> initlist, const allocator_type& allocator = Alloc())
215 : Alloc(allocator),
216 _begin(allocate(initlist.size())),
217 _end(_begin + initlist.size()),
219 iterator destIter = _begin;
220 for (typename std::initializer_list<Tp>::const_iterator i = initlist.begin();
221 i != initlist.end(); ++i) {
222 *destIter = *i;
223 ++destIter;
224 }
225 }
226
228 ~UVector() noexcept { deallocate(); }
229
236 return assign_copy_from(
237 other, typename std::allocator_traits<Alloc>::propagate_on_container_copy_assignment());
238 }
239
246 std::allocator_traits<Alloc>::propagate_on_container_move_assignment::value ||
247 allocator_is_always_equal::value) {
248 return assign_move_from(
249 std::move(other),
250 typename std::allocator_traits<Alloc>::propagate_on_container_move_assignment());
251 }
252
254 iterator begin() noexcept { return _begin; }
255
257 const_iterator begin() const noexcept { return _begin; }
258
260 iterator end() noexcept { return _end; }
261
263 const_iterator end() const noexcept { return _end; }
264
266 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
267
270
272 reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
273
276
278 const_iterator cbegin() const noexcept { return _begin; }
279
281 const_iterator cend() const noexcept { return _end; }
282
285
288
290 size_t size() const noexcept { return _end - _begin; }
291
293 size_t max_size() const noexcept { return Alloc::max_size(); }
294
305 void resize(size_t n) {
306 if (capacity() < n) {
307 size_t newSize = enlarge_size(n);
308 pointer newStorage = allocate(newSize);
309 std::move(_begin, _end, newStorage);
310 deallocate();
311 _begin = newStorage;
312 _endOfStorage = _begin + newSize;
313 }
314 _end = _begin + n;
315 }
316
325 void resize(size_t n, const Tp& val) {
326 size_t oldSize = size();
327 if (capacity() < n) {
328 pointer newStorage = allocate(n);
329 std::move(_begin, _end, newStorage);
330 deallocate();
331 _begin = newStorage;
332 _endOfStorage = _begin + n;
333 }
334 _end = _begin + n;
335 if (oldSize < n) std::uninitialized_fill<Tp*>(_begin + oldSize, _end, val);
336 }
337
340 size_t capacity() const noexcept { return _endOfStorage - _begin; }
341
344 bool empty() const noexcept { return _begin == _end; }
345
357 void reserve(size_t n) {
358 if (capacity() < n) {
359 const size_t curSize = size();
360 pointer newStorage = allocate(n);
361 std::move(_begin, _begin + curSize, newStorage);
362 deallocate();
363 _begin = newStorage;
364 _end = newStorage + curSize;
365 _endOfStorage = _begin + n;
366 }
367 }
368
379 const size_t curSize = size();
380 if (curSize == 0) {
381 deallocate();
382 _begin = nullptr;
383 _end = nullptr;
384 _endOfStorage = nullptr;
385 } else if (curSize < capacity()) {
386 pointer newStorage = allocate(curSize);
387 std::move(_begin, _begin + curSize, newStorage);
388 deallocate();
389 _begin = newStorage;
390 _end = newStorage + curSize;
391 _endOfStorage = _begin + curSize;
392 }
393 }
394
396 Tp& operator[](size_t index) noexcept { return _begin[index]; }
397
399 const Tp& operator[](size_t index) const noexcept { return _begin[index]; }
400
405 Tp& at(size_t index) {
406 check_bounds(index);
407 return _begin[index];
408 }
409
414 const Tp& at(size_t index) const {
415 check_bounds(index);
416 return _begin[index];
417 }
418
420 Tp& front() noexcept { return *_begin; }
421
423 const Tp& front() const noexcept { return *_begin; }
424
426 Tp& back() noexcept { return *(_end - 1); }
427
429 const Tp& back() const noexcept { return *(_end - 1); }
430
432 Tp* data() noexcept { return _begin; }
433
435 const Tp* data() const noexcept { return _begin; }
436
443 template <class InputIterator>
444 void assign(InputIterator first, InputIterator last) {
445 assign_from_range<InputIterator>(first, last, std::is_integral<InputIterator>());
446 }
447
453 void assign(size_t n, const Tp& val) {
454 if (n > capacity()) {
455 iterator newStorage = allocate(n);
456 deallocate();
457 _begin = newStorage;
458 _endOfStorage = _begin + n;
459 }
460 _end = _begin + n;
461 std::uninitialized_fill_n<Tp*, size_t>(_begin, n, val);
462 }
463
469 void assign(std::initializer_list<Tp> initlist) {
470 if (initlist.size() > capacity()) {
471 iterator newStorage = allocate(initlist.size());
472 deallocate();
473 _begin = newStorage;
474 _endOfStorage = _begin + initlist.size();
475 }
476 _end = _begin + initlist.size();
477 iterator destIter = _begin;
478 for (typename std::initializer_list<Tp>::const_iterator i = initlist.begin();
479 i != initlist.end(); ++i) {
480 *destIter = *i;
481 ++destIter;
482 }
483 }
484
489 void push_back(const Tp& item) {
491 *_end = item;
492 ++_end;
493 }
494
503 void push_back(Tp&& item) {
505 *_end = std::move(item);
506 ++_end;
507 }
508
510 void pop_back() { --_end; }
511
520 iterator insert(const_iterator position, const Tp& item) {
521 if (_end == _endOfStorage) {
522 size_t index = position - _begin;
523 enlarge_for_insert(enlarge_size(1), index, 1);
524 position = _begin + index;
525 } else {
526 std::move_backward(const_cast<iterator>(position), _end, _end + 1);
527 ++_end;
528 }
529 *const_cast<iterator>(position) = item;
530 return const_cast<iterator>(position);
531 }
532
543 iterator insert(const_iterator position, size_t n, const Tp& val) {
544 if (capacity() < size() + n) {
545 size_t index = position - _begin;
546 enlarge_for_insert(enlarge_size(n), index, n);
547 position = _begin + index;
548 } else {
549 std::move_backward(const_cast<iterator>(position), _end, _end + n);
550 _end += n;
551 }
552 std::uninitialized_fill_n<Tp*, size_t>(const_cast<iterator>(position), n, val);
553 return const_cast<iterator>(position);
554 }
555
566 template <class InputIterator>
567 iterator insert(const_iterator position, InputIterator first, InputIterator last) {
568 return insert_from_range<InputIterator>(position, first, last,
569 std::is_integral<InputIterator>());
570 }
571
585 iterator insert(const_iterator position, Tp&& item) {
586 if (_end == _endOfStorage) {
587 size_t index = position - _begin;
588 enlarge_for_insert(enlarge_size(1), index, 1);
589 position = _begin + index;
590 } else {
591 std::move_backward(const_cast<iterator>(position), _end, _end + 1);
592 ++_end;
593 }
594 *const_cast<iterator>(position) = std::move(item);
595 return const_cast<iterator>(position);
596 }
597
607 iterator insert(const_iterator position, std::initializer_list<Tp> initlist) {
608 if (capacity() < size() + initlist.size()) {
609 size_t index = position - _begin;
610 enlarge_for_insert(enlarge_size(initlist.size()), index, initlist.size());
611 position = _begin + index;
612 } else {
613 std::move_backward(const_cast<iterator>(position), _end, _end + initlist.size());
614 _end += initlist.size();
615 }
616 iterator destIter = const_cast<iterator>(position);
617 for (typename std::initializer_list<Tp>::const_iterator i = initlist.begin();
618 i != initlist.end(); ++i) {
619 *destIter = *i;
620 ++destIter;
621 }
622 return const_cast<iterator>(position);
623 }
624
632 std::move(const_cast<iterator>(position) + 1, _end, const_cast<iterator>(position));
633 --_end;
634 return const_cast<iterator>(position);
635 }
636
645 std::move(const_cast<iterator>(last), _end, const_cast<iterator>(first));
646 _end -= last - first;
647 return const_cast<iterator>(first);
648 }
649
661 void swap(UVector<Tp, Alloc>& other) noexcept {
662 swap(other, typename std::allocator_traits<Alloc>::propagate_on_container_swap());
663 }
664
666 void clear() { _end = _begin; }
667
676 template <typename... Args>
677 iterator emplace(const_iterator position, Args&&... args) {
678 if (_end == _endOfStorage) {
679 size_t index = position - _begin;
680 enlarge_for_insert(enlarge_size(1), index, 1);
681 position = _begin + index;
682 } else {
683 std::move_backward(const_cast<iterator>(position), _end, _end + 1);
684 ++_end;
685 }
686 *const_cast<iterator>(position) = Tp(std::forward<Args>(args)...);
687 return const_cast<iterator>(position);
688 }
689
695 template <typename... Args>
696 Tp& emplace_back(Args&&... args) {
698 *_end = Tp(std::forward<Args>(args)...);
699 ++_end;
700 return back();
701 }
702
704 allocator_type get_allocator() const noexcept { return *this; }
705
706 // --- NON STANDARD METHODS ---
707
721 if (capacity() < size() + n) {
722 size_t index = position - _begin;
723 enlarge_for_insert(enlarge_size(n), index, n);
724 position = _begin + index;
725 } else {
726 std::move_backward(const_cast<iterator>(position), _end, _end + n);
727 _end += n;
728 }
729 return const_cast<iterator>(position);
730 }
731
739 template <class InputIterator>
740 void push_back(InputIterator first, InputIterator last) {
741 push_back_range<InputIterator>(first, last, std::is_integral<InputIterator>());
742 }
743
751 void push_back(size_t n, const Tp& val) {
752 if (capacity() - size() < n) {
754 }
755 std::uninitialized_fill_n<Tp*, size_t>(_end, n, val);
756 _end += n;
757 }
758
765 void push_back(std::initializer_list<Tp> initlist) {
766 if (capacity() - size() < initlist.size()) {
767 enlarge(enlarge_size(initlist.size()));
768 }
769 for (typename std::initializer_list<Tp>::iterator i = initlist.begin(); i != initlist.end();
770 ++i) {
771 *_end = *i;
772 ++_end;
773 }
774 }
775
782 void push_back_uninitialized(size_t n) { resize(size() + n); }
783
784 private:
785 pointer allocate(size_t n) { return Alloc::allocate(n); }
786
787 void deallocate() noexcept { deallocate(_begin, capacity()); }
788
789 void deallocate(pointer begin, size_t n) noexcept {
790 if (begin != nullptr) Alloc::deallocate(begin, n);
791 }
792
793 template <typename InputIterator>
794 void construct_from_range(InputIterator first, InputIterator last, std::false_type) {
796 first, last, typename std::iterator_traits<InputIterator>::iterator_category());
797 }
798
799 template <typename Integral>
800 void construct_from_range(Integral n, Integral val, std::true_type) {
801 _begin = allocate(n);
802 _end = _begin + n;
804 std::uninitialized_fill_n<Tp*, size_t>(_begin, n, val);
805 }
806
807 template <typename InputIterator>
808 void construct_from_range(InputIterator first, InputIterator last, std::forward_iterator_tag) {
809 size_t n = std::distance(first, last);
810 _begin = allocate(n);
811 _end = _begin + n;
812 _endOfStorage = _begin + n;
813 Tp* destIter = _begin;
814 while (first != last) {
815 *destIter = *first;
816 ++destIter;
817 ++first;
818 }
819 }
820
821 template <typename InputIterator>
822 void assign_from_range(InputIterator first, InputIterator last, std::false_type) {
824 first, last, typename std::iterator_traits<InputIterator>::iterator_category());
825 }
826
827 // This function is called from assign(iter,iter) when Tp is an integral. In
828 // that case, the user tried to call assign(n, &val), but it got caught by the
829 // wrong overload.
830 template <typename Integral>
831 void assign_from_range(Integral n, Integral val, std::true_type) {
832 if (size_t(n) > capacity()) {
833 iterator newStorage = allocate(n);
834 deallocate();
835 _begin = newStorage;
836 _endOfStorage = _begin + n;
837 }
838 _end = _begin + n;
839 std::uninitialized_fill_n<Tp*, size_t>(_begin, n, val);
840 }
841
842 template <typename InputIterator>
843 void assign_from_range(InputIterator first, InputIterator last, std::forward_iterator_tag) {
844 size_t n = std::distance(first, last);
845 if (n > capacity()) {
846 iterator newStorage = allocate(n);
847 deallocate();
848 _begin = newStorage;
849 _endOfStorage = _begin + n;
850 }
851 _end = _begin + n;
852 Tp* destIter = _begin;
853 while (first != last) {
854 *destIter = *first;
855 ++destIter;
856 ++first;
857 }
858 }
859
860 template <typename InputIterator>
861 iterator insert_from_range(const_iterator position, InputIterator first, InputIterator last,
862 std::false_type) {
864 position, first, last, typename std::iterator_traits<InputIterator>::iterator_category());
865 }
866
867 template <typename Integral>
868 iterator insert_from_range(const_iterator position, Integral n, Integral val, std::true_type) {
869 if (capacity() < size() + n) {
870 size_t index = position - _begin;
871 enlarge_for_insert(enlarge_size(n), index, n);
872 position = _begin + index;
873 } else {
874 std::move_backward(const_cast<iterator>(position), _end, _end + n);
875 _end += n;
876 }
877 std::uninitialized_fill_n<Tp*, size_t>(const_cast<iterator>(position), n, val);
878 return const_cast<iterator>(position);
879 }
880
881 template <typename InputIterator>
882 iterator insert_from_range(const_iterator position, InputIterator first, InputIterator last,
883 std::forward_iterator_tag) {
884 size_t n = std::distance(first, last);
885 if (capacity() < size() + n) {
886 size_t index = position - _begin;
887 enlarge_for_insert(enlarge_size(n), index, n);
888 position = _begin + index;
889 } else {
890 std::move_backward(const_cast<iterator>(position), _end, _end + n);
891 _end += n;
892 }
893 Tp* destIter = const_cast<iterator>(position);
894 while (first != last) {
895 *destIter = *first;
896 ++destIter;
897 ++first;
898 }
899 return const_cast<iterator>(position);
900 }
901
902 void check_bounds(size_t index) const {
903 if (index >= size()) throw std::out_of_range("Access to element in UVector past end");
904 }
905
906 size_t enlarge_size(size_t extra_space_needed) const noexcept {
907 return size() + std::max(size(), extra_space_needed);
908 }
909
910 void enlarge(size_t newSize) {
911 pointer newStorage = allocate(newSize);
912 std::copy(_begin, _end, newStorage);
913 deallocate();
914 _end = newStorage + size();
915 _begin = newStorage;
916 _endOfStorage = _begin + newSize;
917 }
918
919 void enlarge_for_insert(size_t newSize, size_t insert_position, size_t insert_count) {
920 pointer newStorage = allocate(newSize);
921 std::copy(_begin, _begin + insert_position, newStorage);
922 std::copy(_begin + insert_position, _end, newStorage + insert_position + insert_count);
923 deallocate();
924 _end = newStorage + size() + insert_count;
925 _begin = newStorage;
926 _endOfStorage = _begin + newSize;
927 }
928
929 // implementation of operator=(const&) without
930 // propagate_on_container_copy_assignment
931 UVector& assign_copy_from(const UVector<Tp, Alloc>& other, std::false_type) {
932 const size_t n = other.size();
933 if (n > capacity()) {
934 iterator newStorage = allocate(n);
935 deallocate();
936 _begin = newStorage;
937 _end = _begin + n;
939 }
940 std::copy(other._begin, other._begin + n, _begin);
941 return *this;
942 }
943
944 // implementation of operator=(const&) with
945 // propagate_on_container_copy_assignment
946 UVector& assign_copy_from(const UVector<Tp, Alloc>& other, std::true_type) {
947 if (allocator_is_always_equal() || static_cast<Alloc&>(other) == static_cast<Alloc&>(*this)) {
948 assign_copy_from(other, std::false_type());
949 } else {
950 const size_t n = other.size();
951 iterator newStorage = static_cast<Alloc&>(other).allocate(n);
952 deallocate();
953 _begin = newStorage;
954 _end = _begin + n;
956 std::copy(other._begin, other._begin + n, _begin);
957 Alloc::operator=(static_cast<Alloc&>(other));
958 }
959 return *this;
960 }
961
962 // implementation of operator=() without
963 // propagate_on_container_move_assignment
965 std::false_type) noexcept(allocator_is_always_equal::value) {
966 if (allocator_is_always_equal::value ||
967 static_cast<Alloc&>(other) == static_cast<Alloc&>(*this)) {
968 deallocate();
969 _begin = other._begin;
970 _end = other._end;
971 _endOfStorage = other._endOfStorage;
972 other._begin = nullptr;
973 other._end = nullptr;
974 other._endOfStorage = nullptr;
975 } else {
976 // We should not propagate the allocator and the allocators are different.
977 // This means we can not swap the allocated space, since then we would
978 // deallocate the space with a different allocator type. Therefore, we
979 // need to copy:
980 assign_copy_from(other, std::false_type());
981 }
982 return *this;
983 }
984
985 // implementation of operator=() with propagate_on_container_move_assignment
986 UVector& assign_move_from(UVector<Tp, Alloc>&& other, std::true_type) noexcept {
987 deallocate();
988 Alloc::operator=(std::move(static_cast<Alloc&>(other)));
989 _begin = other._begin;
990 _end = other._end;
991 _endOfStorage = other._endOfStorage;
992 other._begin = nullptr;
993 other._end = nullptr;
994 other._endOfStorage = nullptr;
995 return *this;
996 }
997
998 // implementation of swap with propagate_on_container_swap
999 void swap(UVector<Tp, Alloc>& other, std::true_type) noexcept {
1000 std::swap(_begin, other._begin);
1001 std::swap(_end, other._end);
1002 std::swap(_endOfStorage, other._endOfStorage);
1003 std::swap(static_cast<Alloc&>(other), static_cast<Alloc&>(*this));
1004 }
1005
1006 // implementation of swap without propagate_on_container_swap
1007 void swap(UVector<Tp, Alloc>& other, std::false_type) noexcept {
1008 std::swap(_begin, other._begin);
1009 std::swap(_end, other._end);
1010 std::swap(_endOfStorage, other._endOfStorage);
1034 }
1035
1036 template <typename InputIterator>
1037 void push_back_range(InputIterator first, InputIterator last, std::false_type) {
1039 first, last, typename std::iterator_traits<InputIterator>::iterator_category());
1040 }
1041
1042 // This function is called from push_back(iter,iter) when Tp is an integral.
1043 // In that case, the user tried to call push_back(n, &val), but it got caught
1044 // by the wrong overload.
1045 template <typename Integral>
1046 void push_back_range(Integral n, Integral val, std::true_type) {
1047 if (capacity() - size() < size_t(n)) {
1049 }
1050 std::uninitialized_fill_n<Tp*, size_t>(_end, n, val);
1051 _end += n;
1052 }
1053
1054 template <typename InputIterator>
1055 void push_back_range(InputIterator first, InputIterator last, std::forward_iterator_tag) {
1056 size_t n = std::distance(first, last);
1057 if (n > capacity() - size()) {
1059 }
1060 while (first != last) {
1061 *_end = *first;
1062 ++_end;
1063 ++first;
1064 }
1065 }
1066};
1067
1069template <class Tp, class Alloc>
1070inline bool operator==(const UVector<Tp, Alloc>& lhs, const UVector<Tp, Alloc>& rhs) noexcept {
1071 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
1072}
1073
1075template <class Tp, class Alloc>
1076inline bool operator!=(const UVector<Tp, Alloc>& lhs, const UVector<Tp, Alloc>& rhs) noexcept {
1077 return !(lhs == rhs);
1078}
1079
1084template <class Tp, class Alloc>
1085inline bool operator<(const UVector<Tp, Alloc>& lhs, const UVector<Tp, Alloc>& rhs) noexcept {
1086 const size_t minSize = std::min(lhs.size(), rhs.size());
1087 for (size_t i = 0; i != minSize; ++i) {
1088 if (lhs[i] < rhs[i])
1089 return true;
1090 else if (lhs[i] > rhs[i])
1091 return false;
1092 }
1093 return lhs.size() < rhs.size();
1094}
1095
1100template <class Tp, class Alloc>
1101inline bool operator<=(const UVector<Tp, Alloc>& lhs, const UVector<Tp, Alloc>& rhs) noexcept {
1102 const size_t minSize = std::min(lhs.size(), rhs.size());
1103 for (size_t i = 0; i != minSize; ++i) {
1104 if (lhs[i] < rhs[i])
1105 return true;
1106 else if (lhs[i] > rhs[i])
1107 return false;
1108 }
1109 return lhs.size() <= rhs.size();
1110}
1111
1116template <class Tp, class Alloc>
1117inline bool operator>(const UVector<Tp, Alloc>& lhs, const UVector<Tp, Alloc>& rhs) noexcept {
1118 return rhs < lhs;
1119}
1120
1125template <class Tp, class Alloc>
1126inline bool operator>=(const UVector<Tp, Alloc>& lhs, const UVector<Tp, Alloc>& rhs) noexcept {
1127 return rhs <= lhs;
1128}
1129
1140template <class Tp, class Alloc>
1142 x.swap(y);
1143}
1144
1146
1147} // namespace aocommon
1148
1149#endif // AOCOMMON_UVECTOR_H_
A container similar to std::vector, but one that allows construction without initializing its element...
Definition uvector.h:77
UVector & assign_copy_from(const UVector< Tp, Alloc > &other, std::false_type)
implementation of operator=(const&) without propagate_on_container_copy_assignment
Definition uvector.h:931
iterator insert_from_range(const_iterator position, InputIterator first, InputIterator last, std::forward_iterator_tag)
Definition uvector.h:882
void push_back_range(InputIterator first, InputIterator last, std::false_type)
Definition uvector.h:1037
size_t size() const noexcept
Get number of elements in container.
Definition uvector.h:290
UVector & assign_move_from(UVector< Tp, Alloc > &&other, std::false_type) noexcept(allocator_is_always_equal::value)
implementation of operator=() without propagate_on_container_move_assignment
Definition uvector.h:964
void push_back(Tp &&item)
Add the given value to the end of the container by moving it in.
Definition uvector.h:503
void push_back_range(InputIterator first, InputIterator last, std::forward_iterator_tag)
Definition uvector.h:1055
void swap(UVector< Tp, Alloc > &other, std::true_type) noexcept
implementation of swap with propagate_on_container_swap
Definition uvector.h:999
const Tp * data() const noexcept
Get constant pointer to internal storage.
Definition uvector.h:435
UVector(UVector< Tp, Alloc > &&other) noexcept
Move construct a UVector.
Definition uvector.h:186
void deallocate(pointer begin, size_t n) noexcept
Definition uvector.h:789
UVector(const UVector< Tp, Alloc > &other, const allocator_type &allocator)
Copy construct a UVector with custom allocator.
Definition uvector.h:175
Tp & emplace_back(Args &&... args)
Add the given value to the end of the container by constructing it in place.
Definition uvector.h:696
void clear()
Remove all elements from the container.
Definition uvector.h:666
UVector & assign_copy_from(const UVector< Tp, Alloc > &other, std::true_type)
implementation of operator=(const&) with propagate_on_container_copy_assignment
Definition uvector.h:946
UVector & operator=(const UVector< Tp, Alloc > &other)
Assign another UVector to this UVector.
Definition uvector.h:235
iterator insert(const_iterator position, size_t n, const Tp &val)
Insert elements at a given position and initialize them with a value.
Definition uvector.h:543
void reserve(size_t n)
Reserve space for a number of elements, to prevent the overhead of extra reallocations.
Definition uvector.h:357
iterator erase(const_iterator first, const_iterator last)
Delete a range of elements from the container.
Definition uvector.h:644
const Tp & at(size_t index) const
Get a constant reference to the element at the given index with bounds checking.
Definition uvector.h:414
void push_back(size_t n, const Tp &val)
Add elements at the end and initialize them with a value.
Definition uvector.h:751
iterator insert(const_iterator position, const Tp &item)
Insert an element at a given position.
Definition uvector.h:520
void assign_from_range(InputIterator first, InputIterator last, std::forward_iterator_tag)
Definition uvector.h:843
size_t capacity() const noexcept
Get the number of elements the container can currently hold without reallocating storage.
Definition uvector.h:340
Tp * data() noexcept
Get pointer to internal storage.
Definition uvector.h:432
pointer allocate(size_t n)
Definition uvector.h:785
void enlarge_for_insert(size_t newSize, size_t insert_position, size_t insert_count)
Definition uvector.h:919
void assign(InputIterator first, InputIterator last)
Assign this container to be equal to the given range.
Definition uvector.h:444
const_reverse_iterator crend() const noexcept
Get constant reverse iterator to element before first element.
Definition uvector.h:287
void swap(UVector< Tp, Alloc > &other, std::false_type) noexcept
implementation of swap without propagate_on_container_swap
Definition uvector.h:1007
void shrink_to_fit()
Change the capacity of the container such that no extra space is hold.
Definition uvector.h:378
std::ptrdiff_t difference_type
Difference between to iterators.
Definition uvector.h:103
iterator emplace(const_iterator position, Args &&... args)
Insert an element at a given position by constructing it in place.
Definition uvector.h:677
const Tp & operator[](size_t index) const noexcept
Get a constant reference to the element at the given index.
Definition uvector.h:399
const Tp & back() const noexcept
Get constant reference to last element in container.
Definition uvector.h:429
iterator insert_from_range(const_iterator position, Integral n, Integral val, std::true_type)
Definition uvector.h:868
void push_back(const Tp &item)
Add the given value to the end of the container.
Definition uvector.h:489
UVector(std::initializer_list< Tp > initlist, const allocator_type &allocator=Alloc())
Construct a UVector from a initializer list.
Definition uvector.h:214
UVector(const allocator_type &allocator=Alloc()) noexcept
Construct an empty UVector.
Definition uvector.h:121
void swap(UVector< Tp, Alloc > &other) noexcept
Swap the contents of this UVector with the given UVector.
Definition uvector.h:661
void resize(size_t n, const Tp &val)
Change the number of elements in the container.
Definition uvector.h:325
iterator erase(const_iterator position)
Delete an element from the container.
Definition uvector.h:631
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator type.
Definition uvector.h:99
void resize(size_t n)
Change the number of elements in the container.
Definition uvector.h:305
const_iterator begin() const noexcept
Get constant iterator to first element.
Definition uvector.h:257
const Tp * const_pointer
Pointer to constant element type.
Definition uvector.h:93
size_t max_size() const noexcept
Get maximum number of elements that this container can hold.
Definition uvector.h:293
std::false_type allocator_is_always_equal
Definition uvector.h:113
UVector(size_t n, const value_type &val, const allocator_type &allocator=Alloc())
Construct a vector with given amount of elements and set these to a specific value.
Definition uvector.h:140
void assign_from_range(InputIterator first, InputIterator last, std::false_type)
Definition uvector.h:822
const_reverse_iterator rbegin() const noexcept
Get constant reverse iterator to last element.
Definition uvector.h:269
void push_back(std::initializer_list< Tp > initlist)
Add elements from an initializer list to the end of the container.
Definition uvector.h:765
UVector(UVector< Tp, Alloc > &&other, const allocator_type &allocator) noexcept
Move construct a UVector with custom allocator.
Definition uvector.h:200
void push_back_uninitialized(size_t n)
Add elements at the end without initializing them.
Definition uvector.h:782
UVector & operator=(UVector< Tp, Alloc > &&other) noexcept(std::allocator_traits< Alloc >::propagate_on_container_move_assignment::value||allocator_is_always_equal::value)
Assign another UVector to this UVector.
Definition uvector.h:245
void assign(std::initializer_list< Tp > initlist)
Assign this container to an initializer list.
Definition uvector.h:469
void assign_from_range(Integral n, Integral val, std::true_type)
This function is called from assign(iter,iter) when Tp is an integral.
Definition uvector.h:831
void construct_from_range(InputIterator first, InputIterator last, std::false_type)
Definition uvector.h:794
reverse_iterator rbegin() noexcept
Get reverse iterator to last element.
Definition uvector.h:266
void enlarge(size_t newSize)
Definition uvector.h:910
std::size_t size_t
Type used for indexing elements.
Definition uvector.h:105
allocator_type get_allocator() const noexcept
Get a copy of the allocator.
Definition uvector.h:704
iterator insert(const_iterator position, InputIterator first, InputIterator last)
Insert elements at a given position and initialize them from a range.
Definition uvector.h:567
UVector(const UVector< Tp, Alloc > &other)
Copy construct a UVector.
Definition uvector.h:162
const_iterator cbegin() const noexcept
Get constant iterator to first element.
Definition uvector.h:278
Tp & operator[](size_t index) noexcept
Get a reference to the element at the given index.
Definition uvector.h:396
UVector(size_t n)
Construct a vector with given amount of elements, without initializing these.
Definition uvector.h:131
void push_back_range(Integral n, Integral val, std::true_type)
This function is called from push_back(iter,iter) when Tp is an integral.
Definition uvector.h:1046
const_iterator cend() const noexcept
Get constant iterator to element past last element.
Definition uvector.h:281
Tp & front() noexcept
Get reference to first element in container.
Definition uvector.h:420
iterator insert_uninitialized(const_iterator position, size_t n)
— NON STANDARD METHODS —
Definition uvector.h:720
void deallocate() noexcept
Definition uvector.h:787
void pop_back()
Remove the last element from the container.
Definition uvector.h:510
const_reverse_iterator crbegin() const noexcept
Get constant reverse iterator to last element.
Definition uvector.h:284
Tp * pointer
Pointer to element type.
Definition uvector.h:91
size_t enlarge_size(size_t extra_space_needed) const noexcept
Definition uvector.h:906
void construct_from_range(InputIterator first, InputIterator last, std::forward_iterator_tag)
Definition uvector.h:808
std::reverse_iterator< const_iterator > const_reverse_iterator
Reverse iterator of constant elements.
Definition uvector.h:101
const Tp * const_iterator
Iterator type of constant elements.
Definition uvector.h:97
~UVector() noexcept
Destructor.
Definition uvector.h:228
UVector(InputIterator first, InputIterator last, const allocator_type &allocator=Alloc())
Construct a vector by copying elements from a range.
Definition uvector.h:151
reverse_iterator rend() noexcept
Get reverse iterator to element before first element.
Definition uvector.h:272
iterator insert(const_iterator position, std::initializer_list< Tp > initlist)
Insert elements at a given position and initialize them from a initializer list.
Definition uvector.h:607
std::size_t size_type
Type used for indexing elements.
Definition uvector.h:107
Tp & at(size_t index)
Get a reference to the element at the given index with bounds checking.
Definition uvector.h:405
void check_bounds(size_t index) const
Definition uvector.h:902
Tp & back() noexcept
Get reference to last element in container.
Definition uvector.h:426
iterator insert(const_iterator position, Tp &&item)
Insert an element at a given position by moving it in.
Definition uvector.h:585
void assign(size_t n, const Tp &val)
Resize the container and assign the given value to all elements.
Definition uvector.h:453
iterator insert_from_range(const_iterator position, InputIterator first, InputIterator last, std::false_type)
Definition uvector.h:861
Tp * iterator
Iterator type.
Definition uvector.h:95
Tp & reference
Reference to element type.
Definition uvector.h:87
UVector & assign_move_from(UVector< Tp, Alloc > &&other, std::true_type) noexcept
implementation of operator=() with propagate_on_container_move_assignment
Definition uvector.h:986
const Tp & front() const noexcept
Get constant reference to first element in container.
Definition uvector.h:423
pointer _endOfStorage
Definition uvector.h:115
const_iterator end() const noexcept
Get constant iterator to element past last element.
Definition uvector.h:263
void push_back(InputIterator first, InputIterator last)
Add a range of items to the end of the container.
Definition uvector.h:740
iterator end() noexcept
Get iterator to element past last element.
Definition uvector.h:260
const_reverse_iterator rend() const noexcept
Get constant reverse iterator to element before first element.
Definition uvector.h:275
bool empty() const noexcept
Determine if the container is currently empty.
Definition uvector.h:344
const Tp & const_reference
Constant reference to element type.
Definition uvector.h:89
Tp value_type
Element type.
Definition uvector.h:83
iterator begin() noexcept
Get iterator to first element.
Definition uvector.h:254
Alloc allocator_type
Type of allocator used to allocate and deallocate space.
Definition uvector.h:85
void construct_from_range(Integral n, Integral val, std::true_type)
Definition uvector.h:800
bool operator!=(const UVector< Tp, Alloc > &lhs, const UVector< Tp, Alloc > &rhs) noexcept
Compare two UVectors for inequality.
Definition uvector.h:1076
void swap(UVector< Tp, Alloc > &x, UVector< Tp, Alloc > &y)
Swap the contents of the two UVectors.
Definition uvector.h:1141
bool operator>(const UVector< Tp, Alloc > &lhs, const UVector< Tp, Alloc > &rhs) noexcept
Compare two UVectors for larger than.
Definition uvector.h:1117
bool operator<=(const UVector< Tp, Alloc > &lhs, const UVector< Tp, Alloc > &rhs) noexcept
Compare two UVectors for smaller than or equal.
Definition uvector.h:1101
bool operator>=(const UVector< Tp, Alloc > &lhs, const UVector< Tp, Alloc > &rhs) noexcept
Compare two UVectors for larger than or equal.
Definition uvector.h:1126
bool operator==(const UVector< Tp, Alloc > &lhs, const UVector< Tp, Alloc > &rhs) noexcept
Compare two UVectors for equality.
Definition uvector.h:1070
bool operator<(const UVector< Tp, Alloc > &lhs, const UVector< Tp, Alloc > &rhs) noexcept
Compare two UVectors for smaller than.
Definition uvector.h:1085
struct Node * first
Definition malloc.h:328
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
Definition Complex.h:350