//{An Example Implementation}
#ifndef __LIST_H_
#define __LIST_H_

template <class T> class list
{ 
  ////////  list - what's under the hood /////////////
  protected:	

        //{Link, a facilitator class working behind the scenes}
    struct link 
    {
	link (const T & v, link *pl = 0, link * nl = 0 ) 
	    : value(v), prevLink(pl), nextLink(nl) { }
	T value;
	link * nextLink;
	link * prevLink;
    }; // end link

	// the list (header) data fields
    link * firstLink;  // ptr to first link in list
    link * lastLink;  // ptr to last link in list
    // Special cases: these two will be 0 (NULL) for an empty list 
    // and will point to the same link for a one item list.

 ////////  list member types /////////////
 public:
        // a list<T> member type
    typedef T value_type;

        // a list<T> member type
    class iterator  // implements bidirectional iterator concept.
    { protected:

	    // an iterator is a "wrapper" of this link pointer
	link * currentLink; 

	    // a constructor used only by member functions 
	iterator (link * cl) : currentLink (cl) { } 
	friend class list; //  and by list's member functions

      public:
        iterator () // default constructor
	    ;
        iterator (const iterator & anotherIter) // copy constructor
	    ;
	    // iterator protocol
	T & operator * () // dereference operator
	    ;
	iterator& operator = (const iterator & rhs) // assignment 
	    ;
	bool operator == (const iterator & rhs) // iterator equality 
	    ;
	bool operator != (const iterator & rhs) // inequality
	    ;
	iterator & operator ++ () // prefix increment
	    ;
	iterator operator ++ (int) // postfix increment
	    ;
	iterator & operator -- () // prefix decrement
	    ;
	iterator operator -- (int) // postfix decrement
	    ;
    }; // end of list<T>::iterator

  ////////  list<T> member functions ///////////////

    list () // default constructor 
	;
    list (const list & L) // copy constructor
	; 
    bool empty ()  // true only of an empty list
	;
    int size() // warning: time to compute is proportional to size of list
	;
 // NEW!! Oh Yeah // 
    T & operator[](int i) // array style indexing.
	;
    T & back () // last value in nonempty list
	;
    T & front () // first value in nonempty list
	;
    void push_front (const T &) // introduce additional value in front of list
	;
    void pop_front () // remove first value in nonempty list
	;
    void push_back (const T &) // introduce additional value as last in list
	;
    void pop_back () // remove last value in nonempty list
	;
    iterator begin () // interator initially referencing front element of list
	;
    iterator end () // iterator referencing nothing but equal to ultimate 
		    // result of incrementing from begin().
	;
    //void sort ();
    iterator insert (iterator&, const value_type&) 
    // insert new value before iterator. returned iterator points to inserted.
	;
    void erase (iterator & itr)  // remove value referenced by itr
	;
    void erase (iterator & b, iterator & e) // remove range *[b..e)
	;

}; // end list<T>

#include "list.inl"  // defs of member functions

#endif //__LIST_H_
