mirror of
https://gitee.com/apaki/unicstl.git
synced 2026-05-28 22:54:19 +08:00
Compare commits
5 Commits
15ab80cc4d
...
f5c3b178c5
| Author | SHA1 | Date | |
|---|---|---|---|
| f5c3b178c5 | |||
| 9ae4aa829c | |||
| 82d0167c81 | |||
| 529cf60218 | |||
| 72db0be317 |
26
README.md
26
README.md
@ -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 : 依赖
|
||||
```
|
||||
|
||||
@ -60,7 +60,7 @@ int main()
|
||||
{
|
||||
demo_queue();
|
||||
demo_stack();
|
||||
demo_list();
|
||||
demo_arraylist();
|
||||
demo_deque();
|
||||
demo_tree();
|
||||
demo_heap();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
}
|
||||
@ -81,6 +81,10 @@ segarray扩容,开新segment,然后指向新的segment,性能也不差。
|
||||
|
||||
## 经典问题
|
||||
|
||||
### 2026-05-17
|
||||
1. 单测多少或者调整顺序都能导致segarray报错?经过排查new之后,函数结构体成员函数的指针应该是异常了。
|
||||
push_back没有执行,而是莫名其妙跳到了segarray_free。暂未找到原因。只是单测先保留已重构的,tree和graph暂时先不测试了。
|
||||
|
||||
### 2026-05-15
|
||||
1. ringbuffer,resize扩容,截断的处理代码简化了。
|
||||
|
||||
|
||||
86
include/arraylist.h
Normal file
86
include/arraylist.h
Normal 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_
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
26
include/mempool.h
Normal 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_
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -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
2
mk.bat
@ -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
442
src/arraylist.c
Normal 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
|
||||
67
src/darray.c
67
src/darray.c
@ -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;
|
||||
|
||||
|
||||
111
src/deque.c
111
src/deque.c
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
461
src/list.c
461
src/list.c
@ -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;
|
||||
}
|
||||
}
|
||||
19
src/logger.c
19
src/logger.c
@ -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
92
src/mempool.c
Normal 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
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
179
src/segarray.c
179
src/segarray.c
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
23
test/test.c
23
test/test.c
@ -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();
|
||||
}
|
||||
|
||||
@ -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
1267
test/test_arraylist.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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))
|
||||
{
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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))
|
||||
{
|
||||
|
||||
778
test/test_list.c
778
test/test_list.c
@ -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);
|
||||
}
|
||||
@ -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))
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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++)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user