00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef CLST_H
00021 #define CLST_H
00022
00023 #include <stdio.h>
00024 #include "host.h"
00025 #include "serialis.h"
00026 #include "lsterr.h"
00027
00028 class CLIST_ITERATOR;
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 class DLLSYM CLIST_LINK
00041 {
00042 friend class CLIST_ITERATOR;
00043 friend class CLIST;
00044
00045 CLIST_LINK *next;
00046 void *data;
00047
00048 public:
00049 CLIST_LINK() {
00050 data = next = NULL;
00051 }
00052
00053 CLIST_LINK(
00054 const CLIST_LINK &) {
00055 data = next = NULL;
00056 }
00057
00058 void operator= (
00059 const CLIST_LINK &) {
00060 data = next = NULL;
00061 }
00062 };
00063
00064
00065
00066
00067
00068
00069
00070 class DLLSYM CLIST
00071 {
00072 friend class CLIST_ITERATOR;
00073
00074 CLIST_LINK *last;
00075
00076 CLIST_LINK *First() {
00077 return last != NULL ? last->next : NULL;
00078 }
00079
00080 public:
00081 CLIST() {
00082 last = NULL;
00083 }
00084
00085 ~CLIST () {
00086 shallow_clear();
00087 }
00088
00089 void internal_deep_clear (
00090 void (*zapper) (void *));
00091
00092 void shallow_clear();
00093
00094
00095 bool empty() const {
00096 return !last;
00097 }
00098
00099 bool singleton() const {
00100 return last != NULL ? (last == last->next) : false;
00101 }
00102
00103 void shallow_copy(
00104 CLIST *from_list) {
00105 last = from_list->last;
00106 }
00107
00108 void assign_to_sublist(
00109 CLIST_ITERATOR *start_it,
00110 CLIST_ITERATOR *end_it);
00111
00112 inT32 length() const;
00113
00114 void sort (
00115 int comparator (
00116 const void *, const void *));
00117
00118
00119
00120
00121
00122
00123
00124
00125 bool add_sorted(int comparator(const void*, const void*),
00126 bool unique, void* new_data);
00127
00128
00129
00130
00131
00132
00133 void set_subtract(int comparator(const void*, const void*), bool unique,
00134 CLIST* minuend, CLIST* subtrahend);
00135
00136 };
00137
00138
00139
00140
00141
00142
00143
00144 class DLLSYM CLIST_ITERATOR
00145 {
00146 friend void CLIST::assign_to_sublist(CLIST_ITERATOR *, CLIST_ITERATOR *);
00147
00148 CLIST *list;
00149 CLIST_LINK *prev;
00150 CLIST_LINK *current;
00151 CLIST_LINK *next;
00152 BOOL8 ex_current_was_last;
00153
00154 BOOL8 ex_current_was_cycle_pt;
00155
00156 CLIST_LINK *cycle_pt;
00157
00158 BOOL8 started_cycling;
00159
00160
00161 CLIST_LINK *extract_sublist(
00162 CLIST_ITERATOR *other_it);
00163
00164 public:
00165 CLIST_ITERATOR() {
00166 list = NULL;
00167 }
00168
00169 CLIST_ITERATOR(
00170 CLIST *list_to_iterate);
00171
00172 void set_to_list(
00173 CLIST *list_to_iterate);
00174
00175 void add_after_then_move(
00176 void *new_data);
00177
00178 void add_after_stay_put(
00179 void *new_data);
00180
00181 void add_before_then_move(
00182 void *new_data);
00183
00184 void add_before_stay_put(
00185 void *new_data);
00186
00187 void add_list_after(
00188 CLIST *list_to_add);
00189
00190 void add_list_before(
00191 CLIST *list_to_add);
00192
00193 void *data() {
00194 #ifndef NDEBUG
00195 if (!list)
00196 NO_LIST.error ("CLIST_ITERATOR::data", ABORT, NULL);
00197 if (!current)
00198 NULL_DATA.error ("CLIST_ITERATOR::data", ABORT, NULL);
00199 #endif
00200 return current->data;
00201 }
00202
00203 void *data_relative(
00204 inT8 offset);
00205
00206 void *forward();
00207
00208 void *extract();
00209
00210 void *move_to_first();
00211
00212 void *move_to_last();
00213
00214 void mark_cycle_pt();
00215
00216 BOOL8 empty() {
00217 #ifndef NDEBUG
00218 if (!list)
00219 NO_LIST.error ("CLIST_ITERATOR::empty", ABORT, NULL);
00220 #endif
00221 return list->empty ();
00222 }
00223
00224 BOOL8 current_extracted() {
00225 return !current;
00226 }
00227
00228 BOOL8 at_first();
00229
00230 BOOL8 at_last();
00231
00232 BOOL8 cycled_list();
00233
00234 void add_to_end(
00235 void *new_data);
00236
00237 void exchange(
00238 CLIST_ITERATOR *other_it);
00239
00240 inT32 length();
00241
00242 void sort (
00243 int comparator (
00244 const void *, const void *));
00245
00246 };
00247
00248
00249
00250
00251
00252
00253
00254
00255 inline void CLIST_ITERATOR::set_to_list(
00256 CLIST *list_to_iterate) {
00257 #ifndef NDEBUG
00258 if (!this)
00259 NULL_OBJECT.error ("CLIST_ITERATOR::set_to_list", ABORT, NULL);
00260 if (!list_to_iterate)
00261 BAD_PARAMETER.error ("CLIST_ITERATOR::set_to_list", ABORT,
00262 "list_to_iterate is NULL");
00263 #endif
00264
00265 list = list_to_iterate;
00266 prev = list->last;
00267 current = list->First ();
00268 next = current != NULL ? current->next : NULL;
00269 cycle_pt = NULL;
00270 started_cycling = FALSE;
00271 ex_current_was_last = FALSE;
00272 ex_current_was_cycle_pt = FALSE;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282 inline CLIST_ITERATOR::CLIST_ITERATOR(CLIST *list_to_iterate) {
00283 set_to_list(list_to_iterate);
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 inline void CLIST_ITERATOR::add_after_then_move(
00295 void *new_data) {
00296 CLIST_LINK *new_element;
00297
00298 #ifndef NDEBUG
00299 if (!this)
00300 NULL_OBJECT.error ("CLIST_ITERATOR::add_after_then_move", ABORT, NULL);
00301 if (!list)
00302 NO_LIST.error ("CLIST_ITERATOR::add_after_then_move", ABORT, NULL);
00303 if (!new_data)
00304 BAD_PARAMETER.error ("CLIST_ITERATOR::add_after_then_move", ABORT,
00305 "new_data is NULL");
00306 #endif
00307
00308 new_element = new CLIST_LINK;
00309 new_element->data = new_data;
00310
00311 if (list->empty ()) {
00312 new_element->next = new_element;
00313 list->last = new_element;
00314 prev = next = new_element;
00315 }
00316 else {
00317 new_element->next = next;
00318
00319 if (current) {
00320 current->next = new_element;
00321 prev = current;
00322 if (current == list->last)
00323 list->last = new_element;
00324 }
00325 else {
00326 prev->next = new_element;
00327 if (ex_current_was_last)
00328 list->last = new_element;
00329 if (ex_current_was_cycle_pt)
00330 cycle_pt = new_element;
00331 }
00332 }
00333 current = new_element;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 inline void CLIST_ITERATOR::add_after_stay_put(
00345 void *new_data) {
00346 CLIST_LINK *new_element;
00347
00348 #ifndef NDEBUG
00349 if (!this)
00350 NULL_OBJECT.error ("CLIST_ITERATOR::add_after_stay_put", ABORT, NULL);
00351 if (!list)
00352 NO_LIST.error ("CLIST_ITERATOR::add_after_stay_put", ABORT, NULL);
00353 if (!new_data)
00354 BAD_PARAMETER.error ("CLIST_ITERATOR::add_after_stay_put", ABORT,
00355 "new_data is NULL");
00356 #endif
00357
00358 new_element = new CLIST_LINK;
00359 new_element->data = new_data;
00360
00361 if (list->empty ()) {
00362 new_element->next = new_element;
00363 list->last = new_element;
00364 prev = next = new_element;
00365 ex_current_was_last = FALSE;
00366 current = NULL;
00367 }
00368 else {
00369 new_element->next = next;
00370
00371 if (current) {
00372 current->next = new_element;
00373 if (prev == current)
00374 prev = new_element;
00375 if (current == list->last)
00376 list->last = new_element;
00377 }
00378 else {
00379 prev->next = new_element;
00380 if (ex_current_was_last) {
00381 list->last = new_element;
00382 ex_current_was_last = FALSE;
00383 }
00384 }
00385 next = new_element;
00386 }
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 inline void CLIST_ITERATOR::add_before_then_move(
00398 void *new_data) {
00399 CLIST_LINK *new_element;
00400
00401 #ifndef NDEBUG
00402 if (!this)
00403 NULL_OBJECT.error ("CLIST_ITERATOR::add_before_then_move", ABORT, NULL);
00404 if (!list)
00405 NO_LIST.error ("CLIST_ITERATOR::add_before_then_move", ABORT, NULL);
00406 if (!new_data)
00407 BAD_PARAMETER.error ("CLIST_ITERATOR::add_before_then_move", ABORT,
00408 "new_data is NULL");
00409 #endif
00410
00411 new_element = new CLIST_LINK;
00412 new_element->data = new_data;
00413
00414 if (list->empty ()) {
00415 new_element->next = new_element;
00416 list->last = new_element;
00417 prev = next = new_element;
00418 }
00419 else {
00420 prev->next = new_element;
00421 if (current) {
00422 new_element->next = current;
00423 next = current;
00424 }
00425 else {
00426 new_element->next = next;
00427 if (ex_current_was_last)
00428 list->last = new_element;
00429 if (ex_current_was_cycle_pt)
00430 cycle_pt = new_element;
00431 }
00432 }
00433 current = new_element;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 inline void CLIST_ITERATOR::add_before_stay_put(
00445 void *new_data) {
00446 CLIST_LINK *new_element;
00447
00448 #ifndef NDEBUG
00449 if (!this)
00450 NULL_OBJECT.error ("CLIST_ITERATOR::add_before_stay_put", ABORT, NULL);
00451 if (!list)
00452 NO_LIST.error ("CLIST_ITERATOR::add_before_stay_put", ABORT, NULL);
00453 if (!new_data)
00454 BAD_PARAMETER.error ("CLIST_ITERATOR::add_before_stay_put", ABORT,
00455 "new_data is NULL");
00456 #endif
00457
00458 new_element = new CLIST_LINK;
00459 new_element->data = new_data;
00460
00461 if (list->empty ()) {
00462 new_element->next = new_element;
00463 list->last = new_element;
00464 prev = next = new_element;
00465 ex_current_was_last = TRUE;
00466 current = NULL;
00467 }
00468 else {
00469 prev->next = new_element;
00470 if (current) {
00471 new_element->next = current;
00472 if (next == current)
00473 next = new_element;
00474 }
00475 else {
00476 new_element->next = next;
00477 if (ex_current_was_last)
00478 list->last = new_element;
00479 }
00480 prev = new_element;
00481 }
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 inline void CLIST_ITERATOR::add_list_after(CLIST *list_to_add) {
00493 #ifndef NDEBUG
00494 if (!this)
00495 NULL_OBJECT.error ("CLIST_ITERATOR::add_list_after", ABORT, NULL);
00496 if (!list)
00497 NO_LIST.error ("CLIST_ITERATOR::add_list_after", ABORT, NULL);
00498 if (!list_to_add)
00499 BAD_PARAMETER.error ("CLIST_ITERATOR::add_list_after", ABORT,
00500 "list_to_add is NULL");
00501 #endif
00502
00503 if (!list_to_add->empty ()) {
00504 if (list->empty ()) {
00505 list->last = list_to_add->last;
00506 prev = list->last;
00507 next = list->First ();
00508 ex_current_was_last = TRUE;
00509 current = NULL;
00510 }
00511 else {
00512 if (current) {
00513 current->next = list_to_add->First ();
00514 if (current == list->last)
00515 list->last = list_to_add->last;
00516 list_to_add->last->next = next;
00517 next = current->next;
00518 }
00519 else {
00520 prev->next = list_to_add->First ();
00521 if (ex_current_was_last) {
00522 list->last = list_to_add->last;
00523 ex_current_was_last = FALSE;
00524 }
00525 list_to_add->last->next = next;
00526 next = prev->next;
00527 }
00528 }
00529 list_to_add->last = NULL;
00530 }
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 inline void CLIST_ITERATOR::add_list_before(CLIST *list_to_add) {
00543 #ifndef NDEBUG
00544 if (!this)
00545 NULL_OBJECT.error ("CLIST_ITERATOR::add_list_before", ABORT, NULL);
00546 if (!list)
00547 NO_LIST.error ("CLIST_ITERATOR::add_list_before", ABORT, NULL);
00548 if (!list_to_add)
00549 BAD_PARAMETER.error ("CLIST_ITERATOR::add_list_before", ABORT,
00550 "list_to_add is NULL");
00551 #endif
00552
00553 if (!list_to_add->empty ()) {
00554 if (list->empty ()) {
00555 list->last = list_to_add->last;
00556 prev = list->last;
00557 current = list->First ();
00558 next = current->next;
00559 ex_current_was_last = FALSE;
00560 }
00561 else {
00562 prev->next = list_to_add->First ();
00563 if (current) {
00564 list_to_add->last->next = current;
00565 }
00566 else {
00567 list_to_add->last->next = next;
00568 if (ex_current_was_last)
00569 list->last = list_to_add->last;
00570 if (ex_current_was_cycle_pt)
00571 cycle_pt = prev->next;
00572 }
00573 current = prev->next;
00574 next = current->next;
00575 }
00576 list_to_add->last = NULL;
00577 }
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 inline void *CLIST_ITERATOR::extract() {
00591 void *extracted_data;
00592
00593 #ifndef NDEBUG
00594 if (!this)
00595 NULL_OBJECT.error ("CLIST_ITERATOR::extract", ABORT, NULL);
00596 if (!list)
00597 NO_LIST.error ("CLIST_ITERATOR::extract", ABORT, NULL);
00598 if (!current)
00599
00600 NULL_CURRENT.error ("CLIST_ITERATOR::extract",
00601 ABORT, NULL);
00602 #endif
00603
00604 if (list->singleton()) {
00605
00606 prev = next = list->last = NULL;
00607 } else {
00608 prev->next = next;
00609
00610 if (current == list->last) {
00611 list->last = prev;
00612 ex_current_was_last = TRUE;
00613 } else {
00614 ex_current_was_last = FALSE;
00615 }
00616 }
00617
00618 ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
00619 extracted_data = current->data;
00620 delete(current);
00621 current = NULL;
00622 return extracted_data;
00623 }
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 inline void *CLIST_ITERATOR::move_to_first() {
00634 #ifndef NDEBUG
00635 if (!this)
00636 NULL_OBJECT.error ("CLIST_ITERATOR::move_to_first", ABORT, NULL);
00637 if (!list)
00638 NO_LIST.error ("CLIST_ITERATOR::move_to_first", ABORT, NULL);
00639 #endif
00640
00641 current = list->First ();
00642 prev = list->last;
00643 next = current != NULL ? current->next : NULL;
00644 return current != NULL ? current->data : NULL;
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 inline void CLIST_ITERATOR::mark_cycle_pt() {
00660 #ifndef NDEBUG
00661 if (!this)
00662 NULL_OBJECT.error ("CLIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
00663 if (!list)
00664 NO_LIST.error ("CLIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
00665 #endif
00666
00667 if (current)
00668 cycle_pt = current;
00669 else
00670 ex_current_was_cycle_pt = TRUE;
00671 started_cycling = FALSE;
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 inline BOOL8 CLIST_ITERATOR::at_first() {
00683 #ifndef NDEBUG
00684 if (!this)
00685 NULL_OBJECT.error ("CLIST_ITERATOR::at_first", ABORT, NULL);
00686 if (!list)
00687 NO_LIST.error ("CLIST_ITERATOR::at_first", ABORT, NULL);
00688 #endif
00689
00690
00691 return ((list->empty ()) || (current == list->First ()) || ((current == NULL) &&
00692 (prev == list->last) &&
00693 !ex_current_was_last));
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 inline BOOL8 CLIST_ITERATOR::at_last() {
00705 #ifndef NDEBUG
00706 if (!this)
00707 NULL_OBJECT.error ("CLIST_ITERATOR::at_last", ABORT, NULL);
00708 if (!list)
00709 NO_LIST.error ("CLIST_ITERATOR::at_last", ABORT, NULL);
00710 #endif
00711
00712
00713 return ((list->empty ()) || (current == list->last) || ((current == NULL) &&
00714 (prev == list->last) &&
00715 ex_current_was_last));
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 inline BOOL8 CLIST_ITERATOR::cycled_list() {
00727 #ifndef NDEBUG
00728 if (!this)
00729 NULL_OBJECT.error ("CLIST_ITERATOR::cycled_list", ABORT, NULL);
00730 if (!list)
00731 NO_LIST.error ("CLIST_ITERATOR::cycled_list", ABORT, NULL);
00732 #endif
00733
00734 return ((list->empty ()) || ((current == cycle_pt) && started_cycling));
00735
00736 }
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 inline inT32 CLIST_ITERATOR::length() {
00747 #ifndef NDEBUG
00748 if (!this)
00749 NULL_OBJECT.error ("CLIST_ITERATOR::length", ABORT, NULL);
00750 if (!list)
00751 NO_LIST.error ("CLIST_ITERATOR::length", ABORT, NULL);
00752 #endif
00753
00754 return list->length ();
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 inline void
00766 CLIST_ITERATOR::sort (
00767 int comparator (
00768 const void *, const void *)) {
00769 #ifndef NDEBUG
00770 if (!this)
00771 NULL_OBJECT.error ("CLIST_ITERATOR::sort", ABORT, NULL);
00772 if (!list)
00773 NO_LIST.error ("CLIST_ITERATOR::sort", ABORT, NULL);
00774 #endif
00775
00776 list->sort (comparator);
00777 move_to_first();
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 inline void CLIST_ITERATOR::add_to_end(
00792 void *new_data) {
00793 CLIST_LINK *new_element;
00794
00795 #ifndef NDEBUG
00796 if (!this)
00797 NULL_OBJECT.error ("CLIST_ITERATOR::add_to_end", ABORT, NULL);
00798 if (!list)
00799 NO_LIST.error ("CLIST_ITERATOR::add_to_end", ABORT, NULL);
00800 if (!new_data)
00801 BAD_PARAMETER.error ("CLIST_ITERATOR::add_to_end", ABORT,
00802 "new_data is NULL");
00803 #endif
00804
00805 if (this->at_last ()) {
00806 this->add_after_stay_put (new_data);
00807 }
00808 else {
00809 if (this->at_first ()) {
00810 this->add_before_stay_put (new_data);
00811 list->last = prev;
00812 }
00813 else {
00814 new_element = new CLIST_LINK;
00815 new_element->data = new_data;
00816
00817 new_element->next = list->last->next;
00818 list->last->next = new_element;
00819 list->last = new_element;
00820 }
00821 }
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831 #define QUOTE_IT( parm ) #parm
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 #define CLISTIZEH_A( CLASSNAME ) \
00866 \
00867 extern DLLSYM void CLASSNAME##_c1_zapper( \
00868 void* link); \
00869 \
00870 extern DLLSYM void* CLASSNAME##_c1_copier( \
00871 void* old_element);
00872
00873 #define CLISTIZEH_B( CLASSNAME ) \
00874 \
00875
00876
00877
00878
00879
00880 \
00881 \
00882 class DLLSYM CLASSNAME##_CLIST : public CLIST \
00883 { \
00884 public: \
00885 CLASSNAME##_CLIST():CLIST() {} \
00886 \
00887 \
00888 CLASSNAME##_CLIST( \
00889 const CLASSNAME##_CLIST&) \
00890 { DONT_CONSTRUCT_LIST_BY_COPY.error( QUOTE_IT( CLASSNAME##_CLIST ), \
00891 ABORT, NULL ); } \
00892 \
00893 void deep_clear() \
00894 { CLIST::internal_deep_clear( &CLASSNAME##_c1_zapper ); } \
00895 \
00896 void operator=( \
00897 const CLASSNAME##_CLIST&) \
00898 { DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_CLIST ), \
00899 ABORT, NULL ); }
00900
00901 #define CLISTIZEH_C( CLASSNAME ) \
00902 \
00903 }; \
00904 \
00905 \
00906 \
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 \
00917 \
00918 class DLLSYM CLASSNAME##_C_IT : public CLIST_ITERATOR \
00919 { \
00920 public: \
00921 CLASSNAME##_C_IT():CLIST_ITERATOR(){} \
00922 \
00923 CLASSNAME##_C_IT( \
00924 CLASSNAME##_CLIST* list):CLIST_ITERATOR(list){} \
00925 \
00926 CLASSNAME* data() \
00927 { return (CLASSNAME*) CLIST_ITERATOR::data(); } \
00928 \
00929 CLASSNAME* data_relative( \
00930 inT8 offset) \
00931 { return (CLASSNAME*) CLIST_ITERATOR::data_relative( offset ); } \
00932 \
00933 CLASSNAME* forward() \
00934 { return (CLASSNAME*) CLIST_ITERATOR::forward(); } \
00935 \
00936 CLASSNAME* extract() \
00937 { return (CLASSNAME*) CLIST_ITERATOR::extract(); } \
00938 \
00939 CLASSNAME* move_to_first() \
00940 { return (CLASSNAME*) CLIST_ITERATOR::move_to_first(); } \
00941 \
00942 CLASSNAME* move_to_last() \
00943 { return (CLASSNAME*) CLIST_ITERATOR::move_to_last(); } \
00944 };
00945
00946 #define CLISTIZEH( CLASSNAME ) \
00947 \
00948 CLISTIZEH_A( CLASSNAME ) \
00949 \
00950 CLISTIZEH_B( CLASSNAME ) \
00951 \
00952 CLISTIZEH_C( CLASSNAME )
00953
00954
00955
00956
00957
00958 #define CLISTIZE( CLASSNAME ) \
00959 \
00960
00961
00962
00963
00964
00965
00966
00967 \
00968 \
00969 DLLSYM void CLASSNAME##_c1_zapper( \
00970 void* link) \
00971 { \
00972 delete (CLASSNAME *) link; \
00973 } \
00974
00975 #endif