00001 #ifndef LL_H
00002 #define LL_H
00003
00092
00093 #ifndef assert
00094 #define assert(v)
00095 #endif
00096
00097
00098 #ifndef PP_H
00099 #include "pp.h"
00100 #endif
00101
00132 #define sll_decllink(type,mlabel)\
00133 type* mlabel
00134
00142 #define sll_initlink(type,mlabel, self)\
00143 (self)->mlabel = NULL
00144
00152 #define sll_decllist(type,mlabel, ilabel)\
00153 type* ilabel
00154
00163 #define sll_autolist(type,mlabel, ilabel)\
00164 type* ilabel = NULL
00165
00174 #define sll_autolist_static(type,mlabel, ilabel)\
00175 static type* ilabel = NULL
00176
00184 #define sll_externlist(type,mlabel, ilabel)\
00185 extern type* ilabel
00186
00195 #define sll_initlist(type,mlabel, ilabel ) \
00196 (ilabel) = NULL
00197
00207 #define sll_initarray(type,mlabel, ilabel, array,count) \
00208 {\
00209 type* ppScr2(sllInit,array) = (array);\
00210 type* ppScr2(sllInit,last) = ppScr2(sllInit,array) + (count) - 1;\
00211 type* ppScr2(sllInit,curr) = ppScr2(sllInit,last);\
00212 ppScr2(sllInit,last)->mlabel = NULL;\
00213 while( ppScr2(sllInit,curr)-- > ppScr2(sllInit,array) )\
00214 ppScr2(sllInit,curr)->mlabel = ppScr2(sllInit,last)--;\
00215 (ilabel) = ppScr2(sllInit,array);\
00216 }
00217
00225 #define sll_empty(type,mlabel, ilabel ) ( NULL == (ilabel) )
00226
00234 #define sll_reset(type,mlabel, ilabel) \
00235 {\
00236 type* __ll_curr = (array);\
00237 type* __ll_next;\
00238 while( __ll_curr ) \
00239 {\
00240 __ll_next = __ll_curr->mlabel;\
00241 __ll_curr->mlabel = NULL;\
00242 __ll_curr = __ll_next;\
00243 }\
00244 (ilabel) = NULL;\
00245 }
00246
00255 #define sll_next(type,mlabel, ilabel, curr ) \
00256 ((curr) = (curr) ? ((curr)->mlabel) : NULL)
00257
00269 #define sll_foreach_const(type,mlabel, ilabel, iterator ) \
00270 const type* iterator = (ilabel); \
00271 for ( ; iterator; iterator = iterator->mlabel )
00272
00284 #define sll_foreach(type,mlabel, ilabel, iterator ) \
00285 type* iterator = (ilabel); \
00286 for ( ; iterator; iterator = iterator->mlabel )
00287
00298 #define sll_foreach_deletable(type,mlabel, ilabel, iterator ) \
00299 type* ppConcat3(__ll_,iterator,_prev) = NULL; \
00300 type* iterator = (ilabel);\
00301 type* ppConcat3(__ll_,iterator,_next) = iterator?iterator->mlabel:NULL; \
00302 for ( ; iterator; ppConcat3(__ll_,iterator,_prev) = iterator, iterator = ppConcat3(__ll_,iterator,_next), sll_next(type,mlabel, ilabel, ppConcat3(__ll_,iterator,_next) ) )
00303
00314 #define sll_foreach_deletable_reverse(type,mlabel, ilabel, iterator ) \
00315 type* ppConcat3(__ll_,iterator,_prev) = NULL; \
00316 type* iterator = (ilabel);\
00317 type* ppConcat3(__ll_,iterator,_next) = iterator?iterator->mlabel:NULL; \
00318 for ( ; iterator; iterator->mlabel = ppConcat3(__ll_,iterator,_prev), ppConcat3(__ll_,iterator,_prev) = (ilabel) = iterator, iterator = ppConcat3(__ll_,iterator,_next), sll_next(type,mlabel, ilabel, ppConcat3(__ll_,iterator,_next) ) )
00319
00328 #define sll_foreach_deletecurr(type,mlabel, ilabel, iterator ) \
00329 if( iterator )\
00330 {\
00331 if ( ppConcat3(__ll_,iterator,_prev) )\
00332 {\
00333 ppConcat3(__ll_,iterator,_prev)->mlabel = ppConcat3(__ll_,iterator,_next);\
00334 }\
00335 else\
00336 {\
00337 ilabel = ppConcat3(__ll_,iterator,_next);\
00338 }\
00339 iterator->mlabel = NULL;\
00340 }
00341
00351 #define sll_push_front(type,mlabel, ilabel, item ) \
00352 {\
00353 (item)->mlabel = (ilabel);\
00354 (ilabel) = (item);\
00355 }
00356
00366 #define sll_push_back(type,mlabel, ilabel, item ) \
00367 {\
00368 type* __ll_iterate_add;\
00369 sll_back(type,mlabel, ilabel, __ll_iterate_add );\
00370 if( __ll_iterate_add ) \
00371 { \
00372 __ll_iterate_add->mlabel = (item);\
00373 } \
00374 else \
00375 { \
00376 (ilabel) = (item);\
00377 } \
00378 (item)->mlabel = NULL;\
00379 }
00380
00389 #define sll_front(type,mlabel, ilabel, get ) \
00390 {(get) = (ilabel);}
00391
00400 #define sll_back(type,mlabel, ilabel, get ) \
00401 {\
00402 type* __ll_iterate = (ilabel);\
00403 if( __ll_iterate ) \
00404 while( __ll_iterate->mlabel )\
00405 __ll_iterate = __ll_iterate->mlabel;\
00406 (get) = __ll_iterate;\
00407 }
00408
00417 #define sll_pop_front(type,mlabel, ilabel, get ) \
00418 {\
00419 (get) = (ilabel);\
00420 (ilabel) = (get)->mlabel;\
00421 (get)->mlabel = NULL;\
00422 }
00423
00432 #define sll_pop_back(type,mlabel, ilabel, get ) \
00433 {\
00434 type* __ll_iterate = (ilabel);\
00435 type* __ll_iterate_prev = NULL;\
00436 if( __ll_iterate ) \
00437 {\
00438 while( __ll_iterate->mlabel )\
00439 {\
00440 __ll_iterate_prev = __ll_iterate->mlabel;\
00441 __ll_iterate = __ll_iterate->mlabel;\
00442 }\
00443 if( __ll_iterate_prev )\
00444 {\
00445 __ll_iterate_prev = NULL;\
00446 }\
00447 else\
00448 {\
00449 (ilabel) = NULL;\
00450 }\
00451 }\
00452 (get) = __ll_iterate;\
00453 }
00454
00464 #define sll_erase(type,mlabel, ilabel, item ) \
00465 {\
00466 type* ppConcat(__ll_iterate_remove,_prev) = NULL; \
00467 type* __ll_iterate_remove = (ilabel); \
00468 while( __ll_iterate_remove )\
00469 {\
00470 if ( __ll_iterate_remove == (item) )\
00471 {\
00472 if ( ppConcat(__ll_iterate_remove,_prev) )\
00473 {\
00474 ppConcat(__ll_iterate_remove,_prev)->mlabel = __ll_iterate_remove->mlabel;\
00475 }\
00476 else\
00477 {\
00478 ilabel = __ll_iterate_remove->mlabel;\
00479 }\
00480 break;\
00481 }\
00482 ppConcat(__ll_iterate_remove,_prev) = __ll_iterate_remove;\
00483 __ll_iterate_remove = __ll_iterate_remove->mlabel;\
00484 }\
00485 }
00486
00498 #define sll_remove_filter(type,mlabel, ilabel, criteria ) \
00499 {\
00500 sll_foreach_deletable(type,mlabel, ilabel, __ll_iterate_delete )\
00501 {\
00502 if ( criteria(__ll_iterate_delete) ) \
00503 sll_foreach_deletecurr(type,mlabel, ilabel, __ll_iterate_delete ); \
00504 }\
00505 }
00506
00516 #define sll_move_filter(type,mlabel, ilabel, criteria, target ) \
00517 {\
00518 sll_foreach_deletable(type,mlabel, ilabel, __ll_iterate_move )\
00519 {\
00520 if ( criteria(__ll_iterate_move) ) \
00521 {\
00522 sll_foreach_deletecurr(type,mlabel, ilabel, __ll_iterate_move ); \
00523 sll_push_front(type,mlabel, target, __ll_iterate_move );\
00524 }\
00525 }\
00526 }
00527
00536 #define sll_size(type,mlabel, ilabel, count) \
00537 {\
00538 size_t ppScr2(__sll_size_,tally) = 0;\
00539 type* ppScr2(__sll_size_,iterator);\
00540 for ( ppScr2(__sll_size_,iterator) = (ilabel); ppScr2(__sll_size_,iterator); ppScr2(__sll_size_,iterator) = ppScr2(__sll_size_,iterator)->mlabel, ppScr2(__sll_size_,tally)++ )\
00541 ;\
00542 (count) = ppScr2(__sll_size_,tally);\
00543 }
00544
00553 #ifndef NDEBUG
00554 #define sll_assert_size(type,mlabel, ilabel, count) \
00555 {\
00556 size_t ppScr2(__sll_assert_size,tally) = 0;\
00557 sll_size(type,mlabel, ilabel, ppScr2(__sll_assert_size,tally));\
00558 assert( ppScr2(__sll_assert_size,tally) == (count) );\
00559 }
00560 #else
00561 #define sll_assert_size(type,mlabel, ilabel, count)
00562 #endif
00563
00571 #define sll_splice(type,mlabel, toFirst, fromFirst) \
00572 {\
00573 if( toFirst ) \
00574 {\
00575 type* sllTail;\
00576 sll_back(type,mlabel, toFirst, sllTail );\
00577 sllTail->mlabel = (fromFirst);\
00578 }\
00579 else\
00580 {\
00581 (toFirst) = (fromFirst);\
00582 }\
00583 (fromFirst) = NULL;\
00584 }
00585
00602 #define sll_bsort(type,mlabel, ilabel, compare ) \
00603 {\
00604 if( (ilabel) && (ilabel)->mlabel )\
00605 {\
00606 type* first = ilabel;\
00607 type* sortBefore, *sortPrev, *sortNext;\
00608 int sorted;\
00609 do\
00610 {\
00611 sorted = 0;\
00612 sortBefore = NULL;\
00613 sortPrev = first;\
00614 sortNext = sortPrev->mlabel;\
00615 while( sortNext )\
00616 {\
00617 if( compare( sortPrev, sortNext ) > 0 )\
00618 {\
00619 if( sortBefore )\
00620 {\
00621 sortBefore->mlabel = sortNext;\
00622 }\
00623 else\
00624 {\
00625 first = sortNext;\
00626 }\
00627 sortPrev->mlabel = sortNext->mlabel;\
00628 sortNext->mlabel = sortPrev;\
00629 sorted++;\
00630 }\
00631 sortBefore = sortPrev;\
00632 sortPrev = sortNext;\
00633 sortNext = sortNext->mlabel;\
00634 }\
00635 }\
00636 while( sorted );\
00637 ilabel = first;\
00638 }\
00639 }
00640
00650 #define sll_decl_qsort(type,mlabel, ilabel, name ) \
00651 void name( type** front, type** back, int (*compare)(const void* p1, const void* p2) )
00652
00662 #define sll_qsort(type,mlabel, ilabel, name, compare ) \
00663 name( &(ilabel), NULL, (int (*)(const void*, const void*))(compare) );\
00664
00665
00687 #define sll_mfg_qsort(type,mlabel, ilabel, deref, name ) \
00688 sll_decl_qsort(type,mlabel, ilabel, name )\
00689 {\
00690 if( *front && (*front)->mlabel )\
00691 {\
00692 type* lesser = NULL;\
00693 type* tlesser = NULL;\
00694 type* greater = NULL;\
00695 type* tgreater = NULL;\
00696 type* equal = *front;\
00697 type* tequal = equal;\
00698 type* curr = equal->mlabel;\
00699 while( curr )\
00700 {\
00701 type* next = curr->mlabel;\
00702 int val = compare(deref(equal),deref(curr));\
00703 if( val > 0 )\
00704 {\
00705 if( tlesser )\
00706 {\
00707 tlesser->mlabel = curr;\
00708 tlesser = curr;\
00709 }\
00710 else\
00711 {\
00712 tlesser = lesser = curr;\
00713 }\
00714 }\
00715 else if( val < 0 )\
00716 {\
00717 if( tgreater )\
00718 {\
00719 tgreater->mlabel = curr;\
00720 tgreater = curr;\
00721 }\
00722 else\
00723 {\
00724 tgreater = greater = curr;\
00725 }\
00726 }\
00727 else \
00728 {\
00729 assert(val==0);\
00730 tequal->mlabel = curr;\
00731 tequal = curr;\
00732 }\
00733 curr = next;\
00734 }\
00735 \
00736 if( lesser )\
00737 {\
00738 tlesser->mlabel = NULL;\
00739 if( lesser != tlesser )\
00740 {\
00741 tlesser->mlabel = NULL;\
00742 name( &lesser, &tlesser, compare );\
00743 }\
00744 }\
00745 \
00746 if( greater )\
00747 {\
00748 tgreater->mlabel = NULL;\
00749 if( greater != tgreater )\
00750 {\
00751 name( &greater, &tgreater, compare );\
00752 }\
00753 }\
00754 \
00755 if( tlesser )\
00756 {\
00757 *front = lesser;\
00758 tlesser->mlabel = equal;\
00759 }\
00760 else\
00761 {\
00762 *front = equal;\
00763 }\
00764 tequal->mlabel = greater;\
00765 if( back )\
00766 *back = tgreater ? tgreater : tequal;\
00767 }\
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00781 #define _dllnext(mlabel) ppConcat(mlabel,_next)
00782
00783 #define _dllprev(mlabel) ppConcat(mlabel,_prev)
00784
00785 #define _dllfront(ilabel) ppConcat(ilabel,_front)
00786
00787 #define _dllback(ilabel) ppConcat(ilabel,_back)
00788
00795 #define dll_decllink(type,mlabel)\
00796 type* _dllprev(mlabel);\
00797 type* _dllnext(mlabel)
00798
00806 #define dll_initlink(type,mlabel, curr)\
00807 (curr)->_dllprev(mlabel) = (curr)->_dllnext(mlabel) = NULL
00808
00816 #define dll_decllist(type,mlabel, ilabel)\
00817 type* _dllfront(ilabel);\
00818 type* _dllback(ilabel)
00819
00828 #define dll_islinked(type,mlabel, ilabel, curr)\
00829 ( (curr)->_dllprev(mlabel) || (curr)->_dllnext(mlabel) || (_dllfront(ilabel)==(curr) && _dllback(ilabel)==(curr)) )
00830
00838 #define dll_initlist(type,mlabel, ilabel)\
00839 _dllfront(ilabel) = _dllback(ilabel) = NULL
00840
00848 #define dll_autolist(type,mlabel, ilabel)\
00849 type* _dllfront(ilabel) = NULL;\
00850 type* _dllback(ilabel) = NULL
00851
00859 #define dll_autolist_static(type,mlabel, ilabel)\
00860 static type* _dllfront(ilabel) = NULL;\
00861 static type* _dllback(ilabel) = NULL
00862
00870 #define dll_externlist(type,mlabel, ilabel)\
00871 extern type* _dllfront(ilabel);\
00872 extern type* _dllback(ilabel)
00873
00883 #define dll_initarray(type,mlabel, ilabel, array,count) \
00884 {\
00885 size_t __ll_remain = (size_t)(count)-1;\
00886 type* __ll_fromHead = (array);\
00887 type* __ll_fromTail = (array)+__ll_remain;\
00888 (_dllfront(ilabel)) = __ll_fromHead;\
00889 (_dllback(ilabel)) = __ll_fromTail;\
00890 while( __ll_remain-- )\
00891 {\
00892 __ll_fromHead->_dllnext(mlabel) = __ll_fromHead+1;\
00893 __ll_fromTail->_dllprev(mlabel) = __ll_fromTail-1;\
00894 __ll_fromHead++;\
00895 __ll_fromTail--;\
00896 }\
00897 (_dllfront(ilabel))->_dllprev(mlabel) = NULL;\
00898 (_dllback(ilabel))->_dllnext(mlabel) = NULL;\
00899 }
00900
00901
00909 #define dll_empty(type,mlabel, ilabel ) ( NULL == _dllfront(ilabel) )
00910
00919 #define dll_check_link(type,mlabel, ilabel, item ) \
00920 ( \
00921 (item) && \
00922 ( (item)->_dllprev(mlabel) ? ((item)->_dllprev(mlabel)->_dllnext(mlabel) == (item)) : (item) == (_dllfront(ilabel)) ) &&\
00923 ( (item)->_dllnext(mlabel) ? ((item)->_dllnext(mlabel)->_dllprev(mlabel) == (item)) : (item) == (_dllback(ilabel)) )\
00924 )
00925
00933 #define dll_check(type,mlabel, ilabel ) \
00934 (\
00935 ( !_dllback(ilabel) && !_dllfront(ilabel) ) ||\
00936 (\
00937 ( _dllback(ilabel) && _dllfront(ilabel) && !_dllfront(ilabel)->_dllprev(mlabel) && !_dllback(ilabel)->_dllnext(mlabel) ) &&\
00938 (\
00939 ( _dllback(ilabel) == _dllfront(ilabel) ) ||\
00940 ( _dllfront(ilabel)->_dllnext(mlabel)->_dllprev(mlabel) == _dllfront(ilabel) && _dllback(ilabel)->_dllprev(mlabel)->_dllnext(mlabel) == _dllback(ilabel) )\
00941 )\
00942 )\
00943 )
00944
00945
00956 #define dll_check_thorough(type,mlabel, ilabel, onfailure ) \
00957 {\
00958 if( dll_check(type,mlabel, ilabel ) )\
00959 {\
00960 const type* fromBack = _dllback(ilabel);\
00961 const type* fromFront = _dllfront(ilabel);\
00962 while( fromBack && fromFront )\
00963 {\
00964 if( !dll_check_link(type,mlabel, ilabel, fromBack ) )\
00965 {\
00966 onfailure("List prev link bad", _dllfront(ilabel),_dllback(ilabel), fromBack);\
00967 fromBack = fromFront = NULL; \
00968 break;\
00969 }\
00970 if( !dll_check_link(type,mlabel, ilabel, fromFront ) )\
00971 {\
00972 onfailure("List next link bad", _dllfront(ilabel),_dllback(ilabel), fromFront);\
00973 fromBack = fromFront = NULL; \
00974 break;\
00975 }\
00976 fromBack = fromBack->_dllprev(mlabel);\
00977 fromFront = fromFront->_dllnext(mlabel);\
00978 }\
00979 if( fromBack )\
00980 onfailure("List prev count higher than next count.", _dllfront(ilabel),_dllback(ilabel), fromBack);\
00981 if( fromFront )\
00982 onfailure("List next count higher than prev count.", _dllfront(ilabel),_dllback(ilabel), fromFront);\
00983 }\
00984 else\
00985 {\
00986 onfailure("List front/back links bad", _dllfront(ilabel),_dllback(ilabel),NULL);\
00987 }\
00988 }
00989
00997 #define dll_reset(type,mlabel, ilabel) \
00998 {\
00999 type* __dllCurr = (_dllfront(ilabel));\
01000 (_dllfront(ilabel)) = (_dllback(ilabel)) = NULL;\
01001 while( _dllCurr )\
01002 {\
01003 type* __dllNext = __dllCurr->_dllnext(mlabel);\
01004 __dllCurr->_dllnext(mlabel) = __dllCurr->_dllprev(mlabel) = NULL;\
01005 __dllCurr = __dllNext;\
01006 }\
01007 }
01008
01017 #define dll_next(type,mlabel, ilabel, curr ) \
01018 ((curr) = (curr) ? ((curr)->_dllnext(mlabel)) : NULL)
01019
01028 #define dll_prev(type,mlabel, ilabel, curr ) \
01029 ((curr) = (curr) ? ((curr)->_dllprev(mlabel)) : NULL)
01030
01042 #define dll_foreach_const(type,mlabel, ilabel, iterator ) \
01043 const type* iterator = (_dllfront(ilabel)); \
01044 for ( ; iterator; iterator = iterator->_dllnext(mlabel) )
01045
01057 #define dll_foreach_reverse_const(type,mlabel, ilabel, iterator ) \
01058 const type* iterator = (_dllback(ilabel)); \
01059 for( ; iterator; iterator = iterator->_dllprev(mlabel) )
01060
01072 #define dll_foreach(type,mlabel, ilabel, iterator ) \
01073 type* iterator = (_dllfront(ilabel)); \
01074 for ( ; iterator; iterator = iterator->_dllnext(mlabel) )
01075
01087 #define dll_foreach_reverse(type,mlabel, ilabel, iterator ) \
01088 type* iterator = (_dllback(ilabel)); \
01089 for( ; iterator; iterator = iterator->_dllprev(mlabel) )
01090
01101 #define dll_foreach_deletable(type,mlabel, ilabel, iterator ) \
01102 type* iterator = (_dllfront(ilabel));\
01103 type* ppConcat3(__ll_,iterator,_next) = iterator?iterator->_dllnext(mlabel):NULL; \
01104 for ( ; iterator; iterator = ppConcat3(__ll_,iterator,_next), dll_next(type,mlabel, ilabel, ppConcat3(__ll_,iterator,_next) ) )
01105
01116 #define dll_foreach_deletable_reverse(type,mlabel, ilabel, iterator ) \
01117 type* iterator = (_dllback(ilabel));\
01118 type* ppConcat3(__ll_,iterator,_next) = iterator?iterator->_dllprev(mlabel):NULL; \
01119 for ( ; iterator; iterator = ppConcat3(__ll_,iterator,_next), dll_prev(type,mlabel, ilabel, ppConcat3(__ll_,iterator,_next) ) )
01120
01131 #define dll_push_front(type,mlabel, ilabel, item ) \
01132 {\
01133 assert( dll_check(type,mlabel, ilabel ) ); \
01134 (item)->_dllnext(mlabel) = (_dllfront(ilabel));\
01135 (item)->_dllprev(mlabel) = NULL;\
01136 if( (_dllfront(ilabel)) )\
01137 {\
01138 (_dllfront(ilabel))->_dllprev(mlabel) = (item);\
01139 }\
01140 else\
01141 {\
01142 (_dllback(ilabel)) = (item);\
01143 }\
01144 (_dllfront(ilabel)) = (item);\
01145 }
01146
01157 #define dll_push_back(type,mlabel, ilabel, item ) \
01158 {\
01159 assert( dll_check(type,mlabel, ilabel ) ); \
01160 (item)->_dllnext(mlabel) = NULL;\
01161 (item)->_dllprev(mlabel) = (_dllback(ilabel));\
01162 if( _dllback(ilabel) )\
01163 {\
01164 (_dllback(ilabel))->_dllnext(mlabel) = (item);\
01165 }\
01166 else\
01167 {\
01168 (_dllfront(ilabel)) = (item);\
01169 }\
01170 (_dllback(ilabel)) = (item);\
01171 }
01172
01184 #define dll_insert(type,mlabel, ilabel, after, item ) \
01185 {\
01186 assert( dll_check(type,mlabel, ilabel ) ); \
01187 if( after )\
01188 { \
01189 (item)->_dllnext(mlabel) = (after)->_dllnext(mlabel);\
01190 (item)->_dllprev(mlabel) = (after);\
01191 (after)->_dllnext(mlabel) = (item);\
01192 if( (item)->_dllnext(mlabel) )\
01193 (item)->_dllnext(mlabel)->_dllprev(mlabel) = (item);\
01194 else\
01195 (_dllback(ilabel)) = (item);\
01196 }\
01197 else\
01198 { \
01199 (item)->_dllnext(mlabel) = (_dllfront(ilabel));\
01200 (item)->_dllprev(mlabel) = NULL;\
01201 if( (_dllfront(ilabel)) )\
01202 (_dllfront(ilabel))->_dllprev(mlabel) = (item);\
01203 else\
01204 (_dllback(ilabel)) = (item);\
01205 (_dllfront(ilabel)) = (item);\
01206 }\
01207 }
01208
01220 #define dll_insert_before(type,mlabel, ilabel, before, item ) \
01221 {\
01222 assert( dll_check(type,mlabel, ilabel ) ); \
01223 if( before )\
01224 { \
01225 (item)->_dllprev(mlabel) = (before)->_dllnext(mlabel);\
01226 (item)->_dllnext(mlabel) = (before);\
01227 (before)->_dllprev(mlabel) = (item);\
01228 if( (item)->_dllprev(mlabel) )\
01229 (item)->_dllprev(mlabel)->_dllnext(mlabel) = (item);\
01230 else\
01231 (_dllfront(ilabel)) = (item);\
01232 }\
01233 else\
01234 { \
01235 (item)->_dllnext(mlabel) = NULL;\
01236 (item)->_dllprev(mlabel) = (_dllback(ilabel));\
01237 if( _dllback(ilabel) )\
01238 (_dllback(ilabel))->_dllnext(mlabel) = (item);\
01239 else\
01240 (_dllfront(ilabel)) = (item);\
01241 (_dllback(ilabel)) = (item);\
01242 }\
01243 }
01244
01253 #define dll_front(type,mlabel, ilabel, get ) \
01254 {(get) = (_dllfront(ilabel));}
01255
01264 #define dll_back(type,mlabel, ilabel, get ) \
01265 {(get) = (_dllback(ilabel));}
01266
01275 #define dll_pop_front(type,mlabel, ilabel, get ) \
01276 {\
01277 assert( dll_check(type,mlabel, ilabel ) ); \
01278 (get) = (_dllfront(ilabel));\
01279 if( (get) && (get)->_dllnext(mlabel) )\
01280 {\
01281 (_dllfront(ilabel)) = (get)->_dllnext(mlabel);\
01282 (get)->_dllnext(mlabel)->_dllprev(mlabel) = NULL;\
01283 }\
01284 else\
01285 {\
01286 (_dllfront(ilabel)) = (_dllback(ilabel)) = NULL;\
01287 }\
01288 }
01289
01298 #define dll_pop_back(type,mlabel, ilabel, get ) \
01299 {\
01300 assert( dll_check(type,mlabel, ilabel ) ); \
01301 (get) = (_dllback(ilabel));\
01302 if( (get) && (get)->_dllprev(mlabel) )\
01303 {\
01304 (_dllback(ilabel)) = (get)->_dllprev(mlabel);\
01305 (get)->_dllprev(mlabel)->_dllnext(mlabel) = NULL;\
01306 }\
01307 else\
01308 {\
01309 (_dllfront(ilabel)) = (_dllback(ilabel)) = NULL;\
01310 }\
01311 }
01312
01323 #define dll_erase(type,mlabel, ilabel, item ) \
01324 {\
01325 assert( dll_check(type,mlabel, ilabel ) ); \
01326 assert( dll_check_link(type,mlabel, ilabel, item ) ); \
01327 if( (item)->_dllprev(mlabel) )\
01328 {\
01329 (item)->_dllprev(mlabel)->_dllnext(mlabel) = (item)->_dllnext(mlabel);\
01330 }\
01331 else\
01332 {\
01333 (_dllfront(ilabel)) = (item)->_dllnext(mlabel);\
01334 }\
01335 if( (item)->_dllnext(mlabel) )\
01336 {\
01337 (item)->_dllnext(mlabel)->_dllprev(mlabel) = (item)->_dllprev(mlabel);\
01338 }\
01339 else\
01340 {\
01341 (_dllback(ilabel)) = (item)->_dllprev(mlabel);\
01342 }\
01343 dll_initlink(type,mlabel, item );\
01344 }
01345
01354 #define dll_remove_filter(type,mlabel, ilabel, criteria ) \
01355 {\
01356 assert( dll_check(type,mlabel, ilabel ) ); \
01357 {\
01358 dll_foreach_deletable(type,mlabel, ilabel, __ll_iterate_delete )\
01359 {\
01360 if ( criteria(__ll_iterate_delete) ) \
01361 dll_erase(type,mlabel, ilabel, __ll_iterate_delete );\
01362 }\
01363 }\
01364 }
01365
01375 #define dll_move_filter(type,mlabel, ilabel, criteria, target ) \
01376 {\
01377 assert( dll_check(type,mlabel, ilabel ) ); \
01378 {\
01379 dll_foreach_deletable(type,mlabel, _dllfront(ilabel), __ll_iterate_move )\
01380 {\
01381 if ( criteria(__ll_iterate_delete) ) \
01382 {\
01383 dll_erase(type,mlabel, ilabel, __ll_iterate_delete );\
01384 dll_push_back(type,mlabel, target, __ll_iterate_move );\
01385 }\
01386 }\
01387 }\
01388 }
01389
01398 #define dll_size(type,mlabel, ilabel, count) sll_size( type,_dllnext(mlabel), _dllfront(ilabel), count )
01399
01408 #define dll_assert_size(type,mlabel, ilabel, count) sll_assert_size( type,_dllnext(mlabel), _dllfront(ilabel), count )
01409
01418 #define dll_splice(type,mlabel, ilabelto, ilabelfrom ) \
01419 {\
01420 assert( dll_check(type,mlabel, ilabelto ) ); \
01421 assert( dll_check(type,mlabel, ilabelfrom ) ); \
01422 if( _dllback(ilabelto) )\
01423 {\
01424 if( _dllfront(ilabelfrom) )\
01425 {\
01426 (_dllfront(ilabelfrom))->_dllprev(mlabel) = (_dllback(ilabelto));\
01427 (_dllback(ilabelto))->_dllnext(mlabel) = (_dllfront(ilabelfrom));\
01428 (_dllback(ilabelto)) = (_dllback(ilabelfrom));\
01429 }\
01430 }\
01431 else\
01432 {\
01433 (_dllfront(ilabelto)) = (_dllfront(ilabelfrom));\
01434 (_dllback(ilabelto)) = (_dllback(ilabelfrom));\
01435 }\
01436 _dllfront(ilabelfrom) = _dllback(ilabelfrom) = NULL;\
01437 }
01438
01439
01447 #define dll_rebuild_back(type,mlabel, ilabel ) \
01448 {\
01449 \
01450 type* __ll_iterator_prev = NULL; \
01451 type* iterator = (_dllfront(ilabel));\
01452 type* __ll_iterator_next = iterator?iterator->_dllnext(mlabel):NULL; \
01453 for ( ; iterator; __ll_iterator_prev = iterator, iterator = __ll_iterator_next, sll_next(type,_dllnext(mlabel), _dllfront(ilabel), __ll_iterator_next ) )\
01454 {\
01455 iterator->_dllprev(mlabel) = __ll_iterator_prev;\
01456 }\
01457 (_dllback(ilabel)) = __ll_iterator_prev;\
01458 }\
01459
01460
01467 #define dll_rebuild_front(type,mlabel, ilabel ) \
01468 {\
01469 \
01470 type* __ll_iterator_next = NULL; \
01471 type* iterator = (_dllback(ilabel));\
01472 type* __ll_iterator_prev = iterator?iterator->_dllprev(mlabel):NULL; \
01473 for ( ; iterator; __ll_iterator_next = iterator, iterator = __ll_iterator_prev, sll_next(type,_dllprev(mlabel), _dllback(ilabel), __ll_iterator_prev ) )\
01474 {\
01475 iterator->_dllnext(mlabel) = __ll_iterator_next;\
01476 }\
01477 (_dllfront(ilabel)) = __ll_iterator_next;\
01478 }\
01479
01480
01488 #define dll_bsort(type,mlabel, ilabel, compare ) \
01489 {\
01490 assert( dll_check(type,mlabel, ilabel ) ); \
01491 sll_bsort(type,_dllnext(mlabel), _dllfront(ilabel), compare );\
01492 dll_rebuild_back(type,mlabel, ilabel );\
01493 }
01494
01503 #define dll_decl_qsort(type,mlabel, ilabel, name ) \
01504 sll_decl_qsort(type,_dllnext(mlabel), _dllfront(ilabel), name )
01505
01515 #define dll_mfg_qsort(type,mlabel, ilabel, deref, name ) \
01516 sll_mfg_qsort(type,_dllnext(mlabel), _dllfront(ilabel), deref, name )
01517
01527 #define dll_qsort(type,mlabel, ilabel, name, compare ) \
01528 {\
01529 assert( dll_check(type,mlabel, ilabel ) ); \
01530 name( &_dllfront(ilabel), &_dllback(ilabel), (int (*)(const void*, const void*))(compare) );\
01531 dll_rebuild_back(type,mlabel, ilabel );\
01532 }
01533
01534
01535 #endif
01536