📄 apr_ring.h
字号:
APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \ APR_RING_NEXT((lep), link) = (ep1); \ } while (0)/** * Insert the element nep into the ring before element lep * (..lep.. becomes ..nep..lep..) * @warning This doesn't work for inserting before the first element or on * empty rings... see APR_RING_INSERT_HEAD for one that does * @param lep Element in the ring to insert before * @param nep Element to insert * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_INSERT_BEFORE(elem *lep, elem *nep, APR_RING_ENTRY link) */#define APR_RING_INSERT_BEFORE(lep, nep, link) \ APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)/** * Insert the element nep into the ring after element lep * (..lep.. becomes ..lep..nep..) * @warning This doesn't work for inserting after the last element or on * empty rings... see APR_RING_INSERT_TAIL for one that does * @param lep Element in the ring to insert after * @param nep Element to insert * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_INSERT_AFTER(elem *lep, elem *nep, APR_RING_ENTRY link) */#define APR_RING_INSERT_AFTER(lep, nep, link) \ APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)/** * Splice the sequence ep1..epN into the ring before the first element * (..hp.. becomes ..hp..ep1..epN..) * @param hp Head of the ring * @param ep1 First element in the sequence to splice in * @param epN Last element in the sequence to splice in * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_SPLICE_HEAD(head *hp, elem *ep1, elem *epN, struct elem, APR_RING_ENTRY link) */#define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) \ APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link), \ (ep1), (epN), link)/** * Splice the sequence ep1..epN into the ring after the last element * (..hp.. becomes ..ep1..epN..hp..) * @param hp Head of the ring * @param ep1 First element in the sequence to splice in * @param epN Last element in the sequence to splice in * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_SPLICE_TAIL(head *hp, elem *ep1, elem *epN, struct elem, APR_RING_ENTRY link) */#define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \ APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link), \ (ep1), (epN), link)/** * Insert the element nep into the ring before the first element * (..hp.. becomes ..hp..nep..) * @param hp Head of the ring * @param nep Element to insert * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_INSERT_HEAD(head *hp, elem *nep, struct elem, APR_RING_ENTRY link) */#define APR_RING_INSERT_HEAD(hp, nep, elem, link) \ APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)/** * Insert the element nep into the ring after the last element * (..hp.. becomes ..nep..hp..) * @param hp Head of the ring * @param nep Element to insert * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_INSERT_TAIL(head *hp, elem *nep, struct elem, APR_RING_ENTRY link) */#define APR_RING_INSERT_TAIL(hp, nep, elem, link) \ APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)/** * Concatenate ring h2 onto the end of ring h1, leaving h2 empty. * @param h1 Head of the ring to concatenate onto * @param h2 Head of the ring to concatenate * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_CONCAT(head *h1, head *h2, struct elem, APR_RING_ENTRY link) */#define APR_RING_CONCAT(h1, h2, elem, link) do { \ if (!APR_RING_EMPTY((h2), elem, link)) { \ APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link), \ APR_RING_FIRST((h2)), \ APR_RING_LAST((h2)), link); \ APR_RING_INIT((h2), elem, link); \ } \ } while (0)/** * Unsplice a sequence of elements from a ring * @warning The unspliced sequence is left with dangling pointers at either end * @param ep1 First element in the sequence to unsplice * @param epN Last element in the sequence to unsplice * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_UNSPLICE(elem *ep1, elem *epN, APR_RING_ENTRY link) */#define APR_RING_UNSPLICE(ep1, epN, link) do { \ APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \ APR_RING_NEXT((epN), link); \ APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \ APR_RING_PREV((ep1), link); \ } while (0)/** * Remove a single element from a ring * @warning The unspliced element is left with dangling pointers at either end * @param ep Element to remove * @param link The name of the APR_RING_ENTRY in the element struct * @deffunc void APR_RING_REMOVE(elem *ep, APR_RING_ENTRY link) */#define APR_RING_REMOVE(ep, link) \ APR_RING_UNSPLICE((ep), (ep), link)/** * Iterate through a ring * @param ep The current element * @param hp The ring to iterate over * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @tip This is the same as either: * <pre> * ep = APR_RING_FIRST(hp); * while (ep != APR_RING_SENTINEL(hp, elem, link)) { * ... * ep = APR_RING_NEXT(ep, link); * } * OR * for (ep = APR_RING_FIRST(hp); * ep != APR_RING_SENTINEL(hp, elem, link); * ep = APR_RING_NEXT(ep, link)) { * ... * } * </pre> * @deffunc void APR_RING_FOREACH(elem *ep, head *hp, struct elem, APR_RING_ENTRY link) */#define APR_RING_FOREACH(ep, hp, elem, link) \ for ((ep) = APR_RING_FIRST((hp)); \ (ep) != APR_RING_SENTINEL((hp), elem, link); \ (ep) = APR_RING_NEXT((ep), link))/** * Iterate through a ring backwards * @param ep The current element * @param hp The ring to iterate over * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @see APR_RING_FOREACH * @deffunc void APR_RING_FOREACH_REVERSE(elem *ep, head *hp, struct elem, APR_RING_ENTRY link) */#define APR_RING_FOREACH_REVERSE(ep, hp, elem, link) \ for ((ep) = APR_RING_LAST((hp)); \ (ep) != APR_RING_SENTINEL((hp), elem, link); \ (ep) = APR_RING_PREV((ep), link))/* Debugging tools: *//** * Print a single pointer value to STDERR * (This is a no-op unless APR_RING_DEBUG is defined.) * @param msg Descriptive message * @param ptr Pointer value to print * @deffunc void APR_RING_CHECK_ONE(char *msg, void *ptr) *//** * Dump all ring pointers to STDERR, starting with the head and looping all * the way around the ring back to the head. Aborts if an inconsistency * is found. * (This is a no-op unless APR_RING_DEBUG is defined.) * @param hp Head of the ring * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @param msg Descriptive message * @deffunc void APR_RING_CHECK(head *hp, struct elem, APR_RING_ENTRY link, char *msg) *//** * Dump all ring pointers to STDERR, starting with the given element and * looping all the way around the ring back to that element. Aborts if * an inconsistency is found. * (This is a no-op unless APR_RING_DEBUG is defined.) * @param ep The element * @param elem The name of the element struct * @param link The name of the APR_RING_ENTRY in the element struct * @param msg Descriptive message * @deffunc void APR_RING_CHECK_ELEM(elem *ep, struct elem, APR_RING_ENTRY link, char *msg) */#ifdef APR_RING_DEBUG#include <stdio.h>#define APR_RING_CHECK_ONE(msg, ptr) \ fprintf(stderr, "*** %s %p\n", msg, ptr)#define APR_RING_CHECK(hp, elem, link, msg) \ APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)#define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \ struct elem *start = (ep); \ struct elem *this = start; \ fprintf(stderr, "*** ring check start -- %s\n", msg); \ do { \ fprintf(stderr, "\telem %p\n", this); \ fprintf(stderr, "\telem->next %p\n", \ APR_RING_NEXT(this, link)); \ fprintf(stderr, "\telem->prev %p\n", \ APR_RING_PREV(this, link)); \ fprintf(stderr, "\telem->next->prev %p\n", \ APR_RING_PREV(APR_RING_NEXT(this, link), link)); \ fprintf(stderr, "\telem->prev->next %p\n", \ APR_RING_NEXT(APR_RING_PREV(this, link), link)); \ if (APR_RING_PREV(APR_RING_NEXT(this, link), link) != this) { \ fprintf(stderr, "\t*** this->next->prev != this\n"); \ break; \ } \ if (APR_RING_NEXT(APR_RING_PREV(this, link), link) != this) { \ fprintf(stderr, "\t*** this->prev->next != this\n"); \ break; \ } \ this = APR_RING_NEXT(this, link); \ } while (this != start); \ fprintf(stderr, "*** ring check end\n"); \ } while (0)#else#define APR_RING_CHECK_ONE(msg, ptr)#define APR_RING_CHECK(hp, elem, link, msg)#define APR_RING_CHECK_ELEM(ep, elem, link, msg)#endif#endif /* !APR_RING_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -