1 /* Copyright (c) 2013, Ben Noordhuis <info (at) bnoordhuis.nl> 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 */ 15 16 #ifndef QUEUE_H_ 17 #define QUEUE_H_ 18 19 #include <stddef.h> 20 21 #define uv__queue_data(pointer, type, field) \ 22 ((type*) ((char*) (pointer) - offsetof(type, field))) 23 24 #define uv__queue_foreach(q, h) \ 25 for ((q) = (h)->next; (q) != (h); (q) = (q)->next) 26 27 static inline void uv__queue_init(struct uv__queue* q) { 28 q->next = q; 29 q->prev = q; 30 } 31 32 static inline int uv__queue_empty(const struct uv__queue* q) { 33 return q == q->next; 34 } 35 36 static inline struct uv__queue* uv__queue_head(const struct uv__queue* q) { 37 return q->next; 38 } 39 40 static inline struct uv__queue* uv__queue_next(const struct uv__queue* q) { 41 return q->next; 42 } 43 44 static inline void uv__queue_add(struct uv__queue* h, struct uv__queue* n) { 45 h->prev->next = n->next; 46 n->next->prev = h->prev; 47 h->prev = n->prev; 48 h->prev->next = h; 49 } 50 51 static inline void uv__queue_split(struct uv__queue* h, 52 struct uv__queue* q, 53 struct uv__queue* n) { 54 n->prev = h->prev; 55 n->prev->next = n; 56 n->next = q; 57 h->prev = q->prev; 58 h->prev->next = h; 59 q->prev = n; 60 } 61 62 static inline void uv__queue_move(struct uv__queue* h, struct uv__queue* n) { 63 if (uv__queue_empty(h)) 64 uv__queue_init(n); 65 else 66 uv__queue_split(h, h->next, n); 67 } 68 69 static inline void uv__queue_insert_head(struct uv__queue* h, 70 struct uv__queue* q) { 71 q->next = h->next; 72 q->prev = h; 73 q->next->prev = q; 74 h->next = q; 75 } 76 77 static inline void uv__queue_insert_tail(struct uv__queue* h, 78 struct uv__queue* q) { 79 q->next = h; 80 q->prev = h->prev; 81 q->prev->next = q; 82 h->prev = q; 83 } 84 85 static inline void uv__queue_remove(struct uv__queue* q) { 86 q->prev->next = q->next; 87 q->next->prev = q->prev; 88 } 89 90 #endif /* QUEUE_H_ */ 91