\documentstyle[cprog]{simslide}
\uppercorners{Data Structures in C++}{\thepage}
\lowercorners{Lists}{Chapter 9}
\begin{document}

\slide{}

{\Huge \bf
\begin{center}
$\;$ \\ $\;$ \\
Data Structures \\
in C++ \\ $\;$ \\
Chapter 9 \\ $\;$ \\
Tim Budd \\ $\;$ \\
Oregon State University \\
Corvallis, Oregon \\
USA \\
\end{center}
}

\slide{Outline -- Chapter 9}

{\bf Lists}

\begin{itemize}
\item
Concept of linked-list
\item
Variations
\begin{itemize}
\item
Head and Tail Pointers
\item
Doubly Linked List
\end{itemize}
\item
Summary of List Operations
\item
Example Programs
\begin{itemize}
\item
An Inventory System
\item
A Course Registration System
\end{itemize}
\item
The implementation of the list data type
\end{itemize}

\slide{Simple Linked List}
\begin{itemize}
\item
Useful when the number of elements is not known or varies widely during 
execution
\item
Allows efficient insertion to head, sequential access.
\end{itemize}

\setlength{\unitlength}{12mm}
\begin{center}
\begin{picture}(8,3.5)
\put(0,2){\framebox(3,1){\em a list}}
\put(1,0){\framebox(1,1){\em link}}
\put(3,0){\framebox(1,1){\em link}}
\put(5,0){\framebox(1,1){\em link}}
\put(7,0){\framebox(1,1){\em link}}
\put(1.5,2){\vector(0,-1){1}}
\put(2,0.5){\vector(1,0){1}}
\put(4,0.5){\vector(1,0){1}}
\put(6,0.5){\vector(1,0){1}}
\end{picture}
\end{center}

\slide{Variation -- Head and Tail Pointers}

Allows efficient insertion and removal from both head and tail

\setlength{\unitlength}{12mm}
\begin{center}
\begin{picture}(8,3.5)
\put(0,2){\framebox(3,1){\em a list}}
\put(1,0){\framebox(1,1){\em link}}
\put(3,0){\framebox(1,1){\em link}}
\put(5,0){\framebox(1,1){\em link}}
\put(7,0){\framebox(1,1){\em link}}
\put(1.5,2){\vector(0,-1){1}}
\put(2,0.5){\vector(1,0){1}}
\put(4,0.5){\vector(1,0){1}}
\put(6,0.5){\vector(1,0){1}}
\put(3,2.5){\vector(1,0){4}}
\put(7,2){\oval(1,1)[tr]}
\put(7.5,2){\vector(0,-1){1}}
\end{picture}
\end{center}

\slide{Variation -- Doubly Linked List}

Allows movement either forward or backward.  

\setlength{\unitlength}{12mm}
\begin{center}
\begin{picture}(8,3.5)
\put(0,2){\framebox(3,1){\em a list}}
\put(1,0){\framebox(1,1){\em link}}
\put(3,0){\framebox(1,1){\em link}}
\put(5,0){\framebox(1,1){\em link}}
\put(7,0){\framebox(1,1){\em link}}
\put(1.5,2){\vector(0,-1){1}}
\put(2,0.4){\vector(1,0){1}}
\put(4,0.4){\vector(1,0){1}}
\put(6,0.4){\vector(1,0){1}}
\put(3,0.6){\vector(-1,0){1}}
\put(5,0.6){\vector(-1,0){1}}
\put(7,0.6){\vector(-1,0){1}}
\end{picture}
\end{center}

STL list is combination of head and tail pointers and double links.

\slide{Summary of List Operations}

