153 lines
5.3 KiB
C
153 lines
5.3 KiB
C
#include <c_SmartPtrVector.h>
|
|||
|
|
|
||
|
|
#define DEFAULT_INITIAL_CAPACITY 4
|
||
|
|
#define DEFAULT_GROW_FACTOR 2
|
||
|
|
|
||
|
|
c_err_t c_SmartPtrVector_Init(c_SmartPtrVector_t* vector, c_size_t capacity) {
|
||
|
|
if (!vector) return C_ERR_PARAM;
|
||
|
|
if (capacity>0) {
|
||
|
|
vector->array = C_CALLOC(capacity, sizeof(c_SmartPtr_t));
|
||
|
|
if (!vector->array) {
|
||
|
|
return C_ERR_NOMEM;
|
||
|
|
}
|
||
|
|
}else {
|
||
|
|
vector->array = NULL;
|
||
|
|
}
|
||
|
|
vector->capacity = capacity;
|
||
|
|
vector->size = 0;
|
||
|
|
return C_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
void c_SmartPtrVector_Destroy(c_SmartPtrVector_t* vector) {
|
||
|
|
if (!vector || !vector->array) return;
|
||
|
|
for (c_size_t i=0; i<vector->size; i++) {
|
||
|
|
c_SmartPtr_Destroy(&vector->array[i]);
|
||
|
|
}
|
||
|
|
C_FREE(vector->array);
|
||
|
|
vector->capacity = 0;
|
||
|
|
vector->size = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_err_t c_SmartPtrVector_PushBack(c_SmartPtrVector_t* vector, const c_SmartPtr_t* ptr) {
|
||
|
|
if (!vector || !ptr) return C_ERR_PARAM;
|
||
|
|
|
||
|
|
// 檢查是否需要自動擴容
|
||
|
|
if (vector->size >= vector->capacity) {
|
||
|
|
c_size_t new_capacity = (vector->capacity == 0) ? DEFAULT_INITIAL_CAPACITY : (vector->capacity * DEFAULT_GROW_FACTOR);
|
||
|
|
c_SmartPtr_t* new_array = (c_SmartPtr_t*)C_CALLOC(new_capacity, sizeof(c_SmartPtr_t));
|
||
|
|
if (!new_array) {
|
||
|
|
return C_ERR_NOMEM;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (c_size_t i = 0; i < vector->size; i++) {
|
||
|
|
c_SmartPtr_Move(&new_array[i], &vector->array[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
C_FREE(vector->array);
|
||
|
|
vector->array = new_array;
|
||
|
|
vector->capacity = new_capacity;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 執行 Copy 語義:在 Vector 內部建立一個新引用,底層引用計數 (ref_count) 自動 +1
|
||
|
|
c_SmartPtr_Copy(&vector->array[vector->size], ptr);
|
||
|
|
vector->size++;
|
||
|
|
|
||
|
|
return C_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_err_t c_SmartPtrVector_Remove(c_SmartPtrVector_t* self, c_size_t index) {
|
||
|
|
if (!self || index >= self->size) return C_ERR_PARAM;
|
||
|
|
|
||
|
|
// 1. 銷毀該 index 的智慧指標(若引用計數歸零,會在此處自動觸發資源 free 回收)
|
||
|
|
c_SmartPtr_Destroy(&self->array[index]);
|
||
|
|
|
||
|
|
// 2. 將後續的所有智慧指標往前遞補
|
||
|
|
// 這裡同樣必須使用 Move 語義進行「所有權搬移」,保持計數器數值不動
|
||
|
|
for (c_size_t i = index; i < self->size - 1; i++) {
|
||
|
|
c_SmartPtr_Move(&self->array[i], &self->array[i + 1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. 將多出來的最後一個格子完全抹零抹乾淨,防止殘留野指標
|
||
|
|
memset(&self->array[self->size - 1], 0, sizeof(c_SmartPtr_t));
|
||
|
|
self->size--;
|
||
|
|
|
||
|
|
return C_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_err_t c_SmartPtrVector_PopBack(c_SmartPtrVector_t* vector, c_SmartPtr_t* ptr) {
|
||
|
|
if (!vector || !ptr) {
|
||
|
|
return C_ERR_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (vector->size == 0) {
|
||
|
|
return C_ERR_EMPTY;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_SmartPtr_Move(ptr, &vector->array[vector->size - 1]);
|
||
|
|
vector->size--;
|
||
|
|
|
||
|
|
return C_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_err_t c_SmartPtrVector_Insert(c_SmartPtrVector_t* vector, c_size_t index, const c_SmartPtr_t* ptr) {
|
||
|
|
if (!vector || !ptr || index > vector->size) {
|
||
|
|
return C_ERR_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 1. 檢查是否需要擴容
|
||
|
|
if (vector->size >= vector->capacity) {
|
||
|
|
c_size_t new_capacity = (vector->capacity == 0) ? DEFAULT_INITIAL_CAPACITY : (vector->capacity * DEFAULT_GROW_FACTOR);
|
||
|
|
c_SmartPtr_t* new_array = (c_SmartPtr_t*)C_CALLOC(new_capacity, sizeof(c_SmartPtr_t));
|
||
|
|
if (!new_array) {
|
||
|
|
return C_ERR_NOMEM;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 擴容搬移:使用 Move 語義,不變動計數
|
||
|
|
for (c_size_t i = 0; i < vector->size; i++) {
|
||
|
|
c_SmartPtr_Move(&new_array[i], &vector->array[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
C_FREE(vector->array);
|
||
|
|
vector->array = new_array;
|
||
|
|
vector->capacity = new_capacity;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. 將插入點之後的元素「從後往前」依序向後挪動一格
|
||
|
|
// 關鍵:必須使用 c_SmartPtr_move 以確保在挪動過程中引用計數不發生任何不必要的增減與震盪
|
||
|
|
for (c_size_t i = vector->size; i > index; i--) {
|
||
|
|
c_SmartPtr_Move(&vector->array[i], &vector->array[i - 1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. 在空出來的 index 位置執行 Copy 語義,正式納入 Vector 管理(引用計數 +1)
|
||
|
|
c_SmartPtr_Copy(&vector->array[index], ptr);
|
||
|
|
vector->size++;
|
||
|
|
|
||
|
|
return C_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_err_t c_SmartPtrVector_RemoveAndTake(c_SmartPtrVector_t* self, c_size_t index, c_SmartPtr_t* ptr) {
|
||
|
|
// 防禦性檢查:確保 self、輸出指標 ptr 有效,且 index 沒有越界
|
||
|
|
if (!self || !ptr || index >= self->size) {
|
||
|
|
return C_ERR_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 1. 執行 Move 語義:將指定 index 處的所有權完美轉移給外面的 ptr
|
||
|
|
// 這會自動安全釋放 ptr 原本持有的舊資源,並將 self->array[index] 掏空抹零。
|
||
|
|
// 底層引用計數(ref_count)數值完全保持不動,沒有任何多餘開銷。
|
||
|
|
c_SmartPtr_Move(ptr, &self->array[index]);
|
||
|
|
|
||
|
|
// 2. 將 index 之後的所有智慧指標往前遞補一格
|
||
|
|
// 因為 self->array[index] 剛才已經被 move 抹零了,
|
||
|
|
// 這裡的迴圈會把 index + 1 的內容 move 過去,依此類推。
|
||
|
|
for (c_size_t i = index; i < self->size - 1; i++) {
|
||
|
|
c_SmartPtr_Move(&self->array[i], &self->array[i + 1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. 將最後一個多出來的殘留格子完全抹乾淨,防止產生野指標,並更新大小
|
||
|
|
memset(&self->array[self->size - 1], 0, sizeof(c_SmartPtr_t));
|
||
|
|
self->size--;
|
||
|
|
|
||
|
|
return C_SUCCESS;
|
||
|
|
}
|
||
|
|
|