#ifndef HEADER_VECTOR #define HEADER_VECTOR #include #include template class Vector { public: Vector(); Vector(size_t capacity); Vector(size_t capacity, T value); Vector(const Vector& other); ~Vector(); size_t Size(); size_t Capacity(); void PushBack(T value); template friend std::ostream& operator<<(std::ostream& stream, const Vector& vec); template friend std::istream& operator>>(std::istream& stream, Vector& vec); Vector& operator=(const Vector& other); Vector& operator()(const Vector& other); T& operator[](const int indice); Vector operator+(const Vector& other); Vector& operator+=(const Vector& other); private: size_t _capacity; size_t _size; T* _values; }; template Vector::Vector() : _capacity(1) , _size(0) , _values(new T[1]) { } template Vector::Vector(size_t capacity) : _capacity(capacity) , _size(0) { // Allocating the heap with the given capacity _values = new T[capacity]; } template Vector::Vector(size_t capacity, T value) : _capacity(capacity) , _size(capacity) { // Allocating the heap and setting the value to each element. _values = new T[capacity]; for (size_t i = 0; i < capacity; i++) _values[i] = value; } template Vector::Vector(const Vector& other) : _capacity(other._capacity) , _size(other._size) , _values(new T[other._capacity]) { for (size_t i = 0; i < other._size; i++) _values[i] = other._values[i]; } template Vector::~Vector() { delete[] _values; } template Vector& Vector::operator=(const Vector& other) { if (this != &other) { this->_capacity = other._capacity; this->_size = other._size; delete[] this->_values; this->_values = new T[other._capacity]; for (size_t i = 0; i < other._size; i++) this->_values[i] = other._values[i]; } return *this; } template Vector& Vector::operator()(const Vector& other) { *this = other; return *this; } template size_t Vector::Capacity() { return _capacity; } template size_t Vector::Size() { return _size; } template void Vector::PushBack(T value) { // if the next size will overload the heap if (_capacity < _size + 1) { // Keep a track of the old pointer T* oldPtr = _values; // Creating a new pointer by resizing its capacity by factor 2. _values = new T[_size * 2]; _capacity *= 2; // Copying the old array onto the new for (size_t i = 0; i < _size; i++) _values[i] = oldPtr[i]; // Deallocating the old array delete[] oldPtr; } // Setting the given value and incrementing the size _values[_size] = value; _size++; } // methode get template std::ostream& operator<<(std::ostream& stream, const Vector& vec) { for (size_t i = 0; i < vec._size; i++) stream << vec._values[i] << ", "; return stream; } // methode put template std::istream& operator>>(std::istream& stream, Vector& vec) { for (size_t i = 0; i < vec._capacity; i++) stream >> vec._values[i]; vec._size = vec._capacity; return stream; } template T& Vector::operator[](const int indice) { if(indice > _size) throw "Indice from the vector is not reachable"; else return _values[indice]; } template Vector Vector::operator+(const Vector& other) { if(_size != other._size) throw "Cannot add two vectors with different sizes together"; else { Vector returnVector(_size); returnVector._size = _size; for(auto i =0; i < _size; i++) returnVector._values[i] = _values[i] + other._values[i]; return returnVector; } } template Vector& Vector::operator+=(const Vector& other) { if(_size != other._size) throw "Cannot add two vectors with different sizes together"; else { for(auto i =0; i < _size; i++) _values[i] += other._values[i]; return *this; } } #endif // HEADER_VECTOR