{\Large
\begin{center}
\begin{tabular}{| l | l |}
\hline
\multicolumn{2}{| l |}{\bf Constructors and Assignment} \\
\hline
{\tt list$<$T$>$ v;} & default constructor \\
{\tt list$<$T$>$ v (aList);} & copy constructor \\
{\tt l $=$ aList}& assignment \\
{\tt l.swap (aList)} & swap values with another list \\
\hline
\multicolumn{2}{| l |}{\bf Element Access} \\
\hline
{\tt l.front ()} & first element in list \\
{\tt l.back ()} & last element in list \\
\hline
\multicolumn{2}{| l |}{\bf Insertion and Removal} \\
\hline
{\tt l.push\_front (value)} & add value to front of list \\
{\tt l.push\_back (value)} & add value to end of list \\
{\tt l.insert (iterator, value)} & insert value at specified location \\
{\tt l.pop\_front ()} & remove value from front of list \\
{\tt l.pop\_back ()} & remove value from end of list \\
{\tt l.erase(iterator)} & remove referenced element \\
{\tt l.erase(iterator,iterator)} & remove range of elements \\
{\tt l.remove (value)} & remove all occurrences of value \\
{\tt l.remove\_if (predicate)} & removal all values that match condition \\
\hline
\multicolumn{2}{| l |}{\bf Size} \\
\hline
{\tt l.empty ()} & true if collection is empty \\
{\tt l.size ()} & return number of elements in collection \\
\hline
\multicolumn{2}{| l |}{\bf Iterators} \\
\hline
{\tt list<T>::iterator itr} & declare a new iterator \\
{\tt l.begin () } & starting iterator \\
{\tt l.end ()} & ending iterator \\
\hline
\multicolumn{2}{| l |}{\bf Miscellaneous} \\
\hline
{\tt l.reverse ()} & reverse order of elements\\
{\tt l.sort ()} & place elements into ascending order \\
{\tt l.sort (comparison)} & order elements using comparison function \\
{\tt l.merge (list)} & merge with another ordered list \\
\hline
\end{tabular}
\end{center}}

\slide{Declaring a new List}

\begin{cprog}

	list <int> list_one;	
		// list of pointers to widgets
	list <Widget *> list;	
	list <Widget> list_three;	// list of widgets

	list <int> list_four (list_one);
	list <Widget> list_five;
	list_five = list_three;

		// exchange values in lists one and four
	list_one.swap (list_four); 
\end{cprog}

\slide{Adding Elements to a List}

\begin{cprog}

	list_one.push_front (12);
	list_three.push_back (Widget(6));

			// insert widget 8 at end of list
	list_three.insert (list_three.end(), Widget(8));

			//  find the location of the 
			// first 5 value in list
	list<int>::iterator location = 
			find (list_one.begin(), list_one.end(), 5);
		// and insert an 11 immediate before it
	location = list_one.insert (location, 11);
\end{cprog}

\slide{Erasing Elements from a List}

\begin{cprog}

	list_nine.erase (location);

			// erase all values between the first 5 
			// and the following 7	
	list<int>::iterator start = 
		find (list_nine.begin(), list_nine.end(), 5);

	list<int>::iterator stop = 
		find (location, list_nine.end(), 7);

	list_nine.erase (start, stop);

	list_nine.remove (4); // remove all fours

		//remove elements divisible by 3
	list_nine.remove_if (divisableByThree); 

\end{cprog}

\slide{Number of Elements}

\begin{cprog}

	cout << "Number of elements: " 
		<< list_nine.size () << endl;

	if ( list_nine.empty () )
		cout << "list is empty " << endl;
	else
		cout << "list is not empty " << endl;


	int num = 0;
	count (list_five.begin(), list_five.end(), 
			17, num);
	if (num > 0)
		cout << "contains a 17" << endl;
	else
		cout << "does not contain a 17" << endl;

\end{cprog}

\slide{Sort, Reverse}

\begin{cprog}

		// place elements into sequence
	list_ten.sort ( );	

		// sort using 
		// the widget compare function
	list_twelve.sort (widgetCompare); 

		// elements are now reversed
	list_ten.reverse(); 

\end{cprog}

\slide{Insert Iterators}

Assignment to an iterator is normally an overwriting operation, replacing
the contents of the targeted location.

\begin{cprog}

	copy (list_one.begin(), list_one.end(), list_two.begin());

\end{cprog}

For lists (and sets) often instead want to perform {\em insertion}.
Can be done by creating a list insert iterator.

\begin{cprog}

	copy (list_one.begin(), list_one.end(), back_inserter(list_two));

\end{cprog}

Other insert iterators {\sf front\_inserter}, and {\sf inserter}.

\slide{Adaptors}

\begin{itemize}
\item
An insert iterator is a form of {\em adaptor}.  
\item
An adaptor changes the interface to an object, but does little or no work itself.
\item
In this case, change the insert interface into the iterator interface.
\item
We will later see many different types of adaptors
\end{itemize}

\slide{Example Program--Inventory System}

A business, {\em WorldWideWidgetWorks}, manufactures widgets.

