// Code from ftp://ftp.aw.com/cp/koenig/code.tar.Z // in conjunction with the book \emph{Ruminations on C++}. /* *********************************************** Copyright, 1997 AT&T Corporation. All rights reserved. Permission is granted for individuals to use this material for educational purposes in connection with the book Ruminations on C++, Addison-Wesley, 1997, ISBN 0-201-42339-1. ************************************************** */ template Seq Seq::tl() const { if (item) return Seq(item->next, len-1); else throw "tl of an empty Seq"; } template Seq_item::Seq_item(const T& t, Seq_item* s): use(1), data(t), next(s) { if (s) s->use++; } template T Seq::hd() const { if (item) return item->data; else throw "hd of an empty Seq"; } template Seq& Seq::operator=(const Seq& s) { if (s.item) s.item->use++; destroy(item); item = s.item; len = s.len; return *this; } template void Seq::destroy(Seq_item* item) { while (item && --item->use == 0) { Seq_item* next = item->next; delete item; item = next; } } template Seq& Seq::operator++() { if (item) { Seq_item* p = item->next; if (p) p->use++; if (--item->use == 0) delete item; item = p; } return *this; } template Seq Seq::operator++(int) { Seq ret = *this; if (item) { --item->use; item = item->next; if (item) item->use++; } return ret; } template Seq& Seq::insert(const T& t) { item = new Seq_item(t, item); return *this; } template Seq_item* Seq::owntail() { if (item == 0) return 0; Seq_item* i = item; Seq_item** p = &item; while (i->use == 1) { if (i->next == 0) return i; p = &i->next; i = i->next; } *p = new Seq_item (i->data); --i->use; i = i->next; Seq_item* j = *p; while (i) { j->next = new Seq_item (i->data); i = i->next; j = j->next; } return j; } template Seq& Seq::flip() { if (item) { Seq_item* k = owntail(); Seq_item* curr = item; Seq_item* behind = 0; do { Seq_item* ahead = curr->next; curr->next = behind; behind = curr; curr = ahead; } while (curr); item = k; } return *this; } template int operator==(const Seq& op1, const Seq& op2) { if (op1.length() != op2.length()) return 0; Seq_item*p = op1.item; Seq_item*q = op2.item; while (p != q) { assert (p != 0 && q != 0); if (*p++ != *q++) return 1; } return 0; } template Seq cons(const T& t, const Seq& s) { return Seq(t, s); }