1#ifndef NEFORCE_CORE_CONTAINER_VECTOR_HPP__
2#define NEFORCE_CORE_CONTAINER_VECTOR_HPP__
15NEFORCE_BEGIN_NAMESPACE__
31template <
bool IsConst,
typename Vector>
32struct vector_iterator :
iiterator<vector_iterator<IsConst, Vector>> {
36 using size_type =
typename container_type::size_type;
40 typename container_type::reference>;
42 typename container_type::pointer>;
49 NEFORCE_CONSTEXPR20 vector_iterator() noexcept = default;
50 NEFORCE_CONSTEXPR20 ~vector_iterator() = default;
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;
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");
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");
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");
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");
112 NEFORCE_DEBUG_VERIFY(container_ == other.container_,
"Attempting to distance to a different container");
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_;
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_;
147 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
pointer base() const noexcept {
return current_; }
166template <
typename T,
typename Alloc = allocator<T>>
168 static_assert(
is_object_v<T>,
"vector only contains object types.");
180 using iterator = vector_iterator<false, vector<T, Alloc>>;
192 template <
bool,
typename>
205 NEFORCE_CONSTEXPR20
void fill_initialize(
size_type n,
const T& value) {
206 start_ = pair_.get_base().allocate(n);
208 finish_ = start_ + n;
209 pair_.value = finish_;
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.");
228 _NEFORCE
destroy(result, finish);
229 pair_.get_base().deallocate(result, n);
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);
250 _NEFORCE
destroy(result, finish);
251 pair_.get_base().deallocate(result, n);
263 template <
typename Iterator>
265 for (; first != last; ++first) {
277 template <
typename Iterator>
280 start_ = vector::allocate_and_copy(n, first, last);
281 finish_ = start_ + n;
282 pair_.value = finish_;
289 NEFORCE_CONSTEXPR20
void deallocate() noexcept {
291 pair_.get_base().deallocate(start_, pair_.value - start_);
302 template <
typename Iterator>
305 while (first != last) {
320 template <
typename Iterator>
327 const size_t n = _NEFORCE
distance(first, last);
329 if (
static_cast<size_t>(pair_.value - finish_) >= n) {
330 const size_t elems_after =
end() - position;
333 if (elems_after > n) {
336 _NEFORCE
copy_backward(position, old_finish - n, old_finish);
337 _NEFORCE
copy(first, last, position);
339 Iterator mid = first;
340 _NEFORCE
advance(mid, elems_after);
342 finish_ += (n - elems_after);
344 finish_ += elems_after;
345 _NEFORCE
copy(first, mid, position);
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;
357 _NEFORCE
destroy(start_, finish_);
361 finish_ = new_finish;
362 pair_.value = new_start + len;
373 template <
typename Iterator>
376 while (first != last) {
389 template <
typename Iterator>
391 const size_t n = _NEFORCE
distance(first, last);
393 pointer new_start = vector::allocate_and_copy(n, first, last);
394 _NEFORCE
destroy(start_, finish_);
397 finish_ = start_ + n;
398 pair_.value = start_ + n;
399 }
else if (n >
size()) {
400 Iterator mid = first;
402 _NEFORCE
copy(first, mid, start_);
405 _NEFORCE
copy(first, last, start_);
419 pointer result = pair_.get_base().allocate(init_cap);
420 finish_ = start_ = result;
421 pair_.value = finish_ + init_cap;
429 start_ = pair_.get_base().allocate(n);
437 _NEFORCE
destroy(start_, finish_);
438 pair_.get_base().deallocate(start_, n);
441 pair_.value = start_ + n;
449 NEFORCE_CONSTEXPR20
explicit vector(
const size_type n,
const T& value) { vector::fill_initialize(n, value); }
456 NEFORCE_CONSTEXPR20
explicit vector(
const int32_t n,
const T& value) { vector::fill_initialize(n, value); }
463 NEFORCE_CONSTEXPR20
explicit vector(
const int64_t n,
const T& value) { vector::fill_initialize(n, value); }
471 start_ = vector::allocate_and_copy(n, other.
begin(), other.
end());
472 finish_ = start_ + n;
473 pair_.value = finish_;
505 NEFORCE_CONSTEXPR20
vector&
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);
534 template <
typename Iterator>
542 NEFORCE_CONSTEXPR20
vector(std::initializer_list<T> ilist) :
559 pointer new_ = vector::allocate_and_move(ilist.end() - ilist.begin(), ilist.begin(), ilist.end());
560 _NEFORCE
destroy(start_, finish_);
563 finish_ = start_ + ilist.size();
564 pair_.value = start_ + ilist.size();
565 }
else if (
size() >= ilist.size()) {
569 _NEFORCE
copy(ilist.begin(), ilist.begin() +
size(), start_);
572 finish_ = start_ + ilist.
size();
667 return static_cast<size_type>(finish_ - start_);
681 return static_cast<size_type>(pair_.value - start_);
688 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool empty() const noexcept {
return start_ == finish_; }
694 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
pointer data() noexcept {
return start_; }
720 return {start_ + off,
count};
730 return {start_ + off,
count};
738 NEFORCE_DEBUG_VERIFY(!
empty(),
"front called on empty vector");
747 NEFORCE_DEBUG_VERIFY(!
empty(),
"front called on empty vector");
756 NEFORCE_DEBUG_VERIFY(!
empty(),
"back called on empty vector");
757 return *(finish_ - 1);
765 NEFORCE_DEBUG_VERIFY(!
empty(),
"back called on empty vector");
766 return *(finish_ - 1);
776 NEFORCE_DEBUG_VERIFY(n <
max_size(),
"vector reserve out of allocate bounds.");
782 pointer new_start = pair_.get_base().allocate(new_capacity);
783 pointer new_finish = new_start;
788 _NEFORCE
destroy(new_start, new_finish);
789 pair_.get_base().deallocate(new_start, new_capacity);
793 _NEFORCE
destroy(start_, finish_);
796 finish_ = new_finish;
797 pair_.value = start_ + new_capacity;
809 if (new_size <
size()) {
828 template <
typename... Args>
830 if (finish_ != pair_.value) {
831 if (position ==
end()) {
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;
855 _NEFORCE
destroy(new_start, new_finish);
856 pair_.get_base().deallocate(new_start, new_cap);
864 finish_ = new_finish;
865 pair_.value = new_start + new_cap;
873 template <
typename... Args>
875 if (finish_ != pair_.value) {
899 NEFORCE_DEBUG_VERIFY(!
empty(),
"pop called in an empty vector")
909 NEFORCE_DEBUG_VERIFY(!
empty(),
"pop called in an empty vector")
910 T value{_NEFORCE
move(*(finish_ - 1))};
913 return _NEFORCE
move(value);
923 pointer new_start = pair_.get_base().allocate(n);
924 pointer new_finish = new_start;
929 _NEFORCE
destroy(new_start, new_finish);
930 pair_.get_base().deallocate(new_start, n);
934 _NEFORCE
destroy(start_, finish_);
938 finish_ = new_finish;
939 pair_.value = start_ + n;
940 }
else if (n >
size()) {
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);
964 NEFORCE_CONSTEXPR20
void assign(std::initializer_list<value_type> ilist) {
1006 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
1008 vector::range_insert(position, first, last);
1016 NEFORCE_CONSTEXPR20
void insert(
iterator position, std::initializer_list<value_type> ilist) {
1031 if (
static_cast<size_type>(pair_.value - finish_) >= n) {
1035 if (elems_after > n) {
1038 _NEFORCE
move_backward(position, old_finish - n, old_finish);
1039 _NEFORCE
fill_n(position, n, value);
1042 finish_ += n - elems_after;
1044 finish_ += elems_after;
1045 _NEFORCE
fill(position, old_finish, value);
1049 const size_type len = old_size + _NEFORCE
max(old_size, n);
1051 pointer new_start = pair_.get_base().allocate(len);
1056 _NEFORCE
destroy(start_, finish_);
1060 finish_ = new_finish;
1061 pair_.value = new_start + len;
1074 NEFORCE_DEBUG_VERIFY(_NEFORCE
distance(first, last) >= 0,
"vector erase out of ranges.");
1076 const auto elems_after =
end() - last;
1077 if (elems_after > 0) {
1081 pointer new_finish = finish_ - (last - first);
1082 _NEFORCE
destroy(new_finish, finish_);
1083 finish_ = new_finish;
1093 if (position + 1 !=
end()) {
1094 _NEFORCE
move(position + 1,
end(), position);
1114 start_ = finish_ = pair_.value =
nullptr;
1118 pointer new_start = pair_.get_base().allocate(
size());
1119 pointer new_finish = new_start;
1124 _NEFORCE
destroy(new_start, new_finish);
1125 pair_.get_base().deallocate(new_start,
size());
1129 _NEFORCE
destroy(start_, finish_);
1133 finish_ = new_finish;
1134 pair_.value = new_start +
size();
1147 _NEFORCE
destroy(start_, finish_);
1157 NEFORCE_DEBUG_VERIFY(position <
size(),
"vector access out of range");
1158 return *(start_ + position);
1167 NEFORCE_DEBUG_VERIFY(position <
size(),
"vector access out of range");
1168 return *(start_ + position);
1177 return at(position);
1186 return at(position);
1194 if (_NEFORCE
addressof(other) ==
this) {
1198 _NEFORCE
swap(start_, other.start_);
1199 _NEFORCE
swap(finish_, other.finish_);
1200 _NEFORCE
swap(pair_, other.pair_);
1224#ifdef NEFORCE_STANDARD_17
1225template <
typename T,
typename Alloc>
1228template <
typename Iterator,
typename Alloc>
1239NEFORCE_END_NAMESPACE__
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 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
获取反向结束迭代器
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
获取常量起始迭代器
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 const_iterator cbegin() const noexcept
获取常量起始迭代器
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
获取常量结束迭代器
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位有符号整数类型
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
内存释放函数
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)
在未初始化内存中用指定值填充指定数量的元素
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
递增操作