{\Large\begin{cprog}

class  Widget {
public:
		// constructors
	Widget () : id_number (0) { }
	Widget (int a) : id(a) { }

		// operations
	int id () { return id_number; }
	void operator =  (Widget & rhs) 
		{ id_number = rhs.id_number; }
	bool operator == (Widget & rhs) 
		{ id_number == rhs.id_number; }
	bool operator <  (Widget & rhs) 
		{ id_number < rhs.id_number; }

protected:
	int id_number;	// widget identification number
};
\end{cprog}}

\slide{Inventory}

Inventory is two lists -- items on hand, items on back order.

\begin{cprog}

//
//	class inventory
//		manage inventory control

class inventory {
public:
		// process order for widget type wid
	void order (int wid);	

		// receive widget of type wid 
		// in shipment
	void receive (int wid);	

protected:
	list <Widget> on_hand;
	list <int> on_order;
};

\end{cprog}

\slide{Item Arrives in Shipment}

\begin{cprog}

void inventory::receive (int wid)
	// process a widget received in shipment
{
	cout << 
		"Received shipment of widget type " 
		<< wid << endl;

	list<int>::iterator we_need = 
			find (on_order.begin(), on_order.end(), wid); 

	if (we_need != on_order.end()) {
		cout << "Ship " << Widget(wid) << 
			" to fill back order" << endl;
		on_order.erase(we_need);
		}
	else
		on_hand.push_front(Widget(wid));
}

\end{cprog}

\slide{Item Arrives on Order}

\begin{cprog}
void inventory::order (int wid)
	// process an order for a widget with given id number
{
	cout << 
		"Received order for widget type " 
			<< wid << endl;

	list<Widget>::iterator we_have = 
		find_if(on_hand.begin(), on_hand.end(), WidgetTester(wid));

	if (we_have != on_hand.end()) {
		cout << "Ship " << *wehave << endl;
		on_hand.erase(we_have);
		}
	else {
		cout << "Back order widget of type "  
			<< wid  << endl;
		on_order.push_front(wid);
		}
}
\end{cprog}

\slide{Function Objects}

Created like an instance of a class, works like a function.

\begin{cprog}

class WidgetTester {
public:
	WidgetTester (int id) : test_id(id) { }
	int test_id;

		// define the function call operator
	bool operator () (Widget & wid)
		{ return wid.id() == test_id; }
};

\end{cprog}

\slide{Course Registration System}

Problem: How to assign students to courses, create reports for both 
instructors and students.  

Two input files

\begin{cprog}

	...
ART101 60
HIS213 75
MTH412 35
	...

\end{cprog}
\begin{cprog}

	...
Smith,Amy ART101
Smith,Amy MTH412
Jones,Randy HIS213
	...

\end{cprog}

\slide{Representation of Classes}

\begin{cprog}
//
//	class course
//		information about one course

class course {
public:
	course (string n, int s) : name(n), size(s) { }

		// operations
	bool full ()	
		{ return students.size() >= max; }
	void addStudent (student * s) 
		{ students.push_back(s); }
	void generateClassList ();


protected:	// data fields
	string name;
	int max;
	list <student *> students;
}
\end{cprog}

\slide{Reading the Course File}

\begin{cprog}

list <course *> all_courses;

void readCourses (istream & infile)
	// read the list of courses from 
	// the given input stream
{
	string name;
	int max;

	while (infile >> name >> max) {
		course * newCourse = 
			new course (name, max);
		all_courses.push_back (newCourse);
		}
}

\end{cprog}

\slide{Representation of Students}

{\Large\begin{cprog}
//
//	class student
//		information about a single student

class student {
	// provide a shorter name for 
	// course iterators
typedef list <course *>::iterator citerator;

public:
		// constructor
	student (string n) : nameText(n) { }

		// operations
	void addCourse (course * c) {courses.push_back(c);}
	citerator firstCourse () {return courses.begin();}
	citerator lastCourse () {return courses.end();}
	void removeCourse (citerator & citr) 
		{courses.erase(citr);}

protected:
	string nameText;
	list <course *> courses;
};
\end{cprog}}

\slide{Reading the Student File}

\begin{cprog}

list <student *> all_students;

void readStudents (istream & infile)
	// read the list of student records 
{
	string name;
	string course;

	while (infile >> name >> course) {
		student * theStudent = 
			findStudent (name);
		course * theCourse = findCourse (course);
		if (theCourse != 0)
			theStudent.addCourse (theCourse);
		else
			cout << "student " << name << 
				" requested invalid course " 
				<< course << "\n";
		}
}
\end{cprog}

\slide{Finding the Student in the list of Students}

\begin{cprog}

