#include "vector.hpp" #include namespace cs427_527 { template Vector::Vector() { capacity = INITIAL_CAPACITY; count = 0; // global new to allocate uninitialized space so we don't require // T to have a default constructor elements = (T*)(::operator new(INITIAL_CAPACITY * sizeof(T))); } template Vector::Vector(const Vector& toCopy) { copy(toCopy); } template Vector::Vector(Vector&& toMove) { move(toMove); } template Vector::~Vector() { deallocate(); } template Vector& Vector::operator=(const Vector& rhs) { if (this != &rhs) { deallocate(); copy(rhs); } return *this; } template Vector& Vector::operator=(Vector&& rhs) { if (this != &rhs) { deallocate(); move(rhs); } return *this; } template int Vector::size() const { return count; } template void Vector::push_back(const T& item) { if (count == capacity) { embiggen(); } new (elements + count) T{item}; count++; } template std::string Vector::toString() const { std::ostringstream out; out << "["; for (int i = 0; i < count; i++) { if (i > 0) { out << ", "; } out << elements[i]; } out << "]"; return out.str(); } template void Vector::deallocate() { // call the destructor manually for (int i = 0; i < count; i++) { elements[i].~T(); } // global delete to free space to match allocation with global new ::operator delete(elements); } template void Vector::copy(const Vector& toCopy) { capacity = toCopy.capacity; count = toCopy.count; // allocate uninitialized space with global new elements = (T*)::operator new(capacity * sizeof(T)); for (int i = 0; i < count; i++) { // initialize already-allocated space with placement new new (elements + i) T{toCopy.elements[i]}; } } template void Vector::move(Vector& toMove) { capacity = toMove.capacity; count = toMove.count; elements = toMove.elements; toMove.capacity = 0; toMove.count = 0; toMove.elements = nullptr; } /** * Expands the capacity of this vector. */ template void Vector::embiggen() { int newCapacity = capacity * 2; // allocate uninitialzed space T *larger = (T*)::operator new(newCapacity * sizeof(T)); for (int i = 0; i < count; i++) { // placement new to initialize already-allocated space new (larger + i) T{std::move(elements[i])}; } deallocate(); elements = larger; capacity = newCapacity; } template std::ostream& operator<<(std::ostream& os, const Vector& v) { return os << v.toString(); } }