00001 #ifndef SmallList_HEADER
00002 #define SmallList_HEADER
00003
00004 #ifdef HAVE_CONFIG_H
00005 # include <config.h>
00006 #endif
00007
00008 #include "SmallMemoryPool.h"
00009 #include <boost/iterator/iterator_facade.hpp>
00010
00011 namespace hudson {
00012
00035 template <class Item> class SmallList
00036 : public SmallMemoryItem< SmallList<Item> > {
00037 struct Node : public SmallMemoryItem<Node> {
00038 Item item_;
00039 Node *next_;
00040
00041 Node(Node *next): item_(), next_(next) { }
00042
00043 template <class ItemCtorArg>
00044 Node(const ItemCtorArg& arg, Node *next): item_(arg), next_(next) { }
00045 };
00046
00047 Node *head_;
00048
00049 public:
00050 typedef Item value_type;
00051 typedef Item& reference;
00052 typedef const Item& const_reference;
00053
00054 SmallList() { head_ = NULL; }
00055 ~SmallList() { clear(); }
00056
00057 private:
00058 void assumed_cleared_copy(const SmallList& other) {
00059 if (other.empty()) {
00060 head_ = NULL;
00061 return;
00062 }
00063 Node *tail = new Node(other.head_->item_, NULL);
00064 head_ = tail;
00065 for(const_iterator it = ++other.begin(); it != other.end(); ++it) {
00066 Node *newtail = new Node(*it, NULL);
00067 tail->next_ = newtail;
00068 tail = newtail;
00069 }
00070 }
00071
00072 public:
00074 SmallList(const SmallList& other) {
00075 assumed_cleared_copy(other);
00076 }
00077
00079 SmallList& operator = (const SmallList& other) {
00080 clear();
00081 assumed_cleared_copy(other);
00082 }
00083
00084 bool empty() const { return head_ == NULL; }
00085
00086 void clear() {
00087 Node *cur = head_;
00088 while (cur) {
00089 Node *next = cur->next_;
00090 delete cur;
00091 cur = next;
00092 }
00093 head_ = NULL;
00094 }
00095
00096 template <class ItemCtorArg>
00097 void push_front(const ItemCtorArg& arg) {
00098 Node *n = new Node(arg, head_);
00099 head_ = n;
00100 }
00101 void push_front() {
00102 Node *n = new Node(head_);
00103 head_ = n;
00104 }
00105
00106 void pop_front() {
00107 assert(head_);
00108 Node *next = head_->next_;
00109 delete head_;
00110 head_ = next;
00111 }
00112
00113 const Item& front() const { assert(head_); return head_->item_; }
00114 Item& front() { assert(head_); return head_->item_; }
00115
00116 class iterator;
00117 class const_iterator;
00118
00119 class iterator : public boost::iterator_facade
00120 < iterator
00121 , Item
00122 , boost::forward_traversal_tag >
00123 {
00124 Node *prev_;
00125 Node *cur_;
00126 friend class SmallList;
00127 friend class const_iterator;
00128
00129 public:
00130 explicit iterator(Node *p, Node *c): prev_(p), cur_(c) { }
00131 void increment() { prev_ = cur_; cur_ = cur_->next_; }
00132 bool equal(const iterator& other) const { return cur_ == other.cur_; }
00133 Item& dereference() const { return cur_->item_; }
00134 };
00135
00136 iterator begin() { return iterator(NULL, head_); }
00137 iterator end() { return iterator(NULL, NULL); }
00138
00139 private:
00140 iterator insertNode(iterator it, Node *n) {
00141 if (it.prev_) {
00142 it.prev_->next_ = n;
00143 } else {
00144 if (it.cur_ != NULL || empty()) {
00145 head_ = n;
00146 } else {
00147
00148 it = begin();
00149 while (it.cur_) { ++it; }
00150 assert(it.prev_);
00151 it.prev_->next_ = n;
00152 }
00153 }
00154 return iterator(it.prev_, n);
00155 }
00156 public:
00157
00158 template <class ItemCtorArg>
00159 iterator insert(iterator it, const ItemCtorArg& arg) {
00160 Node *n = new Node(arg, it.cur_);
00161 return insertNode(it, n);
00162 }
00163
00164 iterator insert(iterator it) {
00165 Node *n = new Node(it.cur_);
00166 return insertNode(it, n);
00167 }
00168
00169 iterator erase(iterator it) {
00170 Node *next = it.cur_->next_;
00171 assert(it.cur_);
00172 if (it.prev_) {
00173 it.prev_->next_ = next;
00174 } else {
00175 head_ = next;
00176 }
00177 delete it.cur_;
00178 return iterator(it.prev_, next);
00179 }
00180
00181
00182 class const_iterator : public boost::iterator_facade
00183 < const_iterator
00184 , Item
00185 , boost::forward_traversal_tag >
00186 {
00187 Node *cur_;
00188 public:
00189 explicit const_iterator(Node *head): cur_(head) { }
00190 const_iterator(iterator it): cur_(it.cur_) { }
00191 void increment() { cur_ = cur_->next_; }
00192 bool equal(const const_iterator& other) const { return cur_ == other.cur_; }
00193 Item& dereference() const { return cur_->item_; }
00194 };
00195
00196 const_iterator begin() const { return const_iterator(head_); }
00197 const_iterator end() const { return const_iterator(NULL); }
00198
00199
00201 void swap(SmallList& other) {
00202 Node *temp = head_;
00203 head_ = other.head_;
00204 other.head_ = temp;
00205 }
00206
00208 void reverse() {
00209 Node *cur = head_;
00210 Node *prev = NULL;
00211 while(cur) {
00212 Node *next = cur->next_;
00213 cur->next_ = prev;
00214 prev = cur;
00215 cur = next;
00216 }
00217 head_ = prev;
00218 }
00219
00225 void merge(SmallList& other) {
00226 if (empty()) {
00227 swap(other);
00228 return;
00229 }
00230
00231 iterator here = begin();
00232 Node *there = other.head_;
00233 while (there) {
00234 while(*here < there->item_) {
00235 ++here;
00236 }
00237 Node *nextthere = there->next_;
00238 there->next_ = here.cur_;
00239 here = insertNode(here, there);
00240 there = nextthere;
00241 }
00242 other.head_ = 0;
00243 }
00244
00248 void unique() {
00249 if (empty()) { return; }
00250
00251 iterator here = ++begin();
00252 while (here != end()) {
00253 if (here.prev_->item_ == here.cur_->item_) {
00254
00255 Node *next = here.cur_->next_;
00256 delete here.cur_;
00257 here.cur_ = next;
00258 here.prev_->next_ = next;
00259 } else {
00260 ++here;
00261 }
00262 }
00263 }
00264
00265
00266 };
00267 }
00268
00269 #endif