#include #include #include using namespace std; template CList::CList() // postcondition: empty list constructed : myCount(0) { myFirst = myLast = 0; } template CList CList::EMPTY = CList(); template int CList::ourConsCount = 0; template int CList::ConsCalls() { return ourConsCount; } template CList::CList(const Type& t, const CList& lst) : myCount(0) { myFirst = new TNode(t,lst.myFirst); ourConsCount++; if (lst.Size() == 0) { myLast = myFirst; } else { myLast = lst.myLast; } myCount = lst.Size() + 1; } template Type CList::First() const { if (myFirst) { return myFirst->info; } cerr << "error: Front of empty list" << endl; return Type(); } template Type CList::Head() const { return First(); } template CListPrinter CList::Printer() const { return CListPrinter(*this); } template CListPrinter CList::Printer(const string& delimiter) const { return CListPrinter(*this,delimiter); } template CList CList::Tail() const { CList lst; if (myFirst == 0 || myFirst->next == 0) { // return lst; return EMPTY; } lst.myFirst = myFirst->next; lst.myLast = myLast; lst.myCount = Size() - 1; return lst; } template Type CList::Last() const { if (myLast) return myLast->info; cerr << "error: Back of empty list" << endl; return Type(); } template bool CList::Contains(const Type & t) const // postcondition: returns true if t contained in list, else false { TNode * temp = myFirst; // start at front, search while (temp) // linearly { if (temp->info == t) return true; temp = temp->next; } return false; } template CList CList::Find(const Type & t) const // postcondition: returns list such that list.Head() == t // or EMPTY if !Contains(t) { if (IsEmpty()) { return EMPTY; } else if (First() == t) { return *this; } else { return Tail().Find(t); } } template int CList::Size() const // postcondition: returns # of elements in list { return myCount; } template bool CList::IsEmpty() const // postcondition: returns true iff list is empty { return Size() == 0; } template string CList::Address() const { ostringstream out; out << hex << myFirst; return out.str(); } template CList CList::cons(const Type& s,const CList& slist) { CList temp(s,slist); return temp; } template CListIterator::CListIterator(const CList& list) { myFirst = list.myFirst; } template void CListIterator::Init() const { myCurrent = myFirst; } template bool CListIterator::HasMore() const { return myCurrent != 0; } template void CListIterator::Next() const { if (HasMore()) { myCurrent= myCurrent->next; } } template Type CListIterator::Current() const { if (HasMore()) { return myCurrent->info; } cerr <<"error empty list iterator" << endl; return Type(); } template CList append(const Type& s,const CList& slist) { if (slist.IsEmpty()) return slist.cons(s,slist); return slist.cons(slist.First(),append(s,slist.Tail())); } template CList appendaux(const CList& slist,const CList& aux) { if (slist.IsEmpty()) return aux; return cons(slist.Head(),appendaux(slist.Tail(), aux)); } template CList oldappend(const Type& s,const CList& slist) { return appendaux(slist,cons(s,CList())); } template ostream& operator << (ostream& output, const CListPrinter& p) { CListIterator it(p.myList); it.Init(); if (it.HasMore()) { output << it.Current(); } for(it.Next(); it.HasMore(); it.Next()) { output << p.myDelimiter << it.Current(); } return output; } template CListPrinter::CListPrinter(const CList& slist) : myList(slist), myDelimiter("\n") { } template CListPrinter::CListPrinter(const CList& slist, const string& delimiter) : myList(slist), myDelimiter(delimiter) { } template ostream& operator << (ostream& output, const CList& list) { output << "(" << list.Printer(",") << ")"; return output; }