Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/nss/slist.h
blob: cd031eecd8b9dd294561777bf81821bf67c01169 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

struct slist { struct slist *next; };

void slist_init(struct slist* self);
bool slist_null(struct slist* self);
bool slist_non_null(struct slist* self);
size_t slist_length(struct slist* self);
void slist_extend(struct slist* self, struct slist* rhs);

#define container_of(PTR, TYPE, MEMBER) \
  (TYPE *)((char *)(PTR) - ((ptrdiff_t) &((TYPE*)0)->MEMBER))

/* FUN should return false to break iteration. */
/* NB: Comma-swallowing paste of gnu-style named variadic macro argument. */
#define slist_metafor(TYPE, MEMBER, PTR, BODY) { \
  struct slist *__slist_head = &((PTR)->MEMBER); \
  struct slist *__slist_iter = __slist_head->next; \
  struct slist *__slist_next; \
  while(__slist_iter != __slist_head) { \
        __slist_next = __slist_iter->next; \
        TYPE* __value_ptr = container_of(__slist_iter, TYPE, MEMBER); \
        BODY; \
        __slist_iter = __slist_next; \
  } \
}

#define slist_search(TYPE, MEMBER, PTR, FOUND_LABEL, NOTFOUND_LABEL, FUN, \
  COOKIE...) \
  slist_metafor(TYPE, MEMBER, PTR, \
    { if(!(FUN)(__value_ptr, ##COOKIE)) goto FOUND_LABEL; } \
  ) \
  goto NOTFOUND_LABEL;

#define slist_while(TYPE, MEMBER, PTR, ERR_LABEL, FUN, COOKIE...) \
  slist_metafor(TYPE, MEMBER, PTR, \
    { if((FUN)(__value_ptr, ##COOKIE)) goto ERR_LABEL; }) \

#define slist_for(TYPE, MEMBER, PTR, FUN, COOKIE...) \
  slist_metafor(TYPE, MEMBER, PTR, { (FUN)(__value_ptr, ##COOKIE); })