//// list<T>::iterator member function definitions ////

    template<class T> list<T>::iterator::
    // list iterator default constructor
iterator () 
    : currentLink (0) { }

    template<class T> list<T>::iterator::
    // list iterator copy constructor
iterator (const iterator & anotherIter)
    : currentLink (anotherIter.currentLink) { }

	    // iterator protocol
    template<class T>
T & list<T>::iterator::operator * () 
{   assert (currentLink != 0);
    return currentLink->value; 
}

    template<class T> 
    typename list<T>::iterator& 
list<T>::iterator::operator = (const list<T>::iterator & rhs) 
{   currentLink = rhs.currentLink; return *this;   }

    template<class T> 
bool list<T>::iterator::operator == (const iterator & rhs) 
{   return currentLink == rhs.currentLink;   }

    template<class T>
bool list<T>::iterator::operator != (const iterator & rhs) 
{   return currentLink != rhs.currentLink;   }

    template<class T>
    typename list<T>::iterator & 
list<T>::iterator::operator ++ ()
{   assert(currentLink != 0);
    currentLink = currentLink->nextLink; 
    return *this; 
}

    template<class T>
    typename list<T>::iterator 
list<T>::iterator::operator ++ (int)
{   assert(currentLink != 0);
    link * temp = currentLink; 
    currentLink = currentLink->nextLink; 
    return iterator(temp);
}

    template<class T>
    typename list<T>::iterator & 
list<T>::iterator::operator -- () 
{   assert(currentLink != 0);
    currentLink = currentLink->prevLink; 
    return *this; 
}

    template<class T>
    typename list<T>::iterator 
list<T>::iterator::operator -- (int)
{   assert(currentLink != 0);
    link * temp = currentLink; 
    currentLink = currentLink->prevLink; 
    return iterator(temp);
}

////////  list<T> member function definitions ///////////////

    template<class T>
    // list default constructor
list<T>::list () : firstLink(0), lastLink(0) { }

    template<class T>
list<T>::list (const list & L) 
    : firstLink(L.firstLink), lastLink(L.lastLink) {}

    	// operations
    template<class T>
bool list<T>::empty ()  { return firstLink == 0; }

//{Walking Down the List}
/*
Internal operations that access the entire structure simply walk down the
list.
*/

    template <class T> 
T& list<T>::operator[](int i)
	// go to i-th position
{
    int counter = 0;
    iterator p;
    for (p = begin(); counter < i; ++p, ++ counter);
    return *p;
}

    template <class T> 
int list<T>::size ()
	// count number of elements in collection
{
    int counter = 0;
    link * ptr = firstLink;
    for (iterator p = begin(); p != end(); ++p) ++counter;
// or loop could be 
//  for ( ; ptr != 0; ptr = ptr->nextLink) counter++;

    return counter;
}

    template<class T>
T & list<T>::back () 
{   assert (lastLink != NULL);
    return lastLink->value; 
}

template<class T>
T & list<T>::front () 
{   assert (firstLink != NULL);
    return firstLink->value; 
}

//{Front and Back Add to List}

    template <class T> 
void list<T>::push_front (const T & newValue)
    // add a new value to the front of a list
{   if ( empty() ) 
	firstLink = lastLink = new link (newValue);
    else {
        firstLink->prevLink = new link(newValue, 0, firstLink);
        firstLink = firstLink->prevLink;
	 }
}

    template <class T> 
void list<T>::push_back (const T & newValue)
    // add a new value to the front of a list
{
    if (empty()) 
    	firstLink = lastLink = new link (newValue);
    else {
    	lastLink->nextLink = new link(newValue, lastLink, 0);
    	lastLink = lastLink->nextLink;
         }
}

//{Front and Back Removal from List}

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

    template <class T> 
void list<T>::pop_back()
    // remove first element from linked list
{
    link * save = lastLink;
    lastLink = lastLink->prevLink;
    if (lastLink != 0)
    	lastLink->nextLink = 0;
    else
    	firstLink = 0;
    delete save;
}    
//Note how removing a list's last element is handled as special case.

    template<class T>
    typename list<T>::iterator 
list<T>::begin () { return iterator (firstLink); }

    template<class T>
    typename list<T>::iterator 
list<T>::end () { return iterator (0); }

//  template<class T>
//void sort ();

    template <class T> 
    typename list<T>::iterator 
list<T>::insert (iterator & wherebefore, const T & value)
    // insert a new element into the 
    // middle of a linked list
{
    link * current = wherebefore.currentLink;
    link * newLink = new link(value, current->prevLink, current);

    current->prevLink = newLink;
    if (begin() != wherebefore)
        newLink->prevLink->nextLink = newLink;
    return iterator(newLink);
}

//{Removal of one item}
    template <class T> 
void list<T>::erase (iterator & position)
{   iterator stop = position;
    ++stop;   // increment to next position;
    erase ( position, stop );
}

//{Removal of an Iterator Range}

    template <class T> 
void list<T>::erase (iterator & start, iterator & stop)
    // remove range of elements
{
    link * first = start.currentLink;
    link * prev = first->prevLink;
    link * next = stop.currentLink;
    /* Suppose last = next->prevLink, (last node to be deleted)
     * Thus the picture is:
     * ... <--> prev <--> first <--> ... <--> last <--> next <--> ...
     *
     * 1. fix list's links to have this:  ... <--> prev <--> next <--> ...
     * 2. delete these removed links:  first <--> ... <--> last 
     */ 

	// fix list at front of excised range
    if (prev != 0)
    	prev->nextLink = next; // removing afer a link
    else 		
    	firstLink = next;      // removing initial link

	// fix list at end of excised range
    if (next != 0)       
        next->prevLink = prev; // removing before a link
    else                
        lastLink = prev;       // removing final link

	// now delete the excised links
    while (first != next) 
    {
    	link * deletable = first;
    	first = first->nextLink;
    	delete deletable;
    }
}

