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 # ifndef DLINK_H
00045 # define DLINK_H
00046
00047 # include <aleph.H>
00048
00049 using namespace Aleph;
00050
00051 namespace Aleph {
00052
00066 class Dlink
00067 {
00068 protected:
00069 mutable Dlink * prev;
00070 mutable Dlink * next;
00071
00072 public:
00073
00074 Dlink() : prev(this), next(this) { }
00076 Dlink(const Dlink &) { reset(); }
00077
00086 Dlink & operator = (const Dlink & l)
00087 {
00088
00089 if (this == &l)
00090 return *this;
00091
00092 if (not is_empty())
00093 throw std::invalid_argument ("left list must be empty");
00094
00095 reset();
00096
00097 return *this;
00098 }
00099 void reset()
00100 {
00101
00102 I(this != NULL);
00103
00104 next = prev = this;
00105 }
00110 void swap(Dlink * link)
00111 {
00112 if (is_empty() and link->is_empty())
00113 return;
00114
00115 if (is_empty())
00116 {
00117 link->next->prev = this;
00118 link->prev->next = this;
00119 next = link->next;
00120 prev = link->prev;
00121 link->reset();
00122
00123 return;
00124 }
00125
00126 if (link->is_empty())
00127 {
00128 next->prev = link;
00129 prev->next = link;
00130 link->next = next;
00131 link->prev = prev;
00132 reset();
00133
00134 return;
00135 }
00136
00137 Aleph::swap(prev->next, link->prev->next);
00138 Aleph::swap(next->prev, link->next->prev);
00139 Aleph::swap(prev, link->prev);
00140 Aleph::swap(next, link->next);
00141 }
00143 bool is_empty() const { return this == next and this == prev; }
00144
00146 bool is_unitarian() const { return this != next and next == prev; }
00147
00149 bool is_unitarian_or_empty() const { return next == prev; }
00155 void insert(Dlink * node)
00156 {
00157
00158 I((this != NULL) and (next != NULL) and (prev != NULL));
00159 I(node != NULL);
00160 I(node->is_empty());
00161
00162 node->prev = this;
00163 node->next = next;
00164 next->prev = node;
00165 next = node;
00166 }
00171 void append(Dlink * node)
00172 {
00173
00174 I((this != NULL) and (next != NULL) and (prev != NULL));
00175 I(node != NULL);
00176 I(node->is_empty());
00177
00178 node->next = this;
00179 node->prev = prev;
00180 prev->next = node;
00181 prev = node;
00182 }
00184 Dlink *& get_next()
00185 {
00186
00187 I((this != NULL) and (next != NULL) and (prev != NULL));
00188
00189 return next;
00190 }
00191
00193 Dlink *& get_prev()
00194 {
00195
00196 I((this != NULL) and (next != NULL) and (prev != NULL));
00197
00198 return prev;
00199 }
00209 void insert_list(Dlink * head)
00210 {
00211 if (head->is_empty())
00212 return;
00213
00214 head->prev->next = next;
00215 head->next->prev = this;
00216 next->prev = head->prev;
00217 next = head->next;
00218 head->reset();
00219 }
00220
00230 void append_list(Dlink * head)
00231 {
00232 if (head->is_empty())
00233 return;
00234
00235 head->next->prev = prev;
00236 head->prev->next = this;
00237 prev->next = head->next;
00238 prev = head->prev;
00239 head->reset();
00240 }
00250 void concat_list(Dlink * head)
00251 {
00252
00253 I(head != NULL);
00254
00255 if (head->is_empty())
00256 return;
00257
00258 if (this->is_empty())
00259 {
00260 swap(head);
00261
00262 return;
00263 }
00264
00265 prev->next = head->next;
00266 head->next->prev = prev;
00267 prev = head->prev;
00268 head->prev->next = this;
00269
00270 head->reset();
00271 }
00272 void del()
00273 {
00274
00275 I((this != NULL) and (next != NULL) and (prev != NULL));
00276
00277 prev->next = next;
00278 next->prev = prev;
00279 reset();
00280 }
00287 Dlink * remove_prev()
00288 {
00289
00290 I((this != NULL) and (next != NULL) and (prev != NULL));
00291 I(prev != this);
00292 I(next != this);
00293
00294 Dlink* retValue = prev;
00295 retValue->del();
00296
00297 return retValue;
00298 }
00299
00300 Dlink * remove_next()
00301 {
00302
00303 I((this != NULL) and (next != NULL) and (prev != NULL));
00304 I(prev != this);
00305 I(next != this);
00306
00307 Dlink* retValue = next;
00308 retValue->del();
00309
00310 return retValue;
00311 }
00317 int reverse_list()
00318 {
00319 if (is_empty())
00320 return 0;
00321
00322 Dlink tmp_head;
00323
00324 int counter = 0;
00325
00326
00327 while (not is_empty())
00328 {
00329 Dlink * current = remove_next();
00330
00331 tmp_head.insert(current);
00332
00333 counter++;
00334 }
00335
00336
00337 swap(&tmp_head);
00338
00339 return counter;
00340 }
00356 size_t split_list(Dlink & l, Dlink & r)
00357 {
00358
00359 I(l.is_empty() and r.is_empty());
00360
00361 size_t count = 0;
00362
00363 while (not is_empty())
00364 {
00365 l.append(remove_next()); ++count;
00366
00367 if (is_empty())
00368 break;
00369
00370 r.insert(remove_prev()); ++count;
00371 }
00372
00373 return count;
00374 }
00389 void cut_list(Dlink * link, Dlink * list)
00390 {
00391
00392 I(list->is_empty());
00393
00394
00395 list->prev = prev;
00396 list->next = link;
00397
00398
00399 prev = link->prev;
00400 link->prev->next = this;
00401
00402 link->prev = list;
00403 list->prev->next = list;
00404 }
00409 class Iterator
00410 {
00411
00412 private:
00413
00414 Dlink * head;
00415 Dlink * curr;
00416
00417 public:
00418
00427 Iterator(Dlink * head_ptr) : head(head_ptr), curr(head->get_next())
00428 {
00429
00430 }
00431
00439 Iterator(Dlink & _head) : head(&_head), curr(head->get_next())
00440 {
00441
00442 }
00443
00455 Iterator(Dlink * head_ptr, Dlink * curr_ptr) : head(head_ptr), curr(curr_ptr)
00456 {
00457
00458 }
00459
00467 Iterator(const Iterator & itor) : head(itor.head), curr(itor.curr)
00468 {
00469
00470 }
00471
00473 Iterator() : head(NULL), curr(NULL) { }
00474
00482 Iterator & operator = (const Iterator & itor)
00483 {
00484
00485 if (this == &itor)
00486 return *this;
00487
00488 head = itor.head;
00489 curr = itor.curr;
00490
00491 return *this;
00492 }
00493
00502 Iterator & operator = (Dlink * head_ptr)
00503 {
00504 head = head_ptr;
00505 curr = head->get_next();
00506
00507 return *this;
00508 }
00509
00510 void reset_first()
00511 {
00512
00513 I(curr != NULL and head != NULL);
00514
00515 curr = head->get_next();
00516 }
00517
00518 void reset_last()
00519 {
00520
00521 I(curr != NULL and head != NULL);
00522
00523 curr = head->get_prev();
00524 }
00535 void set(Dlink * new_curr)
00536 {
00537
00538 I(curr != NULL and head != NULL);
00539
00540 curr = new_curr;
00541 }
00542
00553 void reset(Dlink * new_head, Dlink * new_curr)
00554 {
00555 head = new_head;
00556 curr = new_curr;
00557 }
00558
00559
00568 void reset(Dlink * new_head)
00569 {
00570 head = new_head;
00571 curr = head->get_next();;
00572 }
00574 bool has_current() const
00575 {
00576
00577 I(curr != NULL and head != NULL);
00578
00579 return curr != head;
00580 }
00581
00583 Dlink * get_current() const
00584 {
00585
00586 I(curr != NULL and head != NULL);
00587
00588 if (not has_current())
00589 throw std::overflow_error("Not element in list");
00590
00591 return curr;
00592 }
00593
00595 bool is_in_first() const
00596 {
00597 return curr == head->next;
00598 }
00599
00601 bool is_in_last() const
00602 {
00603 return curr == head->prev;
00604 }
00606 void prev() throw(std::exception, std::underflow_error)
00607 {
00608 if (not has_current())
00609 throw std::underflow_error("Not previous element in list");
00610
00611 curr = curr->get_prev();
00612 }
00613
00615 void next() throw(std::exception, std::overflow_error)
00616 {
00617 if (not has_current())
00618 throw std::overflow_error("Not next element in list");
00619
00620 curr = curr->get_next();
00621 }
00623 bool operator == (const Iterator & it) const
00624 {
00625 return curr == it.curr;
00626 }
00627
00629 bool operator != (const Iterator & it) const
00630 {
00631 return curr != it.curr;
00632 }
00638 Dlink * del()
00639 {
00640
00641 I(curr != NULL and head != NULL);
00642 I(has_current());
00643
00644 Dlink * current = get_current();
00645 next();
00646 current->del();
00647
00648 return current;
00649 }
00650 bool verify(Dlink * l) const { return head == l; }
00651
00652 bool verify(const Iterator & it) const { return head == it.head; }
00653 };
00658 void remove_all_and_delete()
00659 {
00660 Dlink * node;
00661 Iterator itor(this);
00662
00663
00664 while (itor.has_current())
00665 {
00666 node = itor.get_current();
00667 itor.next();
00668 node->del();
00669 delete node;
00670 }
00671 }
00672 bool check()
00673 {
00674 Iterator itor(this);
00675 Dlink* node;
00676
00677 for (; itor.has_current(); itor.next())
00678 {
00679 node = itor.get_current();
00680 if (not (node->get_next()->get_prev() == node))
00681 return false;
00682 if (not (node->get_prev()->get_next() == node))
00683 return false;
00684 }
00685
00686 for (itor.reset_last(); itor.has_current(); itor.prev())
00687 {
00688 node = itor.get_current();
00689 if (not (node->get_next()->get_prev() == node))
00690 return false;
00691 if (not (node->get_prev()->get_next() == node))
00692 return false;
00693 }
00694
00695 return true;
00696 }
00697 };
00698
00726 # define DLINK_TO_TYPE(type_name, link_name) \
00727 inline static type_name * dlink_to_##type_name(Dlink * link) \
00728 { \
00729 type_name * ptr_zero = 0; \
00730 size_t offset_link = reinterpret_cast<size_t>(&(ptr_zero->link_name)); \
00731 char * address_type = reinterpret_cast<char*>(link) - offset_link; \
00732 return reinterpret_cast<type_name *>(address_type); \
00733 }
00734
00772 # define LINKNAME_TO_TYPE(type_name, link_name) \
00773 inline static type_name * link_name##_to_##type_name(Dlink * link) \
00774 { \
00775 type_name * ptr_zero = 0; \
00776 size_t offset_link = reinterpret_cast<size_t>(&(ptr_zero->link_name)); \
00777 char * address_type = reinterpret_cast<char*>(link) - offset_link; \
00778 return reinterpret_cast<type_name *>(address_type); \
00779 }
00780
00781 }
00782 # endif
00783