Copyright by Michael Fischer 11/14/2011 For use in Yale course CPSC 427a/527a, Fall term 2011. ------------------------------------------------------ This is a modification of example 20b-Multiple-template to become fully generic in the sense that a user can create a container for a new type T without making any modifications to the files cell.hpp, container.hpp, item.hpp, linear.hpp, list.hpp, ordered.hpp and pqueue.hpp that implement the container. Rather, the user implements his own class (say "MyData") that defines the type name KeyType, a function key(), and comparison operators < and == on keys. Then the List or PQueue templates are instantiated with MyData as in List or PQueue. (See main() where they have been instantiated with Exam.) Unlike example 20b-Multiple-template, Item is not a derived class; rather, Item composes a T* base. In other words, Item is an adaptor for T that provides the interface needed by Linear and friends. Cell is also changed. The cell contents field, data, has become an Item rather than a T*. This is to avoid creating another level of indirection that would result if we had a Cell pointing to an Item which would then point to a T. This means that an Item object is copied into the cell's data field when the Cell is constructed, but the size of an Item is just the size of a pointer. The type of the sort key is now defined inside class Exam using a typedef to define the type name "KeyType". This allows for other element types than Exam with different sort methods. To refer to the type name "KeyType" defined inside of, say, MyData, one must write "typename MyData::KeyType". The "MyData::" prefix disambiguates it from definitions of KeyType that may appear in other classes. The "typename" keyword is needed (at least in some contexts) to prevent the C++ compiler from misinterpreting the construct T::Keyname during the early phases of compilation, where the template parameter T has not yet been instantiated.