student * findStudent (string & searchName)
	// find (or make) a student record 
	// for the given name
{
	list <student *>::iterator start, stop;
	start = all_students.begin();
	stop = all_students.end();
	for ( ; start != stop; ++start)
		if ((*start)->name() == searchName)
			return *start;

		// not found, make one now
	student * newStudent = 
		new student(searchName);
	all_students.push_back (newStudent);
	return newStudent;
}
\end{cprog}

\slide{Merging the Two Lists}

\begin{cprog}

void fillCourses ()
	// fill students as possible in each course
{
	list<student *>::iterator s_start, s_end;
	s_start = all_students.begin();
	s_end = all_students.end();
	for ( ; s_start != s_end; ++s_start) {
		list<course *>::iterator c_start, c_end;
		list<course *>::iterator c_next;
		c_start = (*s_start)->firstCourse();
		c_end = (*s_start)->lastCourse();
		for ( ; c_start != c_end; c_start = c_next) {
			c_next = c_start; ++c_next;
				// if not full, add student
			if (! (*c_start)->full())
				(*c_start)->addStudent (*s_start);
			else
				(*s_start)->removeCourse(c_start);
			}
	} }
\end{cprog}

\slide{Removal}

Note carefully how the removal is handled.  It is not legal to 
use a list iterator once it has been removed from the list.  So we
must get the next element before doing the removal.

\setlength{\unitlength}{1cm}
\begin{center}
\begin{picture}(9,2.5)
\put(0,0){\framebox(1,1){}}
\put(1,0.4){\vector(1,0){1}}
\put(2,0.6){\vector(-1,0){1}}
\put(2,0){\framebox(1,1){}}
\put(3,0.4){\vector(1,0){1}}
\put(4,0.6){\vector(-1,0){1}}
\put(4,0){\framebox(1,1){}}
\put(5,0.4){\vector(1,0){1}}
\put(6,0.6){\vector(-1,0){1}}
\put(6,0){\framebox(1,1){}}
\put(7,0.4){\vector(1,0){1}}
\put(8,0.6){\vector(-1,0){1}}
\put(8,0){\framebox(1,1){}}
\put(4.5,2){\vector(0,-1){1}}
\put(4,2){\makebox(1,0.5){\sf c\_start}}
\put(6.5,2){\vector(0,-1){1}}
\put(6,2){\makebox(1,0.5){\sf c\_next}}
\put(0,1){\makebox(1,2)[r]{\em before removal}}
\end{picture}
\end{center}

\begin{center}
\begin{picture}(9,2.5)
\put(0,0){\framebox(1,1){}}
\put(1,0.4){\vector(1,0){1}}
\put(2,0.6){\vector(-1,0){1}}
\put(2,0){\framebox(1,1){}}
\put(3,0.4){\vector(1,0){3}}
\put(4,0){\framebox(1,1){}}
\put(4,0){\line(1,1){1}}
\put(4,1){\line(1,-1){1}}
\put(6,0.6){\vector(-1,0){3}}
\put(6,0){\framebox(1,1){}}
\put(7,0.4){\vector(1,0){1}}
\put(8,0.6){\vector(-1,0){1}}
\put(8,0){\framebox(1,1){}}
\put(4,2){\makebox(1,0.5){\sf c\_start}}
\put(6.5,2){\vector(0,-1){1}}
\put(6,2){\makebox(1,0.5){\sf c\_next}}
\put(0,1){\makebox(1,2)[r]{\em after removal}}
\end{picture}
\end{center}

\slide{Generate Class List}

\begin{cprog}

void course::generateClassList ()
	// print the class list of all students
{
		// first sort the list
	students.sort (studentCompare);

		// then print it out
	cout << "Class list for " 
		<< name << "\n";
	list<student *>::iterator start, stop;
	start = students.begin();
	stop = students.end();
	for ( ; start != stop; ++start)
		cout << (*start)->name() << "\n";
}
\end{cprog}

\slide{An Example Implementation}

{\Large\begin{cprog}
template <class T>
class list {
public:
		// type definitions
	typedef T value_type;
	typedef listIterator<T> iterator;

		// constructors
	list () : firstLink(0), lastLink(0) { }

		// operations
	bool empty () { return firstLink == 0; }
	int size();
	T & back () { return lastLink->value; }
	T & front () { return firstLink->value; }
	void pop_front ();
	void pop_back ();
	iterator begin () { return iterator (this, firstLink); }
	iterator end () { return iterator (this, 0); }
	void sort ();
	iterator insert (iterator, value);
	void erase (iterator & itr) { erase (itr, itr); }
	void erase (iterator &, iterator &);

protected:
	link <T> * firstLink;
	link <T> * lastLink;
};
\end{cprog}}

