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