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(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 NEFORCE_DEBUG_VERIFY(first <= last, "vector iterator-constructor out of ranges.");
526 vector::range_initialize(first, last);
527 }
528
535 template <typename Iterator>
536 NEFORCE_CONSTEXPR20 vector(Iterator first, const size_type n) :
537 vector(first, first + n) {}
538
543 NEFORCE_CONSTEXPR20 vector(std::initializer_list<T> ilist) :
544 vector(ilist.begin(), ilist.end()) {}
545
550 NEFORCE_CONSTEXPR20 vector(memory_view<T> view) :
551 vector(view.begin(), view.end()) {}
552
558 NEFORCE_CONSTEXPR20 vector& operator=(std::initializer_list<T> ilist) {
559 if (ilist.size() > capacity()) {
560 pointer new_ = vector::allocate_and_move(ilist.end() - ilist.begin(), ilist.begin(), ilist.end());
561 _NEFORCE destroy(start_, finish_);
562 deallocate();
563 start_ = new_;
564 finish_ = start_ + ilist.size();
565 pair_.value = start_ + ilist.size();
566 } else if (size() >= ilist.size()) {
567 iterator i = _NEFORCE copy(ilist.begin(), ilist.end(), begin());
568 _NEFORCE destroy(i.base(), finish_);
569 } else {
570 _NEFORCE copy(ilist.begin(), ilist.begin() + size(), start_);
571 _NEFORCE uninitialized_copy(ilist.begin() + size(), ilist.end(), finish_);
572 }
573 finish_ = start_ + ilist.size();
574 return *this;
575 }
576
580 NEFORCE_CONSTEXPR20 ~vector() {
581 clear();
582 deallocate();
583 }
584
589 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator begin() noexcept { return iterator(start_, this); }
590
595 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator end() noexcept { return iterator(finish_, this); }
596
601 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator begin() const noexcept { return cbegin(); }
602
607 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator end() const noexcept { return cend(); }
608
613 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
614
619 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
620
625 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rbegin() const noexcept { return crbegin(); }
626
631 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rend() const noexcept { return crend(); }
632
637 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cbegin() const noexcept {
638 return const_iterator(start_, this);
639 }
640
645 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cend() const noexcept { return const_iterator(finish_, this); }
646
651 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crbegin() const noexcept {
653 }
654
659 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crend() const noexcept {
661 }
662
667 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type size() const noexcept {
668 return static_cast<size_type>(finish_ - start_);
669 }
670
675 NEFORCE_NODISCARD static constexpr size_type max_size() noexcept { return static_cast<size_type>(-1) / sizeof(T); }
676
681 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type capacity() const noexcept {
682 return static_cast<size_type>(pair_.value - start_);
683 }
684
689 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool empty() const noexcept { return start_ == finish_; }
690
695 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer data() noexcept {
696 NEFORCE_DEBUG_VERIFY(!empty(), "data called on empty vector");
697 return start_;
698 }
699
704 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_pointer data() const noexcept {
705 NEFORCE_DEBUG_VERIFY(!empty(), "data called on empty vector");
706 return start_;
707 }
708
713 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<T> view() noexcept {
714 NEFORCE_DEBUG_VERIFY(!empty(), "data called on empty vector");
715 return {start_, size()};
716 }
717
722 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<const T> view() const noexcept {
723 NEFORCE_DEBUG_VERIFY(!empty(), "data called on empty vector");
724 return {start_, size()};
725 }
726
731 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<T> view(const size_type off, size_type count = npos) noexcept {
732 NEFORCE_DEBUG_VERIFY(!empty(), "data called on empty vector");
733 count = _NEFORCE min(count, size() - off);
734 return {start_ + off, count};
735 }
736
741 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view<const T> view(const size_type off,
742 size_type count = npos) const noexcept {
743 NEFORCE_DEBUG_VERIFY(!empty(), "data called on empty vector");
744 count = _NEFORCE min(count, size() - off);
745 return {start_ + off, count};
746 }
747
752 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference front() noexcept {
753 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty vector");
754 return *start_;
755 }
756
761 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference front() const noexcept {
762 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty vector");
763 return *start_;
764 }
765
770 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference back() noexcept {
771 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty vector");
772 return *(finish_ - 1);
773 }
774
779 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference back() const noexcept {
780 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty vector");
781 return *(finish_ - 1);
782 }
783
790 NEFORCE_CONSTEXPR20 void reserve(const size_type n) {
791 NEFORCE_DEBUG_VERIFY(n < max_size(), "vector reserve out of allocate bounds.");
792 if (capacity() >= n) {
793 return;
794 }
795
796 size_type new_capacity = _NEFORCE max(capacity() * 2, n);
797 pointer new_start = pair_.get_base().allocate(new_capacity);
798 pointer new_finish = new_start;
799
800 try {
801 new_finish = _NEFORCE uninitialized_move(start_, finish_, new_start);
802 } catch (...) {
803 _NEFORCE destroy(new_start, new_finish);
804 pair_.get_base().deallocate(new_start, new_capacity);
805 throw;
806 }
807
808 _NEFORCE destroy(start_, finish_);
809 deallocate();
810 start_ = new_start;
811 finish_ = new_finish;
812 pair_.value = start_ + new_capacity;
813 }
814
823 NEFORCE_CONSTEXPR20 void resize(size_type new_size, const T& value) {
824 if (new_size < size()) {
825 vector::erase(begin() + new_size, end());
826 } else {
827 vector::insert(end(), new_size - size(), value);
828 }
829 }
830
835 NEFORCE_CONSTEXPR20 void resize(const size_type new_size) { vector::resize(new_size, T()); }
836
843 template <typename... Args>
844 NEFORCE_CONSTEXPR20 void emplace(iterator position, Args&&... args) {
845 if (finish_ != pair_.value) {
846 if (position == end()) {
847 _NEFORCE construct(finish_, _NEFORCE forward<Args>(args)...);
848 ++finish_;
849 } else {
850 _NEFORCE construct(finish_, _NEFORCE move(*(finish_ - 1)));
851 ++finish_;
852 pointer pos_ptr = position.base();
853 _NEFORCE move_backward(pos_ptr, finish_ - 2, finish_ - 1);
854 _NEFORCE construct(pos_ptr, _NEFORCE forward<Args>(args)...);
855 }
856 return;
857 }
858
859 const size_type old_size = size();
860 const size_type new_cap = old_size != 0 ? 2 * old_size : 1;
861 pointer new_start = pair_.get_base().allocate(new_cap);
862 pointer new_finish = new_start;
863
864 try {
865 new_finish = _NEFORCE uninitialized_move(begin(), position, new_start);
866 _NEFORCE construct(new_finish, _NEFORCE forward<Args>(args)...);
867 ++new_finish;
868 new_finish = _NEFORCE uninitialized_move(position, end(), new_finish);
869 } catch (...) {
870 _NEFORCE destroy(new_start, new_finish);
871 pair_.get_base().deallocate(new_start, new_cap);
872 throw;
873 }
874
875 _NEFORCE destroy(begin(), end());
876 deallocate();
877
878 start_ = new_start;
879 finish_ = new_finish;
880 pair_.value = new_start + new_cap;
881 }
882
888 template <typename... Args>
889 NEFORCE_CONSTEXPR20 void emplace_back(Args&&... args) {
890 if (finish_ != pair_.value) {
891 _NEFORCE construct(finish_, _NEFORCE forward<Args>(args)...);
892 ++finish_;
893 } else {
894 vector::emplace(end(), _NEFORCE forward<Args>(args)...);
895 }
896 }
897
902 NEFORCE_CONSTEXPR20 void push_back(const T& value) { vector::emplace_back(value); }
903
908 NEFORCE_CONSTEXPR20 void push_back(T&& value) { vector::emplace_back(_NEFORCE move(value)); }
909
913 NEFORCE_CONSTEXPR20 void pop_back() noexcept(is_nothrow_destructible_v<T>) {
914 NEFORCE_DEBUG_VERIFY(!empty(), "pop called in an empty vector")
915 _NEFORCE destroy(finish_ - 1);
916 --finish_;
917 }
918
923 NEFORCE_CONSTEXPR20 T pop_back_v() noexcept(is_nothrow_destructible_v<T> && is_nothrow_move_constructible_v<T>) {
924 NEFORCE_DEBUG_VERIFY(!empty(), "pop called in an empty vector")
925 T value{_NEFORCE move(finish_ - 1)};
926 _NEFORCE destroy(finish_ - 1);
927 --finish_;
928 return _NEFORCE move(value);
929 }
930
936 NEFORCE_CONSTEXPR20 void assign(size_type n, const value_type& value) {
937 if (n > capacity()) {
938 pointer new_start = pair_.get_base().allocate(n);
939 pointer new_finish = new_start;
940
941 try {
942 new_finish = _NEFORCE uninitialized_fill_n(new_start, n, value);
943 } catch (...) {
944 _NEFORCE destroy(new_start, new_finish);
945 pair_.get_base().deallocate(new_start, n);
946 throw;
947 }
948
949 _NEFORCE destroy(start_, finish_);
950 deallocate();
951
952 start_ = new_start;
953 finish_ = new_finish;
954 pair_.value = start_ + n;
955 } else if (n > size()) {
956 _NEFORCE fill(begin(), end(), value);
957 finish_ = _NEFORCE uninitialized_fill_n(finish_, n - size(), value);
958 } else {
959 _NEFORCE fill_n(begin(), n, value);
960 vector::erase(begin() + n, end());
961 }
962 }
963
970 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
971 NEFORCE_CONSTEXPR20 void assign(Iterator first, Iterator last) {
972 vector::assign_aux(first, last);
973 }
974
979 NEFORCE_CONSTEXPR20 void assign(std::initializer_list<value_type> ilist) {
980 vector::assign(ilist.begin(), ilist.end());
981 }
982
989 NEFORCE_CONSTEXPR20 iterator insert(iterator position, const value_type& value) {
990 size_type n = position - begin();
991 vector::emplace(position, value);
992 return begin() + n;
993 }
994
1001 NEFORCE_CONSTEXPR20 iterator insert(iterator position, value_type&& value) {
1002 size_type n = position - begin();
1003 vector::emplace(position, _NEFORCE move(value));
1004 return begin() + n;
1005 }
1006
1012 NEFORCE_CONSTEXPR20 iterator insert(iterator position) { return vector::insert(position, T()); }
1013
1021 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1022 NEFORCE_CONSTEXPR20 void insert(iterator position, Iterator first, Iterator last) {
1023 vector::range_insert(position, first, last);
1024 }
1025
1031 NEFORCE_CONSTEXPR20 void insert(iterator position, std::initializer_list<value_type> ilist) {
1032 vector::insert(position, ilist.begin(), ilist.end());
1033 }
1034
1041 NEFORCE_CONSTEXPR20 void insert(iterator position, size_type n, const value_type& value) {
1042 if (n == 0) {
1043 return;
1044 }
1045
1046 if (static_cast<size_type>(pair_.value - finish_) >= n) {
1047 const size_type elems_after = _NEFORCE distance(begin(), position);
1048 iterator old_finish = end();
1049
1050 if (elems_after > n) {
1051 _NEFORCE uninitialized_copy(finish_ - n, finish_, finish_);
1052 finish_ += n;
1053 _NEFORCE copy_backward(position, old_finish - n, old_finish);
1054 _NEFORCE fill(position, position + n, value);
1055 } else {
1056 _NEFORCE uninitialized_fill_n(finish_, n - elems_after, value);
1057 finish_ += n - elems_after;
1058 _NEFORCE uninitialized_move(position, old_finish, end());
1059 finish_ += elems_after;
1060 _NEFORCE destroy(position, old_finish);
1061 _NEFORCE uninitialized_fill(position, old_finish, value);
1062 }
1063 } else {
1064 const size_type old_size = size();
1065 const size_type len = old_size + _NEFORCE max(old_size, n);
1066
1067 pointer new_start = pair_.get_base().allocate(len);
1068 pointer new_finish = _NEFORCE uninitialized_copy(begin(), position, new_start);
1069 new_finish = _NEFORCE uninitialized_fill_n(new_finish, n, value);
1070 new_finish = _NEFORCE uninitialized_copy(position, end(), new_finish);
1071
1072 _NEFORCE destroy(start_, finish_);
1073 deallocate();
1074
1075 start_ = new_start;
1076 finish_ = new_finish;
1077 pair_.value = new_start + len;
1078 }
1079 }
1080
1087 NEFORCE_CONSTEXPR20 iterator erase(iterator first,
1090 NEFORCE_DEBUG_VERIFY(_NEFORCE distance(first, last) >= 0, "vector erase out of ranges.");
1091
1092 const auto elems_after = end() - last;
1093 if (elems_after > 0) {
1094 _NEFORCE move_backward(last, end(), first + elems_after);
1095 }
1096
1097 pointer new_finish = finish_ - (last - first);
1098 _NEFORCE destroy(new_finish, finish_);
1099 finish_ = new_finish;
1100 return first;
1101 }
1102
1108 NEFORCE_CONSTEXPR20 iterator erase(iterator position) noexcept(is_nothrow_move_assignable_v<value_type>) {
1109 if (position + 1 != end()) {
1110 _NEFORCE move(position + 1, end(), position);
1111 }
1112
1113 --finish_;
1114 _NEFORCE destroy(finish_);
1115 return position;
1116 }
1117
1123 NEFORCE_CONSTEXPR20 void shrink_to_fit() {
1124 if (capacity() == size()) {
1125 return;
1126 }
1127
1128 if (size() == 0) {
1129 deallocate();
1130 start_ = finish_ = pair_.value = nullptr;
1131 return;
1132 }
1133
1134 pointer new_start = pair_.get_base().allocate(size());
1135 pointer new_finish = new_start;
1136
1137 try {
1138 new_finish = _NEFORCE uninitialized_move(start_, finish_, new_start);
1139 } catch (...) {
1140 _NEFORCE destroy(new_start, new_finish);
1141 pair_.get_base().deallocate(new_start, size());
1142 throw;
1143 }
1144
1145 _NEFORCE destroy(start_, finish_);
1146 deallocate();
1147
1148 start_ = new_start;
1149 finish_ = new_finish;
1150 pair_.value = new_start + size();
1151 }
1152
1158 NEFORCE_CONSTEXPR20 void clear() noexcept(is_nothrow_destructible_v<value_type>) {
1159 if (empty()) {
1160 return;
1161 }
1162
1163 _NEFORCE destroy(start_, finish_);
1164 finish_ = start_;
1165 }
1166
1172 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference at(const size_type position) const noexcept {
1173 NEFORCE_DEBUG_VERIFY(position < size(), "vector access out of range");
1174 return *(start_ + position);
1175 }
1176
1182 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference at(const size_type position) noexcept {
1183 NEFORCE_DEBUG_VERIFY(position < size(), "vector access out of range");
1184 return *(start_ + position);
1185 }
1186
1192 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference operator[](const size_type position) const noexcept {
1193 return at(position);
1194 }
1195
1201 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference operator[](const size_type position) noexcept {
1202 return at(position);
1203 }
1204
1209 NEFORCE_CONSTEXPR20 void swap(vector& other) noexcept(is_nothrow_swappable_v<allocator_type>) {
1210 if (_NEFORCE addressof(other) == this) {
1211 return;
1212 }
1213
1214 _NEFORCE swap(start_, other.start_);
1215 _NEFORCE swap(finish_, other.finish_);
1216 _NEFORCE swap(pair_, other.pair_);
1217 }
1218
1224 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator==(const vector& rhs) const
1225 noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin()))) {
1226 return size() == rhs.size() && _NEFORCE equal(cbegin(), cend(), rhs.cbegin());
1227 }
1228
1234 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator<(const vector& rhs) const
1235 noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend()))) {
1236 return _NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend());
1237 }
1238};
1239
1240#ifdef NEFORCE_STANDARD_17
1241template <typename T, typename Alloc>
1242vector(T, Alloc = Alloc()) -> vector<T, Alloc>;
1243
1244template <typename Iterator, typename Alloc>
1245vector(Iterator, Iterator, Alloc = Alloc()) -> vector<iter_value_t<Iterator>, Alloc>;
1246#endif
1247
1252 // Container
1254
1255NEFORCE_END_NAMESPACE__
1256#endif // NEFORCE_CORE_CONTAINER_VECTOR_HPP__
内存视图模板
动态大小数组容器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference front() noexcept
访问第一个元素
NEFORCE_CONSTEXPR20 void clear() noexcept(is_nothrow_destructible_v< value_type >)
清空向量
NEFORCE_CONSTEXPR20 void assign(std::initializer_list< value_type > ilist)
初始化列表赋值
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
NEFORCE_CONSTEXPR20 void push_back(const T &value)
在末尾拷贝插入元素
NEFORCE_CONSTEXPR20 vector(const int64_t n, const T &value)
构造包含n个指定值元素的向量
NEFORCE_CONSTEXPR20 void shrink_to_fit()
收缩容量以适应当前大小
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rend() noexcept
获取反向结束迭代器
NEFORCE_CONSTEXPR20 vector & operator=(const vector &other)
拷贝赋值运算符
NEFORCE_CONSTEXPR20 vector & operator=(vector &&other) noexcept(is_nothrow_destructible_v< value_type > &&is_nothrow_swappable_v< compressed_pair< allocator_type, pointer > >)
移动赋值运算符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator begin() const noexcept
获取常量起始迭代器
NEFORCE_CONSTEXPR20 iterator insert(iterator position, const value_type &value)
在指定位置拷贝插入元素
NEFORCE_CONSTEXPR20 vector(std::initializer_list< T > ilist)
初始化列表构造函数
NEFORCE_CONSTEXPR20 iterator insert(iterator position, value_type &&value)
在指定位置移动插入元素
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference at(const size_type position) noexcept
带边界检查的索引访问
NEFORCE_CONSTEXPR20 void resize(const size_type new_size)
使用默认构造的元素调整大小
NEFORCE_CONSTEXPR20 void insert(iterator position, size_type n, const value_type &value)
插入n个指定值的元素
const T & const_reference
常量引用类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view< byte_t > view() noexcept
NEFORCE_CONSTEXPR20 void pop_back() noexcept(is_nothrow_destructible_v< T >)
移除末尾元素
NEFORCE_CONSTEXPR20 vector(const vector &other)
拷贝构造函数
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator end() noexcept
获取结束迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference back() const noexcept
访问最后一个常量元素
T value_type
值类型
Alloc allocator_type
分配器类型
const T * const_pointer
常量指针类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type capacity() const noexcept
获取当前容量
NEFORCE_CONSTEXPR20 void insert(iterator position, std::initializer_list< value_type > ilist)
初始化列表插入
NEFORCE_CONSTEXPR20 void swap(vector &other) noexcept(is_nothrow_swappable_v< allocator_type >)
交换两个向量的内容
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
NEFORCE_CONSTEXPR20 iterator erase(iterator position) noexcept(is_nothrow_move_assignable_v< value_type >)
删除指定位置的元素
NEFORCE_CONSTEXPR20 ~vector()
析构函数
NEFORCE_CONSTEXPR20 vector(Iterator first, Iterator last)
范围构造函数
NEFORCE_CONSTEXPR20 vector(const int32_t n, const T &value)
构造包含n个指定值元素的向量
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_pointer data() const noexcept
获取底层数据常量指针
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference back() noexcept
访问最后一个元素
T * pointer
指针类型
NEFORCE_CONSTEXPR20 vector(Iterator first, const size_type n)
范围构造函数
vector_iterator< false, vector< T, Alloc > > iterator
迭代器类型
NEFORCE_CONSTEXPR20 void push_back(T &&value)
在末尾移动插入元素
NEFORCE_CONSTEXPR20 vector(vector &&other) noexcept(is_nothrow_swappable_v< compressed_pair< allocator_type, pointer > >)
移动构造函数
NEFORCE_CONSTEXPR20 vector & operator=(std::initializer_list< T > ilist)
初始化列表赋值运算符
NEFORCE_CONSTEXPR20 iterator erase(iterator first, iterator last) noexcept(is_nothrow_move_assignable_v< value_type > &&is_nothrow_destructible_v< value_type >)
删除指定范围内的元素
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator end() const noexcept
获取常量结束迭代器
NEFORCE_CONSTEXPR20 vector(const size_type n, const T &value)
构造包含n个指定值元素的向量
NEFORCE_CONSTEXPR20 void reserve(const size_type n)
预留容量
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator<(const vector &rhs) const noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend())))
小于比较操作符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 iterator begin() noexcept
获取起始迭代器
T & reference
引用类型
NEFORCE_CONSTEXPR20 void assign(Iterator first, Iterator last)
范围赋值
vector_iterator< true, vector< T, Alloc > > const_iterator
常量迭代器类型
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
NEFORCE_CONSTEXPR20 void assign(size_type n, const value_type &value)
赋值n个指定值的元素
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference operator[](const size_type position) const noexcept
常量下标访问操作符
NEFORCE_CONSTEXPR20 vector(memory_view< T > view)
内存视图构造函数
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view< const T > view(const size_type off, size_type count=npos) const noexcept
获取底层数据的常量视图
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference operator[](const size_type position) noexcept
下标访问操作符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 size_type size() const noexcept
获取当前元素数量
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view< const T > view() const noexcept
获取底层数据的常量视图
static NEFORCE_NODISCARD constexpr size_type max_size() noexcept
获取最大可能大小
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer data() noexcept
获取底层数据指针
NEFORCE_CONSTEXPR20 void insert(iterator position, Iterator first, Iterator last)
范围插入
NEFORCE_CONSTEXPR20 vector()
默认构造函数
NEFORCE_CONSTEXPR20 iterator insert(iterator position)
在指定位置插入默认构造的元素
NEFORCE_CONSTEXPR20 void emplace(iterator position, Args &&... args)
在指定位置构造元素
NEFORCE_CONSTEXPR20 T pop_back_v() noexcept(is_nothrow_destructible_v< T > &&is_nothrow_move_constructible_v< T >)
移除并返回末尾元素
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reverse_iterator rbegin() noexcept
获取反向起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cbegin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool empty() const noexcept
检查是否为空
NEFORCE_CONSTEXPR20 void emplace_back(Args &&... args)
在末尾构造元素
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
size_t size_type
大小类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
ptrdiff_t difference_type
差值类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool operator==(const vector &rhs) const noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin())))
相等比较操作符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 memory_view< T > view(const size_type off, size_type count=npos) noexcept
获取底层数据的视图
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_iterator cend() const noexcept
获取常量结束迭代器
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference front() const noexcept
访问第一个常量元素
NEFORCE_CONSTEXPR20 vector(const size_type n)
构造包含n个默认构造元素的向量
NEFORCE_CONSTEXPR20 void resize(size_type new_size, const T &value)
调整大小
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const_reference at(const size_type position) const noexcept
带边界检查的常量索引访问
static constexpr size_type npos
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_INLINE17 constexpr bool is_object_v
is_object的便捷变量模板
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
NEFORCE_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
NEFORCE_NODISCARD 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 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)
统计范围内等于指定值的元素数量
#define NEFORCE_DEBUG_VERIFY(CON, MESG)
调试模式断言
NEFORCE_CONSTEXPR20 T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
NEFORCE_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
NEFORCE_CONSTEXPR20 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重载
NEFORCE_INLINE17 constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_allocator_v
is_allocator的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_move_assignable_v
is_nothrow_move_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
NEFORCE_CONSTEXPR20 Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
NEFORCE_CONSTEXPR20 void uninitialized_fill(Iterator first, Iterator last, const T &x)
在未初始化内存上填充值
NEFORCE_CONSTEXPR20 Iterator uninitialized_fill_n(Iterator first, size_t n, const T &x)
在未初始化内存中用指定值填充指定数量的元素
NEFORCE_CONSTEXPR20 Iterator2 uninitialized_move(Iterator1 first, Iterator1 last, Iterator2 result)
在未初始化内存中移动元素
内存视图容器
标准分配器
压缩对主模板,使用EBCO优化
constexpr compressed_pair & get_base() noexcept
获取基类引用
连续迭代器标签
默认构造标签
集合器接口模板
迭代器接口模板
向量迭代器
typename container_type::difference_type difference_type
差值类型
NEFORCE_CONSTEXPR20 void advance(difference_type off) noexcept
前进操作
NEFORCE_CONSTEXPR20 void increment() noexcept
递增操作
Vector container_type
容器类型
typename container_type::value_type value_type
值类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 const container_type * container() const noexcept
获取关联容器
typename container_type::size_type size_type
大小类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool equal(const vector_iterator &rhs) const noexcept
相等比较
NEFORCE_CONSTEXPR20 void decrement() noexcept
递减操作
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
contiguous_iterator_tag iterator_category
迭代器类别
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 pointer base() const noexcept
获取底层指针
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference dereference() const noexcept
解引用操作
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 bool less_than(const vector_iterator &rhs) const noexcept
小于比较
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 reference operator[](difference_type off) noexcept
下标访问操作符
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 difference_type distance_to(const vector_iterator &other) const noexcept
计算距离操作
未初始化内存操作