\slide{Link, a facilitator class working behind the scenes}

\begin{cprog}

template <class T> class link {
public:
	link (T & v) 
		: value(v), nextLink(0), prevLink(0) { }
	T value;
	link<T> * nextLink;
	link<T> * prevLink;
};
\end{cprog}

\slide{Walking Down the List}

Internal operations that access the entire structure simply walk down the
list.

\begin{cprog}

template <class T> int list<T>::size ()
	// count number of elements in collection
{
	int counter = 0;
	link<T> * ptr = firstLink;
	for ( ; ptr != 0; ptr = ptr->nextLink)
		counter++;
	return counter;
}

\end{cprog}

\slide{Adding a New Element to Front of List}

\setlength{\unitlength}{1cm}
\begin{center}
\begin{picture}(8,3.5)
\put(0,2){\framebox(3,1){\em a list}}
\put(1,0){\framebox(1,1){\em link}}
\put(3,0){\framebox(1,1){\em link}}
\put(5,0){\framebox(1,1){\em link}}
\put(7,0){\framebox(1,1){\em link}}
\put(1.5,2){\vector(0,-1){1}}
\put(2,0.4){\vector(1,0){1}}
\put(4,0.4){\vector(1,0){1}}
\put(6,0.4){\vector(1,0){1}}
\put(3,0.6){\vector(-1,0){1}}
\put(5,0.6){\vector(-1,0){1}}
\put(7,0.6){\vector(-1,0){1}}
\put(3.5,2){\makebox(1,1)[l]{\sf List Before Adding New Element}}
\end{picture}
\end{center}

\setlength{\unitlength}{1cm}
\begin{center}
\begin{picture}(8,3.5)
\put(0,2){\framebox(3,1){\em a list}}
\put(1,0){\framebox(1,1){\em link}}
\put(3,0){\framebox(1,1){\em link}}
\put(5,0){\framebox(1,1){\em link}}
\put(7,0){\framebox(1,1){\em link}}
\put(-1,0){\framebox(1,1){\em \shortstack{new \\ link}}}
\put(1.5,2){\vector(-2,-1){2}}
\put(0,0.4){\vector(1,0){1}}
\put(2,0.4){\vector(1,0){1}}
\put(4,0.4){\vector(1,0){1}}
\put(6,0.4){\vector(1,0){1}}
\put(1,0.6){\vector(-1,0){1}}
\put(3,0.6){\vector(-1,0){1}}
\put(5,0.6){\vector(-1,0){1}}
\put(7,0.6){\vector(-1,0){1}}
\put(3.5,2){\makebox(1,1)[l]{\sf List After Adding New Element}}
\end{picture}
\end{center}

\slide{Must Check for Empty List}

\begin{cprog}

template <class T> void list<T>::push_front 
		(T & newValue)
	// add a new value to the front of a list
{
	link<T> * newLink = 
		new link<T> (newValue);

	if (empty()) 
		firstLink = lastLink = newLink;
	else {
		firstLink->prevLink = newLink;
		newLink->nextLink = firstLink;
		firstLink = newLink
		}
}
\end{cprog}

\slide{Removal From List}

\begin{cprog}

template <class T> void list<T>::pop_front()
	// remove first element from linked list
{
	link <T> * save = firstLink;
	firstLink = firstLink->nextLink;
	if (firstLink != 0)
		firstLink->prevLink = 0;
	else
		lastLink = 0;
	delete save;
}
\end{cprog}

Note how removing last element from list is handled as special case.

\slide{List Iterators}

List iterators must look like pointers, but act differently.

Can be created as special class that keeps an internal pointer to
the list, and to the current link.

\slide{Iterator Class}

{\Large\begin{cprog}
template <class T> class listIterator {
	typedef listIterator<T> iterator;
public:
		// constructor
	listIterator (list<T> * tl, link<T> * cl)
		: theList(tl), currentLink (cl) { }

		// iterator protocol
	T & operator * () 
		{ return currentLink->value; }
	void operator = (iterator & rhs) 
		{ theList = rhs.theList; 
		currentLink = rhs.currentLink; }
	bool operator == (iterator & rhs) 
		{ return currentLink == rhs.currentLink; }
	iterator & operator ++ (int)
		{ currentLink = currentLink->nextLink; 
		return this; }
	iterator operator ++ ();
	iterator & operator -- (int)
		{ currentLink = currentLink->prevLink; 
		return this; }
	iterator operator -- ();

protected:
	list <T> * theList; link <T> * currentLink; };
\end{cprog}}

