Homework 6 - Template Classes
Due: Friday March 11, 2011 at 5:00pm
Coding Conventions
Use the same coding conventions as described in
Homework 1. Additionally, make sure to indent each
section of the class in the class definition.
Assignment
The purpose of this assignment is to create a template class for a dynamically
sized array. This will be similar to the C++ vector class from the standard
template library (STL). 
You will be creating a template class called GenericList. Since this is a 
template class, do not use seperate compilation for this assignment. Create
a file called hw6.cpp for this assignment and put all code in that file.
In Lab 5 and 
Lab 8, a class for a dynamic 
double array was used. In this homework assignment, you will be making a
template class called GenericList that will support a partially filled 
dynamic array of any datatype. Since it is a partially filled dynamic array,
it will have three member variables: a pointer for the array (template
variable), an integer for the current count of elements in use and an integer 
for the overall capacity of the array. The capacity will reflect how many
elements have been allocated to the array with the new command. The count 
should always be less than or equal to the capacity. GenericList will be 
somewhat similar in functionality to the C++ vector class.
GenericList will have the following features:
- The private member variables will be a pointer for the array, an integer
    for the count of elements in use and an integer for the capacity. Note:
    do not use the variable names "size" or "capacity" as those names are used
    for two of the public member functions.
 - The array pointer should reallocate as needed in the operators and member
    functions to hold all of the data elements it is requested to hold. This
    is similar to how your myString class for 
    Homework 3 worked.
 - The class will raise the following exceptions:
    
    - OutOfMemory - If any memory allocation fails, the OutOfMemory exception
        will be thrown.
    
 - InvalidIndex - If an index less than 0 or greater than count - 1 is
        given to the index operator, the InvalidIndex exception will be thrown.
    
 
 - The class will have the following constructors and destructor:
    
    - Default constructor - Create an empty array that has no memory
        allocated to it.
    
 - Constructor that takes an integer - The integer is the requested number
        of elements for the array. Allocate the requested number of elements
        to the array and set BOTH the count and the capacity to this integer. 
        Initialize all elements in the allocated array to 0.
    
 - Constructor that takes an array and an integer - The array passed to 
        the constructor will be the source of data for the GenericList array.
        The integer passed to the constructor will be both the count and the
        capacity of this GenericList object. Allocate the requested number
        of elements and then copy the source data from the passed array to
        this object's array.
    
 - Copy constructor - Copy the capacity and count from the source object
        to the current object. Allocate the requested number of elements. Then
        copy the elements from the source object to the current object.
    
 - Destructor - If there is memory allocated to the current object,
        deallocate the memory using the delete command.
    
 
 - The class will have the following operators:
    
    - = (assignment) - Takes a source GenericList object. It deletes any
        elements currently allocated the current object. It then reallocates
        based on the capacity of the source object and copies all of the 
        source object's data over to the current object. Be sure to check
        if the source object is the current object (e.g. a = a syntax) and
        do nothing if that is the case.
    
 - << (output) - This will print all the in-use elements (as 
        indicated by count) to the given output stream.
    
 - [] (index) - This take an integer for the requested index and validate
        that the index is in use (as indicated by count). If so, it will 
        return a reference to the element at that index (so it will be 
        writable). If not, it will raise an InvalidIndex exception.
    
 
 - The class will have the following public member functions:
    
    - int capacity() - Returns the current capacity of the object.
    
 - int size() - Returns the current number of elements in-use for the
        object, e.g. the count.
    
 - bool empty() - Returns true if the object is empty; false otherwise.
    
 - void clear() - Sets the value of all elements to 0. Do NOT deallocate 
        the array.
    
 - void reserve(int) - The given integer is the requested capacity of
        the current object. If it is greater than the current capacity of
        the object, reallocate the array and then set capacity to the new 
        value. Set all the newly allocated elements to 0 but do NOT overwrite
        any of the existing elements. Also, do NOT affect count in this
        function. This is purely to allocate more capacity to the object.
    
 - void resize(int) - The given integer is the requested count for the
        current object. All elements between the requested count and the 
        current count will be set to 0. The count will be affected in the
        following fashion. If the requested count is less than the current 
        count, reset count to its value and do NOT affect capacity. If the 
        requested count is greater than the current count and less than or 
        equal to the current capacity, reset count to its value and do NOT 
        affect capacity. If the requested count is greater than the capacity, 
        reallocate the array to the requested count, then set both count and 
        capacity to the requested count. Only reset capacity when the 
        requested count is greater than the current capacity.
    
 - void push_back(element) - Add an element to the end of the array. 
        Increment count. If there is no space on the array for the new element, 
        reallocate the array to add 10 more spaces (e.g. to capacity + 10),
        then add the element. Don't update capacity unless you need to 
        reallocate. 
    
 - element pop_back() - Remove the last element from the array. Decrement
        count and return the value of the last element. In the array, the value
        of the last element will be changed to 0 (e.g. if the GenericList is
        currently 5 2 9 8, pop_back would return 8 and the GenericList would
        be 5 2 9 0). Don't affect capacity in this function.
    
 - int find(element) - Search the array and see if any of its elements
        match the given element. If a match is found, return the index at
        which the match was found. If no match is found, return -1 (since this
        is an invalid index, it serves as a sentinel for the "not found"
        condition). Only search the in-use elements (as indicated by count).
    
 
 
