SmallList.h

Go to the documentation of this file.
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           // we're doing insert(end()); linear-time search
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           /* here = erase(here) -- but faster because we aren't at the head */
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

Generated on Thu Mar 27 19:04:15 2008 by  doxygen 1.4.6