#ifndef VECTOR_H_ #define VECTOR_H_ #include #include namespace KW { template class vector { /*================== This is YOUR part to complete =================*/ /* (do not change any signatures, however) */ public: /** Determines whether the given value is contained in the vector. * @param val The value * @return true if contained, false otherwise */ bool contains(const Item_Type& val) const { } /** Determines the number of occurrences of given value. * @param val The value * @return the number of occurrences */ size_t count(const Item_Type& val) const { } /** Determines the first index at which give value occurs (if any). * @param val The value * @return the first index, if found; otherwise returns size (clearly an invalid index) */ size_t index(const Item_Type& val) const { } /** Removes all occurrences of given value (if any). * @param val The value * * Note: this is difference semantics than Python's remove. */ void remove(const Item_Type& val) { } /** Reverse the contents of the vector. */ void reverse() { } /*============= do not change anything below this point ============*/ private: // Data fields /** The initial capacity of the array*/ static const size_t INITIAL_CAPACITY = 10; /** The current capacity of the array */ size_t current_capacity; /** The current num_items of the array */ size_t num_items; /** The array to contain the data */ Item_Type* the_data; public: /** Constructs an empty vector with the default initial capacity. */ vector() : current_capacity(INITIAL_CAPACITY), num_items(0), the_data(new Item_Type[INITIAL_CAPACITY]) { } /** Get the current size of the vector @return The current size of the vector */ size_t size() const { return num_items; } /** Determine if the vector is empty */ bool empty() const { return num_items == 0; } /** Get the current capacity of the vector @return The current capacity of the vector */ size_t capacity() const { return current_capacity; } /** Get a value in the vector based on its index. This version does NOT verify the index value. @param index - The index of the item desired @return A reference to that element that can be used on either the left or the right side of an assignment. */ Item_Type& operator[](size_t index) { return the_data[index]; } /** Get a constant value in the vector based on its index. This version does NOT verify the index value. @param index - The index of the item desired @return A reference to that element that can be used only on the right side of an assignment. */ const Item_Type& operator[](size_t index) const { return the_data[index]; } /** Get a value in the vector based on its index. @param index - The index of the item desired @return A reference to that element that can be used on either the left or the right side of an assignment. @throws out_of_range if index is greater than or equal to the number of elements. */ Item_Type& at(size_t index) { // Verify that the index is legal if (index < 0 || index >= num_items) { throw std::out_of_range ("index to at is out of range"); } return the_data[index]; } /** Get a constant value in the vector based on its index. @param index - The index of the item desired @return A reference to that element that can be used only on the right side of an assignment. @throws out_of_range if index is either negaive or greater than or equal to the number of elements. */ const Item_Type& at(size_t index) const { // Verify that the index is legal if (index < 0 || index >= num_items) { throw std::out_of_range ("index to at is out of range"); } return the_data[index]; } /** Remove the last item in the vector */ void pop_back() { num_items--; } /** Insert a new item at the end of the vector. @param theValue - The value to be inserted */ void push_back(const Item_Type& the_value) { // Make sure there is space for the new item. if (num_items == current_capacity) { reserve(2 * current_capacity); // Allocate an expanded array } // Insert the new item. the_data[num_items] = the_value; num_items++; } /** Ensure that the capacity is at least a given size. */ void reserve(size_t new_capacity) { if (new_capacity > current_capacity) { if (new_capacity > 2 * current_capacity) current_capacity = new_capacity; else current_capacity *= 2; // Double the capacity. Item_Type* new_data = new Item_Type[current_capacity]; // Copy the data over for (size_t i = 0; i < num_items; i++) new_data[i] = the_data[i]; // Free the memory occupied by the old copy. delete[] the_data; // Now point to the new data the_data = new_data; } } /** Insert an entry to the data inserting it before the item at the specified index. @param index - The index of the time that the new value it to be inserted in front of. @param theValue - The value to be inserted @throws out_of_range if index is either negaive or greater than or equal to the number of elements. */ void insert(size_t index, const Item_Type& the_value) { // Validate index if (index > num_items) { throw std::out_of_range ("index to insert is out of range"); } // Ensure that there is space for the new item if (num_items == current_capacity) { reserve(2 * current_capacity); // allocate an expanded array } // Move data from index to num_items-1 down for (size_t i = num_items; i > index; i--) { the_data[i] = the_data[i - 1]; } // Insert the new item the_data[index] = the_value; num_items++; } /** Remove an entry based on its index @param index - The index of the entry to be removed @throws out_of_range if index is either negaive or greater than or equal to the number of elements. */ void erase(size_t index) { // Validate index. if (index >= num_items) { throw std::out_of_range ("index to erase is out of range"); } // Move items below the removed one up. for (size_t i = index + 1; i < num_items; i++) { the_data[i - 1] = the_data[i]; } num_items--; } /** Exchanges the contents of this vector with another. @param other The other vector */ void swap(vector& other) { std::swap(num_items, other.num_items); std::swap(current_capacity, other.current_capacity); std::swap(the_data, other.the_data); } /*----- See Chapter 4.4 for discussion of these methods -----*/ /** Make a copy of a vector. @param other The vector to be copied */ vector(const vector& other) : current_capacity(other.current_capacity), num_items(other.num_items), the_data(new Item_Type[other.current_capacity]) { for (size_t i = 0; i < num_items; i++) the_data[i] = other.the_data[i]; } /** Destroy a vector */ virtual ~vector() { delete[] the_data; } /** Assign the contents of one vector to another. @param other The vector to be assigned to this vector @return This vector with a copy of the other vector's contents. */ vector& operator=(const vector& other) { // Make a copy of the other vector. vector the_copy(other); // Swap contents of self with the copy. swap(the_copy); // Return -- upon return the copy will be destroyed. return *this; } }; // End vector template inline void swap(vector& x, vector& y) { x.swap(y); } /** Outputs the vector. */ template std::ostream& operator<<(std::ostream& out, const vector& v) { int sz = v.size(); int i; out << std::string("["); if (sz >= 1) out << v[0]; for (i=1; i