// Build don't link: // prms-id: 1989 #define TRUE true #define FALSE false typedef void *Pix; template struct link { T item; link *next; link *prev; link(const T& t): item(t), prev(0), next(0) { }; link(const T& t, link *p, link *n): item(t), prev(p), next(n) { }; }; template class List_DL { public: List_DL(); List_DL(const List_DL&); ~List_DL(); void append(const T& item); void prepend(const T& item); void insert(const T& item, Pix x, bool before); void remove(Pix& x) { T tmp; remove(x, tmp); } void remove(Pix& x, T& item); void clear(); unsigned length() const { return count; } private: unsigned count; link *head; link *tail; public: Pix first() const { return Pix(head); } Pix last() const { return Pix(tail); } void next(Pix& x) const { if (0 != x) x = ((link *) x)->next; } void prev(Pix& x) const { if (0 != x) x = ((link *) x)->prev; } T& operator()(Pix x) const { return ((link *) x)->item; } }; template List_DL::List_DL(): count(0), head(0) { } template List_DL::List_DL(const List_DL& other): count(0), head(0) { for (Pix x=other.first(); 0 != x; other.next(x)) append(other(x)); } template List_DL::~List_DL() { clear(); } template void List_DL::append(const T& item) { count++; if (0 == head) { head = new link(item); tail = head; } else { tail->next = new link(item, tail, 0); tail = tail->next; } } template void List_DL::prepend(const T& item) { count++; if (0 == head) { head = new link(item); tail = head; } else { head = new link(item, 0, head); if (tail == head) tail = tail->next; } } template void List_DL::insert(const T& item, Pix x, bool before = TRUE) { link *l = (link *) x; if (before) { if (0 == l || l == head) { prepend(item); } else { link *n = new link(item, l->prev, l); l->prev->next = n; l->prev = n; } } else { if (0 == l || l == tail) { append(item); } else { link *n = new link(item, l, l->next); l->next->prev = n; l->prev = n; } } } template void List_DL::remove(Pix& x, T& item) { link *l = (link *) x; if (0 == l) return; item = l->item; if (1 == count) { delete head; head = 0; tail = 0; } else { // more than one item in the list if (l == head) { link *old = head; head = head->next; head->prev = 0; delete old; } else if (l == tail) { link *old = tail; tail = tail->prev; tail->next = 0; delete old; } else { l->next->prev = l->prev; l->prev->next = l->next; delete l; } } } template void List_DL::clear() { link *l, *succ; for (l=head; 0 != l; l=succ) { succ = l->next; delete l; } head = 0; tail = 0; } template class List_DLS: public List_DL { public: List_DLS(): List_DL() { }; List_DLS(const List_DLS& other): List_DL(other) { }; bool contains(const T& item) const { return search(item) != 0 ? TRUE: FALSE; } Pix search(const T&) const; }; template Pix List_DLS::search(const T& item) const { for (Pix x=first(); 0 != x; next(x)) { if (item == operator()(x)) // ERROR - const subversion return x; } return 0; } template class List_DLSp: public List_DL { public: List_DLSp(): List_DL() { }; List_DLSp(const List_DLSp& other): List_DL(other) { }; bool contains(const T& item) const #ifndef INTERNAL_ERROR ; #else { return search(item) != 0 ? TRUE: FALSE; } #endif Pix search(const T&) const; }; template bool List_DLSp::contains(const T& item) const { for (Pix x=first(); 0 != x; next(x)) { if (*item == *operator()(x)) return TRUE; } return FALSE; } template class Set { public: Set(); Set(const Set& other); virtual void add(const T& item); void remove(const T& item) { Pix x = search(item); remove(x); } void remove(Pix& x) { T tmp; remove(x, tmp); } virtual void remove(Pix& x, T& item); virtual void clear(); virtual bool contains(const T&) const; virtual Pix search(const T&) const; virtual unsigned length() const; virtual Pix first() const; virtual void next(Pix& x) const; virtual T& operator()(Pix x) const; }; template Set::Set() { } template Set::Set(const Set& other) { } template class Set_DL: public List_DLS { public: Set_DL(); Set_DL(const Set_DL& other); void add(const T& item) { list.append(item); } void remove(Pix& x, T& item) { list.remove(x, item); } void clear() { list.clear(); } bool contains(const T& item) const { return list.contains(item); } Pix search(const T& item) const { return list.search(item); } unsigned length() const { return list.length(); } Pix first() const { return list.first(); } void next(Pix& x) const { list.next(x); } T& operator()(Pix x) const { return list(x); } private: List_DLS list; }; template class Set_DLp: public List_DLSp { public: Set_DLp(); Set_DLp(const Set_DLp& other); void add(const T& item) { list.append(item); } void remove(Pix& x, T& item) { list.remove(x, item); } void clear() { list.clear(); } bool contains(const T& item) const { return list.contains(item); } Pix search(const T& item) const { return list.search(item); } unsigned length() const { return list.length(); } Pix first() const { return list.first(); } void next(Pix& x) const { list.next(x); } T& operator()(Pix x) const { return list(x); } private: List_DLSp list; }; template struct vertex { T item; List_DL *> fanout; vertex(): item(), fanout() // gets bogus error { }; vertex(const T& i): item(), fanout() // gets bogus error { }; }; template class Graph { public: Graph(); Graph(const Graph&); ~Graph(); void add(const T& from, const T& to); bool contains(const T& from, const T& to) const; void clear() { vertices.clear(); } unsigned lengthV() const { return vertices.length(); } Pix firstV() const { return vertices.first(); } void nextV(Pix& x) const { vertices.next(x); } T& V(Pix x) const { return vertices(x).item; } Pix firstV1(Pix vx) const; void nextV1(Pix vx, Pix& x) const; T& V1(Pix vx, Pix x) const; private: vertex *lookup(const T& from) const; vertex *lookup_new(const T& from); List_DLS > vertices; }; template Graph::Graph(): vertices() { } template Graph::Graph(const Graph& other): vertices() { for (Pix vx=firstV(); 0 != vx; nextV(vx)) { for (Pix vx1=firstV1(vx); 0 != vx1; nextV1(vx, vx1)) { add(V(vx), V1(vx, vx1)); } } } template Graph::~Graph() { clear(); } template void Graph::add(const T& from, const T& to) { vertex *fromv = lookup_new(from); if (from == to) return; vertex *tov = lookup_new(to); fromv->fanout.append(tov); } template bool Graph::contains(const T& from, const T& to) const { vertex *fromv = lookup(from); if (0 == fromv) return FALSE; for (Pix x=fromv->fanout.first(); 0 != x; fromv->fanout.next(x)) { if (fromv->fanout(x)->item == to) return TRUE; } return FALSE; } template vertex * Graph::lookup(const T& from) const { for (Pix x=vertices.first(); 0 != x; vertices.next(x)) { if (vertices(x).item == from) return &vertices(x); } return 0; } template vertex * Graph::lookup_new(const T& from) { vertex *v = lookup(from); if (0 == v) { vertices.append(from); return &vertices(vertices.last()); } return v; } template Pix Graph::firstV1(Pix vx) const { vertex *v = (vertex *) vx; return v->fanout.first(); } template void Graph::nextV1(Pix vx, Pix& x) const { vertex *v = (vertex *) vx; return v->fanout.next(x); } template T& Graph::V1(Pix vx, Pix x) const { vertex *v = (vertex *) vx; static T x1; return x1; } class STRLIdentifier; extern int x(List_DL); extern int x(List_DLS); extern int x(Set); extern int x(Set_DL); extern int x(Set_DLp); extern int x(Graph); class STRLIdentifier { char buf[10]; }; extern int operator==(vertex&, vertex&); // ERROR - const subversion extern int operator==(STRLIdentifier&, STRLIdentifier&); // ERROR - fn ref in err msg extern int x(List_DLSp); template class Graph; template class List_DLS >;