🛰️航天仿真算法库 SpaceAST 0.3.1
载入中...
搜索中...
未找到
CorVector.hpp
浏览该文件的文档.
1
20
21#pragma once
22
23#include "AstGlobal.h"
24#include <memory>
25#include <initializer_list>
26#include <algorithm>
27#include <stdexcept>
28#include <cassert>
29#include <type_traits>
30
31AST_NAMESPACE_BEGIN
32
42template<typename T>
44{
45public:
46 using value_type = T;
47 using pointer = T*;
48 using const_pointer = const T*;
49 using reference = T&;
50 using const_reference = const T&;
51 using size_type = size_t;
52 using difference_type = ptrdiff_t;
53 using iterator = T*;
54 using const_iterator = const T*;
55 using reverse_iterator = std::reverse_iterator<iterator>;
56 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
57 using allocator_type = std::allocator<T>;
58
59 // 构造函数
60 CorVector() noexcept : data_(nullptr), size_(0), allocator_() {}
61
62 explicit CorVector(size_type count) : CorVector() {
63 reserve(count);
64 resize(count);
65 }
66
67 CorVector(size_type count, const T& value) : CorVector() {
68 reserve(count);
69 resize(count, value);
70 }
71
72 template<typename InputIt,
73 typename std::enable_if<!std::is_integral<InputIt>::value, int>::type = 0>
74 CorVector(InputIt first, InputIt last) : CorVector() {
75 size_type count = std::distance(first, last);
76 reserve(count);
77 for (; first != last; ++first) {
78 push_back(*first);
79 }
80 }
81
82 CorVector(std::initializer_list<T> init) : CorVector(init.begin(), init.end()) {}
83
84 CorVector(const CorVector& other)
85 : CorVector()
86 {
87 reserve(other.size_);
88 for (size_type i = 0; i < other.size_; ++i) {
89 push_back(other.data_[i]);
90 }
91 }
92
93 CorVector(CorVector&& other) noexcept
94 {
95 this->data_ = other.data_;
96 this->size_ = other.size_;
97 this->allocator_ = other.allocator_;
98 other.data_ = nullptr;
99 other.size_ = 0;
100 other.allocator_.end_of_storage_ = nullptr;
101 }
102
103 ~CorVector() {
104 if (end_of_storage()) {
105 clear();
106 allocator().deallocate(data_, end_of_storage() - data_);
107 }
108 }
109
110 // 赋值操作符
111 CorVector& operator=(const CorVector& other) {
112 if (this != &other) {
113 CorVector temp(other);
114 swap(temp);
115 }
116 return *this;
117 }
118
119 CorVector& operator=(CorVector&& other) noexcept {
120 if (this != &other) {
121 clear();
122 if (end_of_storage()) {
123 allocator().deallocate(data_, end_of_storage() - data_);
124 }
125 data_ = other.data_;
126 size_ = other.size_;
127 allocator_ = other.allocator_;
128 other.data_ = nullptr;
129 other.size_ = 0;
130 other.allocator_.end_of_storage_ = nullptr;
131 }
132 return *this;
133 }
134
135 CorVector& operator=(std::initializer_list<T> init) {
136 CorVector temp(init);
137 swap(temp);
138 return *this;
139 }
140
141 // 元素访问
142 reference operator[](size_type pos) {
143 return data_[pos];
144 }
145
146 const_reference operator[](size_type pos) const {
147 return data_[pos];
148 }
149
150 reference at(size_type pos) {
151 if (pos >= size_) {
152 throw std::out_of_range("CorVector::at: index out of range");
153 }
154 return data_[pos];
155 }
156
157 const_reference at(size_type pos) const {
158 if (pos >= size_) {
159 throw std::out_of_range("CorVector::at: index out of range");
160 }
161 return data_[pos];
162 }
163
164 reference front() {
165 return data_[0];
166 }
167
168 const_reference front() const {
169 return data_[0];
170 }
171
172 reference back() {
173 return data_[size_ - 1];
174 }
175
176 const_reference back() const {
177 return data_[size_ - 1];
178 }
179
180 T* data() noexcept {
181 return data_;
182 }
183
184 const T* data() const noexcept {
185 return data_;
186 }
187
188 // 迭代器
189 iterator begin() noexcept {
190 return data_;
191 }
192
193 const_iterator begin() const noexcept {
194 return data_;
195 }
196
197 const_iterator cbegin() const noexcept {
198 return data_;
199 }
200
201 iterator end() noexcept {
202 return data_ + size();
203 }
204
205 const_iterator end() const noexcept {
206 return data_ + size();
207 }
208
209 const_iterator cend() const noexcept {
210 return data_ + size();
211 }
212
213 reverse_iterator rbegin() noexcept {
214 return reverse_iterator(end());
215 }
216
217 const_reverse_iterator rbegin() const noexcept {
218 return const_reverse_iterator(end());
219 }
220
221 const_reverse_iterator crbegin() const noexcept {
222 return const_reverse_iterator(cend());
223 }
224
225 reverse_iterator rend() noexcept {
226 return reverse_iterator(begin());
227 }
228
229 const_reverse_iterator rend() const noexcept {
230 return const_reverse_iterator(begin());
231 }
232
233 const_reverse_iterator crend() const noexcept {
234 return const_reverse_iterator(cbegin());
235 }
236
237 // 容量
238 bool empty() const noexcept {
239 return size_ == 0;
240 }
241
242 size_type size() const noexcept {
243 return size_;
244 }
245
246 size_type max_size() const noexcept {
247 return allocator().max_size();
248 }
249
250 size_type capacity() const noexcept {
251 return end_of_storage() ? (end_of_storage() - data_) : 0;
252 }
253
254 void reserve(size_type new_cap) {
255 if (new_cap > capacity()) {
256 // 如果当前是共享内存(capacity_为nullptr)或者需要更大的容量,进行复制
257 allocate_and_copy(new_cap);
258 }
259 }
260
261 void shrink_to_fit() {
262 if (capacity() > size()) {
263 allocate_and_copy(size());
264 }
265 }
266
267 // 修改器
268 void clear() noexcept {
269 if (end_of_storage()) {
270 for (size_type i = 0; i < size(); ++i) {
271 allocator().destroy(data_ + i);
272 }
273 size_ = 0;
274 }
275 }
276
277 iterator insert(const_iterator pos, const T& value) {
278 difference_type offset = pos - cbegin();
279 if (size_ >= capacity()) {
280 reserve(size_ + 1);
281 }
282 std::move_backward(data_ + offset, data_ + size_, data_ + size_ + 1);
283 allocator().construct(data_ + offset, value);
284 ++size_;
285 return data_ + offset;
286 }
287
288 iterator insert(const_iterator pos, T&& value) {
289 difference_type offset = pos - cbegin();
290 if (size_ >= capacity()) {
291 reserve(size_ + 1);
292 }
293 std::move_backward(data_ + offset, data_ + size_, data_ + size_ + 1);
294 allocator().construct(data_ + offset, std::move(value));
295 ++size_;
296 return data_ + offset;
297 }
298
299 iterator insert(const_iterator pos, size_type count, const T& value) {
300 difference_type offset = pos - cbegin();
301 if (size_ + count > capacity()) {
302 reserve(size_ + count);
303 }
304 std::move_backward(data_ + offset, data_ + size_, data_ + size_ + count);
305 for (size_type i = 0; i < count; ++i) {
306 allocator().construct(data_ + offset + i, value);
307 }
308 size_ += count;
309 return data_ + offset;
310 }
311
312 template<typename InputIt,
313 typename std::enable_if<!std::is_integral<InputIt>::value, int>::type = 0>
314 iterator insert(const_iterator pos, InputIt first, InputIt last) {
315 difference_type offset = pos - cbegin();
316 size_type count = std::distance(first, last);
317 if (size_ + count > capacity()) {
318 reserve(size_ + count);
319 }
320 std::move_backward(data_ + offset, data_ + size_, data_ + size_ + count);
321 T* cur = data_ + offset;
322 for (; first != last; ++first, ++cur) {
323 allocator().construct(cur, *first);
324 }
325 size_ += count;
326 return data_ + offset;
327 }
328
329 iterator insert(const_iterator pos, std::initializer_list<T> init) {
330 return insert(pos, init.begin(), init.end());
331 }
332
333 iterator erase(const_iterator pos) {
334 difference_type offset = pos - cbegin();
335 std::move(data_ + offset + 1, data_ + size_, data_ + offset);
336 --size_;
337 allocator().destroy(data_ + size_);
338 return data_ + offset;
339 }
340
341 iterator erase(const_iterator first, const_iterator last) {
342 difference_type start = first - cbegin();
343 difference_type count = last - first;
344 std::move(data_ + start + count, data_ + size_, data_ + start);
345 for (difference_type i = 0; i < count; ++i) {
346 allocator().destroy(data_ + size_ - i - 1);
347 }
348 size_ -= count;
349 return data_ + start;
350 }
351
352 void push_back(const T& value) {
353 if (size_ >= capacity()) {
354 reserve(size_ == 0 ? 1 : size_ * 2);
355 }
356 allocator().construct(data_ + size_, value);
357 ++size_;
358 }
359
360 void push_back(T&& value) {
361 if (size_ >= capacity()) {
362 reserve(size_ == 0 ? 1 : size_ * 2);
363 }
364 allocator().construct(data_ + size_, std::move(value));
365 ++size_;
366 }
367
368 void pop_back() {
369 assert(size_ > 0);
370 --size_;
371 allocator().destroy(data_ + size_);
372 }
373
374 void resize(size_type count) {
375 if (count > size_) {
376 if (count > capacity()) {
377 reserve(count);
378 }
379 for (size_type i = size_; i < count; ++i) {
380 allocator().construct(data_ + i);
381 }
382 } else if (count < size_) {
383 for (size_type i = count; i < size_; ++i) {
384 allocator().destroy(data_ + i);
385 }
386 }
387 size_ = count;
388 }
389
390 void resize(size_type count, const T& value) {
391 if (count > size_) {
392 if (count > capacity()) {
393 reserve(count);
394 }
395 for (size_type i = size_; i < count; ++i) {
396 allocator().construct(data_ + i, value);
397 }
398 } else if (count < size_) {
399 for (size_type i = count; i < size_; ++i) {
400 allocator().destroy(data_ + i);
401 }
402 }
403 size_ = count;
404 }
405
406 void swap(CorVector& other) noexcept {
407 std::swap(data_, other.data_);
408 std::swap(size_, other.size_);
409 std::swap(allocator_, other.allocator_);
410 }
411public:
413 bool is_borrowed() const noexcept {
414 return end_of_storage() == nullptr;
415 }
417 bool is_owned() const noexcept {
418 return end_of_storage() != nullptr;
419 }
421 void borrow_from(T* data, size_type size) noexcept {
422 data_ = data;
423 size_ = size;
424 allocator_.end_of_storage_ = nullptr;
425 }
426protected:
427 // EBCO
428 struct CorVectorAllocator: allocator_type {
429 T* end_of_storage_{nullptr};
430 };
431 allocator_type& allocator() noexcept{
432 return allocator_;
433 }
434 const allocator_type& allocator() const noexcept{
435 return allocator_;
436 }
437 T* end_of_storage() const noexcept {
438 return allocator_.end_of_storage_;
439 }
440protected:
441 T* data_{nullptr};
442 size_t size_{0};
443 CorVectorAllocator allocator_{};
444protected:
445
446 // 分配内存并复制数据
447 void allocate_and_copy(size_type new_cap) {
448 if (new_cap == 0) {
449 if (end_of_storage()) {
450 clear();
451 allocator().deallocate(data_, end_of_storage() - data_);
452 data_ = nullptr;
453 allocator_.end_of_storage_ = nullptr;
454 }
455 return;
456 }
457
458 T* new_data = allocator().allocate(new_cap);
459 size_type copy_size = (std::min)(size_, new_cap);
460
461 // 复制现有数据
462 for (size_type i = 0; i < copy_size; ++i) {
463 allocator().construct(new_data + i, data_[i]);
464 }
465
466 // 清理旧数据
467 if (end_of_storage()) {
468 clear();
469 allocator().deallocate(data_, end_of_storage() - data_);
470 }
471
472 data_ = new_data;
473 allocator_.end_of_storage_ = data_ + new_cap;
474 size_ = copy_size;
475 }
476};
477
480AST_NAMESPACE_END
Copy-On-Resize/Reserve Vector
定义 CorVector.hpp:44
T * data_
指向数据的指针
定义 CorVector.hpp:441
CorVectorAllocator allocator_
内存分配器
定义 CorVector.hpp:443
bool is_borrowed() const noexcept
判断容器是否为借用内存
定义 CorVector.hpp:413
bool is_owned() const noexcept
判断容器是否为拥有内存
定义 CorVector.hpp:417
void borrow_from(T *data, size_type size) noexcept
从外部借用内存
定义 CorVector.hpp:421
size_t size_
容器当前大小
定义 CorVector.hpp:442
A_ALWAYS_INLINE void swap(Thread &lhs, Thread &rhs) noexcept
交换两个线程对象
定义 Thread.hpp:82
Unit T
特斯拉
定义 Unit.cpp:492
定义 CorVector.hpp:428
T * end_of_storage_
如果该指针为nullptr,则表示容器为借用内存,如果该指针为非空,则表示容器当前容量,指向容器可用内存末尾的下一个位置
定义 CorVector.hpp:429