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