Files
cKit/Foundation/c_LinkList.h
T
2026-08-30 01:48:03 +08:00

123 lines
4.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef INCLUDED_C_LINKLIST_H
#define INCLUDED_C_LINKLIST_H
#ifndef INCLUDED_C_TYPES_H
#include <c_Types.h>
#endif /*INCLUDED_C_TYPES_H*/
#ifndef INCLUDED_C_ALLOCATOR_H
#include <c_Allocator.h>
#endif /*INCLUDED_C_ALLOCATOR_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct c_LinkNode_t {
struct c_LinkNode_t* next; // 后驱节点
// 后面会紧跟一整块大小为 item_size 的物理连续内存块直接存放真实数据值
} c_LinkNode_t;
// 闭环泛型单向链表控制头
typedef struct {
c_LinkNode_t* head; // 哑哨兵头节点(Dummy Head
c_size_t item_size; // 单个元素的字节大小
c_size_t size; // 当前链表中已有的有效元素个数
c_Allocator_t allocator; // 内部绑定的自主内存管理器
} c_LinkList_t;
typedef struct {
c_LinkList_t* list; // 绑定的非 const 宿主链表,用于联动 size
c_LinkNode_t** pp; // 核心二级指针,映射前驱或控制头指针域物理坑位地址
} c_LinkListIter_t;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
c_err_t c_LinkList_Init(c_LinkList_t* self, c_size_t item_size, c_Allocator_t* allocator);
void c_LinkList_Destroy(c_LinkList_t* self);
// 核心单向链表操作 API (值复制存储模式)
c_err_t c_LinkList_AddHead(c_LinkList_t* self, const void* item);
c_err_t c_LinkList_AddTail(c_LinkList_t* self, const void* item);
c_err_t c_LinkList_RemoveAt(c_LinkList_t* self, c_size_t index, void* out_item);
c_err_t c_LinkList_Read(const c_LinkList_t* self, c_size_t index, void* out_item);
void* c_LinkList_Get(const c_LinkList_t* self, c_size_t index);
void c_LinkList_Clear(c_LinkList_t* self);
// 内联高频辅助接口
C_STATIC_FORCE_INLINE
c_size_t c_LinkList_Size(const c_LinkList_t* self) {
if (!self) return 0;
return self->size; // O(1) 实时读取
}
C_STATIC_FORCE_INLINE
bool c_LinkList_IsEmpty(const c_LinkList_t* self) {
return c_LinkList_Size(self) == 0;
}
C_STATIC_FORCE_INLINE
void* c_LinkNode_Get(const c_LinkNode_t* self) {
if (!self) return NULL;
return ((void*)((char*)(self) + sizeof(c_LinkNode_t)));
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
void c_LinkListIter_Init(c_LinkListIter_t* self, c_LinkList_t* list) {
if (!self) return;
self->list = list;
if (!list) {
self->pp = NULL;
return;
}
// 灵魂一笔:初始直接指向控制头内部的那个真实的 head 指针变量地址
self->pp = &(list->head);
}
C_STATIC_FORCE_INLINE
bool c_LinkListIter_HasNext(const c_LinkListIter_t* self) {
return (self != NULL && self->pp != NULL && *self->pp != NULL);
}
C_STATIC_FORCE_INLINE
void* c_LinkListIter_Get(c_LinkListIter_t* self) {
if (!c_LinkListIter_HasNext(self)) return NULL;
// 获取当前变长节点紧随其后的用户数据地址区域
return ((void*)((char*)(*self->pp) + sizeof(c_LinkNode_t)));
}
C_STATIC_FORCE_INLINE
void* c_LinkListIter_Next(c_LinkListIter_t* self) {
if (!c_LinkListIter_HasNext(self)) return NULL;
void* user_data = ((void*)((char*)(*self->pp) + sizeof(c_LinkNode_t)));
// 大步向前滑进:让二级指针改为指向当前节点内部的 next 域地址
self->pp = &((*self->pp)->next);
return user_data;
}
/**
* @brief 无哨兵裸链表极度抗震防跑飞自主擦除接口 (完美免疫 SIGSEGV)
*/
C_STATIC_FORCE_INLINE
void c_LinkListIter_Remove(c_LinkListIter_t* self) {
if (!c_LinkListIter_HasNext(self) || !self->list) return;
c_LinkList_t* host_list = self->list;
c_LinkNode_t* node_to_free = *self->pp;
// 拓扑剥离:修改前驱指向(若当前是第一个节点,这里会自动就地改写 host_list->head 的指向!)
// 修改完的这一瞬间,迭代器的 pp 变量自动对齐到了下一项有效节点,状态瞬间康复
*self->pp = node_to_free->next;
// 呼叫内置管理器物理火化
c_Allocator_Free(&host_list->allocator, node_to_free);
host_list->size--;
}
#endif /*INCLUDED_C_LINKLIST_H*/