111 lines
2.6 KiB
C
111 lines
2.6 KiB
C
/**
|
||
* Part of the Lccrt Project, under the Apache License v2.0
|
||
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
*
|
||
* lccrt_ilist.h - пользовательский интерфейс (динамической) компиляции.
|
||
*/
|
||
|
||
#ifndef LCCRT_ILIST_H
|
||
#define LCCRT_ILIST_H
|
||
|
||
/**
|
||
* Тип-шаблон для заголовка.
|
||
*/
|
||
#define lccrt_ilist_head( ptr) lccrt_ilist_head__##ptr
|
||
#define lccrt_ilist_head_typedef( ptr) \
|
||
typedef struct \
|
||
{ \
|
||
ptr first; \
|
||
ptr last; \
|
||
} lccrt_ilist_head( ptr)
|
||
|
||
/**
|
||
* Тип-шаблон для связи элементов.
|
||
*/
|
||
#define lccrt_ilist_unit( ptr) lccrt_ilist_unit__##ptr
|
||
#define lccrt_ilist_unit_typedef( ptr) \
|
||
typedef struct \
|
||
{ \
|
||
ptr prev; \
|
||
ptr next; \
|
||
} lccrt_ilist_unit( ptr)
|
||
|
||
/**
|
||
* Инициализация.
|
||
*/
|
||
#define lccrt_ilist_head_init( h) \
|
||
( \
|
||
(h)->first = 0, \
|
||
(h)->last = 0 \
|
||
)
|
||
|
||
/**
|
||
* Инициализация.
|
||
*/
|
||
#define lccrt_ilist_unit_init( h) \
|
||
( \
|
||
(h)->prev = 0, \
|
||
(h)->next = 0 \
|
||
)
|
||
|
||
/**
|
||
* Поменять значение ссылки.
|
||
*/
|
||
#define lccrt_ilist_assign_prev( l, u, v) ((u) ? ((u)->l.prev = (v)) : 0)
|
||
#define lccrt_ilist_assign_next( l, u, v) ((u) ? ((u)->l.next = (v)) : 0)
|
||
|
||
/**
|
||
* Связывание двух узлов со внутренним списком.
|
||
*/
|
||
#define lccrt_ilist_link( l, u, v) \
|
||
(\
|
||
lccrt_ilist_assign_next( l, u, v), \
|
||
lccrt_ilist_assign_prev( l, v, u), \
|
||
0 \
|
||
)
|
||
|
||
/**
|
||
* Вставка во внутренний список после заданного элемента нового узла.
|
||
*/
|
||
#define lccrt_ilist_insert( l, u, v) \
|
||
( \
|
||
lccrt_ilist_link( l, v, ((u) ? (u)->l.next : 0)), \
|
||
lccrt_ilist_link( l, u, v), \
|
||
(v) \
|
||
)
|
||
|
||
/**
|
||
* Вставка во внутренний список после заданного элемента нового узла.
|
||
*/
|
||
#define lccrt_ilist_head_insert( h, l, v) \
|
||
( \
|
||
lccrt_ilist_insert( l, (h)->last, v), \
|
||
((h)->last = v), \
|
||
(((h)->first) ? 0 : ((h)->first = (v))), \
|
||
(v) \
|
||
)
|
||
|
||
/**
|
||
* Удаление из списка текущего элемента.
|
||
*/
|
||
#define lccrt_ilist_remove( l, v) \
|
||
( \
|
||
lccrt_ilist_assign_next( l, (v)->l.prev, 0), \
|
||
lccrt_ilist_assign_prev( l, (v)->l.next, 0), \
|
||
(v)->l.prev \
|
||
)
|
||
|
||
/**
|
||
* Удаление из списка текущего элемента.
|
||
*/
|
||
#define lccrt_ilist_head_remove( h, l, v) \
|
||
( \
|
||
lccrt_ilist_remove( l, v), \
|
||
(((h)->first == (v)) ? ((h)->first = (v)->l.next) : 0), \
|
||
(((h)->last == (v)) ? ((h)->last = (v)->l.prev) : 0), \
|
||
(v)->l.prev \
|
||
)
|
||
|
||
#endif /* LCCRT_ILIST_H */
|