cocos2d for iPhone 1.0.0
2D engine for iOS and OS X
/Users/rquesada/progs/cocos2d-iphone/cocos2d/Support/utlist.h
00001 /*
00002 Copyright (c) 2007-2010, Troy D. Hanson   http://uthash.sourceforge.net
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright
00009       notice, this list of conditions and the following disclaimer.
00010 
00011 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00012 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00013 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00014 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00015 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00016 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00017 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00018 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00019 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00020 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00021 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00022 */
00023 
00024 #ifndef UTLIST_H
00025 #define UTLIST_H
00026 
00027 #define UTLIST_VERSION 1.9.1
00028 
00029 /* 
00030  * This file contains macros to manipulate singly and doubly-linked lists.
00031  *
00032  * 1. LL_ macros:  singly-linked lists.
00033  * 2. DL_ macros:  doubly-linked lists.
00034  * 3. CDL_ macros: circular doubly-linked lists.
00035  *
00036  * To use singly-linked lists, your structure must have a "next" pointer.
00037  * To use doubly-linked lists, your structure must "prev" and "next" pointers.
00038  * Either way, the pointer to the head of the list must be initialized to NULL.
00039  * 
00040  * ----------------.EXAMPLE -------------------------
00041  * struct item {
00042  *      int id;
00043  *      struct item *prev, *next;
00044  * }
00045  *
00046  * struct item *list = NULL:
00047  *
00048  * int main() {
00049  *      struct item *item;
00050  *      ... allocate and populate item ...
00051  *      DL_APPEND(list, item);
00052  * }
00053  * --------------------------------------------------
00054  *
00055  * For doubly-linked lists, the append and delete macros are O(1)
00056  * For singly-linked lists, append and delete are O(n) but prepend is O(1)
00057  * The sort macro is O(n log(n)) for all types of single/double/circular lists.
00058  */
00059 
00060 /* These macros use decltype or the earlier __typeof GNU extension.
00061    As decltype is only available in newer compilers (VS2010 or gcc 4.3+
00062    when compiling c++ code), this code uses whatever method is needed
00063    or, for VS2008 where neither is available, uses casting workarounds. */
00064 #ifdef _MSC_VER            /* MS compiler */
00065 #if _MSC_VER >= 1600 && defined(__cplusplus)  /* VS2010 or newer in C++ mode */
00066 #define LDECLTYPE(x) decltype(x)
00067 #else                     /* VS2008 or older (or VS2010 in C mode) */
00068 #define NO_DECLTYPE
00069 #define LDECLTYPE(x) char*
00070 #endif
00071 #else                      /* GNU, Sun and other compilers */
00072 #define LDECLTYPE(x) __typeof(x)
00073 #endif
00074 
00075 /* for VS2008 we use some workarounds to get around the lack of decltype,
00076  * namely, we always reassign our tmp variable to the list head if we need
00077  * to dereference its prev/next pointers, and save/restore the real head.*/
00078 #ifdef NO_DECLTYPE
00079 #define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); }
00080 #define _NEXT(elt,list) ((char*)((list)->next))
00081 #define _NEXTASGN(elt,list,to) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); }
00082 #define _PREV(elt,list) ((char*)((list)->prev))
00083 #define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
00084 #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
00085 #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
00086 #else 
00087 #define _SV(elt,list)
00088 #define _NEXT(elt,list) ((elt)->next)
00089 #define _NEXTASGN(elt,list,to) ((elt)->next)=(to)
00090 #define _PREV(elt,list) ((elt)->prev)
00091 #define _PREVASGN(elt,list,to) ((elt)->prev)=(to)
00092 #define _RS(list)
00093 #define _CASTASGN(a,b) (a)=(b)
00094 #endif
00095 
00096 /******************************************************************************
00097  * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort    *
00098  * Unwieldy variable names used here to avoid shadowing passed-in variables.  *
00099  *****************************************************************************/
00100 #define LL_SORT(list, cmp)                                                                     \
00101 do {                                                                                           \
00102   LDECLTYPE(list) _ls_p;                                                                       \
00103   LDECLTYPE(list) _ls_q;                                                                       \
00104   LDECLTYPE(list) _ls_e;                                                                       \
00105   LDECLTYPE(list) _ls_tail;                                                                    \
00106   LDECLTYPE(list) _ls_oldhead;                                                                 \
00107   LDECLTYPE(list) _tmp;                                                                        \
00108   int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping;                       \
00109   if (list) {                                                                                  \
00110     _ls_insize = 1;                                                                            \
00111     _ls_looping = 1;                                                                           \
00112     while (_ls_looping) {                                                                      \
00113       _CASTASGN(_ls_p,list);                                                                   \
00114       _CASTASGN(_ls_oldhead,list);                                                             \
00115       list = NULL;                                                                             \
00116       _ls_tail = NULL;                                                                         \
00117       _ls_nmerges = 0;                                                                         \
00118       while (_ls_p) {                                                                          \
00119         _ls_nmerges++;                                                                         \
00120         _ls_q = _ls_p;                                                                         \
00121         _ls_psize = 0;                                                                         \
00122         for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) {                                         \
00123           _ls_psize++;                                                                         \
00124           _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list);                               \
00125           if (!_ls_q) break;                                                                   \
00126         }                                                                                      \
00127         _ls_qsize = _ls_insize;                                                                \
00128         while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) {                                    \
00129           if (_ls_psize == 0) {                                                                \
00130             _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
00131           } else if (_ls_qsize == 0 || !_ls_q) {                                               \
00132             _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
00133           } else if (cmp(_ls_p,_ls_q) <= 0) {                                                  \
00134             _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
00135           } else {                                                                             \
00136             _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
00137           }                                                                                    \
00138           if (_ls_tail) {                                                                      \
00139             _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list);                     \
00140           } else {                                                                             \
00141             _CASTASGN(list,_ls_e);                                                             \
00142           }                                                                                    \
00143           _ls_tail = _ls_e;                                                                    \
00144         }                                                                                      \
00145         _ls_p = _ls_q;                                                                         \
00146       }                                                                                        \
00147       _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list);                            \
00148       if (_ls_nmerges <= 1) {                                                                  \
00149         _ls_looping=0;                                                                         \
00150       }                                                                                        \
00151       _ls_insize *= 2;                                                                         \
00152     }                                                                                          \
00153   } else _tmp=NULL; /* quiet gcc unused variable warning */                                    \
00154 } while (0)
00155 
00156 #define DL_SORT(list, cmp)                                                                     \
00157 do {                                                                                           \
00158   LDECLTYPE(list) _ls_p;                                                                       \
00159   LDECLTYPE(list) _ls_q;                                                                       \
00160   LDECLTYPE(list) _ls_e;                                                                       \
00161   LDECLTYPE(list) _ls_tail;                                                                    \
00162   LDECLTYPE(list) _ls_oldhead;                                                                 \
00163   LDECLTYPE(list) _tmp;                                                                        \
00164   int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping;                       \
00165   if (list) {                                                                                  \
00166     _ls_insize = 1;                                                                            \
00167     _ls_looping = 1;                                                                           \
00168     while (_ls_looping) {                                                                      \
00169       _CASTASGN(_ls_p,list);                                                                   \
00170       _CASTASGN(_ls_oldhead,list);                                                             \
00171       list = NULL;                                                                             \
00172       _ls_tail = NULL;                                                                         \
00173       _ls_nmerges = 0;                                                                         \
00174       while (_ls_p) {                                                                          \
00175         _ls_nmerges++;                                                                         \
00176         _ls_q = _ls_p;                                                                         \
00177         _ls_psize = 0;                                                                         \
00178         for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) {                                         \
00179           _ls_psize++;                                                                         \
00180           _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list);                               \
00181           if (!_ls_q) break;                                                                   \
00182         }                                                                                      \
00183         _ls_qsize = _ls_insize;                                                                \
00184         while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) {                                    \
00185           if (_ls_psize == 0) {                                                                \
00186             _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
00187           } else if (_ls_qsize == 0 || !_ls_q) {                                               \
00188             _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
00189           } else if (cmp(_ls_p,_ls_q) <= 0) {                                                  \
00190             _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
00191           } else {                                                                             \
00192             _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
00193           }                                                                                    \
00194           if (_ls_tail) {                                                                      \
00195             _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list);                     \
00196           } else {                                                                             \
00197             _CASTASGN(list,_ls_e);                                                             \
00198           }                                                                                    \
00199           _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list);                          \
00200           _ls_tail = _ls_e;                                                                    \
00201         }                                                                                      \
00202         _ls_p = _ls_q;                                                                         \
00203       }                                                                                        \
00204       _CASTASGN(list->prev, _ls_tail);                                                         \
00205       _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list);                            \
00206       if (_ls_nmerges <= 1) {                                                                  \
00207         _ls_looping=0;                                                                         \
00208       }                                                                                        \
00209       _ls_insize *= 2;                                                                         \
00210     }                                                                                          \
00211   } else _tmp=NULL; /* quiet gcc unused variable warning */                                    \
00212 } while (0)
00213 
00214 #define CDL_SORT(list, cmp)                                                                    \
00215 do {                                                                                           \
00216   LDECLTYPE(list) _ls_p;                                                                       \
00217   LDECLTYPE(list) _ls_q;                                                                       \
00218   LDECLTYPE(list) _ls_e;                                                                       \
00219   LDECLTYPE(list) _ls_tail;                                                                    \
00220   LDECLTYPE(list) _ls_oldhead;                                                                 \
00221   LDECLTYPE(list) _tmp;                                                                        \
00222   LDECLTYPE(list) _tmp2;                                                                       \
00223   int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping;                       \
00224   if (list) {                                                                                  \
00225     _ls_insize = 1;                                                                            \
00226     _ls_looping = 1;                                                                           \
00227     while (_ls_looping) {                                                                      \
00228       _CASTASGN(_ls_p,list);                                                                   \
00229       _CASTASGN(_ls_oldhead,list);                                                             \
00230       list = NULL;                                                                             \
00231       _ls_tail = NULL;                                                                         \
00232       _ls_nmerges = 0;                                                                         \
00233       while (_ls_p) {                                                                          \
00234         _ls_nmerges++;                                                                         \
00235         _ls_q = _ls_p;                                                                         \
00236         _ls_psize = 0;                                                                         \
00237         for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) {                                         \
00238           _ls_psize++;                                                                         \
00239           _SV(_ls_q,list);                                                                     \
00240           if (_NEXT(_ls_q,list) == _ls_oldhead) {                                              \
00241             _ls_q = NULL;                                                                      \
00242           } else {                                                                             \
00243             _ls_q = _NEXT(_ls_q,list);                                                         \
00244           }                                                                                    \
00245           _RS(list);                                                                           \
00246           if (!_ls_q) break;                                                                   \
00247         }                                                                                      \
00248         _ls_qsize = _ls_insize;                                                                \
00249         while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) {                                    \
00250           if (_ls_psize == 0) {                                                                \
00251             _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
00252             if (_ls_q == _ls_oldhead) { _ls_q = NULL; }                                        \
00253           } else if (_ls_qsize == 0 || !_ls_q) {                                               \
00254             _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
00255             if (_ls_p == _ls_oldhead) { _ls_p = NULL; }                                        \
00256           } else if (cmp(_ls_p,_ls_q) <= 0) {                                                  \
00257             _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
00258             if (_ls_p == _ls_oldhead) { _ls_p = NULL; }                                        \
00259           } else {                                                                             \
00260             _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
00261             if (_ls_q == _ls_oldhead) { _ls_q = NULL; }                                        \
00262           }                                                                                    \
00263           if (_ls_tail) {                                                                      \
00264             _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list);                     \
00265           } else {                                                                             \
00266             _CASTASGN(list,_ls_e);                                                             \
00267           }                                                                                    \
00268           _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list);                          \
00269           _ls_tail = _ls_e;                                                                    \
00270         }                                                                                      \
00271         _ls_p = _ls_q;                                                                         \
00272       }                                                                                        \
00273       _CASTASGN(list->prev,_ls_tail);                                                          \
00274       _CASTASGN(_tmp2,list);                                                                   \
00275       _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp2); _RS(list);                           \
00276       if (_ls_nmerges <= 1) {                                                                  \
00277         _ls_looping=0;                                                                         \
00278       }                                                                                        \
00279       _ls_insize *= 2;                                                                         \
00280     }                                                                                          \
00281   } else _tmp=NULL; /* quiet gcc unused variable warning */                                    \
00282 } while (0)
00283 
00284 /******************************************************************************
00285  * singly linked list macros (non-circular)                                   *
00286  *****************************************************************************/
00287 #define LL_PREPEND(head,add)                                                                   \
00288 do {                                                                                           \
00289   (add)->next = head;                                                                          \
00290   head = add;                                                                                  \
00291 } while (0)
00292 
00293 #define LL_APPEND(head,add)                                                                    \
00294 do {                                                                                           \
00295   LDECLTYPE(head) _tmp;                                                                        \
00296   (add)->next=NULL;                                                                            \
00297   if (head) {                                                                                  \
00298     _tmp = head;                                                                               \
00299     while (_tmp->next) { _tmp = _tmp->next; }                                                  \
00300     _tmp->next=(add);                                                                          \
00301   } else {                                                                                     \
00302     (head)=(add);                                                                              \
00303   }                                                                                            \
00304 } while (0)
00305 
00306 #define LL_DELETE(head,del)                                                                    \
00307 do {                                                                                           \
00308   LDECLTYPE(head) _tmp;                                                                        \
00309   if ((head) == (del)) {                                                                       \
00310     (head)=(head)->next;                                                                       \
00311   } else {                                                                                     \
00312     _tmp = head;                                                                               \
00313     while (_tmp->next && (_tmp->next != (del))) {                                              \
00314       _tmp = _tmp->next;                                                                       \
00315     }                                                                                          \
00316     if (_tmp->next) {                                                                          \
00317       _tmp->next = ((del)->next);                                                              \
00318     }                                                                                          \
00319   }                                                                                            \
00320 } while (0)
00321 
00322 /* Here are VS2008 replacements for LL_APPEND and LL_DELETE */
00323 #define LL_APPEND_VS2008(head,add)                                                             \
00324 do {                                                                                           \
00325   if (head) {                                                                                  \
00326     (add)->next = head;     /* use add->next as a temp variable */                             \
00327     while ((add)->next->next) { (add)->next = (add)->next->next; }                             \
00328     (add)->next->next=(add);                                                                   \
00329   } else {                                                                                     \
00330     (head)=(add);                                                                              \
00331   }                                                                                            \
00332   (add)->next=NULL;                                                                            \
00333 } while (0)
00334 
00335 #define LL_DELETE_VS2008(head,del)                                                             \
00336 do {                                                                                           \
00337   if ((head) == (del)) {                                                                       \
00338     (head)=(head)->next;                                                                       \
00339   } else {                                                                                     \
00340     char *_tmp = (char*)(head);                                                                \
00341     while (head->next && (head->next != (del))) {                                              \
00342       head = head->next;                                                                       \
00343     }                                                                                          \
00344     if (head->next) {                                                                          \
00345       head->next = ((del)->next);                                                              \
00346     }                                                                                          \
00347     {                                                                                          \
00348       char **_head_alias = (char**)&(head);                                                    \
00349       *_head_alias = _tmp;                                                                     \
00350     }                                                                                          \
00351   }                                                                                            \
00352 } while (0)
00353 #ifdef NO_DECLTYPE
00354 #undef LL_APPEND
00355 #define LL_APPEND LL_APPEND_VS2008
00356 #undef LL_DELETE
00357 #define LL_DELETE LL_DELETE_VS2008
00358 #endif
00359 /* end VS2008 replacements */
00360 
00361 #define LL_FOREACH(head,el)                                                                    \
00362     for(el=head;el;el=el->next)
00363 
00364 #define LL_FOREACH_SAFE(head,el,tmp)                                                           \
00365   for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
00366 
00367 #define LL_SEARCH_SCALAR(head,out,field,val)                                                   \
00368 do {                                                                                           \
00369     LL_FOREACH(head,out) {                                                                     \
00370       if ((out)->field == (val)) break;                                                        \
00371     }                                                                                          \
00372 } while(0) 
00373 
00374 #define LL_SEARCH(head,out,elt,cmp)                                                            \
00375 do {                                                                                           \
00376     LL_FOREACH(head,out) {                                                                     \
00377       if ((cmp(out,elt))==0) break;                                                            \
00378     }                                                                                          \
00379 } while(0) 
00380 
00381 /******************************************************************************
00382  * doubly linked list macros (non-circular)                                   *
00383  *****************************************************************************/
00384 #define DL_PREPEND(head,add)                                                                   \
00385 do {                                                                                           \
00386  (add)->next = head;                                                                           \
00387  if (head) {                                                                                   \
00388    (add)->prev = (head)->prev;                                                                 \
00389    (head)->prev = (add);                                                                       \
00390  } else {                                                                                      \
00391    (add)->prev = (add);                                                                        \
00392  }                                                                                             \
00393  (head) = (add);                                                                               \
00394 } while (0)
00395 
00396 #define DL_APPEND(head,add)                                                                    \
00397 do {                                                                                           \
00398   if (head) {                                                                                  \
00399       (add)->prev = (head)->prev;                                                              \
00400       (head)->prev->next = (add);                                                              \
00401       (head)->prev = (add);                                                                    \
00402       (add)->next = NULL;                                                                      \
00403   } else {                                                                                     \
00404       (head)=(add);                                                                            \
00405       (head)->prev = (head);                                                                   \
00406       (head)->next = NULL;                                                                     \
00407   }                                                                                            \
00408 } while (0);
00409 
00410 #define DL_DELETE(head,del)                                                                    \
00411 do {                                                                                           \
00412   if ((del)->prev == (del)) {                                                                  \
00413       (head)=NULL;                                                                             \
00414   } else if ((del)==(head)) {                                                                  \
00415       (del)->next->prev = (del)->prev;                                                         \
00416       (head) = (del)->next;                                                                    \
00417   } else {                                                                                     \
00418       (del)->prev->next = (del)->next;                                                         \
00419       if ((del)->next) {                                                                       \
00420           (del)->next->prev = (del)->prev;                                                     \
00421       } else {                                                                                 \
00422           (head)->prev = (del)->prev;                                                          \
00423       }                                                                                        \
00424   }                                                                                            \
00425 } while (0);
00426 
00427 
00428 #define DL_FOREACH(head,el)                                                                    \
00429     for(el=head;el;el=el->next)
00430 
00431 /* this version is safe for deleting the elements during iteration */
00432 #define DL_FOREACH_SAFE(head,el,tmp)                                                           \
00433   for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
00434 
00435 /* these are identical to their singly-linked list counterparts */
00436 #define DL_SEARCH_SCALAR LL_SEARCH_SCALAR
00437 #define DL_SEARCH LL_SEARCH
00438 
00439 /******************************************************************************
00440  * circular doubly linked list macros                                         *
00441  *****************************************************************************/
00442 #define CDL_PREPEND(head,add)                                                                  \
00443 do {                                                                                           \
00444  if (head) {                                                                                   \
00445    (add)->prev = (head)->prev;                                                                 \
00446    (add)->next = (head);                                                                       \
00447    (head)->prev = (add);                                                                       \
00448    (add)->prev->next = (add);                                                                  \
00449  } else {                                                                                      \
00450    (add)->prev = (add);                                                                        \
00451    (add)->next = (add);                                                                        \
00452  }                                                                                             \
00453 (head)=(add);                                                                                  \
00454 } while (0)
00455 
00456 #define CDL_DELETE(head,del)                                                                   \
00457 do {                                                                                           \
00458   if ( ((head)==(del)) && ((head)->next == (head))) {                                          \
00459       (head) = 0L;                                                                             \
00460   } else {                                                                                     \
00461      (del)->next->prev = (del)->prev;                                                          \
00462      (del)->prev->next = (del)->next;                                                          \
00463      if ((del) == (head)) (head)=(del)->next;                                                  \
00464   }                                                                                            \
00465 } while (0);
00466 
00467 #define CDL_FOREACH(head,el)                                                                   \
00468     for(el=head;el;el=(el->next==head ? 0L : el->next)) 
00469 
00470 #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2)                                                    \
00471   for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL);                                        \
00472       (el) && ((tmp2)=(el)->next, 1);                                                          \
00473       ((el) = (((el)==(tmp1)) ? 0L : (tmp2))))
00474 
00475 #define CDL_SEARCH_SCALAR(head,out,field,val)                                                  \
00476 do {                                                                                           \
00477     CDL_FOREACH(head,out) {                                                                    \
00478       if ((out)->field == (val)) break;                                                        \
00479     }                                                                                          \
00480 } while(0) 
00481 
00482 #define CDL_SEARCH(head,out,elt,cmp)                                                           \
00483 do {                                                                                           \
00484     CDL_FOREACH(head,out) {                                                                    \
00485       if ((cmp(out,elt))==0) break;                                                            \
00486     }                                                                                          \
00487 } while(0) 
00488 
00489 #endif /* UTLIST_H */
00490 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Properties Defines

cocos2d for iPhone API Reference - Generated using Doxygen 1.7.4