// ******************************************************************* // Last Revised: January 13,1998 // // APCS vector class IMPLEMENTATION // // see vector.h for complete documentation of functions // // vector class consistent with a subset of the standard C++ vector class // as defined in the draft ANSI standard (part of standard template library) // ******************************************************************* #include #include #include #include "apvector.h" template apvector::apvector() //postcondition: vector has a capacity of 0 items, and therefore it will // need to be resized : mySize(0), myCapacity(0), myList(0) { } template apvector::apvector(int size) // precondition: size >= 0 // postcondition: vector has a capacity of size items : mySize(0), myCapacity(size), myList(new itemType[size]) { } template apvector::apvector(int size, const itemType & fillValue) // precondition: size >= 0 // postcondition: vector has a capacity of size items, all of which are set // by assignment to fillValue after default construction : mySize(0), myCapacity(size), myList(new itemType[size]) { int k; for(k = 0; k < size; k++) { myList[k] = fillValue; } } template apvector::apvector(const apvector & vec) // postcondition: vector is a copy of vec : mySize(vec.size()), myCapacity(vec.length()), myList(new itemType[myCapacity]) { int k; // copy elements for(k = 0; k < myCapacity; k++){ myList[k] = vec.myList[k]; } } template apvector::~apvector () // postcondition: vector is destroyed { delete [] myList; } template const apvector & apvector::operator = (const apvector & rhs) // postcondition: normal assignment via copying has been performed; // if vector and rhs were different sizes, vector // has been resized to match the size of rhs { if (this != &rhs) // don't assign to self! { delete [] myList; // get rid of old storage myCapacity = rhs.length(); mySize = rhs.size(); myList = new itemType [myCapacity]; // allocate new storage // copy rhs int k; for(k=0; k < myCapacity; k++) { myList[k] = rhs.myList[k]; } } return *this; // permit a = b = c = d } template int apvector::length() const // postcondition: returns vector's size (number of memory cells // allocated for vector) { return myCapacity; } template int apvector::size() const { return mySize; } template void apvector::push_back(const itemType& t) { if (mySize >= myCapacity) { resize(myCapacity == 0 ? 2 : 2*myCapacity); } myList[mySize] = t; mySize++; } template void apvector::pop_back() { mySize--; } template itemType & apvector::operator [] (int k) // description: range-checked indexing, returning kth item // precondition: 0 <= k < length() // postcondition: returns the kth item { if (k < 0 || myCapacity <= k) { cerr << "Illegal vector index: " << k << " max index = "; cerr << (myCapacity-1) << endl; exit(1); } return myList[k]; } template const itemType & apvector::operator [] (int k) const // safe indexing, returning const reference to avoid modification // precondition: 0 <= index < length // postcondition: return index-th item // exception: aborts if index is out-of-bounds { if (k < 0 || myCapacity <= k) { cerr << "Illegal vector index: " << k << " max index = "; cerr << (myCapacity-1) << endl; exit(1); } return myList[k]; } template void apvector::resize(int newSize) // description: resizes the vector to newSize elements // precondition: the current capacity of vector is length(); newSize >= 0 // postcondition: the current capacity of vector is newSize; for each k // such that 0 <= k <= min(length, newSize), vector[k] // is a copy of the original; other elements of vector are // initialized using the 0-argument itemType constructor // Note: if newSize < length, elements may be lost { int k; int numToCopy = newSize < myCapacity ? newSize : myCapacity; // allocate new storage and copy element into new storage itemType * newList = new itemType[newSize]; for(k=0; k < numToCopy; k++) { newList[k] = myList[k]; } delete [] myList; // de-allocate old storage myCapacity = newSize; // assign new storage/size myList = newList; }