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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
/*
* gensio - A library for abstracting stream I/O
* Copyright (C) 2018 Corey Minyard <minyard@acm.org>
*
* SPDX-License-Identifier: LGPL-2.1-only
*/
#ifndef GENSIO_LIST_H
#define GENSIO_LIST_H
#include <gensio/gensioosh_dllvisibility.h>
#include <gensio/gensio_types.h>
#include <stddef.h>
#include <stdbool.h>
/*
* Generic doubly-linked list operations.
*/
struct gensio_list;
struct gensio_link {
struct gensio_list *list;
struct gensio_link *next;
struct gensio_link *prev;
};
struct gensio_list {
struct gensio_link link;
};
GENSIOOSH_DLL_PUBLIC
void gensio_list_rm(struct gensio_list *list, struct gensio_link *link);
GENSIOOSH_DLL_PUBLIC
void gensio_list_add_head(struct gensio_list *list, struct gensio_link *link);
GENSIOOSH_DLL_PUBLIC
void gensio_list_add_tail(struct gensio_list *list, struct gensio_link *link);
GENSIOOSH_DLL_PUBLIC
void gensio_list_add_next(struct gensio_list *list, struct gensio_link *curr,
struct gensio_link *link);
GENSIOOSH_DLL_PUBLIC
void gensio_list_add_prev(struct gensio_list *list, struct gensio_link *curr,
struct gensio_link *link);
GENSIOOSH_DLL_PUBLIC
void gensio_list_init(struct gensio_list *list);
GENSIOOSH_DLL_PUBLIC
bool gensio_list_empty(struct gensio_list *list);
#define gensio_list_first(list) ((list)->link.next)
#define gensio_list_last(list) ((list)->link.prev)
/* Go to the next entry, returning NULL if at the end. */
#define gensio_list_next(list, linkv) ((linkv)->next == &(list)->link ? \
NULL : (linkv)->next)
/* Go to the next entry, wrapping around to the first entry if at end. */
#define gensio_list_next_wrap(list, linkv) ((linkv)->next == &(list)->link ? \
(list)->link.next : (linkv)->next)
#define gensio_list_for_each(list, l) \
for ((l) = (list)->link.next; (l) != &(list)->link; l = l->next)
#define gensio_list_for_each_safe(list, l, l2) \
for ((l) = (list)->link.next, (l2) = (l)->next; \
(l) != &(list)->link; (l) = (l2), (l2) = (l)->next )
/* Is the given list link in a list? */
#define gensio_list_link_inlist(l) ((l)->list != NULL)
/* Is the given list link in a specific list? */
#define gensio_list_link_in_this_list(l, listin) ((l)->list == (listin))
#define gensio_list_link_init(l) \
do { \
(l)->list = NULL; \
(l)->prev = NULL; \
(l)->next = NULL; \
} while(0)
#endif /* GENSIO_LIST_H */
|