libevent中單鏈表操作
阿新 • • 發佈:2018-11-30
#include <stdio.h> #ifdef QUEUE_MACRO_DEBUG /* Store the last 2 places the queue element or head was altered */ struct qm_trace { char * lastfile; int lastline; char * prevfile; int prevline; }; #define TRACEBUF struct qm_trace trace; #define TRASHIT(x) do {(x) = (void *)-1;} while (0) #define QMD_TRACE_HEAD(head) do { \ (head)->trace.prevline = (head)->trace.lastline; \ (head)->trace.prevfile = (head)->trace.lastfile; \ (head)->trace.lastline = __LINE__; \ (head)->trace.lastfile = __FILE__; \ } while (0) #define QMD_TRACE_ELEM(elem) do { \ (elem)->trace.prevline = (elem)->trace.lastline; \ (elem)->trace.prevfile = (elem)->trace.lastfile; \ (elem)->trace.lastline = __LINE__; \ (elem)->trace.lastfile = __FILE__; \ } while (0) #else #define QMD_TRACE_ELEM(elem) #define QMD_TRACE_HEAD(head) #define TRACEBUF #define TRASHIT(x) #endif /* QUEUE_MACRO_DEBUG */ /* * Horrible macros to enable use of code that was meant to be C-specific * (and which push struct onto type) in C++; without these, C++ code * that uses these macros in the context of a class will blow up * due to "struct" being preprended to "type" by the macros, causing * inconsistent use of tags. * * This approach is necessary because these are macros; we have to use * these on a per-macro basis (because the queues are implemented as * macros, disabling this warning in the scope of the header file is * insufficient), whuch means we can't use #pragma, and have to use * _Pragma. We only need to use these for the queue macros that * prepend "struct" to "type" and will cause C++ to blow up. */ #if defined(__clang__) && defined(__cplusplus) #define __MISMATCH_TAGS_PUSH \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wmismatched-tags\"") #define __MISMATCH_TAGS_POP \ _Pragma("clang diagnostic pop") #else #define __MISMATCH_TAGS_PUSH #define __MISMATCH_TAGS_POP #endif /* * Singly-linked List declarations. */ #define SLIST_HEAD(name, type) \ __MISMATCH_TAGS_PUSH \ struct name { \ struct type *slh_first; /* first element */ \ } \ __MISMATCH_TAGS_POP #define SLIST_HEAD_INITIALIZER(head) \ { NULL } #define SLIST_ENTRY(type) \ __MISMATCH_TAGS_PUSH \ struct { \ struct type *sle_next; /* next element */ \ } \ __MISMATCH_TAGS_POP /* * Singly-linked List functions. */ #define SLIST_EMPTY(head) ((head)->slh_first == NULL) #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_FOREACH(var, head, field) \ for ((var) = SLIST_FIRST((head)); \ (var); \ (var) = SLIST_NEXT((var), field)) #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = SLIST_FIRST((head)); \ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ (var) = (tvar)) #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ for ((varp) = &SLIST_FIRST((head)); \ ((var) = *(varp)) != NULL; \ (varp) = &SLIST_NEXT((var), field)) #define SLIST_INIT(head) do { \ SLIST_FIRST((head)) = NULL; \ } while (0) #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ SLIST_NEXT((slistelm), field) = (elm); \ } while (0) #define SLIST_INSERT_HEAD(head, elm, field) do { \ SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ SLIST_FIRST((head)) = (elm); \ } while (0) #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) #define SLIST_REMOVE(head, elm, type, field) \ __MISMATCH_TAGS_PUSH \ do { \ if (SLIST_FIRST((head)) == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } \ else { \ struct type *curelm = SLIST_FIRST((head)); \ while (SLIST_NEXT(curelm, field) != (elm)) \ curelm = SLIST_NEXT(curelm, field); \ SLIST_REMOVE_AFTER(curelm, field); \ } \ TRASHIT((elm)->field.sle_next); \ } while (0) \ __MISMATCH_TAGS_POP #define SLIST_REMOVE_AFTER(elm, field) do { \ SLIST_NEXT(elm, field) = \ SLIST_NEXT(SLIST_NEXT(elm, field), field); \ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \ SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ } while (0) struct Data { SLIST_ENTRY(Data) next; int m_iData; //other object.. }; //利用巨集SLIST_HEAD定義一個表頭 SLIST_HEAD(myHead, Data); static struct myHead listHead; int main(void) { struct Data *pIndex = NULL; struct Data *pIndex_tmp = NULL; struct Data **pIndex_tmp1 = NULL; struct Data listDataElm1 = { NULL, 1 }; struct Data listDataElm2 = { NULL, 2 }; struct Data listDataElm3 = { NULL, 3 }; struct Data listDataElm4 = { NULL, 4 }; struct Data listDataElm5 = { NULL, 5 }; //利用巨集SLIST_INIT初始化表頭 SLIST_INIT(&listHead); //利用巨集SLIST_EMPTY來判斷一個連結串列是否為空 if (SLIST_EMPTY(&listHead)) printf("this Singly-linked List is null!\r\n"); //利用巨集SLIST_INSERT_HEAD向表頭插入一個物件 SLIST_INSERT_HEAD(&listHead, &listDataElm1, next); //利用巨集SLIST_INSERT_AFTER向連結串列的尾部新增物件 SLIST_INSERT_AFTER(&listDataElm1, &listDataElm2, next); SLIST_INSERT_AFTER(&listDataElm2, &listDataElm3, next); SLIST_INSERT_AFTER(&listDataElm3, &listDataElm4, next); SLIST_INSERT_AFTER(&listDataElm4, &listDataElm5, next); SLIST_FOREACH(pIndex, &listHead, next) { if (pIndex != NULL){ printf("SLIST_FOREACH pIndex->m_iData = %d\r\n", pIndex->m_iData); } } // 多遍歷到前一個數據 SLIST_FOREACH_PREVPTR(pIndex, pIndex_tmp1, &listHead, next){ if (pIndex != NULL){ printf("SLIST_FOREACH_PREVPTR pIndex->m_iData = %d\r\n", pIndex->m_iData); } } SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp) { if (pIndex != NULL){ printf("SLIST_FOREACH_SAFE pIndex->m_iData = %d\r\n", pIndex->m_iData); } } // 連結串列頭刪 SLIST_REMOVE_HEAD(&listHead, next); SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp) { if (pIndex != NULL){ printf("SLIST_REMOVE_HEAD pIndex->m_iData = %d\r\n", pIndex->m_iData); } } // 連結串列尾刪 SLIST_REMOVE_AFTER(&listDataElm4, next); SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp) { if (pIndex != NULL){ printf("SLIST_REMOVE_AFTER pIndex->m_iData = %d\r\n", pIndex->m_iData); } } // 刪除連結串列指定位置資料 SLIST_REMOVE(&listHead, &listDataElm3, Data, next); SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp) { if (pIndex != NULL){ printf("SLIST_REMOVE pIndex->m_iData = %d\r\n", pIndex->m_iData); } } return 0; }