Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <cassert>
- #include <cstdlib>
- #include <new>
- #include <utility>
- template <typename T>
- class Vector {
- public:
- Vector() = default;
- explicit Vector(size_t size)
- : data_(Allocate(size))
- , capacity_(size)
- , size_(size) //
- {
- size_t counter = 0;
- try {
- for (; counter != size; ++counter) {
- new (data_ + counter) T();
- }
- }
- catch (...) {
- DestroyN(data_, counter);
- Deallocate(data_);
- throw;
- }
- }
- Vector(const Vector& other)
- : data_(Allocate(other.size_))
- , capacity_(other.size_)
- , size_(other.size_)
- {
- size_t counter = 0;
- try {
- for (; counter != other.size_; ++counter) {
- CopyConstruct(data_ + counter, other.data_[counter]);
- }
- }
- catch (...) {
- DestroyN(data_, counter);
- Deallocate(data_);
- throw;
- }
- }
- ~Vector() {
- DestroyN(data_, size_);
- Deallocate(data_);
- }
- size_t Size() const noexcept {
- return size_;
- }
- size_t Capacity() const noexcept {
- return capacity_;
- }
- void Reserve(size_t new_capacity) {
- if (new_capacity <= capacity_) {
- return;
- }
- size_t counter = 0;
- T* new_data = Allocate(new_capacity);
- try {
- for (; counter != size_; ++counter) {
- CopyConstruct(new_data + counter, data_[counter]);
- }
- DestroyN(data_, size_);
- Deallocate(data_);
- data_ = new_data;
- capacity_ = new_capacity;
- }
- catch (...) {
- DestroyN(new_data, counter);
- Deallocate(new_data);
- throw;
- }
- }
- const T& operator[](size_t index) const noexcept {
- return const_cast<Vector&>(*this)[index];
- }
- T& operator[](size_t index) noexcept {
- assert(index < size_);
- return data_[index];
- }
- private:
- // Выделяет сырую память под n элементов и возвращает указатель на неё
- static T* Allocate(size_t n) {
- return n != 0 ? static_cast<T*>(operator new(n * sizeof(T))) : nullptr;
- }
- // Освобождает сырую память, выделенную ранее по адресу buf при помощи Allocate
- static void Deallocate(T* buf) noexcept {
- operator delete(buf);
- }
- // Вызывает деструкторы n объектов массива по адресу buf
- static void DestroyN(T* buf, size_t n) noexcept {
- for (size_t i = 0; i != n; ++i) {
- Destroy(buf + i);
- }
- }
- // Создаёт копию объекта elem в сырой памяти по адресу buf
- static void CopyConstruct(T* buf, const T& elem) {
- new (buf) T(elem);
- }
- // Вызывает деструктор объекта по адресу buf
- static void Destroy(T* buf) noexcept {
- buf->~T();
- }
- T* data_ = nullptr;
- size_t capacity_ = 0;
- size_t size_ = 0;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement