mirror of
https://gitee.com/apaki/unicstl.git
synced 2026-05-28 22:54:19 +08:00
refactor(heap): 基于darray重构堆
This commit is contained in:
parent
81d9cf3c13
commit
18c67dacb3
25
README.md
25
README.md
@ -23,18 +23,18 @@ classDiagram
|
|||||||
direction TB
|
direction TB
|
||||||
|
|
||||||
namespace basic {
|
namespace basic {
|
||||||
class ringbuf{
|
|
||||||
不扩容或
|
|
||||||
小数据扩容
|
|
||||||
}
|
|
||||||
class rawbuf
|
|
||||||
class darray
|
|
||||||
class linklist{
|
class linklist{
|
||||||
<<单链表>>
|
<<单链表>>
|
||||||
}
|
}
|
||||||
class dlinklist{
|
class dlinklist{
|
||||||
<<双向链表>>
|
<<双向链表>>
|
||||||
}
|
}
|
||||||
|
class ringbuf{
|
||||||
|
不扩容或
|
||||||
|
小数据扩容
|
||||||
|
}
|
||||||
|
class rawbuf
|
||||||
|
class darray
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace embed {
|
namespace embed {
|
||||||
@ -58,7 +58,6 @@ namespace hal {
|
|||||||
切片
|
切片
|
||||||
负索引
|
负索引
|
||||||
}
|
}
|
||||||
class string
|
|
||||||
class hashtable
|
class hashtable
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +68,13 @@ namespace adapter {
|
|||||||
namespace top {
|
namespace top {
|
||||||
class stack
|
class stack
|
||||||
class queue
|
class queue
|
||||||
|
|
||||||
class rbtree
|
class rbtree
|
||||||
class map
|
class map
|
||||||
|
|
||||||
|
class string
|
||||||
class unordered_map
|
class unordered_map
|
||||||
|
class heap
|
||||||
}
|
}
|
||||||
|
|
||||||
%% hal层
|
%% hal层
|
||||||
@ -90,6 +93,7 @@ deque *-- segarray : 组合
|
|||||||
%% 通用标准容器
|
%% 通用标准容器
|
||||||
stack *-- deque : 组合
|
stack *-- deque : 组合
|
||||||
queue *-- deque : 组合
|
queue *-- deque : 组合
|
||||||
|
heap *-- darray : 组合
|
||||||
|
|
||||||
%% 红黑树
|
%% 红黑树
|
||||||
rbtree ..> stack : 依赖
|
rbtree ..> stack : 依赖
|
||||||
@ -108,14 +112,18 @@ equeue ..> ringbuf : 依赖
|
|||||||
|
|
||||||
### 底层基础容器
|
### 底层基础容器
|
||||||
|
|
||||||
|
#### 链表结构
|
||||||
|数据结构 |名称 |说明 |
|
|数据结构 |名称 |说明 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| linklist | 单链表 |
|
| linklist | 单链表 |
|
||||||
| dlinklist | 双向链表 |
|
| dlinklist | 双向链表 |
|
||||||
|
|
||||||
|
#### 数组结构
|
||||||
|
|数据结构 |名称 |说明 |
|
||||||
|
|---|---|---|
|
||||||
| darray | 动态数组 | 扩容
|
| darray | 动态数组 | 扩容
|
||||||
| ringbuf | 环形缓存区 | 扩容/外部缓存
|
| ringbuf | 环形缓存区 | 扩容/外部缓存
|
||||||
| rawbuf | 原始缓冲区 | 动态分配固定容量/外部缓存
|
| rawbuf | 原始缓冲区 | 动态分配固定容量/外部缓存
|
||||||
| segarray | 分段数组 | 扩容
|
|
||||||
|
|
||||||
### 中层容器
|
### 中层容器
|
||||||
|数据结构 |名称 |说明 |
|
|数据结构 |名称 |说明 |
|
||||||
@ -136,6 +144,7 @@ equeue ..> ringbuf : 依赖
|
|||||||
| stack | 栈 | 扩容
|
| stack | 栈 | 扩容
|
||||||
| queue | 队列 | 扩容
|
| queue | 队列 | 扩容
|
||||||
| ustring | 字符串 | 扩容
|
| ustring | 字符串 | 扩容
|
||||||
|
| heap | 堆 | 扩容
|
||||||
|
|
||||||
### 嵌入式专用容器
|
### 嵌入式专用容器
|
||||||
> 适配嵌入式场景、外置内存、无动态堆分配
|
> 适配嵌入式场景、外置内存、无动态堆分配
|
||||||
|
|||||||
@ -20,7 +20,7 @@ void demo_heap_num(void)
|
|||||||
int temp = 0;
|
int temp = 0;
|
||||||
size_t len = sizeof(data) / sizeof(data[0]);
|
size_t len = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
heap_t heap = heap_min_new2(sizeof(int), 64);
|
heap_t heap = heap_min_new(sizeof(int), 64);
|
||||||
heap->print_obj = print_num;
|
heap->print_obj = print_num;
|
||||||
heap->compare = compare_num;
|
heap->compare = compare_num;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ static void demo_heap_struct(void)
|
|||||||
struct _student temp = {0};
|
struct _student temp = {0};
|
||||||
size_t len = sizeof(data) / sizeof(data[0]);
|
size_t len = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
heap_t heap = heap_min_new2(sizeof(struct _student), 64);
|
heap_t heap = heap_min_new(sizeof(struct _student), 64);
|
||||||
heap->print_obj = print_struct;
|
heap->print_obj = print_struct;
|
||||||
heap->compare = compare_struct;
|
heap->compare = compare_struct;
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#define _HEAP_H_
|
#define _HEAP_H_
|
||||||
|
|
||||||
#include "unicstl_internal.h"
|
#include "unicstl_internal.h"
|
||||||
|
#include "darray.h"
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -22,12 +23,7 @@ typedef enum
|
|||||||
struct _heap
|
struct _heap
|
||||||
{
|
{
|
||||||
// -------------------- private --------------------
|
// -------------------- private --------------------
|
||||||
void* obj;
|
darray_t _darray;
|
||||||
|
|
||||||
size_t _size;
|
|
||||||
size_t _obj_size;
|
|
||||||
size_t _capacity;
|
|
||||||
size_t _ratio;
|
|
||||||
|
|
||||||
heap_type _type;
|
heap_type _type;
|
||||||
struct _iterator _iter;
|
struct _iterator _iter;
|
||||||
@ -41,8 +37,10 @@ struct _heap
|
|||||||
bool (*peek)(struct _heap* self, void* obj);
|
bool (*peek)(struct _heap* self, void* obj);
|
||||||
|
|
||||||
// base
|
// base
|
||||||
|
bool (*reserve)(struct _heap* self, size_t capacity);
|
||||||
|
size_t (*capacity)(struct _heap* self);
|
||||||
|
size_t (*size)(struct _heap* self);
|
||||||
bool (*empty)(struct _heap* self);
|
bool (*empty)(struct _heap* self);
|
||||||
size_t(*size)(struct _heap* self);
|
|
||||||
bool (*clear)(struct _heap* self);
|
bool (*clear)(struct _heap* self);
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
@ -58,8 +56,8 @@ struct _heap
|
|||||||
typedef struct _heap* heap_t;
|
typedef struct _heap* heap_t;
|
||||||
|
|
||||||
// create and free heap
|
// create and free heap
|
||||||
heap_t heap_max_new2(size_t obj_size, size_t capacity);
|
heap_t heap_max_new(size_t obj_size, size_t capacity);
|
||||||
heap_t heap_min_new2(size_t obj_size, size_t capacity);
|
heap_t heap_min_new(size_t obj_size, size_t capacity);
|
||||||
|
|
||||||
void heap_free(heap_t* heap);
|
void heap_free(heap_t* heap);
|
||||||
|
|
||||||
|
|||||||
@ -147,6 +147,34 @@ static inline void *unicstl_realloc(void *ptr, size_t size) { return NULL; }
|
|||||||
static inline void unicstl_free(void *ptr) {}
|
static inline void unicstl_free(void *ptr) {}
|
||||||
#endif // UNICSTL_MALLOC_ENABLE
|
#endif // UNICSTL_MALLOC_ENABLE
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief obj compare with obj2
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* obj < obj2 return -1
|
||||||
|
* obj == obj2 return 0
|
||||||
|
* obj > obj2 return 1
|
||||||
|
*/
|
||||||
|
typedef int (*compare_fun_t)(const void *obj, const void *obj2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline size_t ring_index(size_t head, size_t index, size_t capacity)
|
||||||
|
{
|
||||||
|
return (head + index) % capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t ring_index_next(size_t index, size_t capacity)
|
||||||
|
{
|
||||||
|
return (index + 1) % capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t ring_index_prev(size_t index, size_t capacity)
|
||||||
|
{
|
||||||
|
return index == 0 ? (capacity - 1) : index - 1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline const void *obj_at(const void *objs, size_t index, size_t obj_size)
|
static inline const void *obj_at(const void *objs, size_t index, size_t obj_size)
|
||||||
{
|
{
|
||||||
unicstl_assert(objs != NULL);
|
unicstl_assert(objs != NULL);
|
||||||
@ -191,32 +219,27 @@ static inline void obj_zero(const void *objs, size_t index, size_t count, size_t
|
|||||||
memset((char *)objs + index * obj_size, 0, count * obj_size);
|
memset((char *)objs + index * obj_size, 0, count * obj_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void mem_swap(const void *obj1, void *obj2, size_t obj_size)
|
||||||
static inline size_t ring_index(size_t head, size_t index, size_t capacity)
|
|
||||||
{
|
{
|
||||||
return (head + index) % capacity;
|
size_t cnt = obj_size;
|
||||||
|
for(size_t i = 0; i < cnt; ++i)
|
||||||
|
{
|
||||||
|
char tmp = ((char*)obj1)[i];
|
||||||
|
((char*)obj1)[i] = ((char*)obj2)[i];
|
||||||
|
((char*)obj2)[i] = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t ring_index_next(size_t index, size_t capacity)
|
static inline void obj_swap(const void *base, size_t index1, size_t index2, size_t obj_size)
|
||||||
{
|
{
|
||||||
return (index + 1) % capacity;
|
mem_swap((char*)base + index1 * obj_size, (char*)base + index2 * obj_size, obj_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t ring_index_prev(size_t index, size_t capacity)
|
static inline int compare_obj(const void *base, size_t index1, size_t index2, size_t obj_size, compare_fun_t cmp)
|
||||||
{
|
{
|
||||||
return index == 0 ? (capacity - 1) : index - 1;
|
return cmp((char*)base + index1 * obj_size, (char*)base + index2 * obj_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief obj compare with obj2
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* obj < obj2 return -1
|
|
||||||
* obj == obj2 return 0
|
|
||||||
* obj > obj2 return 1
|
|
||||||
*/
|
|
||||||
typedef int (*compare_fun_t)(const void *obj, const void *obj2);
|
|
||||||
|
|
||||||
// default function
|
// default function
|
||||||
int default_compare(const void *obj1, const void *obj2);
|
int default_compare(const void *obj1, const void *obj2);
|
||||||
void default_print_obj(const void *obj);
|
void default_print_obj(const void *obj);
|
||||||
|
|||||||
21
src/algo.c
21
src/algo.c
@ -10,27 +10,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "algo.h"
|
#include "algo.h"
|
||||||
|
|
||||||
static inline void mem_swap(const void *obj1, void *obj2, size_t obj_size)
|
|
||||||
{
|
|
||||||
size_t cnt = obj_size;
|
|
||||||
for(size_t i = 0; i < cnt; ++i)
|
|
||||||
{
|
|
||||||
char tmp = ((char*)obj1)[i];
|
|
||||||
((char*)obj1)[i] = ((char*)obj2)[i];
|
|
||||||
((char*)obj2)[i] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void obj_swap(const void *base, size_t index1, size_t index2, size_t obj_size)
|
|
||||||
{
|
|
||||||
mem_swap((char*)base + index1 * obj_size, (char*)base + index2 * obj_size, obj_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int compare_obj(const void *base, size_t index1, size_t index2, size_t obj_size, compare_fun_t cmp)
|
|
||||||
{
|
|
||||||
return cmp((char*)base + index1 * obj_size, (char*)base + index2 * obj_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 冒泡排序
|
// 1. 冒泡排序
|
||||||
bool bubble_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
bool bubble_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
|
||||||
{
|
{
|
||||||
|
|||||||
201
src/heap.c
201
src/heap.c
@ -8,78 +8,45 @@
|
|||||||
*/
|
*/
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
|
||||||
static int left(int i)
|
static size_t left(size_t i)
|
||||||
{
|
{
|
||||||
return 2 * i + 1;
|
return 2 * i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int right(int i)
|
static size_t right(size_t i)
|
||||||
{
|
{
|
||||||
return (i << 1) + 2;
|
return (i << 1) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parent(int i)
|
static size_t parent(size_t i)
|
||||||
{
|
{
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (i-1) >> 1;
|
return (i - 1) >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool heap_peek(struct _heap* self, void* obj)
|
static bool heap_peek(struct _heap* self, void* obj)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
unicstl_assert(obj != NULL);
|
size_t index = self->size(self) - 1;
|
||||||
if(obj == NULL)
|
if(!self->_darray->get(self->_darray, 0, obj))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(self->empty(self))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memmove(obj, self->obj, self->_obj_size);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_swap(struct _heap* self, int i, int j)
|
static void heap_fixed_up(struct _heap* self, size_t i)
|
||||||
{
|
|
||||||
unicstl_assert(self != NULL);
|
|
||||||
unicstl_assert(self->_obj_size != 0);
|
|
||||||
#if __STDC_VERSION__ >= 199901L
|
|
||||||
// #define C99_VLA // VLA should be avoided for portability reasons and due to the risk of stack overflow.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef C99_VLA
|
|
||||||
char tmp[self->_obj_size];
|
|
||||||
#else
|
|
||||||
char* tmp = unicstl_malloc(self->_obj_size);
|
|
||||||
if (tmp == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memmove(tmp, (char *)self->obj + i * self->_obj_size, self->_obj_size);
|
|
||||||
memmove((char*)self->obj + i * self->_obj_size, (char*)self->obj + j * self->_obj_size, self->_obj_size);
|
|
||||||
memmove((char*)self->obj + j * self->_obj_size, tmp, self->_obj_size);
|
|
||||||
|
|
||||||
#ifndef C99_VLA
|
|
||||||
unicstl_free(tmp);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void heap_fixed_up(struct _heap* self, int i)
|
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
|
unicstl_assert(self->_darray != NULL);
|
||||||
unicstl_assert(self->compare != NULL);
|
unicstl_assert(self->compare != NULL);
|
||||||
int p = 0;
|
|
||||||
|
|
||||||
if(self->compare == NULL)
|
const void *base = self->_darray->at(self->_darray, 0);
|
||||||
{
|
size_t obj_size = self->_darray->_obj_size;
|
||||||
return ;
|
size_t p = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if(self->_type == HEAP_MAX)
|
if(self->_type == HEAP_MAX)
|
||||||
{
|
{
|
||||||
@ -87,12 +54,14 @@ static void heap_fixed_up(struct _heap* self, int i)
|
|||||||
{
|
{
|
||||||
p = parent(i);
|
p = parent(i);
|
||||||
// if current node is greater than its parent, swap the position. otherwise break out of loop
|
// if current node is greater than its parent, swap the position. otherwise break out of loop
|
||||||
if(p < 0 || self->compare((char *)self->obj + i * self->_obj_size, (char *)self->obj + p * self->_obj_size) <= 0)
|
if(p == (size_t)-1 || compare_obj(base, i, p, obj_size, self->compare) <= 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
heap_swap(self, i, p);
|
obj_swap(base, i, p, obj_size);
|
||||||
i = p;
|
i = p;
|
||||||
|
|
||||||
|
self->print(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if(self->_type == HEAP_MIN) */
|
else /* if(self->_type == HEAP_MIN) */
|
||||||
@ -100,13 +69,17 @@ static void heap_fixed_up(struct _heap* self, int i)
|
|||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
p = parent(i);
|
p = parent(i);
|
||||||
|
log_debug("heap_fixed_up: p = %d, i = %zu\n", (ssize_t)p, i);
|
||||||
|
|
||||||
// if current node is less than its parent, swap the position. otherwise break out of loop
|
// if current node is less than its parent, swap the position. otherwise break out of loop
|
||||||
if(p < 0 || self->compare((char *)self->obj + i * self->_obj_size, (char *)self->obj + p * self->_obj_size) >= 0)
|
if(p == (size_t)-1 || compare_obj(base, i, p, obj_size, self->compare) >= 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
heap_swap(self, i, p);
|
obj_swap(base, i, p, obj_size);
|
||||||
i = p;
|
i = p;
|
||||||
|
|
||||||
|
self->print(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,28 +87,24 @@ static void heap_fixed_up(struct _heap* self, int i)
|
|||||||
static bool heap_push(struct _heap* self, void* obj)
|
static bool heap_push(struct _heap* self, void* obj)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
if(self->size(self) > self->_capacity)
|
unicstl_assert(self->_darray != NULL);
|
||||||
|
if(!self->_darray->append(self->_darray, obj))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t index = self->size(self);
|
heap_fixed_up(self, self->size(self) - 1);
|
||||||
memmove((char *)self->obj + index * self->_obj_size, obj, self->_obj_size);
|
|
||||||
self->_size++;
|
|
||||||
|
|
||||||
heap_fixed_up(self, index);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_fixed_down(struct _heap* self, int i)
|
static void heap_fixed_down(struct _heap* self, size_t i)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
int l = 0,r = 0;
|
unicstl_assert(self->_darray != NULL);
|
||||||
int max = 0, min = 0;
|
size_t l = 0,r = 0;
|
||||||
|
size_t max = 0, min = 0;
|
||||||
|
|
||||||
if(self->compare == NULL)
|
const void *base = self->_darray->at(self->_darray, 0);
|
||||||
{
|
size_t obj_size = self->_darray->_obj_size;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(self->_type == HEAP_MAX)
|
if(self->_type == HEAP_MAX)
|
||||||
{
|
{
|
||||||
@ -145,20 +114,20 @@ static void heap_fixed_down(struct _heap* self, int i)
|
|||||||
r = right(i);
|
r = right(i);
|
||||||
max = i;
|
max = i;
|
||||||
|
|
||||||
if(l < self->size(self) && self->compare((char *)self->obj + l * self->_obj_size, (char *)self->obj + max * self->_obj_size) > 0)
|
if(l < self->size(self) && compare_obj(base, l, max, obj_size, self->compare) > 0)
|
||||||
{
|
{
|
||||||
max = l;
|
max = l;
|
||||||
}
|
}
|
||||||
|
if(r < self->size(self) && compare_obj(base, r, max, obj_size, self->compare) > 0)
|
||||||
if(r < self->size(self) && self->compare((char *)self->obj + r * self->_obj_size, (char *)self->obj + max * self->_obj_size) > 0)
|
|
||||||
{
|
{
|
||||||
max = r;
|
max = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(max == i)
|
if(max == i)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
heap_swap(self, i, max);
|
obj_swap(base, i, max, obj_size);
|
||||||
i = max;
|
i = max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,12 +139,12 @@ static void heap_fixed_down(struct _heap* self, int i)
|
|||||||
r = right(i);
|
r = right(i);
|
||||||
min = i;
|
min = i;
|
||||||
|
|
||||||
if(l < self->size(self) && self->compare((char *)self->obj + l * self->_obj_size, (char *)self->obj + min * self->_obj_size) < 0)
|
if(l < self->size(self) && compare_obj(base, l, min, obj_size, self->compare) < 0)
|
||||||
{
|
{
|
||||||
min = l;
|
min = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r < self->size(self) && self->compare((char *)self->obj + r * self->_obj_size, (char *)self->obj + min * self->_obj_size) < 0)
|
if(r < self->size(self) && compare_obj(base, r, min, obj_size, self->compare) < 0)
|
||||||
{
|
{
|
||||||
min = r;
|
min = r;
|
||||||
}
|
}
|
||||||
@ -183,7 +152,7 @@ static void heap_fixed_down(struct _heap* self, int i)
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
heap_swap(self, i, min);
|
obj_swap(self, i, min, obj_size);
|
||||||
i = min;
|
i = min;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,25 +161,34 @@ static void heap_fixed_down(struct _heap* self, int i)
|
|||||||
static bool heap_pop(struct _heap* self, void* obj)
|
static bool heap_pop(struct _heap* self, void* obj)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
if(self->empty(self))
|
unicstl_assert(self->_darray != NULL);
|
||||||
|
if(!self->_darray->pop(self->_darray, obj))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int index = self->size(self) - 1;
|
|
||||||
heap_swap(self, 0, index);
|
|
||||||
if(obj != NULL)
|
|
||||||
{
|
|
||||||
memmove(obj, (char *)self->obj + index * self->_obj_size, self->_obj_size);
|
|
||||||
}
|
|
||||||
self->_size--;
|
|
||||||
heap_fixed_down(self, 0);
|
heap_fixed_down(self, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t heap_reserve(struct _heap* self, size_t capacity)
|
||||||
|
{
|
||||||
|
unicstl_assert(self != NULL);
|
||||||
|
unicstl_assert(self->_darray != NULL);
|
||||||
|
return self->_darray->reserve(self->_darray, capacity);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t heap_size(struct _heap* self)
|
static size_t heap_size(struct _heap* self)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
return self->_size;
|
unicstl_assert(self->_darray != NULL);
|
||||||
|
return self->_darray->size(self->_darray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t heap_capacity(struct _heap* self)
|
||||||
|
{
|
||||||
|
unicstl_assert(self != NULL);
|
||||||
|
unicstl_assert(self->_darray != NULL);
|
||||||
|
return self->_darray->capacity(self->_darray);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool heap_empty(struct _heap* self)
|
static bool heap_empty(struct _heap* self)
|
||||||
@ -222,34 +200,26 @@ static bool heap_empty(struct _heap* self)
|
|||||||
static bool heap_clear(struct _heap* self)
|
static bool heap_clear(struct _heap* self)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
self->_size = 0;
|
unicstl_assert(self->_darray != NULL);
|
||||||
return true;
|
return self->_darray->clear(self->_darray);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_destory(struct _heap* self)
|
static void heap_destory(struct _heap* self)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
self->clear(self);
|
self->clear(self);
|
||||||
if(self->obj)
|
if(self->_darray != NULL)
|
||||||
{
|
{
|
||||||
unicstl_free(self->obj);
|
darray_free(&self->_darray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_print(struct _heap* self)
|
static void heap_print(struct _heap* self)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
unicstl_assert(self->obj != NULL);
|
unicstl_assert(self->_darray != NULL);
|
||||||
|
self->_darray->print_obj = self->print_obj;
|
||||||
void* obj = NULL;
|
self->_darray->print(self->_darray);
|
||||||
size_t offset = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < self->size(self); i++)
|
|
||||||
{
|
|
||||||
offset = self->_obj_size * i;
|
|
||||||
obj = (char *)self->obj + offset;
|
|
||||||
self->print_obj(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool heap_iter_hasnext(struct _iterator* iter)
|
bool heap_iter_hasnext(struct _iterator* iter)
|
||||||
@ -269,15 +239,12 @@ const void* heap_iter_next(struct _iterator* iter)
|
|||||||
{
|
{
|
||||||
unicstl_assert(iter != NULL);
|
unicstl_assert(iter != NULL);
|
||||||
unicstl_assert(iter->_container != NULL);
|
unicstl_assert(iter->_container != NULL);
|
||||||
|
|
||||||
heap_t self = (heap_t)iter->_container;
|
heap_t self = (heap_t)iter->_container;
|
||||||
void *obj = NULL;
|
unicstl_assert(self->_darray != NULL);
|
||||||
|
|
||||||
size_t index = iter->_index;
|
size_t index = iter->_index;
|
||||||
obj = self->obj + self->_obj_size * index;
|
|
||||||
|
|
||||||
iter->_index += 1;
|
iter->_index += 1;
|
||||||
return obj;
|
return self->_darray->at(self->_darray, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator_t heap_iter(struct _heap* self)
|
iterator_t heap_iter(struct _heap* self)
|
||||||
@ -287,28 +254,20 @@ iterator_t heap_iter(struct _heap* self)
|
|||||||
|
|
||||||
iter->_container = self;
|
iter->_container = self;
|
||||||
iter->_index = 0;
|
iter->_index = 0;
|
||||||
iter->_node = self->obj;
|
|
||||||
|
|
||||||
iter->hasnext = heap_iter_hasnext;
|
iter->hasnext = heap_iter_hasnext;
|
||||||
iter->next = heap_iter_next;
|
iter->next = heap_iter_next;
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool heap_init2(struct _heap* self, size_t obj_size, size_t capacity)
|
static bool heap_init(struct _heap* self, size_t obj_size, size_t capacity, heap_type type)
|
||||||
{
|
{
|
||||||
unicstl_assert(self != NULL);
|
unicstl_assert(self != NULL);
|
||||||
|
unicstl_assert(obj_size > 0);
|
||||||
|
|
||||||
// -------------------- private --------------------
|
// -------------------- private --------------------
|
||||||
self->_obj_size = obj_size;
|
self->_darray = NULL;
|
||||||
self->_size = 0;
|
self->_type = type;
|
||||||
self->_capacity = capacity;
|
|
||||||
self->_ratio = 2;
|
|
||||||
|
|
||||||
self->obj = (void*)unicstl_malloc(self->_capacity * self->_obj_size);
|
|
||||||
if(self->obj == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->_destory = heap_destory;
|
self->_destory = heap_destory;
|
||||||
|
|
||||||
@ -320,25 +279,31 @@ static bool heap_init2(struct _heap* self, size_t obj_size, size_t capacity)
|
|||||||
self->empty = heap_empty;
|
self->empty = heap_empty;
|
||||||
|
|
||||||
// base
|
// base
|
||||||
|
self->reserve = heap_reserve;
|
||||||
|
self->capacity = heap_capacity;
|
||||||
self->size = heap_size;
|
self->size = heap_size;
|
||||||
self->clear = heap_clear;
|
self->clear = heap_clear;
|
||||||
|
|
||||||
// iter
|
// iter
|
||||||
self->iter = heap_iter;
|
self->iter = heap_iter;
|
||||||
|
|
||||||
// config
|
|
||||||
self->compare = NULL;
|
|
||||||
|
|
||||||
// -------------------- default --------------------
|
// -------------------- default --------------------
|
||||||
self->compare = default_compare;
|
self->compare = default_compare;
|
||||||
self->print_obj = default_print_obj;
|
self->print_obj = default_print_obj;
|
||||||
|
|
||||||
// -------------------- debug --------------------
|
// -------------------- debug --------------------
|
||||||
self->print = heap_print;
|
self->print = heap_print;
|
||||||
|
|
||||||
|
// -------------------- init --------------------
|
||||||
|
self->_darray = darray_new(obj_size, capacity);
|
||||||
|
if(self->_darray == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_t heap_max_new2(size_t obj_size, size_t capacity)
|
heap_t heap_max_new(size_t obj_size, size_t capacity)
|
||||||
{
|
{
|
||||||
heap_t heap = NULL;
|
heap_t heap = NULL;
|
||||||
heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap));
|
heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap));
|
||||||
@ -347,17 +312,15 @@ heap_t heap_max_new2(size_t obj_size, size_t capacity)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(heap_init2(heap, obj_size, capacity) != true)
|
if(heap_init(heap, obj_size, capacity, HEAP_MAX) != true)
|
||||||
{
|
{
|
||||||
unicstl_free(heap);
|
unicstl_free(heap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap->_type = HEAP_MAX;
|
|
||||||
return heap;
|
return heap;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_t heap_min_new2(size_t obj_size, size_t capacity)
|
heap_t heap_min_new(size_t obj_size, size_t capacity)
|
||||||
{
|
{
|
||||||
heap_t heap = NULL;
|
heap_t heap = NULL;
|
||||||
heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap));
|
heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap));
|
||||||
@ -367,14 +330,12 @@ heap_t heap_min_new2(size_t obj_size, size_t capacity)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(heap_init2(heap, obj_size, capacity) != true)
|
if(heap_init(heap, obj_size, capacity, HEAP_MIN) != true)
|
||||||
{
|
{
|
||||||
log_warn("heap init failed\n");
|
log_warn("heap init failed\n");
|
||||||
unicstl_free(heap);
|
unicstl_free(heap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap->_type = HEAP_MIN;
|
|
||||||
return heap;
|
return heap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,27 +10,39 @@
|
|||||||
*/
|
*/
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
static void* get_max(struct _heap* heap, void *array, int start, int end)
|
static const void* get_max(const void *base, size_t index, size_t count, size_t obj_size, compare_fun_t compare)
|
||||||
{
|
{
|
||||||
void* max = array;
|
const void* max = base;
|
||||||
for (int i = start; i < end; i++)
|
if(count <= 1)
|
||||||
{
|
{
|
||||||
if (heap->compare((char*)array + heap->_obj_size * i, max) > 0)
|
return base;
|
||||||
|
}
|
||||||
|
size_t idx = 0;
|
||||||
|
for (size_t i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
max = (char*)array + heap->_obj_size * i;
|
idx = index + i * obj_size;
|
||||||
|
if (compare((char*)base + idx, max) > 0)
|
||||||
|
{
|
||||||
|
max = (char*)base + idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* get_min(struct _heap* heap, void *array, int start, int end)
|
static const void* get_min(const void *base, size_t index, size_t count, size_t obj_size, compare_fun_t compare)
|
||||||
{
|
{
|
||||||
void* min = array;
|
const void* min = base;
|
||||||
for (int i = start; i < end; i++)
|
if(count <= 1)
|
||||||
{
|
{
|
||||||
if (heap->compare((char*)array + heap->_obj_size * i, min) < 0)
|
return base;
|
||||||
|
}
|
||||||
|
size_t idx = 0;
|
||||||
|
for (size_t i = 0; i < count ; i++)
|
||||||
{
|
{
|
||||||
min = (char*)array + heap->_obj_size * i;
|
idx = index + i * obj_size;
|
||||||
|
if (compare((char*)base + idx, min) < 0)
|
||||||
|
{
|
||||||
|
min = (char*)base + idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return min;
|
return min;
|
||||||
@ -45,8 +57,9 @@ static void test_heap_min_num(void)
|
|||||||
int data[] = { 5,2,3,1,7,8,6,4,9,10,12,11,15,14,13 };
|
int data[] = { 5,2,3,1,7,8,6,4,9,10,12,11,15,14,13 };
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
size_t len = sizeof(data) / sizeof(data[0]);
|
size_t len = sizeof(data) / sizeof(data[0]);
|
||||||
|
int min = 0;
|
||||||
|
|
||||||
heap_t heap = heap_min_new2(sizeof(int), 64);
|
heap_t heap = heap_min_new(sizeof(int), 64);
|
||||||
TEST_ASSERT_NOT_NULL(heap);
|
TEST_ASSERT_NOT_NULL(heap);
|
||||||
heap->print_obj = print_num;
|
heap->print_obj = print_num;
|
||||||
heap->compare = compare_num;
|
heap->compare = compare_num;
|
||||||
@ -58,7 +71,9 @@ static void test_heap_min_num(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
||||||
TEST_ASSERT_EQUAL_INT(*(int *)get_min(heap, data, 0, heap->size(heap)), temp);
|
min = *(int *)get_min(data, 0, i + 1, sizeof(int), compare_num);
|
||||||
|
log_debug("i = %d, min = %d, heap_peek: %d, ", i, min, temp);
|
||||||
|
TEST_ASSERT_EQUAL_INT(min, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(heap->clear(heap));
|
TEST_ASSERT_TRUE(heap->clear(heap));
|
||||||
@ -96,7 +111,7 @@ static void test_heap_min_struct(void)
|
|||||||
struct _student temp = {0};
|
struct _student temp = {0};
|
||||||
size_t len = sizeof(data) / sizeof(data[0]);
|
size_t len = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
heap_t heap = heap_min_new2(sizeof(struct _student), 64);
|
heap_t heap = heap_min_new(sizeof(struct _student), 64);
|
||||||
TEST_ASSERT_NOT_NULL(heap);
|
TEST_ASSERT_NOT_NULL(heap);
|
||||||
heap->print_obj = print_struct;
|
heap->print_obj = print_struct;
|
||||||
heap->compare = compare_struct;
|
heap->compare = compare_struct;
|
||||||
@ -108,8 +123,8 @@ static void test_heap_min_struct(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
||||||
TEST_ASSERT_EQUAL_INT(((struct _student*)get_min(heap, data, 0, heap->size(heap)))->id, temp.id);
|
TEST_ASSERT_EQUAL_INT(((struct _student*)get_min(data, 0, i + 1, sizeof(struct _student), compare_struct))->id, temp.id);
|
||||||
TEST_ASSERT_EQUAL_STRING(((struct _student*)get_min(heap, data, 0, heap->size(heap)))->name, temp.name);
|
TEST_ASSERT_EQUAL_STRING(((struct _student*)get_min(data, 0, i + 1, sizeof(struct _student), compare_struct))->name, temp.name);
|
||||||
}
|
}
|
||||||
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
||||||
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
||||||
@ -143,7 +158,7 @@ static void test_heap_max_num(void)
|
|||||||
int temp = 0;
|
int temp = 0;
|
||||||
size_t len = sizeof(data) / sizeof(data[0]);
|
size_t len = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
heap_t heap = heap_max_new2(sizeof(int), 64);
|
heap_t heap = heap_max_new(sizeof(int), 64);
|
||||||
TEST_ASSERT_NOT_NULL(heap);
|
TEST_ASSERT_NOT_NULL(heap);
|
||||||
heap->print_obj = print_num;
|
heap->print_obj = print_num;
|
||||||
heap->compare = compare_num;
|
heap->compare = compare_num;
|
||||||
@ -155,7 +170,7 @@ static void test_heap_max_num(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
||||||
TEST_ASSERT_EQUAL_INT(*(int *)get_max(heap, data, 0, heap->size(heap)), temp);
|
TEST_ASSERT_EQUAL_INT(*(int *)get_max(data, 0, i + 1, sizeof(int), compare_num), temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(heap->clear(heap));
|
TEST_ASSERT_TRUE(heap->clear(heap));
|
||||||
@ -193,7 +208,7 @@ static void test_heap_max_struct(void)
|
|||||||
struct _student temp = {0};
|
struct _student temp = {0};
|
||||||
size_t len = sizeof(data) / sizeof(data[0]);
|
size_t len = sizeof(data) / sizeof(data[0]);
|
||||||
|
|
||||||
heap_t heap = heap_max_new2(sizeof(struct _student), 64);
|
heap_t heap = heap_max_new(sizeof(struct _student), 64);
|
||||||
TEST_ASSERT_NOT_NULL(heap);
|
TEST_ASSERT_NOT_NULL(heap);
|
||||||
heap->print_obj = print_struct;
|
heap->print_obj = print_struct;
|
||||||
heap->compare = compare_struct;
|
heap->compare = compare_struct;
|
||||||
@ -205,8 +220,8 @@ static void test_heap_max_struct(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
||||||
TEST_ASSERT_EQUAL_INT(((struct _student*)get_max(heap, data, 0, heap->size(heap)))->id, temp.id);
|
TEST_ASSERT_EQUAL_INT(((struct _student*)get_max(data, 0, i + 1, sizeof(struct _student), compare_struct))->id, temp.id);
|
||||||
TEST_ASSERT_EQUAL_STRING(((struct _student*)get_max(heap, data, 0, heap->size(heap)))->name, temp.name);
|
TEST_ASSERT_EQUAL_STRING(((struct _student*)get_max(data, 0, i + 1, sizeof(struct _student), compare_struct))->name, temp.name);
|
||||||
|
|
||||||
// heap->print_obj(&temp);
|
// heap->print_obj(&temp);
|
||||||
// printf("\n");
|
// printf("\n");
|
||||||
@ -260,7 +275,7 @@ static void test_heap_max_iter(void)
|
|||||||
int out[15] = { 0 };
|
int out[15] = { 0 };
|
||||||
int outlen = 0;
|
int outlen = 0;
|
||||||
|
|
||||||
heap_t heap = heap_max_new2(sizeof(int), 64);
|
heap_t heap = heap_max_new(sizeof(int), 64);
|
||||||
TEST_ASSERT_NOT_NULL(heap);
|
TEST_ASSERT_NOT_NULL(heap);
|
||||||
heap->print_obj = print_num;
|
heap->print_obj = print_num;
|
||||||
heap->compare = compare_num;
|
heap->compare = compare_num;
|
||||||
@ -272,7 +287,7 @@ static void test_heap_max_iter(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
TEST_ASSERT_TRUE(heap->peek(heap, &temp));
|
||||||
TEST_ASSERT_EQUAL_INT(*(int *)get_max(heap, data, 0, heap->size(heap)), temp);
|
TEST_ASSERT_EQUAL_INT(*(int *)get_max(data, 0, i + 1, sizeof(int), compare_num), temp);
|
||||||
|
|
||||||
iterator_t iter = heap->iter(heap);
|
iterator_t iter = heap->iter(heap);
|
||||||
|
|
||||||
|
|||||||
@ -512,7 +512,7 @@ static void test_ringbuf_iter(void)
|
|||||||
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
TEST_ASSERT_EQUAL_INT(data[i], temp);
|
||||||
i--;
|
i--;
|
||||||
|
|
||||||
ringbuf->print_obj(&temp);
|
// ringbuf->print_obj(&temp);
|
||||||
}
|
}
|
||||||
TEST_ASSERT_EQUAL_INT(-1, i);
|
TEST_ASSERT_EQUAL_INT(-1, i);
|
||||||
|
|
||||||
|
|||||||
@ -33,10 +33,22 @@ void test_unicstl_capacity(void)
|
|||||||
TEST_ASSERT_EQUAL_UINT32(1125000, unicstl_new_capacity(1000000));
|
TEST_ASSERT_EQUAL_UINT32(1125000, unicstl_new_capacity(1000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_unicstl_compare_obj(void)
|
||||||
|
{
|
||||||
|
int data[] = {1,2,3};
|
||||||
|
int obj_size = sizeof(int);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, compare_obj(data, 0, 0, obj_size, compare_int));
|
||||||
|
TEST_ASSERT_EQUAL_INT(1, compare_obj(data, 2, 1, obj_size, compare_int));
|
||||||
|
TEST_ASSERT_EQUAL_INT(-1, compare_obj(data, 0, 1, obj_size, compare_int));
|
||||||
|
}
|
||||||
|
|
||||||
void test_unicstl(void)
|
void test_unicstl(void)
|
||||||
{
|
{
|
||||||
UnitySetTestFile(__FILE__);
|
UnitySetTestFile(__FILE__);
|
||||||
|
|
||||||
RUN_TEST(test_unicstl_version);
|
RUN_TEST(test_unicstl_version);
|
||||||
RUN_TEST(test_unicstl_capacity);
|
RUN_TEST(test_unicstl_capacity);
|
||||||
|
|
||||||
|
RUN_TEST(test_unicstl_compare_obj);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user