#include "c_LinkList.h" #include #include #include "c_Test.h" typedef struct { int id; int is_processed; } DataEvent_t; TEST_CASE(test_nosentinel_link_list_and_iterator_flow) { c_LinkList_t list; // 验证你的新 Init API ASSERT_INT_EQ(C_ERR_OK, c_LinkList_Init(&list, sizeof(DataEvent_t), NULL)); ASSERT_TRUE(0==list.head); // 确认 head 严格等于 0 ASSERT_TRUE(c_LinkList_IsEmpty(&list)); DataEvent_t e1 = { .id = 10, .is_processed = 1 }; // 已处理,迭代时擦除 DataEvent_t e2 = { .id = 20, .is_processed = 0 }; DataEvent_t e3 = { .id = 30, .is_processed = 1 }; // 已处理,边界连续擦除 DataEvent_t e4 = { .id = 40, .is_processed = 0 }; // 1. 验证 AddTail 与 AddHead 在无哨兵下的完美二级指针闭环运转 ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddTail(&list, &e1)); // Head -> 10 ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddTail(&list, &e2)); // Head -> 10 -> 20 ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddTail(&list, &e3)); // Head -> 10 -> 20 -> 30 ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddHead(&list, &e4)); // 头插 40, 拓扑进化为: Head -> 40 -> 10 -> 20 -> 30 ASSERT_INT_EQ(4, c_LinkList_Size(&list)); // 2. 启动极致无哨兵二级指针迭代清理流 c_LinkListIter_t it; c_LinkListIter_Init(&it, &list); int scanned = 0; while (c_LinkListIter_HasNext(&it)) { DataEvent_t* ev = (DataEvent_t*)c_LinkListIter_Get(&it); ASSERT_PTR_NOT_NULL(ev); scanned++; if (ev->is_processed) { // 自主剔除:当剔除 e1(10) 时,由于它是当时的第二项,其前驱是 e4 的 next // 当剔除头项或末尾项时,二级指针无需任何 if 分支,在硬件层面一路展平串联 c_LinkListIter_Remove(&it); continue; } c_LinkListIter_Next(&it); } // 3. 终极断言验证 ASSERT_INT_EQ(4, scanned); ASSERT_INT_EQ(2, c_LinkList_Size(&list)); // 2 个已处理的脏数据被定点抹杀 // 严苛验证存活项的相对物理连续性 (剩下了 40 和 20) DataEvent_t* r0 = (DataEvent_t*)c_LinkList_Get(&list, 0); DataEvent_t* r1 = (DataEvent_t*)c_LinkList_Get(&list, 1); ASSERT_PTR_NOT_NULL(r0); ASSERT_PTR_NOT_NULL(r1); ASSERT_INT_EQ(40, r0->id); ASSERT_INT_EQ(20, r1->id); // 校验 naked 单链表的物理封底指针是否干净合拢 ASSERT_TRUE(c_LinkNode_Get(list.head) == r0); // list.head 应该妥妥地挂在 40 节点上 ASSERT_TRUE(c_LinkNode_Get(list.head->next) == r1); // 40 的下一个由于 10 死了,直接跨越连到了 20 节点 ASSERT_TRUE(c_LinkNode_Get(list.head->next->next) == NULL); // 20 作为最后一个节点,其 next 指针域必须被强制完美封底为 NULL c_LinkList_Destroy(&list); } int main(void) { TEST_START(C_NoSentinel_LinkList_System_Tests); RUN_TEST(test_nosentinel_link_list_and_iterator_flow); TEST_REPORT(); RETURN_TEST_STATUS; }