queue.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /* Copyright (c) 2013, Ben Noordhuis <info@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. #ifndef QUEUE_H_
  16. #define QUEUE_H_
  17. #include <stddef.h>
  18. typedef void *QUEUE[2];
  19. /* Private macros. */
  20. #define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0]))
  21. #define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1]))
  22. #define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q)))
  23. #define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q)))
  24. /* Public macros. */
  25. #define QUEUE_DATA(ptr, type, field) \
  26. ((type *) ((char *) (ptr) - offsetof(type, field)))
  27. /* Important note: mutating the list while QUEUE_FOREACH is
  28. * iterating over its elements results in undefined behavior.
  29. */
  30. #define QUEUE_FOREACH(q, h) \
  31. for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))
  32. #define QUEUE_EMPTY(q) \
  33. ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q))
  34. #define QUEUE_HEAD(q) \
  35. (QUEUE_NEXT(q))
  36. #define QUEUE_INIT(q) \
  37. do { \
  38. QUEUE_NEXT(q) = (q); \
  39. QUEUE_PREV(q) = (q); \
  40. } \
  41. while (0)
  42. #define QUEUE_ADD(h, n) \
  43. do { \
  44. QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \
  45. QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \
  46. QUEUE_PREV(h) = QUEUE_PREV(n); \
  47. QUEUE_PREV_NEXT(h) = (h); \
  48. } \
  49. while (0)
  50. #define QUEUE_SPLIT(h, q, n) \
  51. do { \
  52. QUEUE_PREV(n) = QUEUE_PREV(h); \
  53. QUEUE_PREV_NEXT(n) = (n); \
  54. QUEUE_NEXT(n) = (q); \
  55. QUEUE_PREV(h) = QUEUE_PREV(q); \
  56. QUEUE_PREV_NEXT(h) = (h); \
  57. QUEUE_PREV(q) = (n); \
  58. } \
  59. while (0)
  60. #define QUEUE_MOVE(h, n) \
  61. do { \
  62. if (QUEUE_EMPTY(h)) \
  63. QUEUE_INIT(n); \
  64. else { \
  65. QUEUE* q = QUEUE_HEAD(h); \
  66. QUEUE_SPLIT(h, q, n); \
  67. } \
  68. } \
  69. while (0)
  70. #define QUEUE_INSERT_HEAD(h, q) \
  71. do { \
  72. QUEUE_NEXT(q) = QUEUE_NEXT(h); \
  73. QUEUE_PREV(q) = (h); \
  74. QUEUE_NEXT_PREV(q) = (q); \
  75. QUEUE_NEXT(h) = (q); \
  76. } \
  77. while (0)
  78. #define QUEUE_INSERT_TAIL(h, q) \
  79. do { \
  80. QUEUE_NEXT(q) = (h); \
  81. QUEUE_PREV(q) = QUEUE_PREV(h); \
  82. QUEUE_PREV_NEXT(q) = (q); \
  83. QUEUE_PREV(h) = (q); \
  84. } \
  85. while (0)
  86. #define QUEUE_REMOVE(q) \
  87. do { \
  88. QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \
  89. QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \
  90. } \
  91. while (0)
  92. #endif /* QUEUE_H_ */