From 210f77d2c32f14d2e99577fd3c9842bb19d47e50 Mon Sep 17 00:00:00 2001 From: Tuowen Zhao Date: Mon, 19 Sep 2016 21:14:58 +0000 Subject: Moved most modules into lib --- lib/omega/include/basic/Bag.h | 405 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 lib/omega/include/basic/Bag.h (limited to 'lib/omega/include/basic/Bag.h') diff --git a/lib/omega/include/basic/Bag.h b/lib/omega/include/basic/Bag.h new file mode 100644 index 0000000..a3d07a0 --- /dev/null +++ b/lib/omega/include/basic/Bag.h @@ -0,0 +1,405 @@ +#if ! defined _Bag_h +#define _Bag_h 1 + +#include +#include +#include +#include +#include + +namespace omega { + +template class Bag : public Collection { +public: +virtual ~Bag(); + Bag(); + Bag(const Bag&); + Bag & operator=(const Bag&); + //! add elements in b + virtual void operator |= (const Bag & b); + Iterator *new_iterator(); + bool empty() const; + void remove(T); + virtual void insert(T); + void clear(); + virtual bool contains(T) const; + int size() const; + T extract(); +// protected: breaks g++ 261 + List_Element* contents; +}; + + +template class Ordered_Bag : public Bag { +public: + Ordered_Bag(); + Ordered_Bag(const Ordered_Bag& B) : Bag(B) {} + void insert(T); + //! add elements in b + virtual void operator |= (const Ordered_Bag & b); + //! add elements in b + void operator |= (const Bag & b); + bool contains(T) const; + bool operator == (const Ordered_Bag&) const; + bool operator != (const Ordered_Bag&) const; + bool operator < (const Ordered_Bag&) const; +}; + +template class Set : public Ordered_Bag { +public: + Set(); + Set(T); + Set(const Set& S) : Ordered_Bag(S) {} + + bool contains (const Set& b) const; + bool contains (T t) const { return Ordered_Bag::contains(t); } + // the above makes "standard" C++ happy + + //! add elements in b + virtual void operator |= (const Set & b); + //! add elements in b + void operator |= (const Ordered_Bag & b); + //! add elements in b + void operator |= (const Bag & b); + + //! delete items also in b + void operator -= (const Set & b); + //! delete items not in b + void operator &= (const Set & b); + //! check for elements in common + bool operator & (const Set &) const; +}; + +} // namespace + +#define instantiate_Bag(T) template class Bag; \ + instantiate_List_Element(T); +#define instantiate_Ordered_Bag(T) template class Ordered_Bag; \ + instantiate_Bag(T) +#define instantiate_Set(T) template class Set; \ + instantiate_Ordered_Bag(T) + + +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 + +#endif -- cgit v1.2.3-70-g09d2