#ifndef _LBVECTOR_H #define _LBVECTOR_H #include #include #include // templated vector class, partially based on Budd, // Classic Data Structures in C++ // written 11/5/93, modified 3/23/94 // changed on 3/9/95 to make all methods inline (defined in class decl) // changed on 10/14/99 to clean up for vector lab in CS 330 // changed on 10/14/04 to update for C++ changes ////////////////////////////////////////////////////////////////////////// // updated 3/09 by ___________________ to allow lower and upper bounds ////////////////////////////////////////////////////////////////////////// // // for a vector of Items use lbvector, // e.g., lbvector intvector; // note: Item must have a default constructor // // constructors: // lbvector( ) -- default, vector of size 0 (no entries) // lbvector(int size) -- vector with size entries // lbvector(int size, // Item fillValue) -- vector w/ size entries all == fillValue // lbvector(const lbvector & vec) -- copy constructor // // int capacity( ) -- returns capacity of vector // // void resize(int newSize) // -- resizes the vector to newSize elements // (can result in losing elements if // new size < old size) // // void fill(Item fillValue) -- set all entries equal to fillValue // // operator = -- assignment operator works properly // operator [] -- indexes both const and non-const vectors // // // examples of use: // lbvector dlist(100); // a list of 100 doubles // lbvector dzlist(100,0.0); // initialized to 0.0 // // lbvector slist(300); // 300 strings // // lbvector ilist; // has room for 0 ints // // // class invariant: // - myList points to the beginning of the allocated space // - myCapacity is the number of elements allocated template class lbvector { public: // default constructor 0 elements // postcondition: vector of zero items constructed lbvector( ) { myCapacity = 0; myList = 0; } // specify size of vector // postcondition: vector of size items constructed lbvector(int size) { assert(size >= 0); myCapacity = size; myList = new Item [size]; assert(myList != 0); } // specify size and fill value // postcondition: constructed vector of size items, // each item initialized to fillValue lbvector(int size, Item fillValue) { assert(size >= 0); myCapacity = size; myList = new Item [size]; assert(myList != 0); fill(fillValue); } // copy constructor // used to create a new and complete copy of the object (vec) // as when passing the object by value or returning object // as a result - need a deep copy when using dynamic memory // precondition: Item supports assignment // postcondition: constructed vector is an exact duplicate of vec lbvector(const lbvector & vec) { // allocate storage myCapacity = vec.myCapacity; myList = new Item [myCapacity]; assert(myList != 0); // copy elements from vec for (int k = 0; k < vec.myCapacity; k++) { myList[k] = vec.myList[k]; } } // free new'd storage // postcondition: dynamically allocated storage freed ~lbvector ( ) { delete [] myList; } // assignment // need a deep copy when using dynamic memory // precondition: Item supports assignment // postcondition: self is assigned vec lbvector & operator = (const lbvector & vec) { // don't assign to self! if (this != &vec) { // out with old list, in with new delete [] myList; myCapacity = vec.myCapacity; myList = new Item [myCapacity]; assert(myList != 0); // copy elements from vec for (int k=0; k < vec.myCapacity; k++) { myList[k] = vec.myList[k]; } } return *this; } // change size dynamically // precondition: vector has room for myCapacity entries // postcondition: vector has room for newSize entries // the first myCapacity of which are copies of original // unless newSize < myCapacity, then truncated copy occurs void resize(int newSize) { assert(newSize >= 0); int numToCopy = newSize < myCapacity ? newSize : myCapacity; // allocate new storage Item * newList = new Item[newSize]; assert(newList != 0); // copy retained values from old to new for (int k=0; k < numToCopy;k++) { newList[k] = myList[k]; } // return space no longer needed delete [] myList; // update instance variables to reflect changes myCapacity = newSize; myList = newList; } // capacity of vector int capacity( ) const { return myCapacity; } // postcondition: all entries are equal to fillValue void fill(Item fillValue) { for (int k=0; k < myCapacity; k++) { myList[k] = fillValue; } } // safe indexing, returning reference // precondition: 0 <= index < myCapacity // postcondition: return index-th item // exception: aborts if index is out-of-bounds Item & operator [] (int index) { checkIndex(index); return myList[index]; } // const index // safe indexing, returning const reference to avoid modification // precondition: 0 <= index < myCapacity // postcondition: return index-th item // exception: aborts if index is out-of-bounds const Item & operator [] (int index) const { checkIndex(index); return myList[index]; } private: Item * myList; // the array of items int myCapacity; // # things in vector (array), 0,1,...,(myCapacity-1) // aborts with appropriate message if index is not in appropriate range // use std:: to access names in std namespace void checkIndex (int index) const { if (index < 0 || myCapacity <= index) { std::cerr << "Illegal vector index: " << index << " (max = " << myCapacity-1 << ")" << std::endl; assert(index >= 0); assert(index < myCapacity); } } }; #endif // _LBVECTOR_H not defined