Main function
Use the following menu program for your main function. This is a nested menu
which means you will have two loops. The outer loop will print the main menu
while the inner loop will print the sub-menu that was selected in the outer
loop. When the program is started, the main menu is presented. The sub-menu
will only be shown when the user selects that sub-menu off the main menu.
To implement the nested menus, have the main menu in the main() function.
Each option in the main menu will call another function which will display
and process the sub-menu.
The main menu appears as follows:
    Welcome to the CS222 Homework 6 Menu
==============================================
1.  Test the GenericList class for integers
2.  Test the GenericList class for doubles
3.  Test the GenericList class for characters
0.  Exit the program
==============================================
The only difference in the sub-menus is what datatype they are processing.
Implement the sub-menus as a single, global template function that takes 
a single template dummy parameter. The purpose of this dummy parameter is
to instantiate the function as either the integer sub-menu, the double
sub-menu or the character sub-menu.
In this sub-menu function, declare a GenericList object of 
the templated datatype. You may need additional template or normal variables
to support the menu operations. Present the following menu to the user to 
manipulate the GenericList object:
            GenericList Sub-Menu 
========================================================================
1.  Print the capacity and size of the list
2.  Clear all the elements on the list
3.  Add an element to the end of the list
4.  Remove the last element from the list and print its value 
5.  Use the index operator to set and print the value of an element
6.  Use the reserve function to change the number of elements allocated 
7.  Use the resize function to change the number of elements in use
8.  Search for a given index in the list
9.  Print the current contents of the list
0.  Return to the main menu
========================================================================
Each menu option is testing a member function or operator in the GenericList
class. Option 1 will print the results of capacity() and size(). Option 2 will
call the clear() function. Option 3 will call the push_back() function. Option
4 calls the pop_back() function. Option 5 uses the index operator. Option 6
uses the reserve() function. Option 7 uses the resize() function. Option 8
uses the find() function. Option 9 uses the output operator.
When the user gives option 0, return back to the main menu by exitting this
function. This will switch back to main()'s scope. As long as your main menu
loop is coded correctly, this should trigger the main menu being printed 
again so the user can test another GenericList object.
For options 1, 2, 4, 8 and 9, if the list is currently empty (empty() returns
true), print out an error message about the list being empty so the operation
could not be completed. Otherwise, perform the indicated operation.
For options 3, 6 and 7, be sure to use a try/catch block to check for the
OutOfMemory exception being thrown. If there is an allocation failure, do 
NOT exit the program. Instead, return back to the main menu by exitting the
sub-menu function. 
For option 3, prompt the user for the new element and then use the push_back()
function to add the element to the list.
For option 5, use a try/catch block to check for an invalid index being
given. You can use the logic in main() for Lab 8 as inspiration for how to
implement this option. Once the user gives a valid index, print the current
value of the element at that index to the screen then ask the user for the 
new value of the element at that index. Read in the user's response and set 
the element at that index to the new value.
For option 6, prompt the user for the new capacity of the GenericList and then
pass that to the reserve() function. For option 7, prompt the user for the new 
count of the GenericList and then pass that to the resize() function.
For option 8, prompt the user for the element they wish to search for. Use
the find() function in the GenericList object. If find returns -1, tell the
user that the element was not found. Otherwise, tell the user that the element
was found at the returned index.
Email hw6.cpp to me to submit the assignment.