#include // 原地初始化:无哨兵模式,初始化 head 和 tail 全部指向 0 c_err_t c_LinkQueue_Init(c_LinkQueue_t* self, c_size_t item_size, c_Allocator_t* allocator) { if (!self || item_size == 0) return C_ERR_PARAM; self->allocator = (allocator != NULL) ? *allocator : c_DefaultAllocator; self->item_size = item_size; self->size = 0; self->head = NULL; self->tail = NULL; return C_ERR_OK; } // 入队操作 (基于二级指针的完美 O(1) 极致分支优化) c_err_t c_LinkQueue_Enqueue(c_LinkQueue_t* self, const void* item) { if (!self || !item) return C_ERR_PARAM; // 1. 分配变长节点空间 (控制壳 + 业务数据一体化) c_size_t total_bytes = sizeof(c_LinkQueueNode_t) + self->item_size; c_LinkQueueNode_t* new_node = (c_LinkQueueNode_t*)c_Allocator_Alloc(&self->allocator, total_bytes); if (!new_node) return C_ERR_NOMEM; new_node->next = NULL; memcpy(QUEUE_NODE_DATA(new_node), item, self->item_size); // 泛型值深度复制 // 2. 【二级指针艺术】:消灭空队列插入的分支 // 如果队列为空,新节点应该挂在 head 上;如果不为空,新节点应该挂在 tail->next 上 c_LinkQueueNode_t** pp = (self->head == NULL) ? &(self->head) : &(self->tail->next); // 一行代码,完美完成旧拓扑到新节点的挂接 *pp = new_node; // 3. 将尾指针直接移到最新插入的节点上,自愈性推进 self->tail = new_node; self->size++; return C_ERR_OK; } // 出队操作 (O(1) 性能,完美防御下溢) c_err_t c_LinkQueue_Dequeue(c_LinkQueue_t* self, void* out_item) { if (!self || self->size == 0 || !self->head) return C_ERR_OUTOFBOUND; // 锁定队头即将被剔除解体的物理节点 c_LinkQueueNode_t* node_to_free = self->head; // 如果用户需要拷出快照副本,执行深度拷贝 if (out_item) { memcpy(out_item, QUEUE_NODE_DATA(node_to_free), self->item_size); } // 队头指针向后大步滑进一格 self->head = node_to_free->next; // 边界特殊维护:如果出队后队列彻底被掏空了,尾指针 tail 必须安全地缩回 NULL if (self->head == NULL) { self->tail = NULL; } // 闭环退还包装内存壳 c_Allocator_Free(&self->allocator, node_to_free); self->size--; return C_ERR_OK; } // 查看队头元素 (只读原位窥探,零拷贝损耗) void* c_LinkQueue_Peek(const c_LinkQueue_t* self) { if (!self || self->size == 0 || !self->head) return NULL; return QUEUE_NODE_DATA(self->head); } // 高效清空队列 void c_LinkQueue_Clear(c_LinkQueue_t* self) { if (!self) return; c_LinkQueueNode_t* curr = self->head; while (curr) { c_LinkQueueNode_t* next_to_free = curr->next; c_Allocator_Free(&self->allocator, curr); curr = next_to_free; } self->head = NULL; self->tail = NULL; self->size = 0; } // 彻底销毁 void c_LinkQueue_Destroy(c_LinkQueue_t* self) { if (!self) return; c_LinkQueue_Clear(self); }