#ifndef INCLUDED_C_SMARTPTR_H #define INCLUDED_C_SMARTPTR_H #ifndef INCLUDED_C_TYPES_H #include #endif /*INCLUDED_C_TYPES_H*/ #ifndef INCLUDED_C_MEMORY_H #include #endif /*INCLUDED_C_MEMORY_H*/ #ifndef INCLUDED_C_ATOMIC_H #include #endif /*INCLUDED_C_ATOMIC_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ // 釋放資源的函數指標類型 typedef void (*c_SmartPtrFreeFn_t)(void* ptr, void* args); // 智慧指標結構體 typedef struct { void* ptr; c_SmartPtrFreeFn_t free_fn; void* args; c_atomic_int_t* ref_count; } c_SmartPtr_t; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE c_SmartPtr_t c_SmartPtr_Make(void* ptr, const c_SmartPtrFreeFn_t free_fn, void* args) { c_SmartPtr_t sptr = { .ptr = ptr, .free_fn = free_fn, .args = args, .ref_count = NULL }; if (ptr == NULL) return sptr; C_NEW(sptr.ref_count); if (sptr.ref_count != NULL) { c_atomic_init_int(sptr.ref_count, 1); } return sptr; } C_STATIC_FORCE_INLINE c_err_t c_SmartPtr_Init(c_SmartPtr_t* self, void* ptr, const c_SmartPtrFreeFn_t free_fn, void* args) { if (ptr == NULL) return C_ERR_PARAM; self->ptr = ptr; self->free_fn = free_fn; self->args = args; self->ref_count = NULL; C_NEW(self->ref_count); if (self->ref_count == NULL) { return C_ERR_NOMEM; } c_atomic_init_int(self->ref_count, 1); return C_ERR_OK; } C_STATIC_FORCE_INLINE void c_SmartPtr_Destroy(c_SmartPtr_t* self) { if (!self || !self->ref_count) return; if (C_ATOMIC_FETCH_SUB(self->ref_count, 1) == 1) { if (self->free_fn && self->ptr) { self->free_fn(self->ptr, self->args); } C_FREE(self->ref_count); } memset(self, 0, sizeof(c_SmartPtr_t)); } C_STATIC_FORCE_INLINE c_err_t c_SmartPtr_Copy(c_SmartPtr_t* dest, const c_SmartPtr_t* src) { if (!dest || !src || dest == src) return C_ERR_PARAM; if (!src->ptr || !src->ref_count) return C_ERR_PARAM; c_SmartPtr_Destroy(dest); dest->ptr = src->ptr; dest->free_fn = src->free_fn; dest->args = src->args; dest->ref_count = src->ref_count; C_ATOMIC_FETCH_ADD(dest->ref_count, 1); return C_SUCCESS; } C_STATIC_FORCE_INLINE c_err_t c_SmartPtr_Move(c_SmartPtr_t* dest, c_SmartPtr_t* src) { if (!dest || !src || dest == src) return C_ERR_PARAM; c_SmartPtr_Destroy(dest); *dest = *src; memset(src, 0, sizeof(c_SmartPtr_t)); return C_SUCCESS; } C_STATIC_FORCE_INLINE int c_SmartPtr_UseCount(const c_SmartPtr_t* self) { if (!self || !self->ref_count) return 0; return (int)C_ATOMIC_LOAD(self->ref_count); } #endif /*INCLUDED_C_SMARTPTR_H*/