# liblist — 侵入式双向循环链表 API 参考

## 模块概述

liblist 是 Linux 内核风格的双向循环链表，纯头文件实现，C/C++ 兼容。
所有增删操作 O(1)，遍历 O(n)。核心思想：将 `struct list_head` 嵌入宿主结构体，
通过 `offsetof` 从链表节点指针反推宿主指针。

## 数据结构

```c
struct list_head
{
    struct list_head *next;   // 后继节点
    struct list_head *prev;   // 前驱节点
};
```

## 接口函数

### 初始化

#### LIST_HEAD(name)
```c
#define LIST_HEAD(name)  struct list_head name = LIST_HEAD_INIT(name)
```
编译期定义并初始化一个链表头。

**示例**:
```c
LIST_HEAD(my_list);  // 定义 my_list 并初始化为空链表
```

#### INIT_LIST_HEAD(h)
```c
void INIT_LIST_HEAD(struct list_head *h);
```
运行时初始化一个已存在的链表头。

**示例**:
```c
struct list_head head;
INIT_LIST_HEAD(&head);
```

### 添加

#### list_add(node, head)
头插法：将 node 插入到 head 之后（作为第一个元素）。

```c
void list_add(struct list_head *node, struct list_head *head);
```

#### list_add_tail(node, head)
尾插法：将 node 插入到 head 之前（作为最后一个元素）。

```c
void list_add_tail(struct list_head *node, struct list_head *head);
```

### 删除

#### list_del(entry)
从链表中移除节点（不释放内存）。

#### list_del_init(entry)
移除节点并重新初始化为自环，防止后续误操作导致悬空指针。

### 移动

#### list_move(list, head)
将节点移动到新链表头部。

#### list_move_tail(list, head)
将节点移动到新链表尾部。

### 替换

#### list_replace(old, node)
用 node 替换 old 的位置。

#### list_replace_init(old, node)
替换后初始化被替换节点。

### 判断

#### list_empty(head)
判断链表是否为空（头节点的 next 指向自身即为空）。

#### list_is_linked(entry)
判断节点是否已链入某个链表（非自环即为已链接）。

### 节点转宿主

#### list_entry(ptr, type, member)
```c
#define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr) - offsetof(type, member)))
```
从链表节点指针取回宿主结构体指针。

#### list_first_entry(head, type, member)
获取第一个宿主元素。

#### list_last_entry(head, type, member)
获取最后一个宿主元素。

#### list_first_entry_or_null(head, type, member)
安全获取第一个元素（链表空返回 NULL）。

### 遍历

#### list_for_each(pos, head)
遍历链表节点（仅获取 `struct list_head *` 指针）。

#### list_for_each_safe(pos, n, head)
安全遍历（可在遍历中删除当前节点 pos）。

#### list_for_each_entry(pos, head, member)
遍历宿主元素，最常用。

#### list_for_each_entry_safe(pos, n, head, member)
安全遍历宿主元素（可在遍历中删除 pos）。

### 拼接

#### list_splice_init(src, dst)
将 src 链表拼接到 dst 头部，src 被清空。

## 使用示例

```c
#include "myBase.h"
#include "list.h"

// 定义宿主结构体
struct sensor
{
    int              id;
    float            value;
    struct list_head node;   // 嵌入的链表节点
};

int main(void)
{
    // 定义链表头
    LIST_HEAD(sensor_list);

    // 创建 3 个传感器
    struct sensor s1 = { .id = 1, .value = 25.5 };
    struct sensor s2 = { .id = 2, .value = 30.0 };
    struct sensor s3 = { .id = 3, .value = 22.1 };

    // 尾插
    list_add_tail(&s1.node, &sensor_list);
    list_add_tail(&s2.node, &sensor_list);
    list_add_tail(&s3.node, &sensor_list);

    // 遍历并打印
    struct sensor *pos;
    list_for_each_entry(pos, &sensor_list, node)
    {
        printf("sensor %d: %.1f\n", pos->id, pos->value);
    }
    // 输出:
    // sensor 1: 25.5
    // sensor 2: 30.0
    // sensor 3: 22.1

    // 安全删除所有节点
    struct sensor *tmp;
    list_for_each_entry_safe(pos, tmp, &sensor_list, node)
    {
        printf("removing sensor %d\n", pos->id);
        list_del(&pos->node);
        free(pos);  // 如果是动态分配的
    }

    printf("list empty: %d\n", list_empty(&sensor_list));  // 1

    return 0;
}
```

## 依赖关系

- **依赖**: `<stddef.h>` (offsetof)
- **被依赖**: liblog, libdatacenter, 所有需要链表管理的模块
