brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.0 KiB · 21e80f4 Raw
263 lines · c
1//===-- Macros defined in sys/queue.h header file -------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H10#define LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H11 12#include "containerof-macro.h"13#include "null-macro.h"14 15#ifdef __cplusplus16#define QUEUE_TYPEOF(type) type17#else18#define QUEUE_TYPEOF(type) struct type19#endif20 21// Singly-linked list definitions.22 23#define SLIST_HEAD(name, type)                                                 \24  struct name {                                                                \25    struct type *slh_first;                                                    \26  }27 28#define SLIST_CLASS_HEAD(name, type)                                           \29  struct name {                                                                \30    class type *slh_first;                                                     \31  }32 33#define SLIST_HEAD_INITIALIZER(head)                                           \34  { NULL }35 36#define SLIST_ENTRY(type)                                                      \37  struct {                                                                     \38    struct type *next;                                                         \39  }40 41#define SLIST_CLASS_ENTRY(type)                                                \42  struct {                                                                     \43    class type *next;                                                          \44  }45 46// Singly-linked list access methods.47 48#define SLIST_EMPTY(head) ((head)->slh_first == NULL)49#define SLIST_FIRST(head) ((head)->slh_first)50#define SLIST_NEXT(elem, field) ((elem)->field.next)51 52#define SLIST_FOREACH(var, head, field)                                        \53  for ((var) = SLIST_FIRST(head); (var); (var) = SLIST_NEXT(var, field))54 55#define SLIST_FOREACH_FROM(var, head, field)                                   \56  if (!(var))                                                                  \57    (var) = SLIST_FIRST(head);                                                 \58  for (; (var); (var) = SLIST_NEXT(var, field))59 60#define SLIST_FOREACH_SAFE(var, head, field, tvar)                             \61  for ((var) = SLIST_FIRST(head);                                              \62       (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar))63 64#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)                        \65  if (!(var))                                                                  \66    (var) = SLIST_FIRST(head);                                                 \67  for (; (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar))68 69// Singly-linked list functions.70 71#define SLIST_CONCAT(head1, head2, type, field)                                \72  do {                                                                         \73    if (SLIST_EMPTY(head1)) {                                                  \74      if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL)                   \75        SLIST_INIT(head2);                                                     \76    } else if (!SLIST_EMPTY(head2)) {                                          \77      QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head1);                            \78      while (SLIST_NEXT(cur, field) != NULL)                                   \79        cur = SLIST_NEXT(cur, field);                                          \80      SLIST_NEXT(cur, field) = SLIST_FIRST(head2);                             \81      SLIST_INIT(head2);                                                       \82    }                                                                          \83  } while (0)84 85#define SLIST_INIT(head)                                                       \86  do {                                                                         \87    SLIST_FIRST(head) = NULL;                                                  \88  } while (0)89 90#define SLIST_INSERT_AFTER(slistelem, elem, field)                             \91  do {                                                                         \92    SLIST_NEXT(elem, field) = SLIST_NEXT(slistelem, field);                    \93    SLIST_NEXT(slistelem, field) = (elem);                                     \94  } while (0)95 96#define SLIST_INSERT_HEAD(head, elem, field)                                   \97  do {                                                                         \98    SLIST_NEXT(elem, field) = SLIST_FIRST(head);                               \99    SLIST_FIRST(head) = (elem);                                                \100  } while (0)101 102#define SLIST_REMOVE(head, elem, type, field)                                  \103  do {                                                                         \104    if (SLIST_FIRST(head) == (elem)) {                                         \105      SLIST_REMOVE_HEAD(head, field);                                          \106    } else {                                                                   \107      QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head);                             \108      while (SLIST_NEXT(cur, field) != (elem))                                 \109        cur = SLIST_NEXT(cur, field);                                          \110      SLIST_REMOVE_AFTER(cur, field);                                          \111    }                                                                          \112  } while (0)113 114#define SLIST_REMOVE_AFTER(elem, field)                                        \115  do {                                                                         \116    SLIST_NEXT(elem, field) = SLIST_NEXT(SLIST_NEXT(elem, field), field);      \117  } while (0)118 119#define SLIST_REMOVE_HEAD(head, field)                                         \120  do {                                                                         \121    SLIST_FIRST(head) = SLIST_NEXT(SLIST_FIRST(head), field);                  \122  } while (0)123 124#define SLIST_SWAP(head1, head2, type)                                         \125  do {                                                                         \126    QUEUE_TYPEOF(type) *first = SLIST_FIRST(head1);                            \127    SLIST_FIRST(head1) = SLIST_FIRST(head2);                                   \128    SLIST_FIRST(head2) = first;                                                \129  } while (0)130 131// Singly-linked tail queue definitions.132 133#define STAILQ_HEAD(name, type)                                                \134  struct name {                                                                \135    struct type *stqh_first;                                                   \136    struct type **stqh_last;                                                   \137  }138 139#define STAILQ_CLASS_HEAD(name, type)                                          \140  struct name {                                                                \141    class type *stqh_first;                                                    \142    class type **stqh_last;                                                    \143  }144 145#define STAILQ_HEAD_INITIALIZER(head)                                          \146  { NULL, &(head).stqh_first }147 148#define STAILQ_ENTRY(type)                                                     \149  struct {                                                                     \150    struct type *next;                                                         \151  }152 153#define STAILQ_CLASS_ENTRY(type)                                               \154  struct {                                                                     \155    class type *next;                                                          \156  }157 158// Singly-linked tail queue access methods.159 160#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)161#define STAILQ_FIRST(head) ((head)->stqh_first)162#define STAILQ_LAST(head, type, field)                                         \163  (STAILQ_EMPTY(head)                                                          \164       ? NULL                                                                  \165       : __containerof((head)->stqh_last, QUEUE_TYPEOF(type), field.next))166#define STAILQ_NEXT(elem, field) ((elem)->field.next)167 168#define STAILQ_FOREACH(var, head, field)                                       \169  for ((var) = STAILQ_FIRST(head); (var); (var) = STAILQ_NEXT(var, field))170 171#define STAILQ_FOREACH_FROM(var, head, field)                                  \172  if (!(var))                                                                  \173    (var) = STAILQ_FIRST(head);                                                \174  for (; (var); (var) = STAILQ_NEXT(var, field))175 176#define STAILQ_FOREACH_SAFE(var, head, field, tvar)                            \177  for ((var) = STAILQ_FIRST(head);                                             \178       (var) && ((tvar) = STAILQ_NEXT(var, field), 1); (var) = (tvar))179 180#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)                       \181  if (!(var))                                                                  \182    (var) = STAILQ_FIRST(head);                                                \183  for (; (var) && ((tvar) = STAILQ_NEXT(var, field), 1); (var) = (tvar))184 185// Singly-linked tail queue functions.186 187#define STAILQ_CONCAT(head1, head2, type, field)                               \188  do {                                                                         \189    if (!STAILQ_EMPTY(head2)) {                                                \190      *(head1)->stqh_last = (head2)->stqh_first;                               \191      (head1)->stqh_last = (head2)->stqh_last;                                 \192      STAILQ_INIT(head2);                                                      \193    }                                                                          \194  } while (0)195 196#define STAILQ_INIT(head)                                                      \197  do {                                                                         \198    STAILQ_FIRST(head) = NULL;                                                 \199    (head)->stqh_last = &STAILQ_FIRST(head);                                   \200  } while (0)201 202#define STAILQ_INSERT_AFTER(head, listelem, elem, field)                       \203  do {                                                                         \204    if ((STAILQ_NEXT(elem, field) = STAILQ_NEXT(listelem, field)) == NULL)     \205      (head)->stqh_last = &STAILQ_NEXT(elem, field);                           \206    STAILQ_NEXT(listelem, field) = (elem);                                     \207  } while (0)208 209#define STAILQ_INSERT_HEAD(head, elem, field)                                  \210  do {                                                                         \211    if ((STAILQ_NEXT(elem, field) = STAILQ_FIRST(head)) == NULL)               \212      (head)->stqh_last = &STAILQ_NEXT(elem, field);                           \213    STAILQ_FIRST(head) = (elem);                                               \214  } while (0)215 216#define STAILQ_INSERT_TAIL(head, elem, field)                                  \217  do {                                                                         \218    STAILQ_NEXT(elem, field) = NULL;                                           \219    *(head)->stqh_last = (elem);                                               \220    (head)->stqh_last = &STAILQ_NEXT(elem, field);                             \221  } while (0)222 223#define STAILQ_REMOVE(head, elem, type, field)                                 \224  do {                                                                         \225    if (STAILQ_FIRST(head) == (elem)) {                                        \226      STAILQ_REMOVE_HEAD(head, field);                                         \227    } else {                                                                   \228      QUEUE_TYPEOF(type) *cur = STAILQ_FIRST(head);                            \229      while (STAILQ_NEXT(cur, field) != (elem))                                \230        cur = STAILQ_NEXT(cur, field);                                         \231      STAILQ_REMOVE_AFTER(head, cur, field);                                   \232    }                                                                          \233  } while (0)234 235#define STAILQ_REMOVE_AFTER(head, elem, field)                                 \236  do {                                                                         \237    if ((STAILQ_NEXT(elem, field) =                                            \238             STAILQ_NEXT(STAILQ_NEXT(elem, field), field)) == NULL)            \239      (head)->stqh_last = &STAILQ_NEXT(elem, field);                           \240  } while (0)241 242#define STAILQ_REMOVE_HEAD(head, field)                                        \243  do {                                                                         \244    if ((STAILQ_FIRST(head) = STAILQ_NEXT(STAILQ_FIRST(head), field)) == NULL) \245      (head)->stqh_last = &STAILQ_FIRST(head);                                 \246  } while (0)247 248#define STAILQ_SWAP(head1, head2, type)                                        \249  do {                                                                         \250    QUEUE_TYPEOF(type) *first = STAILQ_FIRST(head1);                           \251    QUEUE_TYPEOF(type) **last = (head1)->stqh_last;                            \252    STAILQ_FIRST(head1) = STAILQ_FIRST(head2);                                 \253    (head1)->stqh_last = (head2)->stqh_last;                                   \254    STAILQ_FIRST(head2) = first;                                               \255    (head2)->stqh_last = last;                                                 \256    if (STAILQ_EMPTY(head1))                                                   \257      (head1)->stqh_last = &STAILQ_FIRST(head1);                               \258    if (STAILQ_EMPTY(head2))                                                   \259      (head2)->stqh_last = &STAILQ_FIRST(head2);                               \260  } while (0)261 262#endif // LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H263