NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
vector.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_CONTAINER_VECTOR_HPP__
2#define NEFORCE_CORE_CONTAINER_VECTOR_HPP__
3
11
15NEFORCE_BEGIN_NAMESPACE__
16
22
31template <bool IsConst, typename Vector>
32struct vector_iterator : iiterator<vector_iterator<IsConst, Vector>> {
33public:
34 using container_type = Vector;
35 using value_type = typename container_type::value_type;
36 using size_type = typename container_type::size_type;
37 using difference_type = typename container_type::difference_type;
39 using reference = conditional_t<IsConst, typename container_type::const_reference,
40 typename container_type::reference>;
41 using pointer = conditional_t<IsConst, typename container_type::const_pointer,
42 typename container_type::pointer>;
43
44private:
45 pointer current_ = nullptr;
46 const container_type* container_ = nullptr;
47
48public:
49 NEFORCE_CONSTEXPR20 vector_iterator() noexcept = default;
50 NEFORCE_CONSTEXPR20 ~vector_iterator() = default;
51
52 NEFORCE_CONSTEXPR20 vector_iterator(const vector_iterator&) noexcept = default;
53 NEFORCE_CONSTEXPR20 vector_iterator& operator=(const vector_iterator&) noexcept = default;
54 NEFORCE_CONSTEXPR20 vector_iterator(vector_iterator&&) noexcept = default;
55 NEFORCE_CONSTEXPR20 vector_iterator& operator=(vector_iterator&&) noexcept = default;
56
62 NEFORCE_CONSTEXPR20 vector_iterator(pointer ptr, const container_type* vec) noexcept :
63 current_(ptr),
64 container_(vec) {}
65
70 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference dereference() const noexcept {
71 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to dereference on a null pointer");
72 NEFORCE_DEBUG_VERIFY(container_->start_ <= current_ && current_ < container_->finish_,
73 "Attempting to dereference out of boundary");
74 return *current_;
75 }
76
80 NEFORCE_CONSTEXPR20 void increment() noexcept {
81 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to increment a null pointer");
82 NEFORCE_DEBUG_VERIFY(current_ < container_->finish_, "Attempting to increment out of boundary");
83 ++current_;
84 }
85
89 NEFORCE_CONSTEXPR20 void decrement() noexcept {
90 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to decrement a null pointer");
91 NEFORCE_DEBUG_VERIFY(container_->start_ < current_, "Attempting to decrement out of boundary");
92 --current_;
93 }
94
99 NEFORCE_CONSTEXPR20 void advance(difference_type off) noexcept {
100 NEFORCE_DEBUG_VERIFY((current_ && container_) || off == 0, "Attempting to advance a null pointer");
101 NEFORCE_DEBUG_VERIFY((off < 0 ? off >= container_->start_ - current_ : off <= container_->finish_ - current_),
102 "Attempting to advance out of boundary");
103 current_ += off;
104 }
105
111 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 difference_type distance_to(const vector_iterator& other) const noexcept {
112 NEFORCE_DEBUG_VERIFY(container_ == other.container_, "Attempting to distance to a different container");
113 return static_cast<difference_type>(current_ - other.current_);
114 }
115
121 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference operator[](difference_type off) noexcept { return *(*this + off); }
122
128 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool equal_to(const vector_iterator& rhs) const noexcept {
129 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_, "Attempting to equal to a different container");
130 return current_ == rhs.current_;
131 }
132
138 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool less_than(const vector_iterator& rhs) const noexcept {
139 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_, "Attempting to less than a different container");
140 return current_ < rhs.current_;
141 }
142
147 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer base() const noexcept { return current_; }
148
153 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const container_type* container() const noexcept { return container_; }
154};
155
156
166template <typename T, typename Alloc = allocator<T>>
167class vector : public icollector<vector<T, Alloc>> {
168 static_assert(is_object_v<T>, "vector only contains object types.");
169 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
170 static_assert(is_same_v<T, typename Alloc::value_type>, "allocator type mismatch.");
171
172public:
173 using pointer = T*;
174 using reference = T&;
175 using const_pointer = const T*;
176 using const_reference = const T&;
177 using value_type = T;
180 using iterator = vector_iterator<false, vector<T, Alloc>>;
181 using const_iterator = vector_iterator<true, vector<T, Alloc>>;
184 using allocator_type = Alloc;
185
186private:
187 pointer start_ = nullptr;
188 pointer finish_ = nullptr;
190 nullptr};
191
192 template <bool, typename>
193 friend struct vector_iterator;
194
195public:
197 static constexpr size_type npos = static_cast<size_type>(-1);
198
199private:
205 NEFORCE_CONSTEXPR20 void fill_initialize(size_type n, const T& value) {
206 start_ = pair_.get_base().allocate(n);
207 _NEFORCE uninitialized_fill_n(start_, n, value);
208 finish_ = start_ + n;
209 pair_.value = finish_;
210 }
211
220 template <typename Iterator>
221 NEFORCE_CONSTEXPR20 pointer allocate_and_copy(size_type n, Iterator first, Iterator last) {
222 NEFORCE_DEBUG_VERIFY(n < max_size(), "vector allocate out of allocate bounds.");
223 pointer result = pair_.get_base().allocate(n);
224 pointer finish = result;
225 try {
226 finish = _NEFORCE uninitialized_copy(first, last, result);
227 } catch (...) {
228 _NEFORCE destroy(result, finish);
229 pair_.get_base().deallocate(result, n);
230 throw;
231 }
232 return result;
233 }
234
243 template <typename Iterator>
244 NEFORCE_CONSTEXPR20 pointer allocate_and_move(size_type n, Iterator first, Iterator last) {
245 pointer result = pair_.get_base().allocate(n);
246 pointer finish = result;
247 try {
248 finish = _NEFORCE uninitialized_move(first, last, result);
249 } catch (...) {
250 _NEFORCE destroy(result, finish);
251 pair_.get_base().deallocate(result, n);
252 throw;
253 }
254 return result;
255 }
256
263 template <typename Iterator>
264 NEFORCE_CONSTEXPR20 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> range_initialize(Iterator first, Iterator last) {
265 for (; first != last; ++first) {
266 vector::push_back(*first);
267 }
268 return;
269 }
270
277 template <typename Iterator>
278 NEFORCE_CONSTEXPR20 enable_if_t<is_ranges_fwd_iter_v<Iterator>> range_initialize(Iterator first, Iterator last) {
279 size_type n = _NEFORCE distance(first, last);
280 start_ = vector::allocate_and_copy(n, first, last);
281 finish_ = start_ + n;
282 pair_.value = finish_;
283 return;
284 }
285
289 NEFORCE_CONSTEXPR20 void deallocate() noexcept {
290 if (start_) {
291 pair_.get_base().deallocate(start_, pair_.value - start_);
292 }
293 }
294
302 template <typename Iterator>
303 NEFORCE_CONSTEXPR20 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> range_insert(iterator position, Iterator first,
304 Iterator last) {
305 while (first != last) {
306 position = vector::insert(position, *first);
307 ++position;
308 ++first;
309 }
310 return;
311 }
312
320 template <typename Iterator>
321 NEFORCE_CONSTEXPR20 enable_if_t<is_ranges_fwd_iter_v<Iterator>> range_insert(iterator position, Iterator first,
322 Iterator last) {
323 if (first == last) {
324 return;
325 }
326
327 const size_t n = _NEFORCE distance(first, last);
328
329 if (static_cast<size_t>(pair_.value - finish_) >= n) {
330 const size_t elems_after = end() - position;
331 iterator old_finish = end();
332
333 if (elems_after > n) {
334 _NEFORCE uninitialized_copy(finish_ - n, finish_, finish_);
335 finish_ += n;
336 _NEFORCE copy_backward(position, old_finish - n, old_finish);
337 _NEFORCE copy(first, last, position);
338 } else {
339 Iterator mid = first;
340 _NEFORCE advance(mid, elems_after);
341 _NEFORCE uninitialized_copy(mid, last, finish_);
342 finish_ += (n - elems_after);
343 _NEFORCE uninitialized_move(position, old_finish, finish_);
344 finish_ += elems_after;
345 _NEFORCE copy(first, mid, position);
346 }
347 } else {
348 const size_type old_size = size();
349 const size_type len = old_size + _NEFORCE max(old_size, n);
350 pointer new_start = pair_.get_base().allocate(len);
351 pointer new_finish = new_start;
352
353 new_finish = _NEFORCE uninitialized_copy(begin(), position, new_start);
354 new_finish = _NEFORCE uninitialized_copy(first, last, new_finish);
355 new_finish = _NEFORCE uninitialized_copy(position, end(), new_finish);
356
357 _NEFORCE destroy(start_, finish_);
358 deallocate();
359
360 start_ = new_start;
361 finish_ = new_finish;
362 pair_.value = new_start + len;
363 }
364 return;
365 }
366
373 template <typename Iterator>
374 NEFORCE_CONSTEXPR20 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> assign_aux(Iterator first, Iterator last) {
375 clear();
376 while (first != last) {
377 vector::push_back(*first);
378 ++first;
379 }
380 return;
381 }
382
389 template <typename Iterator>
390 NEFORCE_CONSTEXPR20 enable_if_t<is_ranges_fwd_iter_v<Iterator>> assign_aux(Iterator first, Iterator last) {
391 const size_t n = _NEFORCE distance(first, last);
392 if (n > capacity()) {
393 pointer new_start = vector::allocate_and_copy(n, first, last);
394 _NEFORCE destroy(start_, finish_);
395 deallocate();
396 start_ = new_start;
397 finish_ = start_ + n;
398 pair_.value = start_ + n;
399 } else if (n > size()) {
400 Iterator mid = first;
401 _NEFORCE advance(mid, size());
402 _NEFORCE copy(first, mid, start_);
403 finish_ = _NEFORCE uninitialized_copy(mid, last, finish_);
404 } else {
405 _NEFORCE copy(first, last, start_);
406 vector::erase(begin() + n, end());
407 }
408 return;
409 }
410
411public:
417 NEFORCE_CONSTEXPR20 vector() {
418 constexpr size_type init_cap = 1;
419 pointer result = pair_.get_base().allocate(init_cap);
420 finish_ = start_ = result;
421 pair_.value = finish_ + init_cap;
422 }
423
428 NEFORCE_CONSTEXPR20 explicit vector(const size_type n) {
429 start_ = pair_.get_base().allocate(n);
430 finish_ = start_;
431 try {
432 for (size_type i = 0; i < n; ++i) {
433 _NEFORCE construct(finish_);
434 ++finish_;
435 }
436 } catch (...) {
437 _NEFORCE destroy(start_, finish_);
438 pair_.get_base().deallocate(start_, n);
439 throw;
440 }
441 pair_.value = start_ + n;
442 }
443
449 NEFORCE_CONSTEXPR20 explicit vector(const size_type n, const T& value) { vector::fill_initialize(n, value); }
450
456 NEFORCE_CONSTEXPR20 explicit vector(const int32_t n, const T& value) { vector::fill_initialize(n, value); }
457
463 NEFORCE_CONSTEXPR20 explicit vector(const int64_t n, const T& value) { vector::fill_initialize(n, value); }
464
469 NEFORCE_CONSTEXPR20 vector(const vector& other) {
470 const size_type n = other.size();
471 start_ = vector::allocate_and_copy(n, other.begin(), other.end());
472 finish_ = start_ + n;
473 pair_.value = finish_;
474 }
475
481 NEFORCE_CONSTEXPR20 vector& operator=(const vector& other) {
482 if (_NEFORCE addressof(other) == this) {
483 return *this;
484 }
485
487 vector::insert(end(), other.cbegin(), other.cend());
488 return *this;
489 }
490
495 NEFORCE_CONSTEXPR20
499
505 NEFORCE_CONSTEXPR20 vector&
508 if (_NEFORCE addressof(other) == this) {
509 return *this;
510 }
511
513 vector::swap(other);
514 return *this;
515 }
516
523 template <typename Iterator, enable_if_t<is_ranges_iter_v<Iterator>, int> = 0>
524 NEFORCE_CONSTEXPR20 vector(Iterator first, Iterator last) {
525 vector::range_initialize(first, last);
526 }
527
534 template <typename Iterator>
535 NEFORCE_CONSTEXPR20 vector(Iterator first, const size_type n) :
536 vector(first, _NEFORCE next(first, n)) {}
537
542 NEFORCE_CONSTEXPR20 vector(std::initializer_list<T> ilist) :
543 vector(ilist.begin(), ilist.end()) {}
544
549 NEFORCE_CONSTEXPR20 vector(memory_view<T> view) :
550 vector(view.begin(), view.end()) {}
551
557 NEFORCE_CONSTEXPR20 vector& operator=(std::initializer_list<T> ilist) {
558 if (ilist.size() > capacity()) {
559 pointer new_ = vector::allocate_and_move(ilist.end() - ilist.begin(), ilist.begin(), ilist.end());
560 _NEFORCE destroy(start_, finish_);
561 deallocate();
562 start_ = new_;
563 finish_ = start_ + ilist.size();
564 pair_.value = start_ + ilist.size();
565 } else if (size() >= ilist.size()) {
566 iterator i = _NEFORCE copy(ilist.begin(), ilist.end(), begin());
567 _NEFORCE destroy(i.base(), finish_);
568 } else {
569 _NEFORCE copy(ilist.begin(), ilist.begin() + size(), start_);
570 _NEFORCE uninitialized_copy(ilist.begin() + size(), ilist.end(), finish_);
571 }
572 finish_ = start_ + ilist.size();
573 return *this;
574 }
575
579 NEFORCE_CONSTEXPR20 ~vector() {
580 clear();
581 deallocate();
582 }
583
588 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator begin() noexcept { return iterator(start_, this); }
589
594 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator end() noexcept { return iterator(finish_, this); }
595
600 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator begin() const noexcept { return cbegin(); }
601
606 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator end() const noexcept { return cend(); }
607
612 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
613
618 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
619
624 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rbegin() const noexcept { return crbegin(); }
625
630 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rend() const noexcept { return crend(); }
631
636 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cbegin() const noexcept {
637 return const_iterator(start_, this);
638 }
639
644 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cend() const noexcept { return const_iterator(finish_, this); }
645
650 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crbegin() const noexcept {
652 }
653
658 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crend() const noexcept {
660 }
661
666 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type size() const noexcept {
667 return static_cast<size_type>(finish_ - start_);
668 }
669
674 NEFORCE_NODISCARD static constexpr size_type max_size() noexcept { return static_cast<size_type>(-1) / sizeof(T); }
675
680 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type capacity() const noexcept {
681 return static_cast<size_type>(pair_.value - start_);
682 }
683
688 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool empty() const noexcept { return start_ == finish_; }
689
694 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer data() noexcept { return start_; }
695
700 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_pointer data() const noexcept { return start_; }
701
706 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<T> view() noexcept { return {start_, size()}; }
707
712 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<const T> view() const noexcept { return {start_, size()}; }
713
718 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<T> view(const size_type off, size_type count = npos) noexcept {
719 count = _NEFORCE min(count, size() - off);
720 return {start_ + off, count};
721 }
722
727 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<const T> view(const size_type off,
728 size_type count = npos) const noexcept {
729 count = _NEFORCE min(count, size() - off);
730 return {start_ + off, count};
731 }
732
737 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference front() noexcept {
738 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty vector");
739 return *start_;
740 }
741
746 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference front() const noexcept {
747 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty vector");
748 return *start_;
749 }
750
755 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference back() noexcept {
756 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty vector");
757 return *(finish_ - 1);
758 }
759
764 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference back() const noexcept {
765 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty vector");
766 return *(finish_ - 1);
767 }
768
775 NEFORCE_CONSTEXPR20 void reserve(const size_type n) {
776 NEFORCE_DEBUG_VERIFY(n < max_size(), "vector reserve out of allocate bounds.");
777 if (capacity() >= n) {
778 return;
779 }
780
781 size_type new_capacity = _NEFORCE max(capacity() * 2, n);
782 pointer new_start = pair_.get_base().allocate(new_capacity);
783 pointer new_finish = new_start;
784
785 try {
786 new_finish = _NEFORCE uninitialized_move(start_, finish_, new_start);
787 } catch (...) {
788 _NEFORCE destroy(new_start, new_finish);
789 pair_.get_base().deallocate(new_start, new_capacity);
790 throw;
791 }
792
793 _NEFORCE destroy(start_, finish_);
794 deallocate();
795 start_ = new_start;
796 finish_ = new_finish;
797 pair_.value = start_ + new_capacity;
798 }
799
808 NEFORCE_CONSTEXPR20 void resize(size_type new_size, const T& value) {
809 if (new_size < size()) {
810 vector::erase(begin() + new_size, end());
811 } else {
812 vector::insert(end(), new_size - size(), value);
813 }
814 }
815
820 NEFORCE_CONSTEXPR20 void resize(const size_type new_size) { vector::resize(new_size, T()); }
821
828 template <typename... Args>
829 NEFORCE_CONSTEXPR20 void emplace(iterator position, Args&&... args) {
830 if (finish_ != pair_.value) {
831 if (position == end()) {
832 _NEFORCE construct(finish_, _NEFORCE forward<Args>(args)...);
833 ++finish_;
834 } else {
835 _NEFORCE construct(finish_, _NEFORCE move(*(finish_ - 1)));
836 ++finish_;
837 pointer pos_ptr = position.base();
838 _NEFORCE move_backward(pos_ptr, finish_ - 2, finish_ - 1);
839 _NEFORCE construct(pos_ptr, _NEFORCE forward<Args>(args)...);
840 }
841 return;
842 }
843
844 const size_type old_size = size();
845 const size_type new_cap = old_size != 0 ? 2 * old_size : 1;
846 pointer new_start = pair_.get_base().allocate(new_cap);
847 pointer new_finish = new_start;
848
849 try {
850 new_finish = _NEFORCE uninitialized_move(begin(), position, new_start);
851 _NEFORCE construct(new_finish, _NEFORCE forward<Args>(args)...);
852 ++new_finish;
853 new_finish = _NEFORCE uninitialized_move(position, end(), new_finish);
854 } catch (...) {
855 _NEFORCE destroy(new_start, new_finish);
856 pair_.get_base().deallocate(new_start, new_cap);
857 throw;
858 }
859
860 _NEFORCE destroy(begin(), end());
861 deallocate();
862
863 start_ = new_start;
864 finish_ = new_finish;
865 pair_.value = new_start + new_cap;
866 }
867
873 template <typename... Args>
874 NEFORCE_CONSTEXPR20 void emplace_back(Args&&... args) {
875 if (finish_ != pair_.value) {
876 _NEFORCE construct(finish_, _NEFORCE forward<Args>(args)...);
877 ++finish_;
878 } else {
879 vector::emplace(end(), _NEFORCE forward<Args>(args)...);
880 }
881 }
882
887 NEFORCE_CONSTEXPR20 void push_back(const T& value) { vector::emplace_back(value); }
888
893 NEFORCE_CONSTEXPR20 void push_back(T&& value) { vector::emplace_back(_NEFORCE move(value)); }
894
898 NEFORCE_CONSTEXPR20 void pop_back() noexcept(is_nothrow_destructible_v<T>) {
899 NEFORCE_DEBUG_VERIFY(!empty(), "pop called in an empty vector")
900 _NEFORCE destroy(finish_ - 1);
901 --finish_;
902 }
903
908 NEFORCE_CONSTEXPR20 T pop_back_v() noexcept(is_nothrow_destructible_v<T> && is_nothrow_move_constructible_v<T>) {
909 NEFORCE_DEBUG_VERIFY(!empty(), "pop called in an empty vector")
910 T value{_NEFORCE move(*(finish_ - 1))};
911 _NEFORCE destroy(finish_ - 1);
912 --finish_;
913 return _NEFORCE move(value);
914 }
915
921 NEFORCE_CONSTEXPR20 void assign(size_type n, const value_type& value) {
922 if (n > capacity()) {
923 pointer new_start = pair_.get_base().allocate(n);
924 pointer new_finish = new_start;
925
926 try {
927 new_finish = _NEFORCE uninitialized_fill_n(new_start, n, value);
928 } catch (...) {
929 _NEFORCE destroy(new_start, new_finish);
930 pair_.get_base().deallocate(new_start, n);
931 throw;
932 }
933
934 _NEFORCE destroy(start_, finish_);
935 deallocate();
936
937 start_ = new_start;
938 finish_ = new_finish;
939 pair_.value = start_ + n;
940 } else if (n > size()) {
941 _NEFORCE fill(begin(), end(), value);
942 finish_ = _NEFORCE uninitialized_fill_n(finish_, n - size(), value);
943 } else {
944 _NEFORCE fill_n(begin(), n, value);
945 vector::erase(begin() + n, end());
946 }
947 }
948
955 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
956 NEFORCE_CONSTEXPR20 void assign(Iterator first, Iterator last) {
957 vector::assign_aux(first, last);
958 }
959
964 NEFORCE_CONSTEXPR20 void assign(std::initializer_list<value_type> ilist) {
965 vector::assign(ilist.begin(), ilist.end());
966 }
967
974 NEFORCE_CONSTEXPR20 iterator insert(iterator position, const value_type& value) {
975 size_type n = position - begin();
976 vector::emplace(position, value);
977 return begin() + n;
978 }
979
986 NEFORCE_CONSTEXPR20 iterator insert(iterator position, value_type&& value) {
987 size_type n = position - begin();
988 vector::emplace(position, _NEFORCE move(value));
989 return begin() + n;
990 }
991
997 NEFORCE_CONSTEXPR20 iterator insert(iterator position) { return vector::insert(position, T()); }
998
1006 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1007 NEFORCE_CONSTEXPR20 void insert(iterator position, Iterator first, Iterator last) {
1008 vector::range_insert(position, first, last);
1009 }
1010
1016 NEFORCE_CONSTEXPR20 void insert(iterator position, std::initializer_list<value_type> ilist) {
1017 vector::insert(position, ilist.begin(), ilist.end());
1018 }
1019
1026 NEFORCE_CONSTEXPR20 void insert(iterator position, size_type n, const value_type& value) {
1027 if (n == 0) {
1028 return;
1029 }
1030
1031 if (static_cast<size_type>(pair_.value - finish_) >= n) {
1032 const size_type elems_after = end() - position;
1033 iterator old_finish = end();
1034
1035 if (elems_after > n) {
1036 _NEFORCE uninitialized_move(old_finish - n, old_finish, old_finish);
1037 finish_ += n;
1038 _NEFORCE move_backward(position, old_finish - n, old_finish);
1039 _NEFORCE fill_n(position, n, value);
1040 } else {
1041 _NEFORCE uninitialized_fill_n(finish_, n - elems_after, value);
1042 finish_ += n - elems_after;
1043 _NEFORCE uninitialized_move(position, old_finish, finish_);
1044 finish_ += elems_after;
1045 _NEFORCE fill(position, old_finish, value);
1046 }
1047 } else {
1048 const size_type old_size = size();
1049 const size_type len = old_size + _NEFORCE max(old_size, n);
1050
1051 pointer new_start = pair_.get_base().allocate(len);
1052 pointer new_finish = _NEFORCE uninitialized_copy(begin(), position, new_start);
1053 new_finish = _NEFORCE uninitialized_fill_n(new_finish, n, value);
1054 new_finish = _NEFORCE uninitialized_copy(position, end(), new_finish);
1055
1056 _NEFORCE destroy(start_, finish_);
1057 deallocate();
1058
1059 start_ = new_start;
1060 finish_ = new_finish;
1061 pair_.value = new_start + len;
1062 }
1063 }
1064
1071 NEFORCE_CONSTEXPR20 iterator erase(iterator first,
1074 NEFORCE_DEBUG_VERIFY(_NEFORCE distance(first, last) >= 0, "vector erase out of ranges.");
1075
1076 const auto elems_after = end() - last;
1077 if (elems_after > 0) {
1078 _NEFORCE move_backward(last, end(), first + elems_after);
1079 }
1080
1081 pointer new_finish = finish_ - (last - first);
1082 _NEFORCE destroy(new_finish, finish_);
1083 finish_ = new_finish;
1084 return first;
1085 }
1086
1092 NEFORCE_CONSTEXPR20 iterator erase(iterator position) noexcept(is_nothrow_move_assignable_v<value_type>) {
1093 if (position + 1 != end()) {
1094 _NEFORCE move(position + 1, end(), position);
1095 }
1096
1097 --finish_;
1098 _NEFORCE destroy(finish_);
1099 return position;
1100 }
1101
1107 NEFORCE_CONSTEXPR20 void shrink_to_fit() {
1108 if (capacity() == size()) {
1109 return;
1110 }
1111
1112 if (size() == 0) {
1113 deallocate();
1114 start_ = finish_ = pair_.value = nullptr;
1115 return;
1116 }
1117
1118 pointer new_start = pair_.get_base().allocate(size());
1119 pointer new_finish = new_start;
1120
1121 try {
1122 new_finish = _NEFORCE uninitialized_move(start_, finish_, new_start);
1123 } catch (...) {
1124 _NEFORCE destroy(new_start, new_finish);
1125 pair_.get_base().deallocate(new_start, size());
1126 throw;
1127 }
1128
1129 _NEFORCE destroy(start_, finish_);
1130 deallocate();
1131
1132 start_ = new_start;
1133 finish_ = new_finish;
1134 pair_.value = new_start + size();
1135 }
1136
1142 NEFORCE_CONSTEXPR20 void clear() noexcept(is_nothrow_destructible_v<value_type>) {
1143 if (empty()) {
1144 return;
1145 }
1146
1147 _NEFORCE destroy(start_, finish_);
1148 finish_ = start_;
1149 }
1150
1156 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference at(const size_type position) const noexcept {
1157 NEFORCE_DEBUG_VERIFY(position < size(), "vector access out of range");
1158 return *(start_ + position);
1159 }
1160
1166 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference at(const size_type position) noexcept {
1167 NEFORCE_DEBUG_VERIFY(position < size(), "vector access out of range");
1168 return *(start_ + position);
1169 }
1170
1176 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference operator[](const size_type position) const noexcept {
1177 return at(position);
1178 }
1179
1185 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference operator[](const size_type position) noexcept {
1186 return at(position);
1187 }
1188
1193 NEFORCE_CONSTEXPR20 void swap(vector& other) noexcept(is_nothrow_swappable_v<allocator_type>) {
1194 if (_NEFORCE addressof(other) == this) {
1195 return;
1196 }
1197
1198 _NEFORCE swap(start_, other.start_);
1199 _NEFORCE swap(finish_, other.finish_);
1200 _NEFORCE swap(pair_, other.pair_);
1201 }
1202
1208 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool equal_to(const vector& rhs) const
1209 noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin()))) {
1210 return size() == rhs.size() && _NEFORCE equal(cbegin(), cend(), rhs.cbegin());
1211 }
1212
1218 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool less_than(const vector& rhs) const
1219 noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend()))) {
1220 return _NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend());
1221 }
1222};
1223
1224#ifdef NEFORCE_STANDARD_17
1225template <typename T, typename Alloc>
1226vector(T, Alloc = Alloc()) -> vector<T, Alloc>;
1227
1228template <typename Iterator, typename Alloc>
1229vector(Iterator, Iterator, Alloc = Alloc()) -> vector<iter_value_t<Iterator>, Alloc>;
1230#endif
1231
1236 // Container
1238
1239NEFORCE_END_NAMESPACE__
1240#endif // NEFORCE_CORE_CONTAINER_VECTOR_HPP__
内存视图模板
动态大小数组容器
constexpr void reserve(const size_type n)
预留容量
constexpr bool less_than(const vector &rhs) const noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend())))
小于比较操作符
constexpr void clear() noexcept(is_nothrow_destructible_v< value_type >)
清空向量
constexpr pointer data() noexcept
获取底层数据指针
constexpr reference at(const size_type position) noexcept
带边界检查的索引访问
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
constexpr void swap(vector &other) noexcept(is_nothrow_swappable_v< allocator_type >)
交换两个向量的内容
constexpr void resize(const size_type new_size)
使用默认构造的元素调整大小
constexpr vector(vector &&other) noexcept(is_nothrow_swappable_v< compressed_pair< allocator_type, pointer > >)
移动构造函数
constexpr void assign(Iterator first, Iterator last)
范围赋值
constexpr ~vector()
析构函数
constexpr void insert(iterator position, size_type n, const value_type &value)
插入n个指定值的元素
constexpr const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
constexpr iterator erase(iterator position) noexcept(is_nothrow_move_assignable_v< value_type >)
删除指定位置的元素
constexpr iterator insert(iterator position)
在指定位置插入默认构造的元素
const T & const_reference
常量引用类型
constexpr vector(const size_type n, const T &value)
构造包含n个指定值元素的向量
constexpr reverse_iterator rend() noexcept
获取反向结束迭代器
T value_type
值类型
Alloc allocator_type
分配器类型
constexpr void pop_back() noexcept(is_nothrow_destructible_v< T >)
移除末尾元素
constexpr vector(const int64_t n, const T &value)
构造包含n个指定值元素的向量
const T * const_pointer
常量指针类型
static constexpr size_type max_size() noexcept
获取最大可能大小
constexpr vector(const vector &other)
拷贝构造函数
constexpr T pop_back_v() noexcept(is_nothrow_destructible_v< T > &&is_nothrow_move_constructible_v< T >)
移除并返回末尾元素
constexpr void resize(size_type new_size, const T &value)
调整大小
constexpr reverse_iterator rbegin() noexcept
获取反向起始迭代器
constexpr iterator insert(iterator position, const value_type &value)
在指定位置拷贝插入元素
constexpr void push_back(T &&value)
在末尾移动插入元素
constexpr const_iterator begin() const noexcept
获取常量起始迭代器
T * pointer
指针类型
constexpr reference operator[](const size_type position) noexcept
下标访问操作符
constexpr bool equal_to(const vector &rhs) const noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin())))
相等比较操作符
constexpr const_reference back() const noexcept
访问最后一个常量元素
constexpr const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
vector_iterator< false, vector< T, Alloc > > iterator
迭代器类型
constexpr const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
constexpr void insert(iterator position, Iterator first, Iterator last)
范围插入
constexpr vector(Iterator first, Iterator last)
范围构造函数
constexpr void shrink_to_fit()
收缩容量以适应当前大小
constexpr reference front() noexcept
访问第一个元素
constexpr memory_view< T > view(const size_type off, size_type count=npos) noexcept
获取底层数据的视图
constexpr bool empty() const noexcept
检查是否为空
constexpr vector()
默认构造函数
constexpr const_iterator cbegin() const noexcept
获取常量起始迭代器
T & reference
引用类型
constexpr void assign(size_type n, const value_type &value)
赋值n个指定值的元素
constexpr vector(const int32_t n, const T &value)
构造包含n个指定值元素的向量
constexpr reference back() noexcept
访问最后一个元素
vector_iterator< true, vector< T, Alloc > > const_iterator
常量迭代器类型
constexpr memory_view< byte_t > view() noexcept
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
constexpr vector & operator=(const vector &other)
拷贝赋值运算符
constexpr vector & operator=(std::initializer_list< T > ilist)
初始化列表赋值运算符
constexpr const_reference operator[](const size_type position) const noexcept
常量下标访问操作符
constexpr vector(std::initializer_list< T > ilist)
初始化列表构造函数
constexpr void emplace(iterator position, Args &&... args)
在指定位置构造元素
constexpr iterator begin() noexcept
获取起始迭代器
constexpr iterator end() noexcept
获取结束迭代器
constexpr iterator erase(iterator first, iterator last) noexcept(is_nothrow_move_assignable_v< value_type > &&is_nothrow_destructible_v< value_type >)
删除指定范围内的元素
constexpr vector(const size_type n)
构造包含n个默认构造元素的向量
constexpr vector & operator=(vector &&other) noexcept(is_nothrow_destructible_v< value_type > &&is_nothrow_swappable_v< compressed_pair< allocator_type, pointer > >)
移动赋值运算符
constexpr const_reference front() const noexcept
访问第一个常量元素
constexpr void push_back(const T &value)
在末尾拷贝插入元素
constexpr size_type capacity() const noexcept
获取当前容量
constexpr size_type size() const noexcept
获取当前元素数量
constexpr memory_view< const T > view(const size_type off, size_type count=npos) const noexcept
获取底层数据的常量视图
constexpr iterator insert(iterator position, value_type &&value)
在指定位置移动插入元素
constexpr void assign(std::initializer_list< value_type > ilist)
初始化列表赋值
constexpr const_iterator end() const noexcept
获取常量结束迭代器
size_t size_type
大小类型
constexpr const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
constexpr const_iterator cend() const noexcept
获取常量结束迭代器
constexpr vector(Iterator first, const size_type n)
范围构造函数
ptrdiff_t difference_type
差值类型
constexpr const_reference at(const size_type position) const noexcept
带边界检查的常量索引访问
constexpr void insert(iterator position, std::initializer_list< value_type > ilist)
初始化列表插入
constexpr vector(memory_view< T > view)
内存视图构造函数
constexpr const_pointer data() const noexcept
获取底层数据常量指针
static constexpr size_type npos
constexpr memory_view< const T > view() const noexcept
获取底层数据的常量视图
constexpr void emplace_back(Args &&... args)
在末尾构造元素
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr bool is_object_v
is_object的便捷变量模板
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
constexpr bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(comp(*first1, *first2)) &&noexcept(first1==last1 &&first2 !=last2))
字典序比较两个范围
constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
vector< byte_t > byte_vector
字节向量类型别名
long long int64_t
64位有符号整数类型
int int32_t
32位有符号整数类型
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr void deallocate(void *ptr, inner::alloc_size_t bytes) noexcept
内存释放函数
uint64_t size_t
无符号大小类型
int64_t ptrdiff_t
指针差类型
constexpr void fill(Iterator first, Iterator last, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充范围元素
constexpr Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_backward_aux(first, last, result)))
反向复制范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_aux(first, last, result)))
复制范围元素
constexpr Iterator2 move_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向移动范围元素
constexpr Iterator fill_n(Iterator first, iter_difference_t< Iterator > n, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充指定数量的元素
void swap()=delete
删除无参数的swap重载
constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
constexpr bool is_allocator_v
is_allocator的便捷变量模板
constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
constexpr bool is_nothrow_move_assignable_v
is_nothrow_move_assignable的便捷变量模板
constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr bool is_same_v
is_same的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
constexpr Iterator2 uninitialized_move(Iterator1 first, Iterator1 last, Iterator2 result)
在未初始化内存中移动元素
constexpr Iterator uninitialized_fill_n(Iterator first, size_t n, const T &x)
在未初始化内存中用指定值填充指定数量的元素
内存视图容器
标准分配器
压缩对主模板,使用EBCO优化
constexpr compressed_pair & get_base() &noexcept
获取基类引用
连续迭代器标签
默认构造标签
集合器接口模板
迭代器接口模板
向量迭代器
typename container_type::difference_type difference_type
差值类型
constexpr const container_type * container() const noexcept
获取关联容器
constexpr bool equal_to(const vector_iterator &rhs) const noexcept
相等比较
Vector container_type
容器类型
typename container_type::value_type value_type
值类型
constexpr difference_type distance_to(const vector_iterator &other) const noexcept
计算距离操作
typename container_type::size_type size_type
大小类型
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
constexpr reference dereference() const noexcept
解引用操作
contiguous_iterator_tag iterator_category
迭代器类别
constexpr bool less_than(const vector_iterator &rhs) const noexcept
小于比较
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
constexpr pointer base() const noexcept
获取底层指针
constexpr void advance(difference_type off) noexcept
前进操作
constexpr void decrement() noexcept
递减操作
constexpr reference operator[](difference_type off) noexcept
下标访问操作符
constexpr void increment() noexcept
递增操作
未初始化内存操作