47 using const_pointer =
const T*;
49 using const_reference =
const T&;
50 using size_type = size_t;
51 using difference_type = ptrdiff_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>;
59 CorVector() noexcept : data_(
nullptr), size_(0), allocator_() {}
71 template<
typename InputIt>
73 size_type count = std::distance(first, last);
75 for (; first != last; ++first) {
86 for (size_type i = 0; i < other.
size_; ++i) {
87 push_back(other.
data_[i]);
93 this->data_ = other.
data_;
94 this->size_ = other.
size_;
96 other.
data_ =
nullptr;
102 if (end_of_storage()) {
104 allocator().deallocate(data_, end_of_storage() - data_);
110 if (
this != &other) {
118 if (
this != &other) {
120 if (end_of_storage()) {
121 allocator().deallocate(data_, end_of_storage() - data_);
126 other.
data_ =
nullptr;
133 CorVector& operator=(std::initializer_list<T> init) {
140 reference operator[](size_type pos) {
144 const_reference operator[](size_type pos)
const {
148 reference at(size_type pos) {
150 throw std::out_of_range(
"CorVector::at: index out of range");
155 const_reference at(size_type pos)
const {
157 throw std::out_of_range(
"CorVector::at: index out of range");
166 const_reference front()
const {
171 return data_[size_ - 1];
174 const_reference back()
const {
175 return data_[size_ - 1];
182 const T* data()
const noexcept {
187 iterator begin()
noexcept {
191 const_iterator begin()
const noexcept {
195 const_iterator cbegin()
const noexcept {
199 iterator end()
noexcept {
200 return data_ + size();
203 const_iterator end()
const noexcept {
204 return data_ + size();
207 const_iterator cend()
const noexcept {
208 return data_ + size();
211 reverse_iterator rbegin()
noexcept {
212 return reverse_iterator(end());
215 const_reverse_iterator rbegin()
const noexcept {
216 return const_reverse_iterator(end());
219 const_reverse_iterator crbegin()
const noexcept {
220 return const_reverse_iterator(cend());
223 reverse_iterator rend()
noexcept {
224 return reverse_iterator(begin());
227 const_reverse_iterator rend()
const noexcept {
228 return const_reverse_iterator(begin());
231 const_reverse_iterator crend()
const noexcept {
232 return const_reverse_iterator(cbegin());
236 bool empty()
const noexcept {
240 size_type size()
const noexcept {
244 size_type max_size()
const noexcept {
245 return allocator().max_size();
248 size_type capacity()
const noexcept {
249 return end_of_storage() ? (end_of_storage() - data_) : 0;
252 void reserve(size_type new_cap) {
253 if (new_cap > capacity()) {
255 allocate_and_copy(new_cap);
259 void shrink_to_fit() {
260 if (capacity() > size()) {
261 allocate_and_copy(size());
266 void clear()
noexcept {
267 if (end_of_storage()) {
268 for (size_type i = 0; i < size(); ++i) {
269 allocator().destroy(data_ + i);
275 iterator insert(const_iterator pos,
const T& value) {
276 difference_type offset = pos - cbegin();
277 if (size_ >= capacity()) {
280 std::move_backward(data_ + offset, data_ + size_, data_ + size_ + 1);
281 allocator().construct(data_ + offset, value);
283 return data_ + offset;
286 iterator insert(const_iterator pos, T&& value) {
287 difference_type offset = pos - cbegin();
288 if (size_ >= capacity()) {
291 std::move_backward(data_ + offset, data_ + size_, data_ + size_ + 1);
292 allocator().construct(data_ + offset, std::move(value));
294 return data_ + offset;
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);
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);
307 return data_ + offset;
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);
317 std::move_backward(data_ + offset, data_ + size_, data_ + size_ + count);
318 for (; first != last; ++first, ++offset) {
319 allocator().construct(data_ + offset, *first);
322 return data_ + (pos - cbegin());
325 iterator insert(const_iterator pos, std::initializer_list<T> init) {
326 return insert(pos, init.begin(), init.end());
329 iterator erase(const_iterator pos) {
330 difference_type offset = pos - cbegin();
331 std::move(data_ + offset + 1, data_ + size_, data_ + offset);
333 allocator().destroy(data_ + size_);
334 return data_ + offset;
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);
345 return data_ + start;
348 void push_back(
const T& value) {
349 if (size_ >= capacity()) {
350 reserve(size_ == 0 ? 1 : size_ * 2);
352 allocator().construct(data_ + size_, value);
356 void push_back(T&& value) {
357 if (size_ >= capacity()) {
358 reserve(size_ == 0 ? 1 : size_ * 2);
360 allocator().construct(data_ + size_, std::move(value));
367 allocator().destroy(data_ + size_);
370 void resize(size_type count) {
372 if (count > capacity()) {
375 for (size_type i = size_; i < count; ++i) {
376 allocator().construct(data_ + i);
378 }
else if (count < size_) {
379 for (size_type i = count; i < size_; ++i) {
380 allocator().destroy(data_ + i);
386 void resize(size_type count,
const T& value) {
388 if (count > capacity()) {
391 for (size_type i = size_; i < count; ++i) {
392 allocator().construct(data_ + i, value);
394 }
else if (count < size_) {
395 for (size_type i = count; i < size_; ++i) {
396 allocator().destroy(data_ + i);
403 std::swap(data_, other.
data_);
404 std::swap(size_, other.
size_);
410 return end_of_storage() ==
nullptr;
414 return end_of_storage() !=
nullptr;
420 allocator_.end_of_storage_ =
nullptr;
425 T* end_of_storage_{
nullptr};
427 allocator_type& allocator() noexcept{
430 const allocator_type& allocator() const noexcept{
433 T* end_of_storage() const noexcept {
443 void allocate_and_copy(size_type new_cap) {
445 if (end_of_storage()) {
447 allocator().deallocate(data_, end_of_storage() - data_);
449 allocator_.end_of_storage_ =
nullptr;
454 T* new_data = allocator().allocate(new_cap);
455 size_type copy_size = std::min(size_, new_cap);
458 for (size_type i = 0; i < copy_size; ++i) {
459 allocator().construct(new_data + i, data_[i]);
463 if (end_of_storage()) {
465 allocator().deallocate(data_, end_of_storage() - data_);
469 allocator_.end_of_storage_ = data_ + new_cap;