/**************************************************************** * * * Collection constructors, desctructors, assignments * * * ****************************************************************/ #include namespace omega { template Bag::Bag() { contents = new List_Element ; contents->tail = 0; } template Bag::~Bag() { delete contents; } template Ordered_Bag::Ordered_Bag() {} template Set::Set() {} template Bag::Bag(const Bag &L) { contents = new List_Element(*L.contents); } template Bag & Bag::operator=(const Bag &L) { if (this != &L) { delete contents; contents = new List_Element(*L.contents); } return *this; } template Set::Set(T e) { assert(this->contents); this->contents->tail = new List_Element(e, 0); } /**************************************************************** * * * Misc. simple Collection operations * * * ****************************************************************/ template bool Bag::empty() const { return contents->tail == 0; } template Iterator *Bag::new_iterator() { return new List_Element_Iterator(contents->tail); } template void Bag::clear() { if (contents->tail) delete contents->tail; contents->tail = 0; } template int Bag::size() const { int i = 0; List_Element * p = contents->tail; while (p) { p = p->tail; i++; }; return i; } /**************************************************************** * * * Collection/Element operations (e.g. insert, contains) * * * ****************************************************************/ template void Bag::remove(T e) { List_Element * p = contents; while (p->tail && p->tail->head != e) p = p->tail; if (p->tail && p->tail->head == e) { List_Element * q = p->tail; p->tail = q->tail; q->tail = 0; delete q; } } template T Bag::extract() { List_Element * p = contents->tail; T e = p->head; contents->tail = p->tail; p->tail = 0; delete p; return e; } template void Bag::insert(T e) { List_Element * q = new List_Element(e,contents->tail); contents->tail = q; } template void Ordered_Bag::insert(T e) { List_Element * p = this->contents; while (p->tail && p->tail->head < e) p = p->tail; if (!p->tail || p->tail->head != e) { List_Element * q = new List_Element(e,p->tail); p->tail = q; } } template bool Bag::contains(T e) const { List_Element * p = contents; while (p->tail && p->tail->head != e) p = p->tail; return (p->tail && p->tail->head == e); } template bool Ordered_Bag::contains(T e) const { List_Element * p = this->contents; while (p->tail && p->tail->head < e) p = p->tail; return (p->tail && p->tail->head == e); } template bool Set::contains (const Set& b) const { List_Element * p = this->contents; List_Element * q = b.contents; do { /* consume matched elements in p and q */ p = p->tail; q = q->tail; if (!q) return 1; /* no more elements to match */ if (!p) return 0; /* nothing left in p to match with */ if (q->head < p->head) { /* nothing smaller than p->head left in p, so q->head can't be matched */ return 0; }; while (p && p->head < q->head) { /* toss away some elements from p */ p = p->tail; } if (!p || q->head < p->head) return 0; } while (q); return 1; } /**************************************************************** * * * Collection/Collection operations (e.g. |=) * * * ****************************************************************/ template void Bag::operator |= (const Bag & b) { assert(this != &b); List_Element * q = b.contents->tail; while (q) { List_Element * r = new List_Element(q->head,contents->tail); contents->tail = r; q = q->tail; } } template void Ordered_Bag::operator |= (const Ordered_Bag & b) { if (this == &b) return; List_Element * p = this->contents; List_Element * q = b.contents->tail; while (q) { while (p->tail && p->tail->head < q->head) p = p->tail; List_Element * r = new List_Element(q->head,p->tail); p->tail = r; q = q->tail; } } template void Ordered_Bag::operator |= (const Bag & b) { Ordered_Bag tmp; for (List_Element *p = b.contents; p; p=p->tail) { tmp.insert(p->head); } *this |= tmp; } template void Set::operator |= (const Set & b) { if (this == &b) return; List_Element * p = this->contents; List_Element * q = b.contents->tail; while (q) { while (p->tail && p->tail->head < q->head) p = p->tail; if (!p->tail || p->tail->head != q->head) { List_Element * r = new List_Element(q->head,p->tail); p->tail = r; } q = q->tail; } } template void Set::operator |= (const Ordered_Bag & b) { Set tmp; for (List_Element *p = b.contents; p; p=p->tail) { tmp.insert(p->head); } *this |= tmp; } template void Set::operator |= (const Bag & b) { Set tmp; for (List_Element *p = b.contents; p; p=p->tail) { tmp.insert(p->head); } *this |= tmp; } // delete items also in b template void Set::operator -= (const Set & b) { if (this == &b) { this->clear(); return; } List_Element * p = this->contents; List_Element * q = b.contents->tail; while (q) { while (p->tail && p->tail->head < q->head) p = p->tail; if (p->tail && p->tail->head == q->head) { List_Element * r = p->tail; p->tail = r->tail; r->tail = 0; delete r; } q = q->tail; } } // delete items not in b template void Set::operator &= (const Set & b) { if (this == &b) return; List_Element * p = this->contents; List_Element * q = b.contents->tail; while (q) { while (p->tail && p->tail->head < q->head) { List_Element * r = p->tail; p->tail = r->tail; r->tail = 0; delete r; }; if (p->tail && p->tail->head == q->head) { /* allow p->tail->head into the result */ p = p->tail; } /* q->head has matched anything it is going to match */ q = q->tail; } if (p->tail) { delete p->tail; p->tail = 0; }; } template bool Set::operator & (const Set& b) const { List_Element * p = this->contents; List_Element * q = b.contents; do { p = p->tail; q = q->tail; while (p && q && p->head != q->head) { while (p && p->head < q->head) p = p->tail; while (p && q && q->head < p->head) q = q->tail; }; if (p && q && p->head == q->head) return 1; } while (p && q); return 0; } template bool Ordered_Bag::operator == (const Ordered_Bag& b) const { List_Element * p = this->contents; List_Element * q = b.contents; while (1) { p = p->tail; q = q->tail; if (!p && !q) return 1; if (!p || !q) return 0; if (p->head != q->head) return 0; }; } template bool Ordered_Bag::operator != (const Ordered_Bag& b) const { return !(*this == b); } template bool Ordered_Bag::operator < (const Ordered_Bag& b) const { List_Element * p = this->contents; List_Element * q = b.contents; while (1) { p = p->tail; q = q->tail; if (!p && !q) return 0; if (!p) return 1; if (!q) return 0; if (p->head < q->head) return 1; if (q->head < p->head) return 0; }; return 1; } } // namespace