#pragma once #include #include #include template class Vector { public: // Constructor Vector(unsigned int capacity = 10) : capacity(capacity), element_count(0), data(new T[capacity]) { std::cout << "Vector created" << std::endl; } // Copy Constructor Vector(const Vector &other) : capacity(other.capacity), element_count(other.element_count), data(new T[capacity]) { // `std::copy` is used because it is more flexible than `std::memcpy`, // and the compiler will replace it with `memcpy` anyway if appropriate, // so there is no performance loss. std::copy(other.data, other.data + element_count, data); } // Move Constructor using the copy-and-swap-idiom Vector(Vector &&other) : data(new T[capacity]) { swap(*this, other); } // Copy Assignment Operator using the copy-and-swap-idiom // Since this takes a value rather than a const reference due to // copy-and-swap, this is also the Move Assignment Operator Vector &operator=(Vector other) { swap(*this, other); return *this; } // Destructor ~Vector() { delete[] data; std::cout << "Vector deleted" << std::endl; } // Bracket Operator T &operator[](unsigned int position) const { return at(position); } // Swap function for the copy-and-swap idiom. // See also: // https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom // The `friend` keyword is used so it is found through ADL. friend void swap(Vector &first, Vector &second) { // Enable ADL (good practice) using std::swap; swap(first.capacity, second.capacity); swap(first.element_count, second.element_count); swap(first.data, second.data); } void push_back(const T &element) { if (element_count >= capacity) { // TODO: Increase capacity! } // Use placement new to directly use pre-allocated memory new (data + element_count) T(element); element_count++; } void erase(unsigned int position) { assert(position < element_count); std::copy_backward(data + position + 1, data + element_count, data + element_count - 1); element_count--; } unsigned int size() const { return element_count; } unsigned int length() const { return capacity; } T &at(unsigned int position) const { assert(position < element_count); return data[position]; } void reserve(unsigned int); void resize(unsigned int); private: T *data; unsigned int element_count; unsigned int capacity; };