\slide{Postorder Decrement is More Complex}

\begin{cprog}

template <class T> listIterator<T> listIterator<T>::operator ++ ()
	// postfix form of increment
{
		// clone, then increment, return clone
	listIterator<T> clone (theList, currentLink);
	currentLink = currentLink->nextLink;
	return clone;
}
\end{cprog}

\slide{Insertion At an Iterator Position}

\begin{cprog}

template <class T> void list<T>::insert (listIterator<T> & itr, T & value)
	// insert a new element into the 
	// middle of a linked list
{
	link<T> * newLink = new link(value);
	link<T> * current = itr->currentLink;

	newLink->nextLink = current;
	newLink->prevLink = current->prevLink;
	current->prevLink = newLink;
	current = newLink->prevLink;
	if (current != 0)
		current->nextLink = newLink;
}
\end{cprog}

\slide{Removal of an Iterator Range}

{\Large\begin{cprog}

template <class T> 
void list<T>::erase (listIterator<T> & start, listIterator<T> & stop)
	// remove range of elements
{
	link<T> * first = start->currentLink;
	link<T> * prev = first->prevLink;
	link<T> * last = stop->currentLink;
	if (prev == 0) { 	// removing initial 
		firstLink = last;
		if (last == 0)
			lastLink = 0;
		else
			last->prevLink = 0;
		}
	else {
		prev->nextLink = last;
		if (last == 0)
			lastLink = prev;
		else
			last->prevLink = prev;
		}
		// now delete the values
	while (start != stop) {
		link<T> * next = start;
		++next;
		delete start;
		start = next;
		}
}
\end{cprog}}

\slide{Variation through Inheritance}

Inheritance is a powerful technique for creating new classes out of existing
classes.

Basically, you simply say that the new thing is an extension of the old
thing.  All data fields, member functions and the like from the old
abstraction are available for free in the new class.

\begin{cprog}



class newClass : public OldClass {
	...
}

\end{cprog}

\slide{Example, Ordered Lists}

\begin{cprog}

template <class T>
class orderedList : public list<T> {
public:
	void add (T & newValue);
};

\end{cprog}

The only thing we need add is a new method for adding elements
to the list.

All other member functions associated with {\sf list} are still available,
for free, with instances of this new class.

\slide{Adding the New Value}

Here is how a new value gets added to an ordered list.

\begin{cprog}

template <class T>
void orderedList<T>::add (T & newValue)
	// add a new element to an ordered list
{
	list<T>::iterator start, stop;
	start = begin();
	stop = end();
	while ((start != stop) && 
		(*start < newValue))
			++start;
	insert (start, newValue);
}

\end{cprog}

\slide{Application, List Insertion Sort}

\begin{cprog}

template <class T>
void listInsertionSort (vector<T> & v)
	// place a vector into order, 
	// using an ordered list
{
	orderedList<T> sorter;

		// first copy vector to list
	vector<T>::iterator start = v.begin();
	vector<T>::iterator stop = v.end();
	for ( ; start != stop; ++start)
		sorter.add(*start);

		// then copy list back to vector
	list<T>::iterator itr = sorter.begin();
	for (start = v.begin(); start != stop; ++start)
		*start = *itr++;
}

\end{cprog}

\slide{Self Organizing Lists}

\begin{cprog}

template <class T>
class selfOrganizingList<T> : public list<T> {
public:
	bool include (T & value);
};

\end{cprog}

\slide{Includes test for SO list}

\begin{cprog}

template <class T>
bool selfOrganizingList<T>::include (T & value)
	// see if argument value occurs in list
{
		// first find element in list
	list<T>::iterator stop = end();
	list<T>::iterator where = 
		find(begin(), stop, value);
		// if not found, return false
	if (where == stop)
		return false;
		// else remove from list, 
		// and move to front
	if (where != begin()) {
		erase (where);
		push_front (value);
		}
	return true;
}

\end{cprog}

\slide{Private, Protected and Public}

With inheritance, there are three levels of protection:

\begin{itemize}
\item
{\sf public}, accessible to the world
\item
{\sf protected}, accessible to class and subclasses
\item
{\sf private}, accessible only to class (not even to subclasses!)
\end{itemize}

\end{document}
