namespace cs427_527 { // we defined these in the .cpp just to show how it would be done template T& Vector::SkipView::operator[](size_t i) { return target[start + 2 * i]; } template const T& Vector::SkipView::operator[](size_t i) const { return target[start + 2 * i]; } template const T& Vector::ConstSkipView::operator[](size_t 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[](size_t i) { return elements[i]; } template const T& Vector::operator[](size_t i) const { return elements[i]; } /** * Requirement: U has begin method, size method, * iterators that begin returns iterate over things comparable to T */ template template bool Vector::operator==(const Container& rhs) const { if (rhs.size() != size()) { return false; } auto i = begin(); auto j = rhs.begin(); while (i != end() && *i == *j) { ++i; ++j; } return i == end(); } template size_t 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 (size_t 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 (size_t 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 (size_t 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() { size_t newCapacity = capacity * 2; T *larger = (T*)::operator new(newCapacity * sizeof(T)); for (size_t 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(); } }