namespace cs427_527 { // we defined these in the .cpp just to show how it would be done template T& Vector::SkipView::operator[](int i) { return target[start + 2 * i]; } template const T& Vector::SkipView::operator[](int i) const { return target[start + 2 * i]; } template const T& Vector::ConstSkipView::operator[](int i) const { return target[start + 2 * i]; } template Vector::Vector() { capacity = INITIAL_CAPACITY; count = 0; elements = (T*)::operator new(sizeof(T) * capacity); } 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 T& Vector::operator[](int i) { return elements[i]; } template const T& Vector::operator[](int i) const { return elements[i]; } 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 typename Vector::iterator Vector::begin() { return SkippingIterator{*this, 0, 1}; } template typename Vector::iterator Vector::end() { return SkippingIterator{*this, count, 1}; } template typename Vector::const_iterator Vector::begin() const { return ConstSkippingIterator{*this, 0, 1}; } template typename Vector::const_iterator Vector::end() const { return ConstSkippingIterator{*this, count, 1}; } template typename Vector::skip_view Vector::evens() { return SkipView{*this, 0}; } template typename Vector::skip_view Vector::odds() { return SkipView{*this, 1}; } template typename Vector::const_skip_view Vector::evens() const { return ConstSkipView{*this, 0}; } template typename Vector::const_skip_view Vector::odds() const { return ConstSkipView{*this, 1}; } /** * Destroys the elements in this vector and releases the array used * to hold them. */ template void Vector::deallocate() { for (int i = 0; i < count; i++) { elements[i].~T(); } ::operator delete(elements); } /** * Copies the elements from the given vector to this one. */ template void Vector::copy(const Vector& toCopy) { capacity = toCopy.capacity; count = toCopy.count; elements = (T*)::operator new(capacity * sizeof(T)); for (int i = 0; i < count; i++) { new (elements + i) T{toCopy.elements[i]}; } } /** * Moves the elements from the given vector to this one. */ template void Vector::move(Vector& toMove) { capacity = toMove.capacity; count = toMove.count; elements = toMove.elements; toMove.capacity = 0; toMove.count = 0; toMove.elements = nullptr; } /** * Resizes the array held by this container. */ template void Vector::embiggen() { int newCapacity = capacity * 2; T *larger = (T*)::operator new(newCapacity * sizeof(T)); for (int i = 0; i < count; i++) { 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(); } }