list.h
上传用户:szjkjd
上传日期:2022-06-27
资源大小:8968k
文件大小:21k
源码类别:

浏览器

开发平台:

Visual C++

  1. /***********************************************************************
  2.  *                           特殊用法
  3.  * FOREACH(container, var, field)       : 遍历容器各个元素.(暂时仅支持FIFO,STACK,LIST)
  4.  **********************************************************************/
  5. /***********************************************************************
  6.  *                            FIFO 使用说明
  7.  *
  8.  * FIFO(type)                           : 定义一个FIFO.
  9.  * FIFO_V(type)                         : 定义一个FIFO,其中FIFO_COUNT是volatile类型.
  10.  * FIFO_ENTRY(type)                     : 定义FIFO的节点,需要处于结构体中.
  11.  *
  12.  * FIFO_FIRST(fifo)                     : 返回FIFO的首个元素.
  13.  * FIFO_LAST(fifo)                      : 返回FIFO的末尾元素.
  14.  * FIFO_COUNT(fifo)                     : 返回FIFO的元素个数.
  15.  * FIFO_NEXT(elm, field)                : 返回elm的后一个元素.
  16.  *
  17.  * FIFO_INIT(fifo)                      : 初始化FIFO.
  18.  * FIFO_INITIALIZER                     : 静态初始化FIFO.
  19.  * FIFO_POP(fifo, var, field)           : 获取FIFO的元素,该元素从FIFO中移除.
  20.  * FIFO_UNPOP(fifo, elm, field)         : 撤销从FIFO中获取元素的动作.
  21.  * FIFO_PUSH(fifo, elm, field)          : 把元素放到FIFO中.
  22.  *
  23.  ***********************************************************************/
  24. /***********************************************************************
  25.  *                            LIST 使用说明
  26.  *
  27.  * LIST(type)                           : 定义一个LIST.
  28.  * LIST_V(type)                         : 定义一个LIST,其中LIST_COUNT是volatile类型.
  29.  * LIST_ENTRY(type)                     : 定义LIST的节点,需要处于结构体中.
  30.  *
  31.  * LIST_FIRST(fifo)                     : 返回LIST的首个元素.
  32.  * LIST_LAST(fifo)                      : 返回LIST的末尾元素.
  33.  * LIST_COUNT(fifo)                     : 返回LIST的元素个数.
  34.  * LIST_NEXT(elm, field)                : 返回elm的后一个元素.
  35.  * LIST_PREV(elm, field)                : 返回elm的前一个元素.
  36.  *
  37.  * LIST_INIT(fifo)                      : 初始化LIST.
  38.  * LIST_INITIALIZER                     : 静态初始化LIST.
  39.  * LIST_POP_FRONT(list, var, field)     : 获取LIST的首个元素,该元素从LIST中移除.
  40.  * LIST_POP_BACK(list, var, field)      : 获取LIST的末尾元素,该元素从LIST中移除.
  41.  * LIST_PUSH_FRONT(list, elm, field)    : 把元素elm放到LIST的首位.
  42.  * LIST_PUSH_BACK(list, elm, field)     : 把元素elm放到LIST的末尾.
  43.  * LIST_REMOVE(list, elm, field)        : 从LIST中移除元素elm.
  44.  * LIST_MOVE(dstlist, srclist)          : 将srclist中的所有元素移到dstlist中 
  45.  *
  46.  ***********************************************************************/
  47. /***********************************************************************
  48.  *                            MIN_HEAP 使用说明
  49.  *
  50.  * MIN_HEAP(type)                       : 定义一个MIN_HEAP.
  51.  * MIN_HEAP_ENTRY(type)                 : 定义MIN_HEAP的节点,需要处于结构体中.
  52.  *
  53.  * MIN_HEAP_SIZE(heap)                  : 返回heap的容量.
  54.  * MIN_HEAP_COUNT(heap)                 : 返回heap的元素个数.
  55.  *
  56.  * MIN_HEAP_INIT(heap, cmp)             : 初始化heap,cmp为比较函数,cmp返回值是参数1-参数2的结果.
  57.  * MIN_HEAP_INITIALIZER(cmp)            : 静态初始化MIN_HEAP.
  58.  * MIN_HEAP_DESTROY(heap)               : 销毁heap.
  59.  *
  60.  * MIN_HEAP_TOP(heap)                   : 返回heap的首个元素.
  61.  * MIN_HEAP_POP(heap, elm, field)       : 返回heap的最小值.
  62.  * MIN_HEAP_PUSH(heap, elm, field)      : 将元素elm放入heap中.
  63.  * MIN_HEAP_REMOVE(heap, elm, field)    : 把元素elm从heap中移除.
  64.  * MIN_HEAP_FOREACH(heap, index, var, node): 遍历heap的各个元素.
  65.  *
  66.  ***********************************************************************/
  67. #ifndef _LIB_BASE_LIST_H_
  68. #define _LIB_BASE_LIST_H_
  69. #include <stdlib.h>
  70. #define FOREACH(container, var, field)                                
  71.         for ((var) = (container)->first; (var); (var) = (var)->field.next)
  72. /***********************************************************************
  73.  *                            FIFO 数据结构
  74.  ***********************************************************************/
  75. #define FIFO_V(type)                                                    
  76. struct {                                                                
  77.         type *first, *last;                                             
  78.         volatile int count;                                             
  79. }
  80. #define FIFO(type)                                                      
  81. struct {                                                                
  82.         type *first, *last;                                             
  83.         int count;                                                      
  84. }
  85. #define FIFO_ENTRY(type)                                                
  86. struct {                                                                
  87.         type *next;                                                     
  88. }
  89. /***********************************************************************
  90.  *                            FIFO 访问方法
  91.  ***********************************************************************/
  92. #define FIFO_FIRST(fifo)                ((fifo)->first)
  93. #define FIFO_LAST(fifo)                 ((fifo)->last)
  94. #define FIFO_COUNT(fifo)                ((fifo)->count)
  95. #define FIFO_NEXT(elm, field)           ((elm)->field.next)
  96. /***********************************************************************
  97.  *                            FIFO 函数
  98.  ***********************************************************************/
  99. #define FIFO_INIT(fifo)                 (fifo)->first = (fifo)->last = NULL, (fifo)->count = 0
  100. #define FIFO_INITIALIZER                {NULL, NULL, 0}
  101. #ifndef WIN32
  102. #define FIFO_POP(fifo, var, field)                ({                    
  103.         if (((var) = FIFO_FIRST(fifo))) {                               
  104.                 FIFO_FIRST(fifo) = FIFO_NEXT(var, field);               
  105.                 if (!--FIFO_COUNT(fifo)) FIFO_LAST(fifo) = NULL;        
  106.                 FIFO_NEXT(var, field) = NULL;                           
  107.         }                                                               
  108.         (var);                                                          
  109. })
  110. #else
  111. #define FIFO_POP(fifo, var, field) do {                
  112.         if (((var) = FIFO_FIRST(fifo))) {                               
  113.                 FIFO_FIRST(fifo) = FIFO_NEXT(var, field);               
  114.                 if (!--FIFO_COUNT(fifo)) FIFO_LAST(fifo) = NULL;        
  115.                 FIFO_NEXT(var, field) = NULL;                           
  116.         }                                                               
  117. } while(0)
  118. #endif
  119. #define FIFO_UNPOP(fifo, elm, field)              do {                  
  120.         FIFO_NEXT(elm, field) = FIFO_FIRST(fifo);                       
  121.         FIFO_FIRST(fifo) = (elm);                                       
  122.         if (!FIFO_COUNT(fifo)++) FIFO_LAST(fifo) = (elm);               
  123. } while (0)
  124. #define FIFO_PUSH(fifo, elm, field)               do {                  
  125.         if (FIFO_COUNT(fifo)++)                                         
  126.                 FIFO_NEXT(FIFO_LAST(fifo), field) = (elm);              
  127.         else                                                            
  128.                 FIFO_FIRST(fifo) = (elm);                               
  129.         FIFO_LAST(fifo) = (elm);                                        
  130.         FIFO_NEXT(elm, field) = NULL;                                   
  131. } while (0)
  132. ////////////////////////////////////////////////////////////////////////
  133. /***********************************************************************
  134.  *                            LIST 数据结构
  135.  ***********************************************************************/
  136. #define LIST_V(type)                                                    
  137. struct {                                                                
  138.         type *first, *last;                                             
  139.         volatile int count;                                             
  140. }
  141. #define LIST(type)                                                      
  142. struct {                                                                
  143.         type *first, *last;                                             
  144.         int count;                                                      
  145. }
  146. #define LIST_ENTRY(type)                                                
  147. struct {                                                                
  148.         type *prev, *next;                                              
  149. }
  150. /***********************************************************************
  151.  *                            LIST 访问方法
  152.  ***********************************************************************/
  153. #define LIST_FIRST(list)                ((list)->first)
  154. #define LIST_LAST(list)                 ((list)->last)
  155. #define LIST_COUNT(list)                ((list)->count)
  156. #define LIST_NEXT(elm, field)           ((elm)->field.next)
  157. #define LIST_PREV(elm, field)           ((elm)->field.prev)
  158. /***********************************************************************
  159.  *                            LIST 数据结构
  160.  ***********************************************************************/
  161. #define LIST_INIT(list)                 (list)->first = (list)->last = NULL, (list)->count = 0
  162. #define LIST_INITIALIZER                {NULL, NULL, 0}
  163. #define LIST_REMOVE(list, elm, field)                  do {             
  164.         if (!LIST_NEXT(elm, field) && !LIST_PREV(elm, field) && LIST_FIRST(list) != (elm)) break;   
  165.         if (LIST_PREV(elm, field)) LIST_NEXT(LIST_PREV(elm, field), field) = LIST_NEXT(elm, field); 
  166.         if (LIST_NEXT(elm, field)) LIST_PREV(LIST_NEXT(elm, field), field) = LIST_PREV(elm, field); 
  167.         if (LIST_FIRST(list) == (elm)) LIST_FIRST(list) = LIST_NEXT(elm, field); 
  168.         if (LIST_LAST(list) == (elm)) LIST_LAST(list) = LIST_PREV(elm, field); 
  169.         LIST_NEXT(elm, field) = LIST_PREV(elm, field) = NULL;           
  170.         -- LIST_COUNT(list);                                            
  171. } while (0)
  172. #define LIST_POP_FRONT(list, var, field)                ({              
  173.         if (((var) = LIST_FIRST(list))) LIST_REMOVE(list, var, field);  
  174.         (var);                                                          
  175. })
  176. #define LIST_POP_BACK(list, var, field)                 ({              
  177.         if (((var) = LIST_LAST(list))) LIST_REMOVE(list, var, field);   
  178.         (var);                                                          
  179. })
  180. #define LIST_PUSH_FRONT(list, elm, field)              do {             
  181.         LIST_PREV(elm, field) = NULL;                                   
  182.         LIST_NEXT(elm, field) = LIST_FIRST(list);                       
  183.         if (LIST_NEXT(elm, field)) LIST_PREV(LIST_NEXT(elm, field), field) = (elm); 
  184.         LIST_FIRST(list) = (elm);                                       
  185.         if (!LIST_COUNT(list)++) LIST_LAST(list) = (elm);               
  186. } while (0)
  187. #define LIST_PUSH_BACK(list, elm, field)               do {             
  188.         LIST_PREV(elm, field) = LIST_LAST(list);                        
  189.         LIST_NEXT(elm, field) = NULL;                                   
  190.         if (LIST_PREV(elm, field)) LIST_NEXT(LIST_PREV(elm, field), field) = (elm); 
  191.         LIST_LAST(list) = (elm);                                        
  192.         if (!LIST_COUNT(list)++) LIST_FIRST(list) = (elm);              
  193. } while (0)
  194. #define LIST_MOVE(dstlist, srclist)                     do {            
  195.         if (LIST_LAST(dstlist)) LIST_NEXT(LIST_LAST(dstlist)) = LIST_FIRST(srclist); 
  196.         if (LIST_FRIST(srclist)) LIST_NEXT(LIST_FRIST(srclist)) = LIST_FIRST(dstlist); 
  197.         LIST_COUNT(dstlist) += LIST_COUNT(srclist);                     
  198.         LIST_INIT(srclist);                                             
  199. } while (0)
  200. /////////////////////////////////////////////////////////////////////////
  201. typedef struct _ListNode TListNode;
  202. struct _ListNode
  203. {
  204.         LIST_ENTRY(TListNode) node;
  205.         void *ptr;
  206. };
  207. typedef LIST(TListNode) TList;
  208. #define list_init(list)                 do {                            
  209.         alloctor_register(sizeof(TListNode));                           
  210.         LIST_INIT(list);                                                
  211. } while (0)
  212. #define list_count(list)                LIST_COUNT(list)
  213. #define list_first(list)                (LIST_FIRST(list)->ptr)
  214. #define list_last(list)                 (LIST_LAST(list)->ptr)
  215. #define list_push_front(list, node)     do {                            
  216.         TListNode *n = (TListNode *)alloctor_alloc(sizeof(TListNode));  
  217.         n->ptr = node;                                                  
  218.         LIST_PUSH_FRONT(list, n, node);                                 
  219. } while (0)
  220. #define list_push_front(list, node)     do {                            
  221.         TListNode *n = (TListNode *)alloctor_alloc(sizeof(TListNode));  
  222.         n->ptr = node;                                                  
  223.         LIST_PUSH_FRONT(list, n, node);                                 
  224. } while (0)
  225. #define list_push_back(list, node)     do {                             
  226.         TListNode *n = (TListNode *)alloctor_alloc(sizeof(TListNode));  
  227.         n->ptr = node;                                                  
  228.         LIST_PUSH_BACK(list, n, node);                                  
  229. } while (0)
  230. #define list_pop_front(list, node)     do {                             
  231.         TListNode *n = (TListNode *)alloctor_alloc(sizeof(TListNode));  
  232.         n->ptr = node;                                                  
  233.         LIST_POP_FRONT(list, n, node);                                  
  234. } while (0)
  235. #define list_pop_back(list, node)     do {                              
  236.         TListNode *n = (TListNode *)alloctor_alloc(sizeof(TListNode));  
  237.         n->ptr = node;                                                  
  238.         LIST_POP_BACK(list, n, node);                                   
  239. } while (0)
  240. #define list_push_remove(list, node)     do {                           
  241.         TListNode *n = (TListNode *)alloctor_alloc(sizeof(TListNode));  
  242.         n->ptr = node;                                                  
  243.         LIST_REMOVE(list, n, node);                                     
  244. } while (0)
  245. /***********************************************************************
  246.  *                            MIN_HEAP 数据结构
  247.  ***********************************************************************/
  248. #define MIN_HEAP(type) struct {                                         
  249.         type **elements;                                                
  250.         int size, count;                                                
  251.         int (*cmp)(type *, type *);                                     
  252. }
  253. #define MIN_HEAP_ENTRY(type) struct {                                   
  254.         int index;                                                      
  255. }
  256. /***********************************************************************
  257.  *                            MIN_HEAP 访问方法
  258.  ***********************************************************************/
  259. #define MIN_HEAP_SIZE(heap)             ((heap)->size)
  260. #define MIN_HEAP_COUNT(heap)            ((heap)->count)
  261. #define MIN_HEAP_INDEX(elm, field)      ((elm)->field.index)
  262. #define MIN_HEAP_ELMS(heap)             ((heap)->elements)
  263. #define MIN_HEAP_ELM(heap, index)       ((heap)->elements[index - 1])
  264. #define MIN_HEAP_CMP(heap)              ((heap)->cmp)
  265. #define MIN_HEAP_GREATER(heap, e1, e2)  (((heap)->cmp(e1, e2)) > 0)
  266. /***********************************************************************
  267.  *                            MIN_HEAP 函数
  268.  ***********************************************************************/
  269. #define MIN_HEAP_TOP(heap)                              ({              
  270.         (MIN_HEAP_COUNT(heap) ? *(MIN_HEAP_ELMS(heap)) : NULL);         
  271. })
  272. #define MIN_HEAP_SHIFT_UP(heap, index, elm, field)      do {            
  273.         int _up_i = index;                                              
  274.         int _parent = (_up_i) / 2;                                      
  275.         while (_up_i > 1 && MIN_HEAP_GREATER(heap, MIN_HEAP_ELM(heap, _parent), elm)) { 
  276.                 MIN_HEAP_ELM(heap, _up_i) = MIN_HEAP_ELM(heap, _parent); 
  277.                 MIN_HEAP_INDEX(MIN_HEAP_ELM(heap, _up_i), field) = _up_i; 
  278.                 _up_i = _parent;                                        
  279.                 _parent = (_up_i) / 2;                                  
  280.         }                                                               
  281.         MIN_HEAP_ELM(heap, _up_i) = elm;                                
  282.         MIN_HEAP_INDEX(MIN_HEAP_ELM(heap, _up_i), field) = _up_i;       
  283. } while (0)
  284. #define MIN_HEAP_SHIFT_DOWN(heap, index, elm, field)    do {            
  285.         int _down_i = index;                                            
  286.         int _child = 2 * (_down_i) + 1;                                 
  287.         while (_child <= (MIN_HEAP_COUNT(heap) + 1)) {                  
  288.                 if (_child == MIN_HEAP_COUNT(heap) + 1 ||               
  289.                                 MIN_HEAP_GREATER(heap, MIN_HEAP_ELM(heap, _child), MIN_HEAP_ELM(heap, _child - 1))) { 
  290.                         --_child;                                       
  291.                 }                                                       
  292.                 if (!MIN_HEAP_GREATER(heap, elm, MIN_HEAP_ELM(heap, _child))) { 
  293.                         break;                                          
  294.                 }                                                       
  295.                 MIN_HEAP_ELM(heap, _down_i) = MIN_HEAP_ELM(heap, _child); 
  296.                 MIN_HEAP_INDEX(MIN_HEAP_ELM(heap, _down_i), field) = _down_i; 
  297.                 _down_i = _child;                                       
  298.                 _child = 2 * (_down_i) + 1;                             
  299.         }                                                               
  300.         MIN_HEAP_SHIFT_UP(heap, _down_i, elm, field);                   
  301. } while (0)
  302. #define MIN_HEAP_INITIALIZER(cmp)               {NULL, 0, 0, cmp}
  303. #define MIN_HEAP_INIT(heap, cmp)                        do {            
  304.         MIN_HEAP_ELMS(heap) = NULL;                                     
  305.         MIN_HEAP_SIZE(heap) = 0;                                        
  306.         MIN_HEAP_COUNT(heap) = 0;                                       
  307.         MIN_HEAP_CMP(heap) = cmp;                                       
  308. } while (0)
  309. #define MIN_HEAP_DESTROY(heap)                          do {            
  310.         free(MIN_HEAP_ELMS(heap));                                      
  311.         MIN_HEAP_ELMS(heap) = NULL;                                     
  312.         MIN_HEAP_COUNT(heap) = MIN_HEAP_SIZE(heap) = 0;                 
  313. } while (0)
  314. #define MIN_HEAP_ADD_SIZE(size)                 (size) = ((size) > 256 ? (size) * 3 / 2 : (size) ? (size) * 2 : 8)
  315. #define MIN_HEAP_PUSH(heap, elm, field)                 do {            
  316.         if (MIN_HEAP_COUNT(heap) >= MIN_HEAP_SIZE(heap)) {              
  317.                 MIN_HEAP_ADD_SIZE(MIN_HEAP_SIZE(heap));                 
  318.                 MIN_HEAP_ELMS(heap) = realloc(MIN_HEAP_ELMS(heap), MIN_HEAP_SIZE(heap) * sizeof(elm)); 
  319.         } else if (MIN_HEAP_SIZE(heap) / 2 > MIN_HEAP_COUNT(heap) && MIN_HEAP_SIZE(heap) > 8) { 
  320.                 MIN_HEAP_SIZE(heap) = MIN_HEAP_SIZE(heap) * 3 / 4;      
  321.                 MIN_HEAP_ELMS(heap) = realloc(MIN_HEAP_ELMS(heap), MIN_HEAP_SIZE(heap) * sizeof(elm)); 
  322.         }                                                               
  323.         if (MIN_HEAP_COUNT(heap) < MIN_HEAP_SIZE(heap))                 
  324.                 MIN_HEAP_SHIFT_UP(heap, ++MIN_HEAP_COUNT(heap), elm, field); 
  325. } while (0)
  326. #define MIN_HEAP_POP(heap, elm, field)                  ({              
  327.         if (MIN_HEAP_COUNT(heap)) {                                     
  328.                 elm = MIN_HEAP_TOP(heap);                               
  329.                 --MIN_HEAP_COUNT(heap);                                 
  330.                 MIN_HEAP_SHIFT_DOWN(heap, 1, MIN_HEAP_ELM(heap, MIN_HEAP_COUNT(heap) + 1), field); 
  331.                 MIN_HEAP_INDEX(elm, field) = 0;                         
  332.         }                                                               
  333.         else {                                                          
  334.                 (elm) = NULL;                                           
  335.         }                                                               
  336.         (elm);                                                          
  337. })
  338. #define MIN_HEAP_REMOVE(heap, elm, field)               do {            
  339.         if (MIN_HEAP_INDEX(elm, field)) {                               
  340.                 --MIN_HEAP_COUNT(heap);                                 
  341.                 MIN_HEAP_SHIFT_DOWN(heap, MIN_HEAP_INDEX(elm, field), MIN_HEAP_ELM(heap, MIN_HEAP_COUNT(heap) + 1), field); 
  342.                 MIN_HEAP_INDEX(elm, field) = 0;                         
  343.         }                                                               
  344. } while (0)
  345. #define MIN_HEAP_FREE(head)                             do {            
  346.         free(MIN_HEAP_ELMS(heap));                                      
  347. } while (0)
  348. #define MIN_HEAP_FOREACH(heap, index, var, node)                        
  349.         for ((index) = 1, (var) = MIN_HEAP_ELM(heap, index);            
  350.                         (index) <= MIN_HEAP_COUNT(heap); ++(index), (var) = MIN_HEAP_ELM(heap, index))
  351. #endif
  352. // vim: ts=8 sw=8 expandtab