#pragma once #include const size_t DEFAULT_CAPACITY = 4; template class Vector { private: T* data; size_t size; size_t capacity; public: Vector(); Vector(const Vector&); Vector(Vector&&); Vector& operator=(const Vector&); Vector& operator=(Vector&&); ~Vector(); size_t getSize() const; size_t getCapacity() const; void pushBack(const T&); void pushBack(T&& n); void pushAt(const T&, const size_t); void pushAt(T&&, const size_t); T& popBack(); T& popAt(const size_t); T& operator[](const size_t); const T& operator[](const size_t) const; bool empty() const; void clear(); void swap(const Vector&); private: void copy(const Vector&); void free(); void move(Vector&&); size_t calculateCapacity(const size_t) const; void resize(const size_t); }; template Vector::Vector() { data = nullptr; capacity = size = 0; } template Vector::Vector(const Vector& other) { copy(other); } template Vector::Vector(Vector&& other) { move(std::move(other)); } template Vector& Vector::operator=(const Vector& other) { if (this != &other) { free(); copy(other); } return *this; } template Vector& Vector::operator=(Vector&& other) { if (this != &other) { free(); move(std::move(other)); } return *this; } template Vector::~Vector() { free(); } template size_t Vector::getSize() const { return size; } template size_t Vector::getCapacity() const { return capacity; } template void Vector::pushBack(const T& element) { if (size + 1 > capacity) resize(size + 1); data[size++] = element; } template void Vector::pushBack(T&& element) { if (size + 1 > capacity) resize(size + 1); data[size++] = element; } template void Vector::pushAt(const T& element, const size_t index) { if (size + 1 > capacity) resize(size + 1); for (size_t i = size; i > index; i--) data[i] = data[i - 1]; data[index] = element; size++; } template void Vector::pushAt(T&& element, const size_t index) { if (size + 1 > capacity) resize(size + 1); for (size_t i = size; i > index; i--) data[i] = data[i - 1]; data[index] = element; size++; } template T& Vector::popBack() { if (empty()) throw "Vector is empty"; return data[--size]; } template T& Vector::popAt(size_t index) { if (index < 0 || index >= size) throw "Invalid index"; T temp = data[index]; for (size_t i = index; i < size - 1; i++) data[i] = data[i + 1]; size--; return temp; } template T& Vector::operator[](const size_t index) { if (index < 0 || index >= size) throw "Invalid index"; return data[index]; } template const T& Vector::operator[](const size_t index) const { if (index < 0 || index >= size) throw "Invalid index"; return data[index]; } template bool Vector::empty() const { return size == 0; } template void Vector::clear() { delete[] data; capacity = DEFAULT_CAPACITY; data = new T[capacity]; size = 0; } template void Vector::swap(const Vector& other) { Vector tempVector(std::move(*this)); *this = std::move(other); other = std::move(tempVector); } template void Vector::copy(const Vector& other) { size = other.size; capacity = other.capacity; data = new T[capacity]; for (size_t i = 0; i < size; i++) data[i] = other[i]; } template void Vector::free() { delete[] data; data = nullptr; capacity = size = 0; } template void Vector::move(Vector&& other) { data = other.data; size = other.size; capacity = other.capacity; other.data = nullptr; other.capacity = other.size = 0; } template size_t Vector::calculateCapacity(const size_t number) const { size_t result = DEFAULT_CAPACITY; while (number > result) result *= 2; return result; } template void Vector::resize(const size_t expectedCapacityToFit) { capacity = calculateCapacity(expectedCapacityToFit); T* temp = new T[capacity]; for (size_t i = 0; i < size; i++) temp[i] = data[i]; delete[] data; data = temp; }