Go to the documentation of this file. 27 #define UTLIST_VERSION 2.0.2 66 #if !defined(LDECLTYPE) && !defined(NO_DECLTYPE) 68 #if _MSC_VER >= 1600 && defined(__cplusplus) 69 #define LDECLTYPE(x) decltype(x) 73 #elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) 76 #define LDECLTYPE(x) __typeof(x) 84 #define IF_NO_DECLTYPE(x) x 85 #define LDECLTYPE(x) char* 86 #define UTLIST_SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } 87 #define UTLIST_NEXT(elt,list,next) ((char*)((list)->next)) 88 #define UTLIST_NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } 90 #define UTLIST_PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } 91 #define UTLIST_RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } 92 #define UTLIST_CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } 94 #define IF_NO_DECLTYPE(x) 95 #define UTLIST_SV(elt,list) 96 #define UTLIST_NEXT(elt,list,next) ((elt)->next) 97 #define UTLIST_NEXTASGN(elt,list,to,next) ((elt)->next)=(to) 99 #define UTLIST_PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) 100 #define UTLIST_RS(list) 101 #define UTLIST_CASTASGN(a,b) (a)=(b) 108 #define LL_SORT(list, cmp) \ 109 LL_SORT2(list, cmp, next) 111 #define LL_SORT2(list, cmp, next) \ 113 LDECLTYPE(list) _ls_p; \ 114 LDECLTYPE(list) _ls_q; \ 115 LDECLTYPE(list) _ls_e; \ 116 LDECLTYPE(list) _ls_tail; \ 117 IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ 118 int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ 122 while (_ls_looping) { \ 123 UTLIST_CASTASGN(_ls_p,list); \ 131 for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ 133 UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ 136 _ls_qsize = _ls_insize; \ 137 while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ 138 if (_ls_psize == 0) { \ 139 _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ 140 UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ 141 } else if (_ls_qsize == 0 || !_ls_q) { \ 142 _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ 143 UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ 144 } else if (cmp(_ls_p,_ls_q) <= 0) { \ 145 _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ 146 UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ 148 _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ 149 UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ 152 UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ 154 UTLIST_CASTASGN(list,_ls_e); \ 161 UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ 163 if (_ls_nmerges <= 1) { \ 172 #define DL_SORT(list, cmp) \ 173 DL_SORT2(list, cmp, prev, next) 175 #define DL_SORT2(list, cmp, prev, next) \ 177 LDECLTYPE(list) _ls_p; \ 178 LDECLTYPE(list) _ls_q; \ 179 LDECLTYPE(list) _ls_e; \ 180 LDECLTYPE(list) _ls_tail; \ 181 IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ 182 int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ 186 while (_ls_looping) { \ 187 UTLIST_CASTASGN(_ls_p,list); \ 195 for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ 197 UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ 200 _ls_qsize = _ls_insize; \ 201 while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \ 202 if (_ls_psize == 0) { \ 203 _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ 204 UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ 205 } else if ((_ls_qsize == 0) || (!_ls_q)) { \ 206 _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ 207 UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ 208 } else if (cmp(_ls_p,_ls_q) <= 0) { \ 209 _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ 210 UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ 212 _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ 213 UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ 216 UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ 218 UTLIST_CASTASGN(list,_ls_e); \ 220 UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ 225 UTLIST_CASTASGN((list)->prev, _ls_tail); \ 226 UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ 227 if (_ls_nmerges <= 1) { \ 235 #define CDL_SORT(list, cmp) \ 236 CDL_SORT2(list, cmp, prev, next) 238 #define CDL_SORT2(list, cmp, prev, next) \ 240 LDECLTYPE(list) _ls_p; \ 241 LDECLTYPE(list) _ls_q; \ 242 LDECLTYPE(list) _ls_e; \ 243 LDECLTYPE(list) _ls_tail; \ 244 LDECLTYPE(list) _ls_oldhead; \ 245 LDECLTYPE(list) _tmp; \ 246 int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ 250 while (_ls_looping) { \ 251 UTLIST_CASTASGN(_ls_p,list); \ 252 UTLIST_CASTASGN(_ls_oldhead,list); \ 260 for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ 262 UTLIST_SV(_ls_q,list); \ 263 if (UTLIST_NEXT(_ls_q,list,next) == _ls_oldhead) { \ 266 _ls_q = UTLIST_NEXT(_ls_q,list,next); \ 271 _ls_qsize = _ls_insize; \ 272 while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ 273 if (_ls_psize == 0) { \ 274 _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ 275 UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ 276 if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ 277 } else if (_ls_qsize == 0 || !_ls_q) { \ 278 _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ 279 UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ 280 if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ 281 } else if (cmp(_ls_p,_ls_q) <= 0) { \ 282 _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ 283 UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ 284 if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ 286 _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ 287 UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ 288 if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ 291 UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ 293 UTLIST_CASTASGN(list,_ls_e); \ 295 UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ 300 UTLIST_CASTASGN((list)->prev,_ls_tail); \ 301 UTLIST_CASTASGN(_tmp,list); \ 302 UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_tmp,next); UTLIST_RS(list); \ 303 if (_ls_nmerges <= 1) { \ 314 #define LL_PREPEND(head,add) \ 315 LL_PREPEND2(head,add,next) 317 #define LL_PREPEND2(head,add,next) \ 319 (add)->next = (head); \ 323 #define LL_CONCAT(head1,head2) \ 324 LL_CONCAT2(head1,head2,next) 326 #define LL_CONCAT2(head1,head2,next) \ 328 LDECLTYPE(head1) _tmp; \ 331 while (_tmp->next) { _tmp = _tmp->next; } \ 332 _tmp->next=(head2); \ 338 #define LL_APPEND(head,add) \ 339 LL_APPEND2(head,add,next) 341 #define LL_APPEND2(head,add,next) \ 343 LDECLTYPE(head) _tmp; \ 347 while (_tmp->next) { _tmp = _tmp->next; } \ 354 #define LL_INSERT_INORDER(head,add,cmp) \ 355 LL_INSERT_INORDER2(head,add,cmp,next) 357 #define LL_INSERT_INORDER2(head,add,cmp,next) \ 359 LDECLTYPE(head) _tmp; \ 361 LL_LOWER_BOUND(head, _tmp, add, cmp); \ 362 LL_APPEND_ELEM(head, _tmp, add); \ 365 (head)->next = NULL; \ 369 #define LL_LOWER_BOUND(head,elt,like,cmp) \ 370 LL_LOWER_BOUND2(head,elt,like,cmp,next) 372 #define LL_LOWER_BOUND2(head,elt,like,cmp,next) \ 374 if ((head) == NULL || (cmp(head, like)) >= 0) { \ 377 for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ 378 if (cmp((elt)->next, like) >= 0) { \ 385 #define LL_DELETE(head,del) \ 386 LL_DELETE2(head,del,next) 388 #define LL_DELETE2(head,del,next) \ 390 LDECLTYPE(head) _tmp; \ 391 if ((head) == (del)) { \ 392 (head)=(head)->next; \ 395 while (_tmp->next && (_tmp->next != (del))) { \ 399 _tmp->next = (del)->next; \ 404 #define LL_COUNT(head,el,counter) \ 405 LL_COUNT2(head,el,counter,next) \ 407 #define LL_COUNT2(head,el,counter,next) \ 410 LL_FOREACH2(head,el,next) { ++(counter); } \ 413 #define LL_FOREACH(head,el) \ 414 LL_FOREACH2(head,el,next) 416 #define LL_FOREACH2(head,el,next) \ 417 for ((el) = (head); el; (el) = (el)->next) 419 #define LL_FOREACH_SAFE(head,el,tmp) \ 420 LL_FOREACH_SAFE2(head,el,tmp,next) 422 #define LL_FOREACH_SAFE2(head,el,tmp,next) \ 423 for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) 425 #define LL_SEARCH_SCALAR(head,out,field,val) \ 426 LL_SEARCH_SCALAR2(head,out,field,val,next) 428 #define LL_SEARCH_SCALAR2(head,out,field,val,next) \ 430 LL_FOREACH2(head,out,next) { \ 431 if ((out)->field == (val)) break; \ 435 #define LL_SEARCH(head,out,elt,cmp) \ 436 LL_SEARCH2(head,out,elt,cmp,next) 438 #define LL_SEARCH2(head,out,elt,cmp,next) \ 440 LL_FOREACH2(head,out,next) { \ 441 if ((cmp(out,elt))==0) break; \ 445 #define LL_REPLACE_ELEM2(head, el, add, next) \ 447 LDECLTYPE(head) _tmp; \ 448 assert((head) != NULL); \ 449 assert((el) != NULL); \ 450 assert((add) != NULL); \ 451 (add)->next = (el)->next; \ 452 if ((head) == (el)) { \ 456 while (_tmp->next && (_tmp->next != (el))) { \ 460 _tmp->next = (add); \ 465 #define LL_REPLACE_ELEM(head, el, add) \ 466 LL_REPLACE_ELEM2(head, el, add, next) 468 #define LL_PREPEND_ELEM2(head, el, add, next) \ 471 LDECLTYPE(head) _tmp; \ 472 assert((head) != NULL); \ 473 assert((add) != NULL); \ 474 (add)->next = (el); \ 475 if ((head) == (el)) { \ 479 while (_tmp->next && (_tmp->next != (el))) { \ 483 _tmp->next = (add); \ 487 LL_APPEND2(head, add, next); \ 491 #define LL_PREPEND_ELEM(head, el, add) \ 492 LL_PREPEND_ELEM2(head, el, add, next) 494 #define LL_APPEND_ELEM2(head, el, add, next) \ 497 assert((head) != NULL); \ 498 assert((add) != NULL); \ 499 (add)->next = (el)->next; \ 500 (el)->next = (add); \ 502 LL_PREPEND2(head, add, next); \ 506 #define LL_APPEND_ELEM(head, el, add) \ 507 LL_APPEND_ELEM2(head, el, add, next) 513 #define LL_CONCAT2(head1,head2,next) \ 517 _tmp = (char*)(head1); \ 518 while ((head1)->next) { (head1) = (head1)->next; } \ 519 (head1)->next = (head2); \ 527 #define LL_APPEND2(head,add,next) \ 530 (add)->next = head; \ 531 while ((add)->next->next) { (add)->next = (add)->next->next; } \ 532 (add)->next->next=(add); \ 539 #undef LL_INSERT_INORDER2 540 #define LL_INSERT_INORDER2(head,add,cmp,next) \ 542 if ((head) == NULL || (cmp(head, add)) >= 0) { \ 543 (add)->next = (head); \ 546 char *_tmp = (char*)(head); \ 547 while ((head)->next != NULL && (cmp((head)->next, add)) < 0) { \ 548 (head) = (head)->next; \ 550 (add)->next = (head)->next; \ 551 (head)->next = (add); \ 557 #define LL_DELETE2(head,del,next) \ 559 if ((head) == (del)) { \ 560 (head)=(head)->next; \ 562 char *_tmp = (char*)(head); \ 563 while ((head)->next && ((head)->next != (del))) { \ 564 (head) = (head)->next; \ 566 if ((head)->next) { \ 567 (head)->next = ((del)->next); \ 573 #undef LL_REPLACE_ELEM2 574 #define LL_REPLACE_ELEM2(head, el, add, next) \ 576 assert((head) != NULL); \ 577 assert((el) != NULL); \ 578 assert((add) != NULL); \ 579 if ((head) == (el)) { \ 582 (add)->next = head; \ 583 while ((add)->next->next && ((add)->next->next != (el))) { \ 584 (add)->next = (add)->next->next; \ 586 if ((add)->next->next) { \ 587 (add)->next->next = (add); \ 590 (add)->next = (el)->next; \ 593 #undef LL_PREPEND_ELEM2 594 #define LL_PREPEND_ELEM2(head, el, add, next) \ 597 assert((head) != NULL); \ 598 assert((add) != NULL); \ 599 if ((head) == (el)) { \ 602 (add)->next = (head); \ 603 while ((add)->next->next && ((add)->next->next != (el))) { \ 604 (add)->next = (add)->next->next; \ 606 if ((add)->next->next) { \ 607 (add)->next->next = (add); \ 610 (add)->next = (el); \ 612 LL_APPEND2(head, add, next); \ 621 #define DL_PREPEND(head,add) \ 622 DL_PREPEND2(head,add,prev,next) 624 #define DL_PREPEND2(head,add,prev,next) \ 626 (add)->next = (head); \ 628 (add)->prev = (head)->prev; \ 629 (head)->prev = (add); \ 631 (add)->prev = (add); \ 636 #define DL_APPEND(head,add) \ 637 DL_APPEND2(head,add,prev,next) 639 #define DL_APPEND2(head,add,prev,next) \ 642 (add)->prev = (head)->prev; \ 643 (head)->prev->next = (add); \ 644 (head)->prev = (add); \ 645 (add)->next = NULL; \ 648 (head)->prev = (head); \ 649 (head)->next = NULL; \ 653 #define DL_INSERT_INORDER(head,add,cmp) \ 654 DL_INSERT_INORDER2(head,add,cmp,next) 656 #define DL_INSERT_INORDER2(head,add,cmp,next) \ 658 LDECLTYPE(head) _tmp; \ 660 DL_LOWER_BOUND(head, _tmp, add, cmp); \ 661 DL_APPEND_ELEM(head, _tmp, add); \ 664 (head)->prev = (head); \ 665 (head)->next = NULL; \ 669 #define DL_LOWER_BOUND(head,elt,like,cmp) \ 670 DL_LOWER_BOUND2(head,elt,like,cmp,next) 672 #define DL_LOWER_BOUND2(head,elt,like,cmp,next) \ 674 if ((head) == NULL || (cmp(head, like)) >= 0) { \ 677 for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ 678 if ((cmp((elt)->next, like)) >= 0) { \ 685 #define DL_CONCAT(head1,head2) \ 686 DL_CONCAT2(head1,head2,prev,next) 688 #define DL_CONCAT2(head1,head2,prev,next) \ 690 LDECLTYPE(head1) _tmp; \ 693 UTLIST_CASTASGN(_tmp, (head2)->prev); \ 694 (head2)->prev = (head1)->prev; \ 695 (head1)->prev->next = (head2); \ 696 UTLIST_CASTASGN((head1)->prev, _tmp); \ 703 #define DL_DELETE(head,del) \ 704 DL_DELETE2(head,del,prev,next) 706 #define DL_DELETE2(head,del,prev,next) \ 708 assert((head) != NULL); \ 709 assert((del)->prev != NULL); \ 710 if ((del)->prev == (del)) { \ 712 } else if ((del)==(head)) { \ 713 (del)->next->prev = (del)->prev; \ 714 (head) = (del)->next; \ 716 (del)->prev->next = (del)->next; \ 718 (del)->next->prev = (del)->prev; \ 720 (head)->prev = (del)->prev; \ 725 #define DL_COUNT(head,el,counter) \ 726 DL_COUNT2(head,el,counter,next) \ 728 #define DL_COUNT2(head,el,counter,next) \ 731 DL_FOREACH2(head,el,next) { ++(counter); } \ 734 #define DL_FOREACH(head,el) \ 735 DL_FOREACH2(head,el,next) 737 #define DL_FOREACH2(head,el,next) \ 738 for ((el) = (head); el; (el) = (el)->next) 741 #define DL_FOREACH_SAFE(head,el,tmp) \ 742 DL_FOREACH_SAFE2(head,el,tmp,next) 744 #define DL_FOREACH_SAFE2(head,el,tmp,next) \ 745 for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) 748 #define DL_SEARCH_SCALAR LL_SEARCH_SCALAR 749 #define DL_SEARCH LL_SEARCH 750 #define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 751 #define DL_SEARCH2 LL_SEARCH2 753 #define DL_REPLACE_ELEM2(head, el, add, prev, next) \ 755 assert((head) != NULL); \ 756 assert((el) != NULL); \ 757 assert((add) != NULL); \ 758 if ((head) == (el)) { \ 760 (add)->next = (el)->next; \ 761 if ((el)->next == NULL) { \ 762 (add)->prev = (add); \ 764 (add)->prev = (el)->prev; \ 765 (add)->next->prev = (add); \ 768 (add)->next = (el)->next; \ 769 (add)->prev = (el)->prev; \ 770 (add)->prev->next = (add); \ 771 if ((el)->next == NULL) { \ 772 (head)->prev = (add); \ 774 (add)->next->prev = (add); \ 779 #define DL_REPLACE_ELEM(head, el, add) \ 780 DL_REPLACE_ELEM2(head, el, add, prev, next) 782 #define DL_PREPEND_ELEM2(head, el, add, prev, next) \ 785 assert((head) != NULL); \ 786 assert((add) != NULL); \ 787 (add)->next = (el); \ 788 (add)->prev = (el)->prev; \ 789 (el)->prev = (add); \ 790 if ((head) == (el)) { \ 793 (add)->prev->next = (add); \ 796 DL_APPEND2(head, add, prev, next); \ 800 #define DL_PREPEND_ELEM(head, el, add) \ 801 DL_PREPEND_ELEM2(head, el, add, prev, next) 803 #define DL_APPEND_ELEM2(head, el, add, prev, next) \ 806 assert((head) != NULL); \ 807 assert((add) != NULL); \ 808 (add)->next = (el)->next; \ 809 (add)->prev = (el); \ 810 (el)->next = (add); \ 812 (add)->next->prev = (add); \ 814 (head)->prev = (add); \ 817 DL_PREPEND2(head, add, prev, next); \ 821 #define DL_APPEND_ELEM(head, el, add) \ 822 DL_APPEND_ELEM2(head, el, add, prev, next) 827 #undef DL_INSERT_INORDER2 828 #define DL_INSERT_INORDER2(head,add,cmp,next) \ 830 if ((head) == NULL) { \ 831 (add)->prev = (add); \ 832 (add)->next = NULL; \ 834 } else if ((cmp(head, add)) >= 0) { \ 835 (add)->prev = (head)->prev; \ 836 (add)->next = (head); \ 837 (head)->prev = (add); \ 840 char *_tmp = (char*)(head); \ 841 while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ 842 (head) = (head)->next; \ 844 (add)->prev = (head); \ 845 (add)->next = (head)->next; \ 846 (head)->next = (add); \ 849 (add)->next->prev = (add); \ 851 (head)->prev = (add); \ 860 #define CDL_APPEND(head,add) \ 861 CDL_APPEND2(head,add,prev,next) 863 #define CDL_APPEND2(head,add,prev,next) \ 866 (add)->prev = (head)->prev; \ 867 (add)->next = (head); \ 868 (head)->prev = (add); \ 869 (add)->prev->next = (add); \ 871 (add)->prev = (add); \ 872 (add)->next = (add); \ 877 #define CDL_PREPEND(head,add) \ 878 CDL_PREPEND2(head,add,prev,next) 880 #define CDL_PREPEND2(head,add,prev,next) \ 883 (add)->prev = (head)->prev; \ 884 (add)->next = (head); \ 885 (head)->prev = (add); \ 886 (add)->prev->next = (add); \ 888 (add)->prev = (add); \ 889 (add)->next = (add); \ 894 #define CDL_INSERT_INORDER(head,add,cmp) \ 895 CDL_INSERT_INORDER2(head,add,cmp,next) 897 #define CDL_INSERT_INORDER2(head,add,cmp,next) \ 899 LDECLTYPE(head) _tmp; \ 901 CDL_LOWER_BOUND(head, _tmp, add, cmp); \ 902 CDL_APPEND_ELEM(head, _tmp, add); \ 905 (head)->next = (head); \ 906 (head)->prev = (head); \ 910 #define CDL_LOWER_BOUND(head,elt,like,cmp) \ 911 CDL_LOWER_BOUND2(head,elt,like,cmp,next) 913 #define CDL_LOWER_BOUND2(head,elt,like,cmp,next) \ 915 if ((head) == NULL || (cmp(head, like)) >= 0) { \ 918 for ((elt) = (head); (elt)->next != (head); (elt) = (elt)->next) { \ 919 if ((cmp((elt)->next, like)) >= 0) { \ 926 #define CDL_DELETE(head,del) \ 927 CDL_DELETE2(head,del,prev,next) 929 #define CDL_DELETE2(head,del,prev,next) \ 931 if (((head)==(del)) && ((head)->next == (head))) { \ 934 (del)->next->prev = (del)->prev; \ 935 (del)->prev->next = (del)->next; \ 936 if ((del) == (head)) (head)=(del)->next; \ 940 #define CDL_COUNT(head,el,counter) \ 941 CDL_COUNT2(head,el,counter,next) \ 943 #define CDL_COUNT2(head, el, counter,next) \ 946 CDL_FOREACH2(head,el,next) { ++(counter); } \ 949 #define CDL_FOREACH(head,el) \ 950 CDL_FOREACH2(head,el,next) 952 #define CDL_FOREACH2(head,el,next) \ 953 for ((el)=(head);el;(el)=(((el)->next==(head)) ? NULL : (el)->next)) 955 #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ 956 CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) 958 #define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ 959 for ((el) = (head), (tmp1) = (head) ? (head)->prev : NULL; \ 960 (el) && ((tmp2) = (el)->next, 1); \ 961 (el) = ((el) == (tmp1) ? NULL : (tmp2))) 963 #define CDL_SEARCH_SCALAR(head,out,field,val) \ 964 CDL_SEARCH_SCALAR2(head,out,field,val,next) 966 #define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ 968 CDL_FOREACH2(head,out,next) { \ 969 if ((out)->field == (val)) break; \ 973 #define CDL_SEARCH(head,out,elt,cmp) \ 974 CDL_SEARCH2(head,out,elt,cmp,next) 976 #define CDL_SEARCH2(head,out,elt,cmp,next) \ 978 CDL_FOREACH2(head,out,next) { \ 979 if ((cmp(out,elt))==0) break; \ 983 #define CDL_REPLACE_ELEM2(head, el, add, prev, next) \ 985 assert((head) != NULL); \ 986 assert((el) != NULL); \ 987 assert((add) != NULL); \ 988 if ((el)->next == (el)) { \ 989 (add)->next = (add); \ 990 (add)->prev = (add); \ 993 (add)->next = (el)->next; \ 994 (add)->prev = (el)->prev; \ 995 (add)->next->prev = (add); \ 996 (add)->prev->next = (add); \ 997 if ((head) == (el)) { \ 1003 #define CDL_REPLACE_ELEM(head, el, add) \ 1004 CDL_REPLACE_ELEM2(head, el, add, prev, next) 1006 #define CDL_PREPEND_ELEM2(head, el, add, prev, next) \ 1009 assert((head) != NULL); \ 1010 assert((add) != NULL); \ 1011 (add)->next = (el); \ 1012 (add)->prev = (el)->prev; \ 1013 (el)->prev = (add); \ 1014 (add)->prev->next = (add); \ 1015 if ((head) == (el)) { \ 1019 CDL_APPEND2(head, add, prev, next); \ 1023 #define CDL_PREPEND_ELEM(head, el, add) \ 1024 CDL_PREPEND_ELEM2(head, el, add, prev, next) 1026 #define CDL_APPEND_ELEM2(head, el, add, prev, next) \ 1029 assert((head) != NULL); \ 1030 assert((add) != NULL); \ 1031 (add)->next = (el)->next; \ 1032 (add)->prev = (el); \ 1033 (el)->next = (add); \ 1034 (add)->next->prev = (add); \ 1036 CDL_PREPEND2(head, add, prev, next); \ 1040 #define CDL_APPEND_ELEM(head, el, add) \ 1041 CDL_APPEND_ELEM2(head, el, add, prev, next) 1046 #undef CDL_INSERT_INORDER2 1047 #define CDL_INSERT_INORDER2(head,add,cmp,next) \ 1049 if ((head) == NULL) { \ 1050 (add)->prev = (add); \ 1051 (add)->next = (add); \ 1053 } else if ((cmp(head, add)) >= 0) { \ 1054 (add)->prev = (head)->prev; \ 1055 (add)->next = (head); \ 1056 (add)->prev->next = (add); \ 1057 (head)->prev = (add); \ 1060 char *_tmp = (char*)(head); \ 1061 while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ 1062 (head) = (head)->next; \ 1064 (add)->prev = (head); \ 1065 (add)->next = (head)->next; \ 1066 (add)->next->prev = (add); \ 1067 (head)->next = (add); \