Compare commits

...

5 Commits

Author SHA1 Message Date
f5c3b178c5 feat(deque): 支持 segarray 后端实现
关于容量有些争议,后续考虑怎么处理。

- 重构 `deque` 源码,使用条件编译适配 `ringbuf` 或 `segarray`
- 修复 `segarray` 扩容逻辑,使用正确的段大小 `_segsize` 进行分配
- 优化 `segarray` 初始化逻辑,支持容量为 0 时的延迟分配
2026-05-17 17:08:22 +08:00
9ae4aa829c refactor(list)!: 将 list 模块替换为 arraylist
- 移除 list 源码、头文件及测试用例
- 将 demo 及测试迁移至 arraylist
- 在 arraylist 中实现 slice 功能并支持负索引
- 修复 arraylist 负数索引计算逻辑
- 修复 darray 打印函数参数错误
- 优化 mempool 日志输出格式

BREAKING CHANGE: 移除 list 模块;arraylist::slice 返回值改为新列表实例
2026-05-17 15:58:31 +08:00
82d0167c81 feat(mempool)!: 添加内存追踪及修复多处内存泄漏
- 新增 mempool 模块用于统计内存分配次数并检测泄漏
- 启用 UNICSTL_MALLOC_CUSTOM 宏以接管标准库内存函数
- 修复 segarray 销毁时未释放 _mapfree 导致的内存泄漏
- 修复 darray 迭代器 next 方法中错误的对象访问方式
- 调整 segarray 不支持外部缓存
- 修复测试用例中未释放 arraylist 导致的误报
2026-05-17 14:13:33 +08:00
529cf60218 refactor(arraylist): 基于 darray 重构实现并支持负索引
- 将 arraylist 内部实现改为组合 darray 对象,委托核心操作至 darray
- 移除 arraylist 中冗余的内存管理代码(如手动维护 obj、capacity 等)
- 新增负索引支持(如 -1 访问末尾元素),完善 get/set/at 的边界检查
- 优化 darray 源码,使用内联辅助函数(obj_shift, obj_copy)封装指针操作
2026-05-17 12:57:20 +08:00
72db0be317 feat(stl): 新增 arraylist 并统一迭代器顺序枚举类型
- 重构迭代器顺序枚举,引入 linear_order_t、tree_order_t 等通用类型,并替换。
- 修复 darray 中二分查找返回索引计算错误的问题
- 优化 segarray 的内存分配错误处理
- 增强 logger 模块,支持时间戳打印及格式化输出
2026-05-17 10:48:19 +08:00
40 changed files with 2354 additions and 1558 deletions

View File

