/** ***************************************************************************** * file name : UBVector.cpp * author : Hung Ngo * description : implement the UBVector template interface ***************************************************************************** */ #include #include #include "UBVector.h" using namespace std; // actually allocate the const member template const size_t UBVector::INITIAL_CAPACITY = 10; /** * ----------------------------------------------------------------------------- * constructor which contains a default constructor * ----------------------------------------------------------------------------- */ template UBVector::UBVector(size_t n) : num_items(n), current_capacity(max(n, UBVector::INITIAL_CAPACITY)), item_ptr(new Item[max(n, UBVector::INITIAL_CAPACITY)]) { /* constructor has empty body */ } /** * ----------------------------------------------------------------------------- * deep copy constructor * - copy the members other than the pointer * - allocate space for the pointer * - copy items one by one * ----------------------------------------------------------------------------- */ template UBVector::UBVector(const UBVector& the_other) : num_items(the_other.num_items), current_capacity(the_other.num_items), item_ptr(new Item[the_other.num_items]) { for (size_t i=0; i UBVector::~UBVector() { delete [] item_ptr; } /** * ----------------------------------------------------------------------------- * the [] operator, throw an exception if out of range * returned value can be used as an lvalue, e.g., ubvec[10] = a; * ----------------------------------------------------------------------------- */ template Item& UBVector::operator[](size_t index) { if (index < num_items) return item_ptr[index]; else throw out_of_range("index is out of range"); } /** * ----------------------------------------------------------------------------- * the [] operator, throw an exception if out of range * returned value can only be used on the right of an assignment * such as a = ubvec[10]; * ----------------------------------------------------------------------------- */ template const Item& UBVector::operator[](size_t index) const { if (index < num_items) return item_ptr[index]; else throw out_of_range("index is out of range"); } /** * ----------------------------------------------------------------------------- * front and back member functions * ----------------------------------------------------------------------------- */ template Item& UBVector::front() { return (*this)[0]; } template const Item& UBVector::front() const { return (*this)[0]; } template Item& UBVector::back() { return (*this)[num_items-1]; } template const Item& UBVector::back() const { return (*this)[num_items-1]; } /** * ----------------------------------------------------------------------------- * append the item at the end, reserve new space if necessary * ----------------------------------------------------------------------------- */ template void UBVector::push_back(const Item& item) { if (num_items == current_capacity) reserve(2*current_capacity); item_ptr[num_items++] = item; } /** * ----------------------------------------------------------------------------- * insert an item, reserve new capacity if the new size exceeds the current * capacity, and shift all items back one position * ----------------------------------------------------------------------------- */ template void UBVector::insert(size_t position, const Item& new_item) { if (num_items == current_capacity) reserve(2*current_capacity); for (size_t i=num_items; i>position; --i) item_ptr[i] = item_ptr[i-1]; item_ptr[position] = new_item; ++num_items; } /** * ----------------------------------------------------------------------------- * reserve space so that the new vector can store at least n items * if n is less than twice the current capacity, double the current capacity * ----------------------------------------------------------------------------- */ template void UBVector::reserve(size_t n) { if (n > current_capacity) { current_capacity = max(n, 2*current_capacity); Item *new_data_ptr = new Item[current_capacity]; for (size_t i=0; i void UBVector::erase(size_t position) { if (position >= 0 && position < num_items) { for (size_t i=position; i void UBVector::pop_back() { erase(num_items-1); } /** * ----------------------------------------------------------------------------- * swapping two UBVectors: swap the num_items, current_capacity, and the two * item pointers. * have to use std::swap instead of just swap because there's a naming conflict * ----------------------------------------------------------------------------- */ template void UBVector::swap(UBVector& the_other) { std::swap(num_items, the_other.num_items); std::swap(current_capacity, the_other.current_capacity); std::swap(item_ptr, the_other.item_ptr); } /** * ----------------------------------------------------------------------------- * assignment operator for UBVector: * - create a new copy of the other object using the copy constructor * - swap the content of this object with the temporary object * - return a reference to this object. * - when we return, the temporary object will be destroyed * have to use std::swap instead of just swap because there's a naming conflict * ----------------------------------------------------------------------------- */ template UBVector& UBVector::operator=(const UBVector& the_other) { UBVector temp(the_other); // uses (deep) copy constructor here swap(temp); return *this; }