123 lines
4.2 KiB
C
123 lines
4.2 KiB
C
#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*/
|