mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Add slist.h
Add a macro-based singly-linked list implementation to the codebase, inspired by the doubly-linked list in list.h.
This commit is contained in:
parent
2d72b48e62
commit
04fdf242a8
1 changed files with 82 additions and 0 deletions
82
lib/isc/include/isc/slist.h
Normal file
82
lib/isc/include/isc/slist.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*! \file isc/slist.h
|
||||
* \brief
|
||||
* Implements macros for singly-linked lists.
|
||||
*
|
||||
* This module provides a generic implementation of singly-linked lists
|
||||
* similar to isc/list.h but optimized for forward-only traversal.
|
||||
*/
|
||||
|
||||
#define ISC_SLIST_INITIALIZER \
|
||||
{ \
|
||||
.head = NULL, \
|
||||
}
|
||||
|
||||
#define ISC_SLINK_INITIALIZER \
|
||||
{ \
|
||||
.next = NULL, \
|
||||
}
|
||||
|
||||
#define ISC_SLIST(type) \
|
||||
struct { \
|
||||
type *head; \
|
||||
}
|
||||
|
||||
#define ISC_SLINK(type) \
|
||||
struct { \
|
||||
type *next; \
|
||||
}
|
||||
|
||||
#define ISC_SLIST_HEAD(list) ((list).head)
|
||||
#define ISC_SLIST_EMPTY(list) ((list).head == NULL)
|
||||
|
||||
#define ISC_SLIST_PREPEND(list, elt, link) \
|
||||
({ \
|
||||
(elt)->link.next = (list).head; \
|
||||
(list).head = (elt); \
|
||||
})
|
||||
|
||||
#define ISC_SLIST_INSERTAFTER(after, elt, link) \
|
||||
({ \
|
||||
(elt)->link.next = (after)->link.next; \
|
||||
(after)->link.next = (elt); \
|
||||
})
|
||||
|
||||
#define ISC_SLIST_NEXT(elt, link) ((elt)->link.next)
|
||||
|
||||
/* clang-format off */
|
||||
#define ISC_SLIST_FOREACH_FROM(elt, list, link, first) \
|
||||
for (typeof(first) elt = first, \
|
||||
elt##_next = (elt != NULL) ? ISC_SLIST_NEXT(elt, link) : NULL; \
|
||||
elt != NULL; \
|
||||
elt = elt##_next, \
|
||||
elt##_next = (elt != NULL) ? ISC_SLIST_NEXT(elt, link) : NULL)
|
||||
|
||||
#define ISC_SLIST_FOREACH(elt, list, link) \
|
||||
ISC_SLIST_FOREACH_FROM(elt, list, link, ISC_SLIST_HEAD(list))
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
/* Iteration over pointer-to-pointer for safe operations */
|
||||
#define ISC_SLIST_FOREACH_PTR(p, head) \
|
||||
for (typeof(head) p = (head); *p != NULL; )
|
||||
|
||||
#define ISC_SLIST_PTR_REMOVE(p, elt, link_field) \
|
||||
(*(p) = ISC_SLIST_NEXT(elt, link_field))
|
||||
|
||||
#define ISC_SLIST_PTR_ADVANCE(p, link_field) \
|
||||
(p = &ISC_SLIST_NEXT(*p, link_field))
|
||||
Loading…
Reference in a new issue