@ -24,8 +24,8 @@ direction TB
namespace basic {
class ringbuf{
小数据
扩容
不扩容或
小数据扩容
}
class rawbuf
class darray
@ -54,6 +54,10 @@ namespace hal {
大数据
优先扩容
}
class arraylist{
切片
负索引
}
class string
class hashtable
}
@ -70,34 +74,32 @@ namespace top {
class unordered_map
}
%% ========== 以下全部按你真实逻辑修正 ==========
%% segarray 包含 ringbuf同生共死
%% hal层
segarray *-- ringbuf : 组合
segarray *-- rawbuf : 组合
%% string / hashtable 底层使用darray
arraylist *-- darray : 组合
string *-- darray : 组合
hashtable *-- darray : 组合
%% deque 当前ringbuf可换segarray
%% 适配器
deque *-- ringbuf : 组合
deque *-- segarray : 组合
%% stack/queue 持有deque*,管理生命周期
%% 通用标准容器
stack *-- deque : 组合
queue *-- deque : 组合
%% 临时使用 → 依赖
%% 红黑树
rbtree ..> stack : 依赖
rbtree ..> queue : 依赖
%% map/unordered_map 底层使用 rbtree/hashtable
%% 高级容器
map *-- rbtree : 组合
unordered_map *-- hashtable : 组合
%% embed 是内联函数,仅调用 → 依赖
%% 嵌入式专用容器
estack ..> ringbuf : 依赖
equeue ..> ringbuf : 依赖
```

View File

@ -60,7 +60,7 @@ int main()
{
demo_queue();
demo_stack();
demo_list();
demo_arraylist();
demo_deque();
demo_tree();
demo_heap();

View File

@ -39,7 +39,7 @@ void print_str(const void* obj);
* @brief test function
*
*/
void demo_list(void);
void demo_arraylist(void);
void demo_stack(void);
void demo_deque(void);
void demo_queue(void);

View File

@ -1,16 +1,16 @@
/**
* @file demo_list->c
* @file demo_arraylist.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2024-08-27
* @date 2026-05-17
*
* @copyright Copyright (c) 2024
* @copyright Copyright (c) 2026
*
*/
#include "demo.h"
static void demo_list_num(void)
static void demo_arraylist_num(void)
{
int i = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
@ -18,7 +18,7 @@ static void demo_list_num(void)
int index = 0;
int len = sizeof(data) / sizeof(data[0]);
list_t list = list_new2(sizeof(int), 64);
arraylist_t list = arraylist_new(sizeof(int), 64);
list->print_obj = print_num;
printf("\n\n----- list_demo_num -----\n");
@ -32,15 +32,15 @@ static void demo_list_num(void)
printf("\n");
printf("----- pop -----\n");
list->delete(list, 9, NULL);
list->remove(list, 9, NULL);
list->print(list);
printf("\n");
list->delete(list, 0, NULL);
list->remove(list, 0, NULL);
list->print(list);
printf("\n");
list->delete(list, 4, NULL);
list->remove(list, 4, NULL);
list->print(list);
printf("\n");
@ -138,10 +138,10 @@ static void demo_list_num(void)
}
}
list_free(&list);
arraylist_free(&list);
}
static void demo_list_struct(void)
static void demo_arraylist_struct(void)
{
int i = 0;
struct _student data[] = {
@ -153,7 +153,7 @@ static void demo_list_struct(void)
int index = 0;
int len = sizeof(data) / sizeof(data[0]);
list_t list = list_new2(sizeof(struct _student), 64);
arraylist_t list = arraylist_new(sizeof(struct _student), 64);
list->print_obj = print_struct;
printf("\n\n----- list_demo_num -----\n");
@ -167,15 +167,15 @@ static void demo_list_struct(void)
printf("\n");
printf("----- pop -----\n");
list->delete(list, 9, NULL);
list->remove(list, 9, NULL);
list->print(list);
printf("\n");
list->delete(list, 0, NULL);
list->remove(list, 0, NULL);
list->print(list);
printf("\n");
list->delete(list, 4, NULL);
list->remove(list, 4, NULL);
list->print(list);
printf("\n");
@ -295,11 +295,11 @@ static void demo_list_struct(void)
}
}
list_free(&list);
arraylist_free(&list);
}
void demo_list(void)
void demo_arraylist(void)
{
demo_list_num();
demo_list_struct();
demo_arraylist_num();
demo_arraylist_struct();
}

View File

@ -81,6 +81,10 @@ segarray扩容开新segment然后指向新的segment性能也不差。
## 经典问题
### 2026-05-17
1. 单测多少或者调整顺序都能导致segarray报错经过排查new之后函数结构体成员函数的指针应该是异常了。
push_back没有执行而是莫名其妙跳到了segarray_free。暂未找到原因。只是单测先保留已重构的tree和graph暂时先不测试了。
### 2026-05-15
1. ringbufferresize扩容截断的处理代码简化了。

86
include/arraylist.h Normal file
View File

@ -0,0 +1,86 @@
/**
* @file arraylist.h
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-17
*
* @copyright Copyright (c) 2026
*
*/
#ifndef _ARRAYLIST_H_
#define _ARRAYLIST_H_
#include "unicstl_internal.h"
#include "iterator.h"
#include "darray.h"
#ifdef UNICSTL_ARRAYLIST
#ifndef _SSIZE_T_DECLARED
typedef ptrdiff_t ssize_t;
#define _SSIZE_T_DECLARED
#endif
#define SLICE_UNLIMITED SSIZE_MAX
struct _arraylist
{
// -------------------- private --------------------
darray_t _darray;
iterator_t _iter_darray;
struct _iterator _iter;
void (*_destory)(struct _arraylist *self);
// -------------------- public --------------------
// kernel
bool (*append)(struct _arraylist *self, const void *obj); // O(1)
bool (*pop)(struct _arraylist *self, void *obj); // O(1)
bool (*insert)(struct _arraylist *self, ssize_t index, const void *obj); // O(n)
bool (*remove)(struct _arraylist *self, ssize_t index, void *obj); // O(n)
// -------------------- random access --------------------
bool (*set)(struct _arraylist *self, ssize_t index, const void *obj); // O(1)
bool (*get)(struct _arraylist *self, ssize_t index, void *obj); // O(1)
const void* (*at)(struct _arraylist *self, ssize_t index); // O(1)
// base
bool (*resize)(struct _arraylist *self, size_t capacity);
size_t (*size)(struct _arraylist *self);
size_t (*capacity)(struct _arraylist *self);
bool (*empty)(struct _arraylist *self);
bool (*full)(struct _arraylist *self);
bool (*clear)(struct _arraylist *self);
// sort and search
ssize_t (*index)(struct _arraylist *self, const void *obj); // O(n) return (size_t)-1 if not found
bool (*contains)(struct _arraylist *self, const void *obj); // O(n)
bool (*sort)(struct _arraylist *self); // O(nlogn)
ssize_t (*search)(struct _arraylist *self, const void *obj); // O(n) if not sorted; O(logn) if sorted
// return leftmost matched index; return (size_t)-1 if not found
size_t (*count)(struct _arraylist *self, const void *obj); // O(nlogn) if sorted; O(n) if not sorted
// slice
struct _arraylist* (*slice)(struct _arraylist *self, ssize_t start, ssize_t end, ssize_t step); // O(n)
// iter
iterator_t (*iter)(struct _arraylist *self, linear_order_t order);
// config
compare_fun_t compare; // !!! you have to implement this function
// -------------------- debug --------------------
void (*print)(struct _arraylist *self);
void (*print_obj)(const void *obj);
};
typedef struct _arraylist *arraylist_t;
arraylist_t arraylist_new(size_t obj_size, size_t capacity);
void arraylist_free(arraylist_t *arraylist);
#endif // UNICSTL_ARRAYLIST
#endif // _ARRAYLIST_H_

View File

@ -14,12 +14,6 @@
#include "unicstl_internal.h"
#include "iterator.h"
enum _darray_order
{
DARRAY_FORWARD,
DARRAY_REVERSE,
};
struct _darray
{
// -------------------- private --------------------
@ -66,7 +60,7 @@ struct _darray
size_t (*count)(struct _darray *self, const void *obj); // O(nlogn) if sorted; O(n) if not sorted
// iter
iterator_t (*iter)(struct _darray *self, enum _darray_order order);
iterator_t (*iter)(struct _darray *self, linear_order_t order);
// config
compare_fun_t compare; // !!! you have to implement this function

View File

@ -13,12 +13,24 @@
#include "unicstl_internal.h"
#include "ringbuf.h"
#include "segarray.h"
enum _deque_order
{
DEQUE_FORWARD,
DEQUE_REVERSE,
};
#define DEQUE_DEFAULT_SELECT 0
#if DEQUE_DEFAULT_SELECT == 1
#define DEQUE_RINGBUF 0
#define DEQUE_SEGARRAY 1
#else
#define DEQUE_RINGBUF 1
#define DEQUE_SEGARRAY 0
#endif
#if DEQUE_RINGBUF && DEQUE_SEGARRAY
#error "Cannot enable both DEQUE_RINGBUF and DEQUE_SEGARRAY at the same time."
#endif
#if !(DEQUE_RINGBUF || DEQUE_SEGARRAY)
#error "You must enable at least one backend: DEQUE_RINGBUF or DEQUE_SEGARRAY."
#endif
struct _deque
{
@ -26,8 +38,9 @@ struct _deque
union
{
ringbuf_t ringbuf;
segarray_t _segarray;
};
iterator_t _iter_ringbuf;
iterator_t _iter_ptr;
struct _iterator _iter;
void (*_destory)(struct _deque* self);
@ -50,7 +63,7 @@ struct _deque
bool (*full)(struct _deque* self);
// iter
iterator_t (*iter)(struct _deque* self, enum _deque_order order);
iterator_t (*iter)(struct _deque* self, linear_order_t order);
// -------------------- debug --------------------
void (*print)(struct _deque* self);

View File

@ -13,12 +13,6 @@
#include "unicstl_internal.h"
enum _dlinklist_order
{
DLLIST_FORWARD,
DLLIST_REVERSE,
};
struct _dlinklist_node
{
void* obj;
@ -56,7 +50,7 @@ struct _dlinklist
bool (*empty)(struct _dlinklist* self);
// iter
iterator_t (*iter)(struct _dlinklist* self, enum _dlinklist_order order);
iterator_t (*iter)(struct _dlinklist* self, linear_order_t order);
// -------------------- debug --------------------
void (*print)(struct _dlinklist* self);

View File

@ -24,13 +24,6 @@ enum _graph_type
// GRAPH_DIRECTED_WEIGHT,
};
enum _graph_search
{
GRAPH_DFS,
GRAPH_BFS,
};
struct _graph_edge
{
size_t weight;
@ -58,7 +51,7 @@ struct _graph
size_t _ratio;
enum _graph_type _type;
enum _graph_search _search;
graph_order_t _search;
stack_t stack;
queue_t queue;
@ -86,7 +79,7 @@ struct _graph
bool (*clear)(struct _graph* self);
// iter
iterator_t (*iter)(struct _graph* self, enum _graph_search search, void *obj);
iterator_t (*iter)(struct _graph* self, graph_order_t search, void *obj);
// config
compare_fun_t compare; // !!! you have to implement this function

View File

@ -1,79 +0,0 @@
/**
* @file list.h
* @author wenjf (Orig5826@163.com)
* @brief
*
* @details dynamic array list.
* similar to python list/ java ArrayList / C++ std::vector
*
* @version 0.1
* @date 2024-06-23
*
* @copyright Copyright (c) 2024
*
*/
#ifndef _LIST_H_
#define _LIST_H_
#include "unicstl_internal.h"
#include "iterator.h"
#define LIST_UNLIMITED INT32_MAX
struct _list
{
// -------------------- private --------------------
void *obj;
size_t _obj_size;
size_t _size;
size_t _capacity;
size_t _ratio;
size_t _cur;
struct _iterator _iter;
void (*_destory)(struct _list *self);
// -------------------- public --------------------
// kernel
bool (*append)(struct _list *self, void *obj);
bool (*pop)(struct _list *self, void *obj);
bool (*insert)(struct _list *self, int index, void *obj);
bool (*delete)(struct _list *self, int index, void *obj);
bool (*get)(struct _list *self, int index, void *obj);
bool (*set)(struct _list *self, int index, void *obj);
int (*index)(struct _list *self, void *obj); // retval -1 if not found
// bool (*contains)(struct _list *self, void *obj);
// base
size_t (*size)(struct _list *self);
size_t (*capacity)(struct _list *self);
bool (*empty)(struct _list *self);
bool (*clear)(struct _list *self);
// iter
iterator_t (*iter)(struct _list *self);
// others
struct _list* (*slice)(struct _list *self, int start, int end, int step);
// struct _list* (*copy)(struct _list *self);
// config
compare_fun_t compare; // !!! you have to implement this function
// -------------------- debug --------------------
void (*print)(struct _list *self);
void (*print_obj)(const void *obj);
};
typedef struct _list *list_t;
// create and free list
list_t list_new2(size_t obj_size, size_t capacity);
void list_free(list_t *list);
#endif // _LIST_H_

26
include/mempool.h Normal file
View File

@ -0,0 +1,26 @@
/**
* @file mempool.h
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-17
*
* @copyright Copyright (c) 2026
*
*/
#ifndef _MEMPOOL_H_
#define _MEMPOOL_H_
#include "unicstl_internal.h"
#ifdef UNICSTL_MALLOC_CUSTOM
extern void *unicstl_malloc(size_t size);
extern void *unicstl_calloc(size_t num, size_t size);
extern void *unicstl_realloc(void *ptr, size_t size);
extern void unicstl_free(void *ptr);
#endif
void mempool_init(void);
void mempool_deinit(void);
#endif // _MEMPOOL_H_

View File

@ -13,12 +13,6 @@
#include "unicstl_internal.h"
enum _ringbuf_order
{
RINGBUF_FORWARD,
RINGBUF_REVERSE,
};
struct _ringbuf
{
// -------------------- private --------------------
@ -58,7 +52,7 @@ struct _ringbuf
bool (*clear)(struct _ringbuf* self);
// iter
iterator_t (*iter)(struct _ringbuf* self, enum _ringbuf_order order);
iterator_t (*iter)(struct _ringbuf* self, linear_order_t order);
// -------------------- debug --------------------
void (*print)(struct _ringbuf* self);

View File

@ -15,12 +15,6 @@
#include "ringbuf.h"
#include "rawbuf.h"
enum _segarray_order
{
SEGARRAY_FORWARD,
SEGARRAY_REVERSE,
};
struct _segarray
{
// -------------------- private --------------------
@ -63,7 +57,7 @@ struct _segarray
bool (*clear)(struct _segarray* self);
// iter
iterator_t (*iter)(struct _segarray* self, enum _segarray_order order);
iterator_t (*iter)(struct _segarray* self, linear_order_t order);
// -------------------- debug --------------------
void (*print)(struct _segarray* self);

View File

@ -13,6 +13,8 @@
#include "unicstl_internal.h"
#include "mempool.h"
#include "darray.h"
#include "linklist.h"
#include "dlinklist.h"
@ -20,11 +22,12 @@
#include "rawbuf.h"
#include "segarray.h"
#include "arraylist.h"
#include "deque.h"
#include "list.h"
#include "stack.h"
#include "queue.h"
#include "deque.h"
#include "tree.h"
#include "heap.h"
#include "graph.h"

View File

@ -21,6 +21,8 @@
* @brief unicstl contains which module
*
*/
#define UNICSTL_ARRAYLIST
#define UNICSTL_LIST
#define UNICSTL_STACK
#define UNICSTL_QUEUE
@ -35,7 +37,7 @@
*
*/
#define UNICSTL_MALLOC_ENABLE // malloc enable
// #define UNICSTL_MALLOC_CUSTOM // malloc custom support
#define UNICSTL_MALLOC_CUSTOM // malloc custom support
/**

View File

@ -62,6 +62,31 @@
#define UNICSTL_UNUSED(x) (void)(x)
// clang-format on
typedef enum {
LINEAR_FORWARD,
LINEAR_REVERSE,
} linear_order_t;
typedef enum {
TREE_PRE,
TREE_IN,
TREE_POST,
TREE_BREADTH,
TREE_PRE_R,
TREE_IN_R,
TREE_POST_R,
TREE_BREADTH_R,
} tree_order_t;
typedef enum {
GRAPH_BFS,
GRAPH_DFS,
GRAPH_BFS_R,
GRAPH_DFS_R,
} graph_order_t;
/**
* @brief assert function
*
@ -124,39 +149,42 @@ static inline void unicstl_free(void *ptr) {}
static inline const void *obj_at(const void *objs, size_t index, size_t obj_size)
{
#ifdef UNICSTL_DEBUG
unicstl_assert(objs != NULL);
#endif
return (const char *)objs + obj_size * index;
}
static inline void obj_set(void *objs, size_t index, const void *obj, size_t obj_size)
{
#ifdef UNICSTL_DEBUG
unicstl_assert(objs != NULL);
unicstl_assert(obj != NULL);
#endif
memmove((char *)objs + obj_size * index, obj, obj_size);
}
static inline void obj_get(const void *objs, size_t index, void *obj, size_t obj_size)
{
#ifdef UNICSTL_DEBUG
unicstl_assert(objs != NULL);
unicstl_assert(obj != NULL);
#endif
memmove(obj, (const char *)objs + obj_size * index, obj_size);
}
static inline size_t obj_index(const void *objs, const void *obj, size_t obj_size)
{
return ((const char *)obj - (const char *)objs) / obj_size;
}
static inline void obj_copy(void *dst, const void *src, size_t count, size_t obj_size)
{
#ifdef UNICSTL_DEBUG
unicstl_assert(dst != NULL);
unicstl_assert(src != NULL);
#endif
memmove(dst, src, obj_size * count);
}
static inline void obj_shift(void *objs, size_t dst_idx, size_t src_idx, size_t count, size_t obj_size)
{
unicstl_assert(objs != NULL);
obj_copy((char *)objs + obj_size * dst_idx, (const char *)objs + obj_size * src_idx, count, obj_size);
}
static inline size_t ring_index(size_t head, size_t index, size_t capacity)
{
return (head + index) % capacity;

2
mk.bat
View File

@ -1,6 +1,8 @@
@REM D:\Lang\cmake-3.27.5-windows-x86_64\bin\cmake.EXE --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=D:\Software\mingw64\bin\gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=D:\Software\mingw64\bin\g++.exe -SF:/OpenDemo/1_vsc_cmake -Bf:/OpenDemo/1_vsc_cmake/build -G "MinGW Makefiles"
@REM cmake -Bbuild -G "Visual Studio 17 2022"
del ".\build\release\bin\test.exe"
cmake -B build -G "MinGW Makefiles"
@REM cmake -B build -G "Unix Makefiles"

442
src/arraylist.c Normal file
View File

@ -0,0 +1,442 @@
/**
* @file arraylist.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-17
*
* @copyright Copyright (c) 2026
*
*/
#include "arraylist.h"
#include "algo.h"
#ifdef UNICSTL_ARRAYLIST
static inline size_t calc_index(ssize_t index, size_t size)
{
if(index < 0)
{
return index + size;
}
return index;
}
static size_t arraylist_size(struct _arraylist *self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
return self->_darray->size(self->_darray);
}
static size_t arraylist_capacity(struct _arraylist *self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
return self->_darray->capacity(self->_darray);
}
static bool arraylist_empty(struct _arraylist *self)
{
unicstl_assert(self != NULL);
return self->size(self) == 0;
}
static bool arraylist_full(struct _arraylist *self)
{
unicstl_assert(self != NULL);
return self->size(self) == self->capacity(self);
}
static bool arraylist_clear(struct _arraylist *self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
self->_darray->clear(self->_darray);
return true;
}
static void arraylist_destory(struct _arraylist *self)
{
unicstl_assert(self != NULL);
if(self->_darray != NULL)
{
darray_free(&self->_darray);
}
}
static void arraylist_print(struct _arraylist *self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
self->_darray->print_obj = self->print_obj;
self->_darray->print(self->_darray);
}
static bool arraylist_resize(struct _arraylist *self, size_t capacity)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
return self->_darray->resize(self->_darray, capacity);
}
static bool arraylist_insert(struct _arraylist *self, ssize_t index, const void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
index = calc_index(index, self->size(self));
if(index < 0)
{
index += 1;
log_debug("index < 0, index = %zd", index);
}
return self->_darray->insert(self->_darray, index, obj);
}
static bool arraylist_remove(struct _arraylist *self, ssize_t index, void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
index = calc_index(index, self->size(self));
return self->_darray->remove(self->_darray, index, obj);
}
static bool arraylist_append(struct _arraylist *self, const void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
return self->_darray->append(self->_darray, obj);
}
static bool arraylist_pop(struct _arraylist *self, void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
return self->_darray->pop(self->_darray, obj);
}
static bool arraylist_set(struct _arraylist *self, ssize_t index, const void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
index = calc_index(index, self->size(self));
return self->_darray->set(self->_darray, index, obj);
}
static bool arraylist_get(struct _arraylist *self, ssize_t index, void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
index = calc_index(index, self->size(self));
return self->_darray->get(self->_darray, (size_t)index, obj);
}
const void *arraylist_at(struct _arraylist *self, ssize_t index)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
index = calc_index(index, self->size(self));
return self->_darray->at(self->_darray, index);
}
bool arraylist_iter_hasnext(struct _iterator *iter)
{
unicstl_assert(iter != NULL);
unicstl_assert(iter->_container != NULL);
arraylist_t self = (arraylist_t)iter->_container;
unicstl_assert(self->_iter_darray != NULL);
return self->_iter_darray->hasnext(self->_iter_darray);
}
const void *arraylist_iter_next(struct _iterator *iter)
{
unicstl_assert(iter != NULL);
unicstl_assert(iter->_container != NULL);
arraylist_t self = (arraylist_t)iter->_container;
unicstl_assert(self->_iter_darray != NULL);
return self->_iter_darray->next(self->_iter_darray);
}
iterator_t arraylist_iter(struct _arraylist *self, linear_order_t order)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_order = order;
self->_iter_darray = self->_darray->iter(self->_darray, order);
iter->hasnext = arraylist_iter_hasnext;
iter->next = arraylist_iter_next;
return iter;
}
static ssize_t arraylist_index(struct _arraylist *self, const void *obj)
{
unicstl_assert(self != NULL);
return self->search(self, obj);
}
static bool arraylist_contains(struct _arraylist *self, const void *obj)
{
unicstl_assert(self != NULL);
return self->search(self, obj) != (size_t)-1;
}
static bool arraylist_sort(struct _arraylist *self)
{
unicstl_assert(self != NULL);
self->_darray->compare = self->compare;
return self->_darray->sort(self->_darray);
}
static ssize_t arraylist_search(struct _arraylist *self, const void *obj)
{
unicstl_assert(self != NULL);
self->_darray->compare = self->compare;
return self->_darray->search(self->_darray, obj);
}
static size_t arraylist_count(struct _arraylist *self, const void *obj)
{
unicstl_assert(self != NULL);
return self->_darray->count(self->_darray, obj);
}
static int list_index_exchange(struct _arraylist *self, int index)
{
unicstl_assert(self != NULL);
int size = (int)self->size(self);
if (index < 0)
{
index += size;
if (index < 0)
{
index = 0;
}
}
else
{
if (index > size)
{
index = size;
}
}
return index;
}
/**
* @brief list slice
* if index < 0, from the end of list. for example:
* list[-1] is the last element in list.
*
* @param self
* @param start start index
* @param end end index
* @param step step, if step < 0, return a reverse list.
* @return struct _list*
* a copy of the list, from start to end, step by step.
* if step < 0, return a reverse list.
* if step > 0, return a forward list.
* if step == 0, return NULL.
*/
struct _arraylist * arraylist_slice(struct _arraylist *self, ssize_t start, ssize_t end, ssize_t step)
{
unicstl_assert(self != NULL);
int i = 0;
bool contains_last_obj = false;
int size = (int)self->size(self);
int capicity = 1;
arraylist_t list = NULL;
if (step == 0)
{
return NULL;
}
if (step > 0)
{
if (start == SLICE_UNLIMITED)
{
start = 0;
}
if (end == SLICE_UNLIMITED)
{
end = size;
}
}
else
{
if (start == SLICE_UNLIMITED)
{
start = size - 1;
}
if (end == SLICE_UNLIMITED)
{
end = 0;
contains_last_obj = true;
}
}
start = list_index_exchange(self, start);
end = list_index_exchange(self, end);
if(abs(end - start) != 0)
{
capicity = abs(end - start);
}
list = arraylist_new(self->_darray->_obj_size, 0);
if (list == NULL)
{
return NULL;
}
list->compare = self->compare;
list->print_obj = self->print_obj;
if (step > 0)
{
if (start >= end)
{
goto done;
}
if (contains_last_obj != true)
{
for (i = start; i < end; i += step)
{
list->append(list, self->at(self, i));
}
}
else
{
for (i = start; i <= end; i += step)
{
list->append(list, self->at(self, i));
}
}
}
else /*if(step < 0)*/
{
if (start <= end)
{
goto done;
}
if (contains_last_obj != true)
{
for (i = start; i > end; i += step)
{
list->append(list, self->at(self, i));
}
}
else
{
for (i = start; i >= end; i += step)
{
list->append(list, self->at(self, i));
}
}
}
done:
return list;
}
static bool arraylist_init(struct _arraylist *self, size_t obj_size, size_t capacity)
{
unicstl_assert(self != NULL);
unicstl_assert(obj_size > 0);
// -------------------- private --------------------
self->_darray = NULL;
self->_destory = arraylist_destory;
// -------------------- public --------------------
// kernel
self->insert = arraylist_insert;
self->remove = arraylist_remove;
self->append = arraylist_append;
self->pop = arraylist_pop;
self->set = arraylist_set;
self->get = arraylist_get;
self->at = arraylist_at;
// base
self->resize = arraylist_resize;
self->size = arraylist_size;
self->capacity = arraylist_capacity;
self->empty = arraylist_empty;
self->full = arraylist_full;
self->clear = arraylist_clear;
// iter
self->iter = arraylist_iter;
// sort and search
self->index = arraylist_index;
self->contains = arraylist_contains;
self->sort = arraylist_sort;
self->search = arraylist_search;
//
self->slice = arraylist_slice;
// -------------------- default --------------------
self->print_obj = default_print_obj;
// -------------------- debug --------------------
self->print = arraylist_print;
// -------------------- init --------------------
self->_darray = darray_new(obj_size, capacity);
if(self->_darray == NULL)
{
log_warn("self->_darray failed!");
return false;
}
self->_darray->compare = self->compare;
self->_darray->print_obj = self->print_obj;
return true;
}
arraylist_t arraylist_new(size_t obj_size, size_t capacity)
{
struct _arraylist *arraylist = NULL;
arraylist = (struct _arraylist *)unicstl_malloc(sizeof(struct _arraylist));
if (arraylist == NULL)
{
log_warn("arraylist malloc failed!");
return NULL;
}
if (arraylist_init(arraylist, obj_size, capacity) != true)
{
log_warn("arraylist init failed!");
unicstl_free(arraylist);
return NULL;
}
return arraylist;
}
void arraylist_free(arraylist_t *arraylist)
{
if (arraylist != NULL && *arraylist != NULL)
{
if ((*arraylist)->_destory != NULL)
{
(*arraylist)->_destory((*arraylist));
}
unicstl_free(*arraylist);
*arraylist = NULL;
}
}
#endif // UNICSTL_ARRAYLIST

View File

@ -60,13 +60,10 @@ static void darray_print(struct _darray *self)
return;
}
void *obj = NULL;
size_t offset = 0;
const void *obj = NULL;
for (size_t i = 0; i < self->size(self); i++)
{
offset = self->_obj_size * i;
obj = (char *)self->obj + offset;
obj = obj_at(self->obj, i, self->_obj_size);
self->print_obj(obj);
}
}
@ -110,18 +107,14 @@ static bool darray_insert(struct _darray *self, size_t index, const void *obj)
}
}
size_t offset = index * self->_obj_size;
if (index < self->size(self))
{
size_t offset1 = (index + 1) * self->_obj_size;
size_t count = self->size(self) - index;
// move data to right
memmove((char *)self->obj + offset1, (char *)self->obj + offset, count * self->_obj_size);
obj_shift(self->obj, index + 1, index, self->size(self) - index, self->_obj_size);
}
// copy new data
memmove((char *)self->obj + offset, obj, self->_obj_size);
self->_size += 1;
obj_copy((char *)self->obj + index * self->_obj_size, obj, 1, self->_obj_size);
self->_size += 1;
self->_sorted = false;
return true;
}
@ -134,26 +127,26 @@ static bool darray_remove(struct _darray *self, size_t index, void *obj)
return false;
}
size_t offset = index * self->_obj_size;
size_t offset1 = (index + 1) * self->_obj_size;
size_t count = self->size(self) - 1 - index;
if (obj != NULL)
{
memmove(obj, (char *)self->obj + offset, self->_obj_size);
size_t offset = index * self->_obj_size;
obj_copy(obj, self->obj + offset, 1, self->_obj_size);
}
memmove((char *)self->obj + offset, (char *)self->obj + offset1, count * self->_obj_size);
obj_shift(self->obj, index, index + 1, count, self->_obj_size);
self->_size -= 1;
return true;
}
static bool darray_append(struct _darray *self, const void *obj)
{
return darray_insert(self, self->size(self), obj);
return self->insert(self, self->size(self), obj);
}
static bool darray_pop(struct _darray *self, void *obj)
{
return darray_remove(self, self->size(self) - 1, obj);
return self->remove(self, self->size(self) - 1, obj);
}
static bool darray_set(struct _darray *self, size_t index, const void *obj)
@ -163,8 +156,7 @@ static bool darray_set(struct _darray *self, size_t index, const void *obj)
{
return false;
}
size_t offset = index * self->_obj_size;
memmove((char *)self->obj + offset, obj, self->_obj_size);
obj_set(self->obj, index, obj, self->_obj_size);
return true;
}
@ -175,8 +167,7 @@ static bool darray_get(struct _darray *self, size_t index, void *obj)
{
return false;
}
size_t offset = index * self->_obj_size;
memmove(obj, (char *)self->obj + offset, self->_obj_size);
obj_get(self->obj, index, obj, self->_obj_size);
return true;
}
@ -187,8 +178,7 @@ const void *darray_at(struct _darray *self, size_t index)
{
return false;
}
size_t offset = index * self->_obj_size;
return (const char *)self->obj + offset;
return obj_at(self->obj, index, self->_obj_size);
}
bool darray_iter_hasnext(struct _iterator *iter)
@ -198,7 +188,7 @@ bool darray_iter_hasnext(struct _iterator *iter)
darray_t self = (darray_t)iter->_container;
if (iter->_order == DARRAY_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
if (iter->_index >= self->size(self))
{
@ -223,7 +213,7 @@ const void *darray_iter_next(struct _iterator *iter)
darray_t self = (darray_t)iter->_container;
size_t index = iter->_index;
if (iter->_order == DARRAY_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
iter->_index++;
}
@ -231,10 +221,10 @@ const void *darray_iter_next(struct _iterator *iter)
{
iter->_index = iter->_index - 1;
}
return obj_at(self->obj, index, self->_obj_size);
return self->at(self, index);
}
iterator_t darray_iter(struct _darray *self, enum _darray_order order)
iterator_t darray_iter(struct _darray *self, linear_order_t order)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
@ -242,7 +232,7 @@ iterator_t darray_iter(struct _darray *self, enum _darray_order order)
iter->_container = self;
iter->_index = 0;
iter->_order = order;
if (iter->_order == DARRAY_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
iter->_index = 0;
}
@ -265,7 +255,7 @@ static size_t darray_index(struct _darray *self, const void *obj)
static bool darray_contains(struct _darray *self, const void *obj)
{
unicstl_assert(self != NULL);
return self->search(self, obj) != (size_t)-1;
return self->search(self, obj) != (size_t) - 1;
}
static bool darry_sort(struct _darray *self)
@ -299,7 +289,12 @@ static size_t darry_search(struct _darray *self, const void *obj)
#else
if(self->_sorted)
{
bsearch(obj, self->obj, self->size(self), self->_obj_size, self->compare);
log_debug("bsearch of standard library");
const void *addr = bsearch(obj, self->obj, self->size(self), self->_obj_size, self->compare);
if(addr != NULL)
{
return (addr - self->obj) / self->_obj_size;
}
}
#endif
return linear_search(obj, self->obj, self->size(self), self->_obj_size, self->compare);
@ -350,21 +345,19 @@ static bool darray_init(struct _darray *self, size_t obj_size, size_t capacity)
self->obj = NULL;
self->_destory = darray_destory;
// -------------------- public --------------------
// kernel
self->resize = darray_resize;
self->insert = darray_insert;
self->remove = darray_remove;
self->append = darray_append;
self->pop = darray_pop;
self->set = darray_set;
self->get = darray_get;
self->at = darray_at;
self->index = darray_index;
self->contains = darray_contains;
// base
self->resize = darray_resize;
self->size = darray_size;
self->capacity = darray_capacity;
self->empty = darray_empty;
@ -375,6 +368,8 @@ static bool darray_init(struct _darray *self, size_t obj_size, size_t capacity)
self->iter = darray_iter;
// sort and search
self->index = darray_index;
self->contains = darray_contains;
self->sort = darry_sort;
self->search = darry_search;

View File

@ -14,91 +14,156 @@ static bool deque_push_back(struct _deque* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->push_back(self->ringbuf, obj);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->push_back(self->_segarray, obj);
#endif
}
static bool deque_push_front(struct _deque* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->push_front(self->ringbuf, obj);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->push_front(self->_segarray, obj);
#endif
}
static bool deque_pop_back(struct _deque* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->pop_back(self->ringbuf, obj);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->pop_back(self->_segarray, obj);
#endif
}
static bool deque_pop_front(struct _deque* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->pop_front(self->ringbuf, obj);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->pop_front(self->_segarray, obj);
#endif
}
static bool deque_back(struct _deque* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->back(self->ringbuf, obj);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->back(self->_segarray, obj);
#endif
}
static bool deque_front(struct _deque* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->front(self->ringbuf, obj);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->front(self->_segarray, obj);
#endif
}
static bool deque_resize(struct _deque *self, size_t capacity)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->resize(self->ringbuf, capacity);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->resize(self->_segarray, capacity);
#endif
}
static size_t deque_size(struct _deque* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->size(self->ringbuf);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->size(self->_segarray);
#endif
}
static size_t deque_capacity(struct _deque* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->capacity(self->ringbuf);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->capacity(self->_segarray);
#endif
}
static bool deque_empty(struct _deque* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->empty(self->ringbuf);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->empty(self->_segarray);
#endif
}
static bool deque_full(struct _deque* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->full(self->ringbuf);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->full(self->_segarray);
#endif
}
static bool deque_clear(struct _deque* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
return self->ringbuf->clear(self->ringbuf);
#endif
#if DEQUE_SEGARRAY == 1
return self->_segarray->clear(self->_segarray);
#endif
}
static void deque_destory(struct _deque* self)
{
unicstl_assert(self != NULL);
self->clear(self);
#if DEQUE_RINGBUF == 1
ringbuf_free(&self->ringbuf);
#endif
#if DEQUE_SEGARRAY == 1
segarray_free(&self->_segarray);
#endif
}
static void deque_print(struct _deque* self)
@ -106,8 +171,14 @@ static void deque_print(struct _deque* self)
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
#if DEQUE_RINGBUF == 1
self->ringbuf->print_obj = self->print_obj;
self->ringbuf->print(self->ringbuf);
#endif
#if DEQUE_SEGARRAY == 1
self->_segarray->print_obj = self->print_obj;
self->_segarray->print(self->_segarray);
#endif
}
bool deque_iter_hasnext(struct _iterator* iter)
@ -116,7 +187,7 @@ bool deque_iter_hasnext(struct _iterator* iter)
unicstl_assert(iter->_container != NULL);
deque_t self = (deque_t)iter->_container;
return self->_iter_ringbuf->hasnext(self->_iter_ringbuf);
return self->_iter_ptr->hasnext(self->_iter_ptr);
}
const void* deque_iter_next(struct _iterator* iter)
@ -125,10 +196,10 @@ const void* deque_iter_next(struct _iterator* iter)
unicstl_assert(iter->_container != NULL);
deque_t self = (deque_t)iter->_container;
return self->_iter_ringbuf->next(self->_iter_ringbuf);
return self->_iter_ptr->next(self->_iter_ptr);
}
iterator_t deque_iter(struct _deque* self, enum _deque_order order)
iterator_t deque_iter(struct _deque* self, linear_order_t order)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
@ -136,7 +207,13 @@ iterator_t deque_iter(struct _deque* self, enum _deque_order order)
iter->_container = self;
iter->_index = 0;
iter->_order = order;
self->_iter_ringbuf = self->ringbuf->iter(self->ringbuf, order);
#if DEQUE_RINGBUF == 1
self->_iter_ptr = self->ringbuf->iter(self->ringbuf, order);
#endif
#if DEQUE_SEGARRAY == 1
self->_iter_ptr = self->_segarray->iter(self->_segarray, order);
#endif
iter->hasnext = deque_iter_hasnext;
iter->next = deque_iter_next;
@ -149,11 +226,6 @@ static bool deque_init(struct _deque* self, size_t obj_size, size_t capacity)
unicstl_assert(obj_size > 0);
// -------------------- private --------------------
self->ringbuf = ringbuf_new(obj_size, capacity);
if(self->ringbuf == NULL)
{
return false;
}
self->_destory = deque_destory;
// -------------------- public --------------------
@ -182,6 +254,25 @@ static bool deque_init(struct _deque* self, size_t obj_size, size_t capacity)
// -------------------- debug --------------------
self->print = deque_print;
// -------------------- init --------------------
#if DEQUE_RINGBUF == 1
self->ringbuf = ringbuf_new(obj_size, capacity);
if(self->ringbuf == NULL)
{
return false;
}
self->ringbuf->print_obj = default_print_obj;
#endif
#if DEQUE_SEGARRAY == 1
self->_segarray = segarray_new(obj_size, capacity);
if(self->_segarray == NULL)
{
return false;
}
self->_segarray->print_obj = default_print_obj;
#endif
return true;
}
@ -210,6 +301,6 @@ void deque_free(deque_t *deque)
{
(*deque)->_destory(*deque);
unicstl_free(*deque);
*deque = NULL;
}
*deque = NULL;
}

View File

@ -271,7 +271,7 @@ const void* dlinklist_iter_next(struct _iterator* iter)
}
obj = cur_node->obj;
if(iter->_order == DLLIST_FORWARD)
if(iter->_order == LINEAR_FORWARD)
{
iter->_node = cur_node->next;
}
@ -284,7 +284,7 @@ const void* dlinklist_iter_next(struct _iterator* iter)
return obj;
}
iterator_t dlinklist_iter(struct _dlinklist* self, enum _dlinklist_order order)
iterator_t dlinklist_iter(struct _dlinklist* self, linear_order_t order)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
@ -292,7 +292,7 @@ iterator_t dlinklist_iter(struct _dlinklist* self, enum _dlinklist_order order)
iter->_container = self;
iter->_index = 0;
iter->_order = order;
if(iter->_order == DLLIST_FORWARD)
if(iter->_order == LINEAR_FORWARD)
{
iter->_node = self->_head;
}

View File

@ -941,7 +941,7 @@ const void *graph_iter_next(struct _iterator *iter)
return obj;
}
iterator_t graph_iter(struct _graph *self, enum _graph_search search_type, void *start)
iterator_t graph_iter(struct _graph *self, graph_order_t search_type, void *start)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;

View File

@ -1,461 +0,0 @@
/**
* @file list.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2024-06-23
*
* @copyright Copyright (c) 2024
*
*/
#include "list.h"
static bool list_insert(struct _list* self, int index, void* obj)
{
// unicstl_assert(index >= 0 && index < (int)self->size(self));
// unicstl_assert(index >= 0 && index <= (int)self->size(self));
if (index < 0 || index >(int)self->size(self))
{
return false;
}
if (self->size(self) == self->_capacity)
{
int capacity = self->_capacity * self->_ratio;
void* obj_new = (void*)unicstl_realloc(self->obj, capacity * self->_obj_size);
if (obj_new == NULL)
{
return false;
}
self->obj = obj_new;
self->_capacity = capacity;
}
size_t offset = index * self->_obj_size;
size_t offset1 = (index + 1) * self->_obj_size;
size_t count = self->size(self) - index;
// move data to right
memmove((char*)self->obj + offset1, (char*)self->obj + offset, count * self->_obj_size);
// copy new data
memmove((char*)self->obj + offset, obj, self->_obj_size);
self->_size += 1;
return true;
}
static bool list_delete(struct _list* self, int index, void* obj)
{
unicstl_assert(self != NULL);
// unicstl_assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self));
if (index < (int)(0 - self->size(self)) || index >= (int)self->size(self))
{
return false;
}
if (self->empty(self))
{
return false;
}
if (index < 0)
{
index += self->size(self);
}
size_t offset = index * self->_obj_size;
size_t offset1 = (index + 1) * self->_obj_size;
size_t count = self->size(self) - 1 - index;
if (obj != NULL)
{
memmove(obj, (char*)self->obj + offset, self->_obj_size);
}
memmove((char*)self->obj + offset, (char*)self->obj + offset1, count * self->_obj_size);
self->_size -= 1;
return true;
}
static bool list_append(struct _list* self, void* obj)
{
return self->insert(self, (int)self->size(self), obj);
}
static bool list_pop(struct _list* self, void* obj)
{
if (self->empty(self))
{
return false;
}
return self->delete(self, (int)self->size(self) - 1, obj);
}
static int list_index(struct _list* self, void* obj)
{
unicstl_assert(self != NULL);
int index = 0;
if (obj == NULL)
{
return -1;
}
while (index < (int)self->size(self))
{
if (self->compare(self->obj + index * self->_obj_size, obj) == 0)
{
return index;
}
index++;
}
return -1;
}
static bool list_clear(struct _list* self)
{
unicstl_assert(self != NULL);
self->_size = 0;
return true;
}
static bool list_get(struct _list* self, int index, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(obj != NULL);
unicstl_assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self));
if (index < 0)
{
index += self->size(self);
}
size_t offset = index * self->_obj_size;
memmove(obj, (char*)self->obj + offset, self->_obj_size);
return true;
}
static bool list_set(struct _list* self, int index, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(index >= (int)(0 - self->size(self)) && index < (int)self->size(self));
if (index < 0)
{
index += self->size(self);
}
size_t offset = index * self->_obj_size;
memmove((char*)self->obj + offset, obj, self->_obj_size);
return true;
}
static size_t list_size(struct _list* self)
{
unicstl_assert(self != NULL);
return self->_size;
}
static size_t list_capacity(struct _list* self)
{
unicstl_assert(self != NULL);
return self->_capacity;
}
static bool list_empty(struct _list* self)
{
unicstl_assert(self != NULL);
return !self->size(self);
}
// unicstl_free
static void list_destory(struct _list* self)
{
unicstl_assert(self != NULL);
if (self->obj != NULL)
{
unicstl_free(self->obj);
}
}
// print
static void list_print(struct _list* self)
{
unicstl_assert(self != NULL);
if (!self->empty(self))
{
void* obj = NULL;
for (size_t i = 0; i < self->size(self); i++)
{
obj = (char*)self->obj + i * self->_obj_size;
self->print_obj(obj);
}
}
}
static int list_index_exchange(struct _list* self, int index)
{
unicstl_assert(self != NULL);
int size = (int)self->size(self);
if (index < 0)
{
index += size;
if (index < 0)
{
index = 0;
}
}
else
{
if (index > size)
{
index = size;
}
}
return index;
}
/**
* @brief list slice
* if index < 0, from the end of list. for example:
* list[-1] is the last element in list.
*
* @param self
* @param start start index
* @param end end index
* @param step step, if step < 0, return a reverse list.
* @return struct _list*
* a copy of the list, from start to end, step by step.
* if step < 0, return a reverse list.
* if step > 0, return a forward list.
* if step == 0, return NULL.
*/
struct _list* list_slice(struct _list* self, int start, int end, int step)
{
unicstl_assert(self != NULL);
int i = 0;
bool contains_last_obj = false;
int size = (int)self->size(self);
int capicity = 1;
list_t list = NULL;
if (step == 0)
{
return NULL;
}
if (step > 0)
{
if (start == LIST_UNLIMITED)
{
start = 0;
}
if (end == LIST_UNLIMITED)
{
end = size;
}
}
else
{
if (start == LIST_UNLIMITED)
{
start = size - 1;
}
if (end == LIST_UNLIMITED)
{
end = 0;
contains_last_obj = true;
}
}
start = list_index_exchange(self, start);
end = list_index_exchange(self, end);
if(abs(end - start) != 0)
{
capicity = abs(end - start);
}
list = list_new2(self->_obj_size, capicity);
if (list == NULL)
{
return NULL;
}
list->compare = self->compare;
list->print_obj = self->print_obj;
if (step > 0)
{
if (start >= end)
{
goto done;
}
if (contains_last_obj != true)
{
for (i = start; i < end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
else
{
for (i = start; i <= end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
}
else /*if(step < 0)*/
{
if (start <= end)
{
goto done;
}
if (contains_last_obj != true)
{
for (i = start; i > end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
else
{
for (i = start; i >= end; i += step)
{
list->append(list, (char*)self->obj + i * self->_obj_size);
}
}
}
done:
return list;
}
static bool list_iter_hasnext(struct _iterator* iter)
{
list_t self = (list_t)iter->_container;
if (iter->_index < self->size(self))
{
return true;
}
return false;
}
static const void* list_iter_next(struct _iterator* iter)
{
list_t self = (list_t)iter->_container;
void* obj = self->obj + iter->_index * self->_obj_size;
iter->_index += 1;
return obj;
}
iterator_t list_iter(struct _list* self)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->hasnext = list_iter_hasnext;
iter->next = list_iter_next;
return iter;
}
static bool list_init2(struct _list* self, size_t obj_size, size_t capacity)
{
unicstl_assert(self != NULL);
unicstl_assert(obj_size != 0);
if (capacity == 0)
{
return false;
}
// -------------------- private --------------------
self->_obj_size = obj_size;
self->_size = 0;
self->_capacity = capacity;
self->_ratio = 2;
self->_cur = 0;
self->obj = (void*)unicstl_malloc(self->_capacity * self->_obj_size);
if (self->obj == NULL)
{
return false;
}
self->_iter.next = list_iter_next;
self->_iter.hasnext = list_iter_hasnext;
self->_destory = list_destory;
// -------------------- public --------------------
// kernel
self->append = list_append;
self->pop = list_pop;
self->insert = list_insert;
self->delete = list_delete;
self->get = list_get;
self->set = list_set;
self->index = list_index;
// self->contains = list_contains;
// base
self->clear = list_clear;
self->size = list_size;
self->empty = list_empty;
self->capacity = list_capacity;
// iter
self->iter = list_iter;
// others
self->slice = list_slice;
// -------------------- default --------------------
self->compare = default_compare;
self->print_obj = default_print_obj;
// -------------------- debug --------------------
self->print = list_print;
return true;
}
list_t list_new2(size_t obj_size, size_t capacity)
{
struct _list* list = NULL;
list = (struct _list*)unicstl_calloc(1, sizeof(struct _list));
if (list == NULL)
{
log_warn("list calloc failed\n");
return NULL;
}
if (list_init2(list, obj_size, capacity) != true)
{
log_warn("list init failed\n");
unicstl_free(list);
return NULL;
}
return list;
}
void list_free(list_t* list)
{
unicstl_assert(list != NULL);
if (list != NULL && *list != NULL)
{
if ((*list)->_destory != NULL)
{
(*list)->_destory(*list);
}
unicstl_free(*list);
*list = NULL;
}
}

View File

@ -13,6 +13,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
struct log_string
{
@ -30,6 +31,20 @@ struct log_string log_str[] = {
LOG_NONE, NULL
};
void timestamp(FILE *file)
{
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
fprintf(file, "[%04d-%02d-%02d %02d:%02d:%02d] ", timeinfo->tm_year + 1900,
timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour,
timeinfo->tm_min,
timeinfo->tm_sec);
}
void logger_init(const char *file_name)
{
@ -39,6 +54,8 @@ void logger_init(const char *file_name)
perror("Failed to open log file");
exit(-1);
}
timestamp(log_file);
fprintf(log_file, "\n\n ============================== log start ============================== \n\n");
fflush(log_file);
}
@ -65,7 +82,7 @@ void logger(loglevel_t level, const char *file_name, int line, const char *func_
}
fprintf(file, "[%5s] ", log_str[level].str);
fprintf(file, "%s:%d %s()\t", file_name, line, func_name);
fprintf(file, "%s:%-4d %-24s: ", file_name, line, func_name);
va_list args;
va_start(args, format);

92
src/mempool.c Normal file
View File

@ -0,0 +1,92 @@
/**
* @file mempool.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-17
*
* @copyright Copyright (c) 2026
*
*/
#include "mempool.h"
#ifdef UNICSTL_MALLOC_CUSTOM
typedef struct _mempool
{
size_t count_total;
size_t count_free;
size_t count_malloc;
size_t count_calloc;
size_t count_realloc;
}mempool_t;
static mempool_t mempool;
void mempool_init()
{
memset(&mempool, 0, sizeof(mempool_t));
}
void mempool_deinit()
{
printf("\n-------------------- \n");
printf("count_malloc: %zu\n", mempool.count_malloc);
printf("count_calloc: %zu\n", mempool.count_calloc);
printf("count_realloc: %zu\n", mempool.count_realloc);
printf("\n");
printf("count_total: %zu\n", mempool.count_total);
printf("count_free: %zu\n", mempool.count_free);
printf("-------------------- \n");
size_t leak = mempool.count_total - mempool.count_free;
if (mempool.count_total > mempool.count_free)
{
printf("ERROR: maybe leak: %zu\n", leak);
}
else if (mempool.count_total < mempool.count_free)
{
printf("ERROR: maybe free too many\n");
}
else
{
printf("OK: no leak\n");
}
memset(&mempool, 0, sizeof(mempool_t));
}
void *unicstl_malloc(size_t size)
{
mempool.count_malloc++;
mempool.count_total++;
return malloc(size);
}
void *unicstl_calloc(size_t num, size_t size)
{
mempool.count_calloc++;
mempool.count_total++;
return calloc(num, size);
}
void *unicstl_realloc(void *ptr, size_t size)
{
mempool.count_realloc++;
if(ptr == NULL)
{
mempool.count_total++;
}
return realloc(ptr, size);
}
void unicstl_free(void *ptr)
{
if (ptr != NULL)
{
mempool.count_free++;
free(ptr);
}
}
#endif

View File

@ -122,7 +122,7 @@ static iterator_t queue_iter(struct _queue* self)
unicstl_assert(self != NULL);
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
self->_iter_deque = deque->iter(deque, DEQUE_FORWARD);
self->_iter_deque = deque->iter(deque, LINEAR_FORWARD);
iterator_t iter = &self->_iter;
iter->_container = self;

View File

@ -297,7 +297,7 @@ bool ringbuf_iter_hasnext(struct _iterator *iter)
ringbuf_t self = (ringbuf_t)iter->_container;
if (iter->_order == RINGBUF_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
if (iter->_index == self->_tail)
{
@ -322,7 +322,7 @@ const void *ringbuf_iter_next(struct _iterator *iter)
ringbuf_t self = (ringbuf_t)iter->_container;
size_t index = iter->_index;
if (iter->_order == RINGBUF_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
iter->_index = ring_index_next(index, self->_capacity);
}
@ -334,7 +334,7 @@ const void *ringbuf_iter_next(struct _iterator *iter)
return obj_at(self->obj, index, self->_obj_size);
}
iterator_t ringbuf_iter(struct _ringbuf *self, enum _ringbuf_order order)
iterator_t ringbuf_iter(struct _ringbuf *self, linear_order_t order)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
@ -342,7 +342,7 @@ iterator_t ringbuf_iter(struct _ringbuf *self, enum _ringbuf_order order)
iter->_container = self;
iter->_index = 0;
iter->_order = order;
if (iter->_order == RINGBUF_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
iter->_index = self->_head;
}
@ -453,6 +453,6 @@ void ringbuf_free(ringbuf_t *ringbuf)
{
(*ringbuf)->_destory(*ringbuf);
unicstl_free(*ringbuf);
*ringbuf = NULL;
}
*ringbuf = NULL;
}

View File

@ -13,9 +13,38 @@
static inline size_t clac_start_index(size_t capacity)
{
// return 0;
// return capacity - 1;
return capacity <= 2 ? 0 : (capacity - 1) / 2;
}
static bool segarray_add_first_segment(struct _segarray *self)
{
ringbuf_t map = self->_map;
ringbuf_t mapfree = self->_mapfree;
if(self->_map->empty(map)) // first segment
{
log_debug("map is empty!");
rawbuf_t seg = rawbuf_new(self->_obj_size, self->_segsize);
if (seg == NULL)
{
log_error("rawbuf_new failed!");
return false;
}
if (!map->push_back(map, &seg))
{
log_error("map->push_back failed!");
return false;
}
self->_seghead = clac_start_index(self->_segsize);
self->_segtail = 0;
self->_capacity = self->_segsize;
return true;
}
return false;
}
static bool segarray_push_back(struct _segarray *self, const void *obj)
{
unicstl_assert(self != NULL);
@ -23,6 +52,7 @@ static bool segarray_push_back(struct _segarray *self, const void *obj)
{
return false;
}
segarray_add_first_segment(self);
ringbuf_t map = self->_map;
ringbuf_t mapfree = self->_mapfree;
@ -31,6 +61,7 @@ static bool segarray_push_back(struct _segarray *self, const void *obj)
{
if(self->_mapfree->empty(mapfree))
{
log_debug("mapfree is empty!");
if (map->full(map))
{
// need resize
@ -39,18 +70,22 @@ static bool segarray_push_back(struct _segarray *self, const void *obj)
}
else
{
rawbuf_t seg = rawbuf_new(self->_obj_size, self->_capacity);
rawbuf_t seg = rawbuf_new(self->_obj_size, self->_segsize);
if (seg == NULL)
{
log_error("rawbuf_new failed!");
return false;
}
map->push_back(map, &seg);
self->_segtail = 0;
if (!map->push_back(map, &seg))
{
log_error("map->push_back failed!");
return false;
}
}
}
else
{
log_debug("mapfree is not empty!");
rawbuf_t seg;
if (!mapfree->pop_back(mapfree, &seg))
{
@ -62,9 +97,11 @@ static bool segarray_push_back(struct _segarray *self, const void *obj)
log_error("map->push_back failed!");
return false;
}
self->_segtail = 0;
}
self->_segtail = 0;
}
log_debug("self->_segtail=%zu", self->_segtail);
rawbuf_t seg;
if (!map->back(map, &seg))
@ -81,7 +118,7 @@ static bool segarray_push_back(struct _segarray *self, const void *obj)
}
self->_segtail = index + 1;
log_info("push_back success!");
log_debug("push_back success!");
self->_size++;
return true;
}
@ -93,10 +130,11 @@ static bool segarray_push_front(struct _segarray *self, const void *obj)
{
return false;
}
segarray_add_first_segment(self);
ringbuf_t map = self->_map;
ringbuf_t mapfree = self->_mapfree;
if (self->_seghead == 0)
{
if(self->_mapfree->empty(mapfree))
@ -109,14 +147,13 @@ static bool segarray_push_front(struct _segarray *self, const void *obj)
}
else
{
rawbuf_t seg = rawbuf_new(self->_obj_size, self->_capacity);
rawbuf_t seg = rawbuf_new(self->_obj_size, self->_segsize);
if (seg == NULL)
{
log_error("rawbuf_new failed!");
return false;
}
map->push_front(map, &seg);
self->_seghead = self->_segsize;
}
}
else
@ -132,8 +169,9 @@ static bool segarray_push_front(struct _segarray *self, const void *obj)
log_error("map->push_back failed!");
return false;
}
self->_seghead = self->_segsize;
}
self->_seghead = self->_segsize;
}
rawbuf_t seg;
@ -150,7 +188,7 @@ static bool segarray_push_front(struct _segarray *self, const void *obj)
}
self->_seghead = index;
log_info("push_front success!");
log_debug("push_front success!");
self->_size++;
return true;
}
@ -181,6 +219,7 @@ static bool segarray_pop_back(struct _segarray *self, void *obj)
return false;
}
}
self->_segtail = index;
if(self->_segtail == 0)
{
@ -199,7 +238,7 @@ static bool segarray_pop_back(struct _segarray *self, void *obj)
}
}
log_info("pop_back success!");
log_debug("pop_back success!");
self->_size--;
return true;
}
@ -254,7 +293,7 @@ static bool segarray_pop_front(struct _segarray *self, void *obj)
}
}
log_info("pop_front success!");
log_debug("pop_front success!");
self->_size--;
return true;
}
@ -266,6 +305,7 @@ static bool segarray_back(struct _segarray *self, void *obj)
{
return false;
}
log_debug("back");
return self->get(self, self->size(self) - 1, obj);
}
@ -276,6 +316,7 @@ static bool segarray_front(struct _segarray *self, void *obj)
{
return false;
}
log_debug("front");
return self->get(self, 0, obj);
}
@ -421,24 +462,35 @@ static bool segarray_clear(struct _segarray *self)
static void segarray_destory(struct _segarray *self)
{
unicstl_assert(self != NULL);
ringbuf_t map = self->_map;
if (self->_dynamic && map != NULL)
ringbuf_t map_used[2] = {
self->_map,
self->_mapfree
};
if(self->_dynamic == true)
{
rawbuf_t seg = NULL;
while(!map->empty(map))
ringbuf_t map = self->_map;
for(size_t i = 0; i < 2; i++)
{
if (map->pop_back(map, &seg))
map = map_used[i];
while(!map->empty(map))
{
if(seg == NULL)
if (map->pop_back(map, &seg))
{
log_error("seg is NULL");
if(seg == NULL)
{
log_error("seg is NULL");
}
rawbuf_free(&seg);
}
rawbuf_free(&seg);
}
}
ringbuf_free(&self->_map);
ringbuf_free(&self->_mapfree);
}
log_info("segarray destoryed!");
log_debug("segarray destoryed!");
}
static void segarray_print(struct _segarray *self)
@ -464,7 +516,7 @@ bool segarray_iter_hasnext(struct _iterator *iter)
unicstl_assert(iter->_container != NULL);
segarray_t self = (segarray_t)iter->_container;
if (iter->_order == SEGARRAY_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
if (iter->_index >= self->size(self))
{
@ -489,7 +541,7 @@ const void *segarray_iter_next(struct _iterator *iter)
const void *obj = NULL;
obj = self->at(self, iter->_index);
if (iter->_order == SEGARRAY_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
iter->_index++;
}
@ -500,7 +552,7 @@ const void *segarray_iter_next(struct _iterator *iter)
return obj;
}
iterator_t segarray_iter(struct _segarray *self, enum _segarray_order order)
iterator_t segarray_iter(struct _segarray *self, linear_order_t order)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
@ -509,7 +561,7 @@ iterator_t segarray_iter(struct _segarray *self, enum _segarray_order order)
iter->_index = 0;
iter->_order = order;
if (iter->_order == SEGARRAY_FORWARD)
if (iter->_order == LINEAR_FORWARD)
{
iter->_index = 0;
}
@ -529,11 +581,10 @@ iterator_t segarray_iter(struct _segarray *self, enum _segarray_order order)
* @param self
* @param obj_size
* @param capacity
* @param mem_pool !!! mem_pool_size = capacity * obj_size
* @return true
* @return false
*/
bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, void *mem_pool)
static bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity)
{
unicstl_assert(self != NULL);
unicstl_assert(obj_size > 0);
@ -542,43 +593,15 @@ bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, voi
self->_obj_size = obj_size;
self->_size = 0;
self->_capacity = capacity;
self->_segsize = capacity;
if (mem_pool != NULL)
if(capacity == 0)
{
self->obj = (char *)mem_pool;
self->_segsize = UNICSTL_CAPACITY_INIT;
self->_dynamic = false;
}
else
{
self->_segsize = self->_capacity;
self->_dynamic = true;
self->_map = ringbuf_new(sizeof(rawbuf_t), 8);
if (self->_map == NULL)
{
return false;
}
self->_mapfree = ringbuf_new(sizeof(rawbuf_t), 8);
if (self->_mapfree == NULL)
{
ringbuf_free(&self->_map);
return false;
}
rawbuf_t seg = rawbuf_new(obj_size, self->_segsize);
if (seg == NULL)
{
ringbuf_free(&self->_map);
ringbuf_free(&self->_mapfree);
return false;
}
// config first obj index in seg array
self->_seghead = clac_start_index(self->_segsize);
self->_segtail = self->_seghead;
// add first seg array to map
self->_map->push_back(self->_map, &seg);
}
self->_destory = segarray_destory;
@ -614,6 +637,46 @@ bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, voi
// -------------------- debug --------------------
self->print = segarray_print;
// -------------------- memory --------------------
self->_map = ringbuf_new(sizeof(rawbuf_t), 8);
if (self->_map == NULL)
{
log_warn("self->_map new failed!");
return false;
}
self->_mapfree = ringbuf_new(sizeof(rawbuf_t), 8);
if (self->_mapfree == NULL)
{
log_warn("self->_mapfree new failed!");
ringbuf_free(&self->_map);
return false;
}
if(capacity != 0)
{
rawbuf_t seg = rawbuf_new(obj_size, self->_segsize);
if (seg == NULL)
{
log_warn("seg new failed!");
ringbuf_free(&self->_map);
ringbuf_free(&self->_mapfree);
return false;
}
// config first obj index in seg array
self->_seghead = clac_start_index(self->_segsize);
self->_segtail = self->_seghead;
// add first seg array to map
if(!self->_map->push_back(self->_map, &seg))
{
log_warn("self->_map push back failed!");
rawbuf_free(&seg);
ringbuf_free(&self->_map);
ringbuf_free(&self->_mapfree);
return false;
}
}
return true;
}
@ -627,7 +690,7 @@ segarray_t segarray_new(size_t obj_size, size_t capacity)
return NULL;
}
if (segarray_init(segarray, obj_size, capacity, NULL) != true)
if (segarray_init(segarray, obj_size, capacity) != true)
{
log_warn("segarray init failed");
unicstl_free(segarray);

View File

@ -136,7 +136,7 @@ iterator_t stack_iter(struct _stack* self)
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
self->_iter_deque = deque->iter(deque, DEQUE_FORWARD);
self->_iter_deque = deque->iter(deque, LINEAR_FORWARD);
iterator_t iter = &self->_iter;
iter->_container = self;

View File

@ -75,31 +75,34 @@ void tearDown(void)
int main(int argc, char const *argv[])
{
log_init();
printf("----- Unicstl Unit Test -----\n");
UNITY_BEGIN();
log_init();
mempool_init();
TEST_ADD(test_unicstl);
TEST_ADD(test_darray);
TEST_ADD(test_linklist);
TEST_ADD(test_dlinklist);
TEST_ADD(test_darray);
TEST_ADD(test_ringbuf);
TEST_ADD(test_rawbuf);
TEST_ADD(test_deque);
TEST_ADD(test_queue);
TEST_ADD(test_stack);
TEST_ADD(test_list);
TEST_ADD(test_heap);
TEST_ADD(test_tree);
TEST_ADD(test_graph);
TEST_ADD(test_rawbuf);
TEST_ADD(test_heap);
// TEST_ADD(test_tree);
// TEST_ADD(test_graph);
TEST_ADD(test_segarray);
TEST_ADD(test_arraylist);
mempool_deinit();
log_deinit();
return UNITY_END();
}

View File

@ -49,9 +49,10 @@ void test_linklist(void);
void test_dlinklist(void);
void test_ringbuf(void);
void test_rawbuf(void);
void test_segarray(void);
void test_deque(void);
void test_arraylist(void);
void test_queue(void);
void test_stack(void);

1267
test/test_arraylist.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -524,7 +524,7 @@ static void test_darray_iter(void)
darray->append(darray, &data[i]);
}
iterator_t iter = darray->iter(darray, DARRAY_FORWARD);
iterator_t iter = darray->iter(darray, LINEAR_FORWARD);
i = 0;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
@ -535,7 +535,7 @@ static void test_darray_iter(void)
}
TEST_ASSERT_EQUAL_INT(len, i);
iter = darray->iter(darray, DARRAY_REVERSE);
iter = darray->iter(darray, LINEAR_REVERSE);
i = len - 1;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
@ -588,7 +588,7 @@ static void test_darray_sort(void)
}
TEST_ASSERT_TRUE(darray->sort(darray));
iterator_t iter = darray->iter(darray, DARRAY_FORWARD);
iterator_t iter = darray->iter(darray, LINEAR_FORWARD);
i = 0;
while(iter->hasnext(iter))
{
@ -603,7 +603,7 @@ static void test_darray_sort(void)
TEST_ASSERT_TRUE(darray->sort(darray));
iter = darray->iter(darray, DARRAY_FORWARD);
iter = darray->iter(darray, LINEAR_FORWARD);
i = 0;
while(iter->hasnext(iter))
{

View File

@ -355,7 +355,7 @@ static void test_deque_iter(void)
deque->push_back(deque, &data[i]);
}
iterator_t iter = deque->iter(deque, RINGBUF_FORWARD);
iterator_t iter = deque->iter(deque, LINEAR_FORWARD);
i = 0;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
@ -366,7 +366,7 @@ static void test_deque_iter(void)
}
TEST_ASSERT_EQUAL_INT(len, i);
iter = deque->iter(deque, RINGBUF_REVERSE);
iter = deque->iter(deque, LINEAR_REVERSE);
i = len - 1;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))

View File

@ -292,7 +292,7 @@ static void test_dlinklist_iter(void)
TEST_ASSERT_EQUAL_INT(i + 1, dlinklist->size(dlinklist));
}
iterator_t iter = dlinklist->iter(dlinklist, DLLIST_FORWARD);
iterator_t iter = dlinklist->iter(dlinklist, LINEAR_FORWARD);
i = 0;
while(iter->hasnext(iter))
{
@ -301,7 +301,7 @@ static void test_dlinklist_iter(void)
i++;
}
iter = dlinklist->iter(dlinklist, DLLIST_FORWARD);
iter = dlinklist->iter(dlinklist, LINEAR_FORWARD);
i = 0;
while(iter->hasnext(iter))
{
@ -310,7 +310,7 @@ static void test_dlinklist_iter(void)
i++;
}
iter = dlinklist->iter(dlinklist, DLLIST_REVERSE);
iter = dlinklist->iter(dlinklist, LINEAR_REVERSE);
i = len - 1;
while(iter->hasnext(iter))
{

View File

@ -1,778 +0,0 @@
/**
* @file test_list->c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2024-08-30
*
* @copyright Copyright (c) 2024
*
*/
#include "test.h"
static void test_list_new(void)
{
list_t list = NULL;
list = list_new2(sizeof(int), 1);
TEST_ASSERT_NOT_NULL(list);
list_free(&list);
TEST_ASSERT_NULL(list);
list_free(&list); // list_free(NULL);
TEST_ASSERT_NULL(list);
// TEST_ASSERT_NULL(list_new2(0, 1)); // nomeaing
// TEST_ASSERT_NULL(list_new2(sizeof(int), 0)); //
}
static void test_list_append(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
TEST_ASSERT_TRUE(list->empty(list));
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
TEST_ASSERT_TRUE(list->get(list, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
TEST_ASSERT_FALSE(list->empty(list));
}
list_free(&list);
// ------------------------------
// if capacity is less than data len
list = list_new2(sizeof(int), len - 2);
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
}
list_free(&list);
}
static void test_list_pop(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
for (i = 0; i < len; i++)
{
list->append(list, &data[i]);
}
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->pop(list, &temp));
}
TEST_ASSERT_TRUE(list->empty(list));
TEST_ASSERT_FALSE(list->pop(list, &temp));
list_free(&list);
}
static void test_list_insert(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->print_obj = print_num;
TEST_ASSERT_TRUE(list->empty(list));
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->insert(list, i, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
TEST_ASSERT_TRUE(list->get(list, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
// list->print(list);
// printf("\n");
}
list->clear(list);
TEST_ASSERT_TRUE(list->empty(list));
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->insert(list, 0, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
TEST_ASSERT_TRUE(list->get(list, 0, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
// list->print(list);
// printf("\n");
}
TEST_ASSERT_FALSE(list->empty(list));
list_free(&list);
}
static void test_list_delete(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
for (i = 0; i < len; i++)
{
list->append(list, &data[i]);
}
TEST_ASSERT_TRUE(list->delete(list, len - 1, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 1], temp);
for (i = 0; i < len - 1; i++)
{
TEST_ASSERT_TRUE(list->delete(list, 0, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
TEST_ASSERT_TRUE(list->empty(list));
TEST_ASSERT_FALSE(list->pop(list, &temp));
list_free(&list);
}
static void test_list_clear(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
TEST_ASSERT_TRUE(list->clear(list));
for (i = 0; i < len; i++)
{
list->append(list, &data[i]);
}
TEST_ASSERT_FALSE(list->empty(list));
TEST_ASSERT_TRUE(list->clear(list));
TEST_ASSERT_TRUE(list->empty(list));
TEST_ASSERT_TRUE(list->clear(list));
list_free(&list);
}
static void test_list_num(void)
{
int i = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
int temp = 0;
int index = 0;
int len = sizeof(data) / sizeof(data[0]);
list_t list = NULL;
list = list_new2(sizeof(int), 64);
TEST_ASSERT_TRUE(list != NULL);
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
TEST_ASSERT_TRUE(list->delete(list, 9, NULL));
TEST_ASSERT_TRUE(list->delete(list, 0, NULL));
TEST_ASSERT_TRUE(list->delete(list, 4, NULL));
TEST_ASSERT_TRUE(list->clear(list));
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
index = 0;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = 4;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = 9;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = 0;
temp = 11;
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = 4;
temp = 22;
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = 9;
temp = 33;
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = -1;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = -6;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = -10;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = -1;
temp = 99;
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = -6;
temp = 98;
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = -10;
temp = 97;
TEST_ASSERT_TRUE(list->set(list, index, &temp));
for (i = 0; i < len + 1; i++)
{
TEST_ASSERT_TRUE(list->pop(list, &temp));
if (list->empty(list))
{
break;
}
}
list_free(&list);
TEST_ASSERT_NULL(list);
}
static void test_list_struct(void)
{
int i = 0;
struct _student data[] = {
"zhao", 1001, "qian", 1002, "sun", 1003, "li", 1004,
"zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008,
"feng", 1009, "cheng",1010,
};
struct _student temp = { 0 };
int index = 0;
int len = sizeof(data) / sizeof(data[0]);
list_t list = list_new2(sizeof(struct _student), 64);
list->print_obj = print_struct;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
TEST_ASSERT_TRUE(list->delete(list, 9, NULL));
TEST_ASSERT_TRUE(list->delete(list, 0, NULL));
TEST_ASSERT_TRUE(list->delete(list, 4, NULL));
TEST_ASSERT_TRUE(list->clear(list));
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
index = 0;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = 4;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = 9;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = 0;
temp.id = 11;
sprintf(temp.name, "robot_%02d", temp.id);
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = 4;
temp.id = 22;
sprintf(temp.name, "robot_%02d", temp.id);
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = 9;
temp.id = 33;
sprintf(temp.name, "robot_%02d", temp.id);
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = -1;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = -6;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = -10;
TEST_ASSERT_TRUE(list->get(list, index, &temp));
index = -1;
temp.id = 99;
sprintf(temp.name, "robot_%02d", temp.id);
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = -6;
temp.id = 98;
sprintf(temp.name, "robot_%02d", temp.id);
TEST_ASSERT_TRUE(list->set(list, index, &temp));
index = -10;
temp = (struct _student){ "robot", 97 };
TEST_ASSERT_TRUE(list->set(list, index, &temp));
for (i = 0; i < len + 1; i++)
{
TEST_ASSERT_TRUE(list->pop(list, &temp));
if (list->empty(list))
{
break;
}
}
list_free(&list);
TEST_ASSERT_NULL(list);
}
void test_list_iter(void)
{
int temp = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
TEST_ASSERT_TRUE(list->empty(list));
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, list->size(list));
TEST_ASSERT_TRUE(list->get(list, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
TEST_ASSERT_FALSE(list->empty(list));
}
iterator_t iter = list->iter(list);
int iter_data = 0;
int idx = 0;
while (iter->hasnext(iter))
{
iter_data = *(int*)iter->next(iter);
// printf("%d ", iter_data);
TEST_ASSERT_EQUAL_INT(data[idx], iter_data);
idx++;
}
list_free(&list);
}
static void test_list_index(void)
{
int temp = 0;
int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
TEST_ASSERT_EQUAL_INT(0, list->index(list, &data[0]));
TEST_ASSERT_EQUAL_INT(5, list->index(list, &data[5]));
TEST_ASSERT_EQUAL_INT(9, list->index(list, &data[9]));
temp = 11;
TEST_ASSERT_EQUAL_INT(-1, list->index(list, &temp));
list_free(&list);
}
static void test_list_slice_empty(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- NULL --------------------
// python: list[0:] -> []
list2 = list->slice(list, 1, 5, 0); // if step == 0
TEST_ASSERT_NULL(list2);
// list_free(&list2);
// -------------------- empty --------------------
list2 = list->slice(list, 0, 0, 1); // if start == end
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, len, LIST_UNLIMITED, 1); // if start == end
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, 1, 5, -1); // if start < end && step < 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, 5, 1, 1); // if start > end && step > 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, -1, -5, 1); // if start < end && step < 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, -5, -1, -1); // if start > end && step > 0
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
// -------------------- empty --------------------
list2 = list->slice(list, len, len + 1, 1); // if start > start_max
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list2 = list->slice(list, -len - 1, -len, 1); // if end < end_min
TEST_ASSERT_NOT_NULL(list2);
TEST_ASSERT_TRUE(list2->empty(list2));
list_free(&list2);
list_free(&list);
}
static void test_list_slice_positive(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- elements --------------------
// python: list[0:]
list2 = list->slice(list, 0, len, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[0:11] if len(list) == 10
list2 = list->slice(list, 0, len + 1, 1);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[-6:8] or list[-6:-2] or list[4:8]
list2 = list->slice(list, 4, 8, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 6 + i], temp);
}
list_free(&list2);
// python: list[4:0:-1]
list2 = list->slice(list, 4, 0, -1);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - i], temp);
}
list_free(&list2);
// python: list[::2]
list2 = list->slice(list, 0, len, 2);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i * 2], temp);
}
list_free(&list2);
list_free(&list);
}
static void test_list_slice_negative(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- elements --------------------
// python: list[:-1]
list2 = list->slice(list, 0, -1, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len - 1, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[:-1]
list2 = list->slice(list, -1, len, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(1, list2->size(list2));
TEST_ASSERT_TRUE(list2->get(list2, 0, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 1], temp);
list_free(&list2);
// python: list[-6:8] or list[-6:-2]
// list2 = list->slice(list, -6, 8, 1); // It can be executed, but it's not intuitive
list2 = list->slice(list, -6, -2, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(4, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[len - 6 + i], temp);
}
list_free(&list2);
// -------------------- step == 2 --------------------
// python: list[::-2]
list2 = list->slice(list, len-1, 0, -2);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[9 - i * 2], temp);
}
list_free(&list2);
// -------------------- start_limit --------------------
// list[-len-1:-1]
list2 = list->slice(list, -len-1, -1, 1);
TEST_ASSERT_NOT_NULL(list2);
// list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len - 1, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
list_free(&list);
}
static void test_list_slice_unlimited(void)
{
int temp = 0;
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
size_t len = sizeof(data) / sizeof(data[0]);
size_t i = 0;
list_t list = NULL;
list_t list2 = NULL;
// ------------------------------
list = list_new2(sizeof(int), len);
list->compare = compare_num;
list->print_obj = print_num;
for (i = 0; i < len; i++)
{
TEST_ASSERT_TRUE(list->append(list, &data[i]));
}
// -------------------- umlimited --------------------
// python: list[0:]
list2 = list->slice(list, 0, LIST_UNLIMITED, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
// python: list[4::-1]
list2 = list->slice(list, 4, LIST_UNLIMITED, -1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - 1 - i], temp);
}
list_free(&list2);
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, 1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i], temp);
}
list_free(&list2);
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, -1);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(len, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[list2->size(list2) - 1 - i], temp);
}
list_free(&list2);
// -------------------- step == 2 --------------------
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, 2);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[i * 2], temp);
}
list_free(&list2);
list2 = list->slice(list, LIST_UNLIMITED, LIST_UNLIMITED, -2);
TEST_ASSERT_NOT_NULL(list2);
//list2->print(list2); printf("\n");
TEST_ASSERT_EQUAL_INT(5, list2->size(list2));
for(i = 0; i < list2->size(list2); i++)
{
TEST_ASSERT_TRUE(list2->get(list2, i, &temp));
TEST_ASSERT_EQUAL_INT(data[9 - i*2], temp);
}
list_free(&list2);
list_free(&list);
}
void test_list(void)
{
UnitySetTestFile(__FILE__);
RUN_TEST(test_list_new);
RUN_TEST(test_list_append);
RUN_TEST(test_list_pop);
RUN_TEST(test_list_insert);
RUN_TEST(test_list_delete);
RUN_TEST(test_list_clear);
RUN_TEST(test_list_num);
RUN_TEST(test_list_struct);
RUN_TEST(test_list_iter);
RUN_TEST(test_list_index);
RUN_TEST(test_list_slice_empty);
RUN_TEST(test_list_slice_positive);
RUN_TEST(test_list_slice_negative);
RUN_TEST(test_list_slice_unlimited);
}

View File

@ -492,7 +492,7 @@ static void test_ringbuf_iter(void)
ringbuf->push_back(ringbuf, &data[i]);
}
iterator_t iter = ringbuf->iter(ringbuf, RINGBUF_FORWARD);
iterator_t iter = ringbuf->iter(ringbuf, LINEAR_FORWARD);
i = 0;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
@ -503,7 +503,7 @@ static void test_ringbuf_iter(void)
}
TEST_ASSERT_EQUAL_INT(len, i);
iter = ringbuf->iter(ringbuf, RINGBUF_REVERSE);
iter = ringbuf->iter(ringbuf, LINEAR_REVERSE);
i = len - 1;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))

View File

@ -22,17 +22,17 @@ static void test_segarray_new(void)
TEST_ASSERT_NULL(segarray);
}
// static void test_segarray_new_lazy(void)
// {
// segarray_t segarray = segarray_new(sizeof(int), 0);
// TEST_ASSERT_NOT_NULL(segarray);
// TEST_ASSERT_EQUAL_size_t(0, segarray->capacity(segarray));
static void test_segarray_new_lazy(void)
{
segarray_t segarray = segarray_new(sizeof(int), 0);
TEST_ASSERT_NOT_NULL(segarray);
TEST_ASSERT_EQUAL_size_t(0, segarray->capacity(segarray));
// int temp = 0;
// TEST_ASSERT_TRUE(segarray->push_back(segarray, &temp));
// TEST_ASSERT_EQUAL_size_t(UNICSTL_CAPACITY_INIT, segarray->capacity(segarray));
// segarray_free(&segarray);
// }
int temp = 0;
TEST_ASSERT_TRUE(segarray->push_back(segarray, &temp));
TEST_ASSERT_EQUAL_size_t(UNICSTL_CAPACITY_INIT, segarray->capacity(segarray));
segarray_free(&segarray);
}
// #ifdef UNICSTL_STATIC_MEMORY
// static void test_segarray_init(void)
@ -73,13 +73,16 @@ static void test_segarray_push_back(void)
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int temp = 0;
size_t len = sizeof(data) / sizeof(data[0]);
log_info("test_segarray_push_back");
segarray_t segarray = segarray_new(sizeof(int), len);
segarray->print_obj = print_num;
for (i = 0; i < len; i++)
{
log_debug("i:%d", i);
TEST_ASSERT_TRUE(segarray->push_back(segarray, &data[i]));
log_debug("push_back ok. size:%d, capacity:%d", segarray->size(segarray), segarray->capacity(segarray));
TEST_ASSERT_TRUE(segarray->front(segarray, &temp));
TEST_ASSERT_EQUAL_INT(data[0], temp);
@ -94,6 +97,7 @@ static void test_segarray_push_back(void)
TEST_ASSERT_EQUAL_INT(len + 2, segarray->size(segarray));
segarray_free(&segarray);
log_info("test_segarray_push_back ok");
}
static void test_segarray_push_back_invalid(void)
@ -101,6 +105,7 @@ static void test_segarray_push_back_invalid(void)
segarray_t segarray = segarray_new(sizeof(int), 1);
TEST_ASSERT_FALSE(segarray->push_back(segarray, NULL));
segarray_free(&segarray);
log_info("test_segarray_push_back_invalid ok");
}
static void test_segarray_push_front(void)
@ -475,6 +480,7 @@ static void test_segarray_at(void)
TEST_ASSERT_EQUAL_INT(100, temp);
segarray_free(&segarray);
log_info("segarray_at cuccess!");
}
static void test_segarray_iter(void)
@ -493,12 +499,12 @@ static void test_segarray_iter(void)
}
TEST_ASSERT_EQUAL_INT(len, segarray->size(segarray));
iterator_t iter = segarray->iter(segarray, RINGBUF_FORWARD);
iterator_t iter = segarray->iter(segarray, LINEAR_FORWARD);
i = 0;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
{
log_debug("iter-test: i=%d\n", i);
log_debug("iter-test: i=%d", i);
temp = *(int *)iter->next(iter);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i++;
@ -506,12 +512,12 @@ static void test_segarray_iter(void)
TEST_ASSERT_EQUAL_INT(len, i);
log_info("iter-forward cuccess!");
iter = segarray->iter(segarray, RINGBUF_REVERSE);
iter = segarray->iter(segarray, LINEAR_REVERSE);
i = len - 1;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
{
log_debug("iter-test: i=%d\n", i);
log_debug("iter-test: i=%d", i);
temp = *(int *)iter->next(iter);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i--;
@ -834,7 +840,7 @@ void test_segarray(void)
// ---------- kernel ----------
RUN_TEST(test_segarray_new);
// RUN_TEST(test_segarray_new_lazy);
RUN_TEST(test_segarray_new_lazy);
// #ifdef UNICSTL_STATIC_MEMORY
// RUN_TEST(test_segarray_init);

View File

@ -171,6 +171,7 @@ static void test_avltree_delete(void)
int count = 0;
iterator_t iter = NULL;
log_info("test_avltree_delete");
tree_t tree = tree_avl_new(sizeof(int));
TEST_ASSERT_NOT_NULL(tree);
tree->print_obj = print_num;
@ -182,6 +183,7 @@ static void test_avltree_delete(void)
temp = data[i];
TEST_ASSERT_TRUE(tree->insert(tree, &temp));
}
log_info("insert finished! tree size: %d\n", tree->size(tree));
for (i = 0; i < len; i++)
{