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/List.h | 233 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 lib/omega/include/basic/List.h (limited to 'lib/omega/include/basic/List.h') diff --git a/lib/omega/include/basic/List.h b/lib/omega/include/basic/List.h new file mode 100644 index 0000000..28ab1d5 --- /dev/null +++ b/lib/omega/include/basic/List.h @@ -0,0 +1,233 @@ +#if ! defined _List_h +#define _List_h 1 + +/* + * Linked lists with an interface like a bit of libg++'s SLList class + */ +#include // for NULL +#include +#include +#include +#include + +namespace omega { + +template class List_Iterator; + +// +// indexing of Lists starts at 1, index == 0 means not there +// + +template class List : public Sequence { +public: + List(const List &l) + { contents = l.contents ? new List_Element(*l.contents) : 0; } + List() { contents = 0; } + virtual ~List() { delete contents; } + + Iterator *new_iterator(); + const T &operator[](int) const; + T &operator[](int); + + int index(const T &) const; + + int size() const; + int length() const { return size(); } + bool empty() const { return size() == 0; } + + T &front() const; + +// insertion/deletion on a list invalidates any iterators +// that are on/after the element added/removed + + T remove_front(); + + void prepend(const T &item); + void append(const T &item); + void ins_after(List_Iterator i, const T &item); + + void del_front(); + void del_after(List_Iterator i); + void clear(); + + void join(List &consumed); + +private: + friend class List_Iterator; + List_Element **end() + { + List_Element **e = &contents; + while (*e) + e = &((*e)->tail); + return e; + } + + List_Element *contents; +}; + + +template class List_Iterator : public List_Element_Iterator { +public: + List_Iterator(List &l); + List_Iterator(const List &l); + List_Iterator(); +private: + List_Element &element() { return *List_Element_Iterator::i; } ; + friend class List; +}; + +} // namespace + +#define instantiate_List(T) template class List; \ + template class List_Iterator; \ + instantiate_Only_List_Element(T) \ + instantiate_Sequence(T) + +namespace omega { + +template List_Iterator::List_Iterator(List &l) +: List_Element_Iterator(l.contents) {} + +template List_Iterator::List_Iterator(const List &l) +: List_Element_Iterator(l.contents) {} + +template List_Iterator::List_Iterator() +: List_Element_Iterator(0) {} + +template Iterator *List::new_iterator() +{ + return new List_Iterator(*this); +} + +template const T &List::operator[](int i) const +{ + assert(i > 0 && "Subscript out of bounds"); + List_Iterator p(*this); + + while(--i > 0 && p) + p++; + + if (p) + return *p; + else + return *((T *)0); +} + +template T &List::operator[](int i) +{ + assert(i > 0 && "Subscript out of bounds"); + List_Iterator p(*this); + + while(--i > 0 && p) + p++; + + if (p) + return *p; + else + return *((T *)0); +} + +template int List::index(const T &item) const +{ + List_Iterator p(*this); + int i = 1; + + while(p && *p != item) + { + p++; + i++; + } + + if (p) + return i; + else + return 0; +} + +template int List::size() const + { + int i = 0; + List_Element * p = contents; + while (p) + { + p = p->tail; + i++; + } + return i; + } + +template T &List::front() const + { + return contents->head; + } + +template T List::remove_front() + { + List_Element *frunt = contents; + contents = contents->tail; + T fruntT = frunt->head; + frunt->tail = 0; + delete frunt; + return fruntT; + } + +template void List::prepend(const T &item) + { + contents = new List_Element(item, contents); + } + + +template void List::append(const T &item) + { + *(end()) = new List_Element(item, 0); + } + +template void List::ins_after(List_Iterator i, + const T &item) + { +#if ! defined NDEBUG + for (List_Element *e = contents; e != &(i.element()); e=e->tail) + { + assert(e); + } +#endif + i.element().tail = new List_Element(item, i.element().tail); + } + +template void List::del_front() + { + List_Element *e = contents; + contents = contents->tail; + e->tail = 0; + delete e; + } + +template void List::del_after(List_Iterator i) + { +#if ! defined NDEBUG + for (List_Element *e0 = contents; e0 != &(i.element()); e0=e0->tail) + { + assert(e0); + } +#endif + List_Element *e = i.element().tail; + i.element().tail = e->tail; + e->tail = 0; + delete e; + } + +template void List::clear() + { + delete contents; + contents = 0; + } + +template void List::join(List &consumed) + { + List_Element *e = consumed.contents; + consumed.contents = 0; + *(end()) = e; + } + +} // namespace +#endif -- cgit v1.2.3-70-g09d2