00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 #ifndef _List_h_
00055 #define _List_h_
00056 
00057 #include <stdint.h>
00058 
00059 #include "ink_assert.h"
00060 #include "ink_queue.h"
00061 #include "Compatability.h"
00062 #include "defalloc.h"
00063 
00064 
00065 
00066 
00067 template <class C> class SLink {
00068  public:
00069   C *next;
00070   SLink() : next(NULL) {};
00071 };
00072 #define SLINK(_c,_f) class Link##_##_f : public SLink<_c> { public:    \
00073     static _c *& next_link(_c *c) { return c->_f.next; }                \
00074     static const _c * next_link(const _c *c) { return c->_f.next; } \
00075   }; SLink<_c> _f
00076 #define SLINKM(_c,_m,_f) class Link##_##_m##_##_f : public SLink<_c> { public: \
00077     static _c *& next_link(_c *c) { return c->_m._f.next; }             \
00078   };
00079 
00080 
00081 
00082 
00083 template <class C> struct Link : public SLink<C> {
00084   C *prev;
00085   Link() : prev(NULL) {}
00086 };
00087 #define LINK(_c,_f) class Link##_##_f : public Link<_c> { public:       \
00088     static _c *& next_link(_c *c) { return c->_f.next; }                \
00089     static _c *& prev_link(_c *c) { return c->_f.prev; }                \
00090     static const _c * next_link(const _c *c) { return c->_f.next; }     \
00091     static const _c * prev_link(const _c *c) { return c->_f.prev; }     \
00092   }; Link<_c> _f
00093 #define LINKM(_c,_m,_f) class Link##_##_m##_##_f : public Link<_c> { public:  \
00094     static _c *& next_link(_c *c) { return c->_m._f.next; }             \
00095     static _c *& prev_link(_c *c) { return c->_m._f.prev; }             \
00096   };
00097 #define LINK_FORWARD_DECLARATION(_c,_f) class Link##_##_c##_##_f : public Link<_c> { public:     \
00098     static _c *& next_link(_c *c);                                      \
00099     static _c *& prev_link(_c *c);                                      \
00100   };
00101 #define LINK_DEFINITION(_c,_f)  \
00102   inline _c *& Link##_##_c##_##_f::next_link(_c *c) { return c->_f.next; } \
00103   inline _c *& Link##_##_c##_##_f::prev_link(_c *c) { return c->_f.prev; } \
00104 
00105 
00106 
00107 
00108 template <class C, class L = typename C::Link_link> class SLL {
00109  public:
00110   C *head;
00111   bool empty() const { return head == NULL; }
00112   void push(C *e);
00113   C *pop();
00114   void clear() { head = NULL; }
00115   C *& next(C *e) { return L::next_link(e); }
00116   const C * next(const C *e) const { return L::next_link(e); }
00117 
00118   SLL() : head(NULL) {}
00119   SLL(C *c) : head(c) {}
00120 };
00121 #define SList(_c, _f)  SLL<_c, _c::Link##_##_f>
00122 #define SListM(_c, _m, _ml, _l) SLL<_c, _c::Link##_##_ml##_##_l>
00123 #define forl_LL(_c, _p, _l) for (_c *_p = (_l).head; _p; _p = (_l).next(_p))
00124 
00125 template <class C, class L> inline void
00126 SLL<C,L>::push(C *e) {
00127   next(e) = head;
00128   head = e;
00129 }
00130 
00131 template <class C, class L> inline C *
00132 SLL<C,L>::pop() {
00133   C *ret = head;
00134   if (ret) {
00135     head = next(ret);
00136     next(ret) = NULL;
00137   }
00138   return ret;
00139 }
00140 
00141 
00142 
00143 
00144 template <class C, class L = typename C::Link_link> struct DLL {
00145   C *head;
00146   bool empty() const { return head == NULL; }
00147   void push(C *e);
00148   C *pop();
00149   void remove(C *e);
00150   void insert(C *e, C *after);
00151   bool in(C *e) { return head == e || next(e) || prev(e); }
00152   void clear() { head = NULL; }
00153   static C *&next(C *e) { return reinterpret_cast<C*&>(L::next_link(e)); }
00154   static C *&prev(C *e) { return reinterpret_cast<C*&>(L::prev_link(e)); }
00155   static C const* next(const C *e) { return L::next_link(e); }
00156   static C const* prev(const C *e) { return L::prev_link(e); }
00157 
00158   DLL() : head(NULL) {}
00159 };
00160 #define DList(_c, _f)  DLL<_c, _c::Link##_##_f>
00161 #define DListM(_c, _m, _ml, _l) DLL<_c, _c::Link##_##_ml##_##_l>
00162 
00163 template <class C, class L> inline void
00164 DLL<C,L>::push(C *e) {
00165   if (head)
00166     prev(head) = e;
00167   next(e) = head;
00168   head = e;
00169 }
00170 
00171 template <class C, class L> inline void
00172 DLL<C,L>::remove(C *e) {
00173   if (!head) return;
00174   if (e == head) head = next(e);
00175   if (prev(e)) next(prev(e)) = next(e);
00176   if (next(e)) prev(next(e)) = prev(e);
00177   prev(e) = NULL;
00178   next(e) = NULL;
00179 }
00180 
00181 template <class C, class L> inline C *
00182 DLL<C,L>::pop() {
00183   C *ret = head;
00184   if (ret) {
00185     head = next(ret);
00186     if (head)
00187       prev(head) = NULL;
00188     next(ret) = NULL;
00189     return ret;
00190   } else
00191     return NULL;
00192 }
00193 
00194 template <class C, class L> inline void
00195 DLL<C,L>::insert(C *e, C *after) {
00196   if (!after) { push(e); return; }
00197   prev(e) = after;
00198   next(e) = next(after);
00199   next(after) = e;
00200   if (next(e)) prev(next(e)) = e;
00201 }
00202 
00203 
00204 
00205 
00206 template <class C, class L = typename C::Link_link> class Queue : public DLL<C,L> {
00207  public:
00208   using DLL<C,L>::head;
00209   C *tail;
00210   void push(C *e);
00211   C *pop();
00212   void enqueue(C *e);
00213   void in_or_enqueue(C *e);
00214   C *dequeue();
00215   void remove(C *e);
00216   void insert(C *e, C *after);
00217   void append(Queue<C,L> q);
00218   void append(DLL<C,L> q);
00219   void clear() { head = NULL; tail = NULL; }
00220   bool empty() const { return head == NULL; }
00221 
00222   Queue() : tail(NULL) {}
00223 };
00224 #define Que(_c, _f) Queue<_c, _c::Link##_##_f>
00225 #define QueM(_c, _m, _mf, _f) Queue<_c, _c::Link##_##_mf##_##_f>
00226 
00227 template <class C, class L> inline void
00228 Queue<C,L>::push(C *e) {
00229   DLL<C,L>::push(e);
00230   if (!tail) tail = head;
00231 }
00232 
00233 template <class C, class L> inline C *
00234 Queue<C,L>::pop() {
00235   C *ret = DLL<C,L>::pop();
00236   if (!head) tail = NULL;
00237   return ret;
00238 }
00239 
00240 template <class C, class L> inline void
00241 Queue<C,L>::insert(C *e, C *after) {
00242   DLL<C,L>::insert(e, after);
00243   if (!tail)
00244     tail = head;
00245   else if (tail == after)
00246     tail = e;
00247 }
00248 
00249 template <class C, class L> inline void
00250 Queue<C,L>::remove(C *e) {
00251   if (tail == e)
00252     tail = (C*)this->prev(e);
00253   DLL<C,L>::remove(e);
00254 }
00255 
00256 template <class C, class L> inline void
00257 Queue<C,L>::append(DLL<C,L> q) {
00258   C *qtail = q.head;
00259   if (qtail)
00260     while (this->next(qtail))
00261       qtail = this->next(qtail);
00262   if (!head) {
00263     head = q.head;
00264     tail = qtail;
00265   } else {
00266     if (q.head) {
00267       this->next(tail) = q.head;
00268       this->prev(q.head) = tail;
00269       tail = qtail;
00270     }
00271   }
00272 }
00273 
00274 template <class C, class L> inline void
00275 Queue<C,L>::append(Queue<C,L> q) {
00276   if (!head) {
00277     head = q.head;
00278     tail = q.tail;
00279   } else {
00280     if (q.head) {
00281       this->next(tail) = q.head;
00282       this->prev(q.head) = tail;
00283       tail = q.tail;
00284     }
00285   }
00286 }
00287 
00288 template <class C, class L> inline void
00289 Queue<C,L>::enqueue(C *e) {
00290   if (tail)
00291     insert(e, tail);
00292   else
00293     push(e);
00294 }
00295 
00296 template <class C, class L> inline void
00297 Queue<C,L>::in_or_enqueue(C *e) {
00298   if (!this->in(e)) enqueue(e);
00299 }
00300 
00301 template <class C, class L> inline C *
00302 Queue<C,L>::dequeue() {
00303   return pop();
00304 }
00305 
00306 
00307 
00308 
00309 
00310 template<class C, class L = typename C::Link_link> struct SortableQueue: public Queue<C,L>
00311 {
00312   using DLL<C,L>::head;
00313   using Queue<C,L>::tail;
00314   void sort() {
00315     if (!head) return;
00316     bool clean = false;
00317     while (!clean) {
00318       clean = true;
00319       C *v = head;
00320       C *n = this->next(head);
00321       while (n) {
00322         C *f = this->next(n);
00323         if (*n < *v) {
00324           clean = false;
00325           
00326           if (head == v)
00327             head = n;
00328           if (tail == n)
00329             tail = v;
00330           
00331           C *p = this->prev(v);
00332           if (p) {
00333             this->next(p) = n;
00334             this->prev(n) = p;
00335           } else
00336             this->prev(n) = NULL;
00337           
00338           if (f) {
00339             this->prev(f) = v;
00340             this->next(v) = f;
00341           } else
00342             this->next(v) = NULL;
00343           
00344           this->prev(v) = n;
00345           this->next(n) = v;
00346         } else
00347           v = n;
00348         n = f;
00349       }
00350     }
00351   }
00352 };
00353 #define SortableQue(_c, _l) SortableQueue<_c, _c::Link##_##_f>
00354 
00355 
00356 
00357 
00358 
00359 template <class C, class L = typename C::Link_link> struct CountQueue : public Queue<C,L> {
00360   int size;
00361   inline CountQueue(void) : size(0) {}
00362   inline void push(C *e);
00363   inline C *pop();
00364   inline void enqueue(C *e);
00365   inline C *dequeue();
00366   inline void remove(C *e);
00367   inline void insert(C *e, C *after);
00368   inline void append(CountQueue<C,L> &q);
00369   inline void append_clear(CountQueue<C,L> &q);
00370 };
00371 #define CountQue(_c, _f) CountQueue<_c, _c::Link##_##_f>
00372 #define CountQueM(_c, _m, _mf, _f) CountQueue<_c, _c::Link##_##_mf##_##_f>
00373 
00374 template <class C, class L> inline void
00375 CountQueue<C,L>::push(C *e) {
00376   Queue<C,L>::push(e);
00377   size++;
00378 }
00379 
00380 template <class C, class L> inline C *
00381 CountQueue<C,L>::pop() {
00382   C *ret = Queue<C,L>::pop();
00383   if (ret)
00384     size--;
00385   return ret;
00386 }
00387 
00388 template <class C, class L> inline void
00389 CountQueue<C,L>::remove(C *e) {
00390   Queue<C,L>::remove(e);
00391   size--;
00392 }
00393 
00394 template <class C, class L> inline void
00395 CountQueue<C,L>::enqueue(C *e) {
00396   Queue<C,L>::enqueue(e);
00397   size++;
00398 }
00399 
00400 template <class C, class L> inline C *
00401 CountQueue<C,L>::dequeue() {
00402   return pop();
00403 }
00404 
00405 template <class C, class L> inline void
00406 CountQueue<C,L>::insert(C *e, C *after) {
00407   Queue<C,L>::insert(e, after);
00408   size++;
00409 }
00410 
00411 template <class C, class L> inline void
00412 CountQueue<C,L>::append(CountQueue<C,L> &q) {
00413   Queue<C,L>::append(q);
00414   size += q.size;
00415 }
00416 
00417 template <class C, class L> inline void
00418 CountQueue<C,L>::append_clear(CountQueue<C,L> &q) {
00419   append(q);
00420   q.head = q.tail = 0;
00421   q.size = 0;
00422 }
00423 
00424 
00425 
00426 
00427 
00428 template <class C, class A = DefaultAlloc>
00429 struct ConsCell {
00430   C             car;
00431   ConsCell      *cdr;
00432   ConsCell(C acar, ConsCell *acdr) : car(acar), cdr(acdr) {}
00433   ConsCell(C acar) : car(acar), cdr(NULL) {}
00434   ConsCell(ConsCell *acdr) : cdr(acdr) {}
00435   static void *operator new(size_t size) { return A::alloc(size); }
00436   static void operator delete(void *p, size_t ) { A::free(p); }
00437 };
00438 
00439 template <class C, class A = DefaultAlloc>
00440 struct List {
00441   ConsCell<C,A> *head;
00442   C first() { if (head) return head->car; else return 0; }
00443   C car() { return first(); }
00444   ConsCell<C,A> *rest() { if (head) return head->cdr; else return 0; }
00445   ConsCell<C,A> *cdr() { return rest(); }
00446   void push(C a) { head = new ConsCell<C,A>(a, head); }
00447   void push() { head = new ConsCell<C,A>(head); }
00448   C pop() { C a = car(); head = cdr(); return a; }
00449   void clear() { head = NULL; }
00450   void reverse();
00451   List(C acar) : head(new ConsCell<C,A>(acar)) {}
00452   List(C a, C b) : head(new ConsCell<C,A>(a, new ConsCell<C,A>(b))) {}
00453   List(C a, C b, C c) : head(new ConsCell<C,A>(a, new ConsCell<C,A>(b, new ConsCell<C,A>(c)))) {}
00454   List() : head(0) {}
00455 };
00456 #define forc_List(_c, _p, _l) if ((_l).head) for (_c *_p  = (_l).head; _p; _p = _p->cdr)
00457 
00458 template <class C,class A> void
00459 List<C,A>::reverse() {
00460   ConsCell<C,A> *n, *t;
00461   for (ConsCell<C,A> *p = head; p; p = n) {
00462     n = p->cdr;
00463     p->cdr = t;
00464     t = p;
00465   }
00466   head = t;
00467 }
00468 
00469 
00470 
00471 
00472 
00473 template<class C, class L = typename C::Link_link> struct AtomicSLL
00474 {
00475   void push(C * c) { ink_atomiclist_push(&al, c); }
00476   C *pop() { return (C *) ink_atomiclist_pop(&al); }
00477   C *popall() { return (C *) ink_atomiclist_popall(&al); }
00478   bool empty() { return INK_ATOMICLIST_EMPTY(al); }
00479 
00480   
00481 
00482 
00483 
00484 
00485 
00486   C *remove(C * c) { return (C *) ink_atomiclist_remove(&al, c); }
00487   C *head() { return (C *) TO_PTR(FREELIST_POINTER(al.head)); }
00488   C *next(C * c) { return (C *) TO_PTR(c); }
00489 
00490   InkAtomicList al;
00491 
00492   AtomicSLL();
00493 };
00494 
00495 #define ASLL(_c, _l) AtomicSLL<_c, _c::Link##_##_l>
00496 #define ASLLM(_c, _m, _ml, _l) AtomicSLL<_c, _c::Link##_##_ml##_##_l>
00497 
00498 template<class C, class L> inline AtomicSLL<C,L>::AtomicSLL() {
00499   ink_atomiclist_init(&al, "AtomicSLL", (uint32_t)(uintptr_t)&L::next_link((C*)0));
00500 }
00501 
00502 #endif