More tests
This commit is contained in:
1 parent
a9314ee8f7
commit
846d0bbba6
9 files changed
+1147
-88
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
CC = gcc
|
||||
CFLAGS = -std=c11 -Wall -Wextra
|
||||
CFLAGS += -Wno-unused-function -Wno-unused-paramter -Wno-unused-variable -Wno-unused-label
|
||||
CFLAGS += -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-unused-label
|
||||
CVFLAGS = --coverage -O0
|
||||
INCLUDE = ../../src/
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "unt/deque.c"
|
||||
#include "unt/hashmap.c"
|
||||
#include "unt/hashset.c"
|
||||
#include "unt/heap.c"
|
||||
#include "unt/linkedlist.c"
|
||||
#include "unt/list.c"
|
||||
|
||||
int main(void)
|
||||
@@ -8,6 +10,8 @@ int main(void)
|
||||
deque_test();
|
||||
hashmap_test();
|
||||
hashset_test();
|
||||
heap_test();
|
||||
linkedlist_test();
|
||||
list_test();
|
||||
|
||||
return 0;
|
||||
|
||||
+64
-64
@@ -15,36 +15,36 @@ typedef struct deque_iter_s
|
||||
struct deque_s *target;
|
||||
size_t cursor;
|
||||
size_t index;
|
||||
_Bool start;
|
||||
_Bool end;
|
||||
bool start;
|
||||
bool end;
|
||||
} deque_iter, *deque_iter_ptr;
|
||||
deque *d_new(size_t capacity);
|
||||
void d_clear(deque *_deque_);
|
||||
void d_free(deque *_deque_);
|
||||
_Bool d_push_front(deque *_deque_, size_t element);
|
||||
_Bool d_push_back(deque *_deque_, size_t element);
|
||||
_Bool d_pop_front(deque *_deque_);
|
||||
_Bool d_pop_back(deque *_deque_);
|
||||
_Bool d_push_front_if(deque *_deque_, size_t element, _Bool condition);
|
||||
_Bool d_push_back_if(deque *_deque_, size_t element, _Bool condition);
|
||||
_Bool d_pop_front_if(deque *_deque_, _Bool condition);
|
||||
_Bool d_pop_back_if(deque *_deque_, _Bool condition);
|
||||
bool d_push_front(deque *_deque_, size_t element);
|
||||
bool d_push_back(deque *_deque_, size_t element);
|
||||
bool d_pop_front(deque *_deque_);
|
||||
bool d_pop_back(deque *_deque_);
|
||||
bool d_push_front_if(deque *_deque_, size_t element, bool condition);
|
||||
bool d_push_back_if(deque *_deque_, size_t element, bool condition);
|
||||
bool d_pop_front_if(deque *_deque_, bool condition);
|
||||
bool d_pop_back_if(deque *_deque_, bool condition);
|
||||
size_t d_front(deque *_deque_);
|
||||
size_t d_back(deque *_deque_);
|
||||
_Bool d_contains(deque *_deque_, size_t element, int (*comparator)(size_t, size_t));
|
||||
_Bool d_empty(deque *_deque_);
|
||||
_Bool d_full(deque *_deque_);
|
||||
bool d_contains(deque *_deque_, size_t element, int (*comparator)(size_t, size_t));
|
||||
bool d_empty(deque *_deque_);
|
||||
bool d_full(deque *_deque_);
|
||||
size_t d_count(deque *_deque_);
|
||||
size_t d_capacity(deque *_deque_);
|
||||
deque_iter *d_iter_new(deque *target);
|
||||
void d_iter_free(deque_iter *iter);
|
||||
void d_iter_init(deque_iter *iter, deque *target);
|
||||
_Bool d_iter_start(deque_iter *iter);
|
||||
_Bool d_iter_end(deque_iter *iter);
|
||||
bool d_iter_start(deque_iter *iter);
|
||||
bool d_iter_end(deque_iter *iter);
|
||||
void d_iter_to_start(deque_iter *iter);
|
||||
void d_iter_to_end(deque_iter *iter);
|
||||
_Bool d_iter_next(deque_iter *iter);
|
||||
_Bool d_iter_prev(deque_iter *iter);
|
||||
bool d_iter_next(deque_iter *iter);
|
||||
bool d_iter_prev(deque_iter *iter);
|
||||
size_t d_iter_value(deque_iter *iter);
|
||||
size_t *d_iter_rvalue(deque_iter *iter);
|
||||
size_t d_iter_index(deque_iter *iter);
|
||||
@@ -54,21 +54,21 @@ static inline size_t d_impl_default_value(void)
|
||||
memset(&_empty_value_, 0, sizeof(size_t));
|
||||
return _empty_value_;
|
||||
}
|
||||
static _Bool d_impl_grow(deque *_deque_);
|
||||
static bool d_impl_grow(deque *_deque_);
|
||||
static deque_iter d_impl_it_start(deque *_deque_);
|
||||
static deque_iter d_impl_it_end(deque *_deque_);
|
||||
deque *d_new(size_t capacity)
|
||||
{
|
||||
if (capacity < 1)
|
||||
return ((void *)0);
|
||||
return NULL;
|
||||
deque *_deque_ = malloc(sizeof(deque));
|
||||
if (!_deque_)
|
||||
return ((void *)0);
|
||||
return NULL;
|
||||
_deque_->buffer = malloc(sizeof(size_t) * capacity);
|
||||
if (!_deque_->buffer)
|
||||
{
|
||||
free(_deque_);
|
||||
return ((void *)0);
|
||||
return NULL;
|
||||
}
|
||||
memset(_deque_->buffer, 0, sizeof(size_t) * capacity);
|
||||
_deque_->capacity = capacity;
|
||||
@@ -91,71 +91,71 @@ void d_free(deque *_deque_)
|
||||
free(_deque_->buffer);
|
||||
free(_deque_);
|
||||
}
|
||||
_Bool d_push_front(deque *_deque_, size_t element)
|
||||
bool d_push_front(deque *_deque_, size_t element)
|
||||
{
|
||||
if (d_full(_deque_))
|
||||
{
|
||||
if (!d_impl_grow(_deque_))
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1;
|
||||
_deque_->buffer[_deque_->front] = element;
|
||||
_deque_->count++;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
_Bool d_push_back(deque *_deque_, size_t element)
|
||||
bool d_push_back(deque *_deque_, size_t element)
|
||||
{
|
||||
if (d_full(_deque_))
|
||||
{
|
||||
if (!d_impl_grow(_deque_))
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
_deque_->buffer[_deque_->back] = element;
|
||||
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1;
|
||||
_deque_->count++;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
_Bool d_pop_front(deque *_deque_)
|
||||
bool d_pop_front(deque *_deque_)
|
||||
{
|
||||
if (d_empty(_deque_))
|
||||
return 0;
|
||||
return false;
|
||||
_deque_->buffer[_deque_->front] = d_impl_default_value();
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1;
|
||||
_deque_->count--;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
_Bool d_pop_back(deque *_deque_)
|
||||
bool d_pop_back(deque *_deque_)
|
||||
{
|
||||
if (d_empty(_deque_))
|
||||
return 0;
|
||||
return false;
|
||||
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1;
|
||||
_deque_->buffer[_deque_->back] = d_impl_default_value();
|
||||
_deque_->count--;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
_Bool d_push_front_if(deque *_deque_, size_t element, _Bool condition)
|
||||
bool d_push_front_if(deque *_deque_, size_t element, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return d_push_front(_deque_, element);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
_Bool d_push_back_if(deque *_deque_, size_t element, _Bool condition)
|
||||
bool d_push_back_if(deque *_deque_, size_t element, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return d_push_back(_deque_, element);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
_Bool d_pop_front_if(deque *_deque_, _Bool condition)
|
||||
bool d_pop_front_if(deque *_deque_, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return d_pop_front(_deque_);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
_Bool d_pop_back_if(deque *_deque_, _Bool condition)
|
||||
bool d_pop_back_if(deque *_deque_, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return d_pop_back(_deque_);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
size_t d_front(deque *_deque_)
|
||||
{
|
||||
@@ -169,24 +169,24 @@ size_t d_back(deque *_deque_)
|
||||
d_impl_default_value();
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1];
|
||||
}
|
||||
_Bool d_contains(deque *_deque_, size_t element, int (*comparator)(size_t, size_t))
|
||||
bool d_contains(deque *_deque_, size_t element, int (*comparator)(size_t, size_t))
|
||||
{
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++)
|
||||
{
|
||||
if (comparator(_deque_->buffer[i], element) == 0)
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
_Bool d_empty(deque *_deque_) { return _deque_->count == 0; }
|
||||
_Bool d_full(deque *_deque_) { return _deque_->count >= _deque_->capacity; }
|
||||
bool d_empty(deque *_deque_) { return _deque_->count == 0; }
|
||||
bool d_full(deque *_deque_) { return _deque_->count >= _deque_->capacity; }
|
||||
size_t d_count(deque *_deque_) { return _deque_->count; }
|
||||
size_t d_capacity(deque *_deque_) { return _deque_->capacity; }
|
||||
deque_iter *d_iter_new(deque *target)
|
||||
{
|
||||
deque_iter *iter = malloc(sizeof(deque_iter));
|
||||
if (!iter)
|
||||
return ((void *)0);
|
||||
return NULL;
|
||||
d_iter_init(iter, target);
|
||||
return iter;
|
||||
}
|
||||
@@ -196,16 +196,16 @@ void d_iter_init(deque_iter *iter, deque *target)
|
||||
iter->target = target;
|
||||
iter->cursor = target->front;
|
||||
iter->index = 0;
|
||||
iter->start = 1;
|
||||
iter->start = true;
|
||||
iter->end = d_empty(target);
|
||||
}
|
||||
_Bool d_iter_start(deque_iter *iter) { return d_empty(iter->target) || iter->start; }
|
||||
_Bool d_iter_end(deque_iter *iter) { return d_empty(iter->target) || iter->end; }
|
||||
bool d_iter_start(deque_iter *iter) { return d_empty(iter->target) || iter->start; }
|
||||
bool d_iter_end(deque_iter *iter) { return d_empty(iter->target) || iter->end; }
|
||||
void d_iter_to_start(deque_iter *iter)
|
||||
{
|
||||
iter->cursor = iter->target->front;
|
||||
iter->index = 0;
|
||||
iter->start = 1;
|
||||
iter->start = true;
|
||||
iter->end = d_empty(iter->target);
|
||||
}
|
||||
void d_iter_to_end(deque_iter *iter)
|
||||
@@ -216,35 +216,35 @@ void d_iter_to_end(deque_iter *iter)
|
||||
iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1;
|
||||
iter->index = iter->target->count - 1;
|
||||
iter->start = d_empty(iter->target);
|
||||
iter->end = 1;
|
||||
iter->end = true;
|
||||
}
|
||||
_Bool d_iter_next(deque_iter *iter)
|
||||
bool d_iter_next(deque_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return 0;
|
||||
return false;
|
||||
iter->start = d_empty(iter->target);
|
||||
if (iter->index == iter->target->count - 1)
|
||||
iter->end = 1;
|
||||
iter->end = true;
|
||||
else
|
||||
{
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity);
|
||||
iter->index++;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
_Bool d_iter_prev(deque_iter *iter)
|
||||
bool d_iter_prev(deque_iter *iter)
|
||||
{
|
||||
if (iter->start)
|
||||
return 0;
|
||||
return false;
|
||||
iter->end = d_empty(iter->target);
|
||||
if (iter->index == 0)
|
||||
iter->start = 1;
|
||||
iter->start = true;
|
||||
else
|
||||
{
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1;
|
||||
iter->index--;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
size_t d_iter_value(deque_iter *iter)
|
||||
{
|
||||
@@ -255,16 +255,16 @@ size_t d_iter_value(deque_iter *iter)
|
||||
size_t *d_iter_rvalue(deque_iter *iter)
|
||||
{
|
||||
if (d_empty(iter->target))
|
||||
return ((void *)0);
|
||||
return NULL;
|
||||
return &(iter->target->buffer[iter->cursor]);
|
||||
}
|
||||
size_t d_iter_index(deque_iter *iter) { return iter->index; }
|
||||
static _Bool d_impl_grow(deque *_deque_)
|
||||
static bool d_impl_grow(deque *_deque_)
|
||||
{
|
||||
size_t new_capacity = _deque_->capacity * 2;
|
||||
size_t *new_buffer = malloc(sizeof(size_t) * new_capacity);
|
||||
if (!new_buffer)
|
||||
return 0;
|
||||
return false;
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++)
|
||||
{
|
||||
new_buffer[j] = _deque_->buffer[i];
|
||||
@@ -274,7 +274,7 @@ static _Bool d_impl_grow(deque *_deque_)
|
||||
_deque_->capacity = new_capacity;
|
||||
_deque_->front = 0;
|
||||
_deque_->back = _deque_->count;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
static deque_iter d_impl_it_start(deque *_deque_)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
#include "cmc/heap.h"
|
||||
|
||||
typedef struct heap_s
|
||||
{
|
||||
size_t *buffer;
|
||||
size_t capacity;
|
||||
size_t count;
|
||||
enum HeapOrder HO;
|
||||
int (*cmp)(size_t, size_t);
|
||||
struct heap_iter_s (*it_start)(struct heap_s *);
|
||||
struct heap_iter_s (*it_end)(struct heap_s *);
|
||||
} heap, *heap_ptr;
|
||||
typedef struct heap_iter_s
|
||||
{
|
||||
struct heap_s *target;
|
||||
size_t cursor;
|
||||
bool start;
|
||||
bool end;
|
||||
} heap_iter, *heap_iter_ptr;
|
||||
heap *h_new(size_t capacity, HeapOrder HO, int (*compare)(size_t, size_t));
|
||||
void h_clear(heap *_heap_);
|
||||
void h_free(heap *_heap_);
|
||||
bool h_insert(heap *_heap_, size_t element);
|
||||
bool h_remove(heap *_heap_, size_t *result);
|
||||
bool h_insert_if(heap *_heap_, size_t element, bool condition);
|
||||
bool h_remove_if(heap *_heap_, size_t *result, bool condition);
|
||||
size_t h_peek(heap *_heap_);
|
||||
size_t *h_peek_ref(heap *_heap_);
|
||||
bool h_contains(heap *_heap_, size_t element);
|
||||
bool h_empty(heap *_heap_);
|
||||
bool h_full(heap *_heap_);
|
||||
size_t h_count(heap *_heap_);
|
||||
size_t h_capacity(heap *_heap_);
|
||||
heap_iter *h_iter_new(heap *target);
|
||||
void h_iter_free(heap_iter *iter);
|
||||
void h_iter_init(heap_iter *iter, heap *target);
|
||||
bool h_iter_start(heap_iter *iter);
|
||||
bool h_iter_end(heap_iter *iter);
|
||||
void h_iter_to_start(heap_iter *iter);
|
||||
void h_iter_to_end(heap_iter *iter);
|
||||
bool h_iter_next(heap_iter *iter);
|
||||
bool h_iter_prev(heap_iter *iter);
|
||||
size_t h_iter_value(heap_iter *iter);
|
||||
size_t h_iter_index(heap_iter *iter);
|
||||
static inline size_t h_impl_default_value(void)
|
||||
{
|
||||
size_t _empty_value_;
|
||||
memset(&_empty_value_, 0, sizeof(size_t));
|
||||
return _empty_value_;
|
||||
}
|
||||
static bool h_impl_grow(heap *_heap_);
|
||||
static size_t h_impl_p(size_t index);
|
||||
static size_t h_impl_l(size_t index);
|
||||
static size_t h_impl_r(size_t index);
|
||||
static bool h_impl_float_up(heap *_heap_, size_t index);
|
||||
static bool h_impl_float_down(heap *_heap_, size_t index);
|
||||
static heap_iter h_impl_it_start(heap *_heap_);
|
||||
static heap_iter h_impl_it_end(heap *_heap_);
|
||||
heap *h_new(size_t capacity, HeapOrder HO, int (*compare)(size_t, size_t))
|
||||
{
|
||||
if (capacity < 1)
|
||||
return NULL;
|
||||
if (HO != MinHeap && HO != MaxHeap)
|
||||
return NULL;
|
||||
heap *_heap_ = malloc(sizeof(heap));
|
||||
if (!_heap_)
|
||||
return NULL;
|
||||
_heap_->buffer = malloc(sizeof(size_t) * capacity);
|
||||
if (!_heap_->buffer)
|
||||
{
|
||||
free(_heap_);
|
||||
return NULL;
|
||||
}
|
||||
memset(_heap_->buffer, 0, sizeof(size_t) * capacity);
|
||||
_heap_->capacity = capacity;
|
||||
_heap_->count = 0;
|
||||
_heap_->HO = HO;
|
||||
_heap_->cmp = compare;
|
||||
_heap_->it_start = h_impl_it_start;
|
||||
_heap_->it_end = h_impl_it_end;
|
||||
return _heap_;
|
||||
}
|
||||
void h_clear(heap *_heap_)
|
||||
{
|
||||
memset(_heap_->buffer, 0, sizeof(size_t) * _heap_->capacity);
|
||||
_heap_->count = 0;
|
||||
}
|
||||
void h_free(heap *_heap_)
|
||||
{
|
||||
free(_heap_->buffer);
|
||||
free(_heap_);
|
||||
}
|
||||
bool h_insert(heap *_heap_, size_t element)
|
||||
{
|
||||
if (h_full(_heap_))
|
||||
{
|
||||
if (!h_impl_grow(_heap_))
|
||||
return false;
|
||||
}
|
||||
if (_heap_->count == 0)
|
||||
{
|
||||
_heap_->buffer[_heap_->count++] = element;
|
||||
return true;
|
||||
}
|
||||
_heap_->buffer[_heap_->count++] = element;
|
||||
if (!h_impl_float_up(_heap_, _heap_->count - 1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool h_remove(heap *_heap_, size_t *result)
|
||||
{
|
||||
if (h_empty(_heap_))
|
||||
return false;
|
||||
*result = _heap_->buffer[0];
|
||||
_heap_->buffer[0] = _heap_->buffer[_heap_->count - 1];
|
||||
_heap_->buffer[_heap_->count - 1] = h_impl_default_value();
|
||||
_heap_->count--;
|
||||
if (!h_impl_float_down(_heap_, 0))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool h_insert_if(heap *_heap_, size_t element, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return h_insert(_heap_, element);
|
||||
return false;
|
||||
}
|
||||
bool h_remove_if(heap *_heap_, size_t *result, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return h_remove(_heap_, result);
|
||||
return false;
|
||||
}
|
||||
size_t h_peek(heap *_heap_)
|
||||
{
|
||||
if (h_empty(_heap_))
|
||||
return h_impl_default_value();
|
||||
return _heap_->buffer[0];
|
||||
}
|
||||
size_t *h_peek_ref(heap *_heap_)
|
||||
{
|
||||
if (h_empty(_heap_))
|
||||
return NULL;
|
||||
return &(_heap_->buffer[0]);
|
||||
}
|
||||
bool h_contains(heap *_heap_, size_t element)
|
||||
{
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
{
|
||||
if (_heap_->cmp(_heap_->buffer[i], element) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool h_empty(heap *_heap_) { return _heap_->count == 0; }
|
||||
bool h_full(heap *_heap_) { return _heap_->count >= _heap_->capacity; }
|
||||
size_t h_count(heap *_heap_) { return _heap_->count; }
|
||||
size_t h_capacity(heap *_heap_) { return _heap_->capacity; }
|
||||
heap_iter *h_iter_new(heap *target)
|
||||
{
|
||||
heap_iter *iter = malloc(sizeof(heap_iter));
|
||||
if (!iter)
|
||||
return NULL;
|
||||
h_iter_init(iter, target);
|
||||
return iter;
|
||||
}
|
||||
void h_iter_free(heap_iter *iter) { free(iter); }
|
||||
void h_iter_init(heap_iter *iter, heap *target)
|
||||
{
|
||||
iter->target = target;
|
||||
iter->cursor = 0;
|
||||
iter->start = true;
|
||||
iter->end = h_empty(target);
|
||||
}
|
||||
bool h_iter_start(heap_iter *iter) { return h_empty(iter->target) || iter->start; }
|
||||
bool h_iter_end(heap_iter *iter) { return h_empty(iter->target) || iter->end; }
|
||||
void h_iter_to_start(heap_iter *iter)
|
||||
{
|
||||
iter->cursor = 0;
|
||||
iter->start = true;
|
||||
iter->end = h_empty(iter->target);
|
||||
}
|
||||
void h_iter_to_end(heap_iter *iter)
|
||||
{
|
||||
iter->cursor = iter->target->count - 1;
|
||||
iter->start = h_empty(iter->target);
|
||||
iter->end = true;
|
||||
}
|
||||
bool h_iter_next(heap_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return false;
|
||||
iter->start = false;
|
||||
if (iter->cursor == iter->target->count - 1)
|
||||
iter->end = true;
|
||||
else
|
||||
iter->cursor++;
|
||||
return true;
|
||||
}
|
||||
bool h_iter_prev(heap_iter *iter)
|
||||
{
|
||||
if (iter->start)
|
||||
return false;
|
||||
iter->end = false;
|
||||
if (iter->cursor == 0)
|
||||
iter->start = true;
|
||||
else
|
||||
iter->cursor--;
|
||||
return true;
|
||||
}
|
||||
size_t h_iter_value(heap_iter *iter)
|
||||
{
|
||||
if (h_empty(iter->target))
|
||||
return h_impl_default_value();
|
||||
return iter->target->buffer[iter->cursor];
|
||||
}
|
||||
size_t h_iter_index(heap_iter *iter) { return iter->cursor; }
|
||||
static bool h_impl_grow(heap *_heap_)
|
||||
{
|
||||
size_t new_capacity = _heap_->capacity * 2;
|
||||
size_t *new_buffer = realloc(_heap_->buffer, sizeof(size_t) * new_capacity);
|
||||
if (!new_buffer)
|
||||
return false;
|
||||
_heap_->buffer = new_buffer;
|
||||
_heap_->capacity = new_capacity;
|
||||
return true;
|
||||
}
|
||||
static size_t h_impl_p(size_t index)
|
||||
{
|
||||
if (index == 0)
|
||||
return 0;
|
||||
return (index - 1) / 2;
|
||||
}
|
||||
static size_t h_impl_l(size_t index) { return 2 * index + 1; }
|
||||
static size_t h_impl_r(size_t index) { return 2 * index + 2; }
|
||||
static bool h_impl_float_up(heap *_heap_, size_t index)
|
||||
{
|
||||
size_t C = index;
|
||||
size_t child = _heap_->buffer[C];
|
||||
size_t parent = _heap_->buffer[h_impl_p(C)];
|
||||
int mod = _heap_->HO;
|
||||
while (C > 0 && _heap_->cmp(child, parent) * mod > 0)
|
||||
{
|
||||
size_t tmp = _heap_->buffer[C];
|
||||
_heap_->buffer[C] = _heap_->buffer[h_impl_p(C)];
|
||||
_heap_->buffer[h_impl_p(C)] = tmp;
|
||||
C = h_impl_p(C);
|
||||
child = _heap_->buffer[C];
|
||||
parent = _heap_->buffer[h_impl_p(C)];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool h_impl_float_down(heap *_heap_, size_t index)
|
||||
{
|
||||
int mod = _heap_->HO;
|
||||
while (index < _heap_->count)
|
||||
{
|
||||
size_t L = h_impl_l(index);
|
||||
size_t R = h_impl_r(index);
|
||||
size_t C = index;
|
||||
if (L < _heap_->count && _heap_->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0)
|
||||
{
|
||||
C = L;
|
||||
}
|
||||
if (R < _heap_->count && _heap_->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0)
|
||||
{
|
||||
C = R;
|
||||
}
|
||||
if (C != index)
|
||||
{
|
||||
size_t tmp = _heap_->buffer[index];
|
||||
_heap_->buffer[index] = _heap_->buffer[C];
|
||||
_heap_->buffer[C] = tmp;
|
||||
index = C;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static heap_iter h_impl_it_start(heap *_heap_)
|
||||
{
|
||||
heap_iter iter;
|
||||
h_iter_init(&iter, _heap_);
|
||||
h_iter_to_start(&iter);
|
||||
return iter;
|
||||
}
|
||||
static heap_iter h_impl_it_end(heap *_heap_)
|
||||
{
|
||||
heap_iter iter;
|
||||
h_iter_init(&iter, _heap_);
|
||||
h_iter_to_end(&iter);
|
||||
return iter;
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
#include "cmc/linkedlist.h"
|
||||
|
||||
typedef struct linkedlist_s
|
||||
{
|
||||
struct linkedlist_node_s *head;
|
||||
struct linkedlist_node_s *tail;
|
||||
size_t count;
|
||||
struct linkedlist_iter_s (*it_start)(struct linkedlist_s *);
|
||||
struct linkedlist_iter_s (*it_end)(struct linkedlist_s *);
|
||||
} linkedlist, *linkedlist_ptr;
|
||||
typedef struct linkedlist_node_s
|
||||
{
|
||||
size_t data;
|
||||
struct linkedlist_node_s *next;
|
||||
struct linkedlist_node_s *prev;
|
||||
} linkedlist_node, *linkedlist_node_ptr;
|
||||
typedef struct linkedlist_iter_s
|
||||
{
|
||||
struct linkedlist_s *target;
|
||||
struct linkedlist_node_s *cursor;
|
||||
size_t index;
|
||||
bool start;
|
||||
bool end;
|
||||
} linkedlist_iter, *linkedlist_iter_ptr;
|
||||
linkedlist *ll_new(void);
|
||||
void ll_clear(linkedlist *_list_);
|
||||
void ll_free(linkedlist *_list_);
|
||||
bool ll_push_front(linkedlist *_list_, size_t element);
|
||||
bool ll_push(linkedlist *_list_, size_t element, size_t index);
|
||||
bool ll_push_back(linkedlist *_list_, size_t element);
|
||||
bool ll_pop_front(linkedlist *_list_);
|
||||
bool ll_pop(linkedlist *_list_, size_t index);
|
||||
bool ll_pop_back(linkedlist *_list_);
|
||||
bool ll_push_if(linkedlist *_list_, size_t element, size_t index, bool condition);
|
||||
bool ll_pop_if(linkedlist *_list_, size_t index, bool condition);
|
||||
size_t ll_front(linkedlist *_list_);
|
||||
size_t ll_get(linkedlist *_list_, size_t index);
|
||||
size_t *ll_get_ref(linkedlist *_list_, size_t index);
|
||||
size_t ll_back(linkedlist *_list_);
|
||||
bool ll_contains(linkedlist *_list_, size_t element, int (*comparator)(size_t, size_t));
|
||||
bool ll_empty(linkedlist *_list_);
|
||||
size_t ll_count(linkedlist *_list_);
|
||||
linkedlist_node *ll_new_node(size_t element);
|
||||
void ll_free_node(linkedlist_node *_node_);
|
||||
linkedlist_node *ll_head(linkedlist *_list_);
|
||||
linkedlist_node *ll_get_node(linkedlist *_list_, size_t index);
|
||||
linkedlist_node *ll_tail(linkedlist *_list_);
|
||||
bool ll_insert_after(linkedlist *_owner_, linkedlist_node *_node_, size_t element);
|
||||
bool ll_insert_before(linkedlist *_owner_, linkedlist_node *_node_, size_t element);
|
||||
bool ll_remove_after(linkedlist *_owner_, linkedlist_node *_node_);
|
||||
bool ll_remove_current(linkedlist *_owner_, linkedlist_node *_node_);
|
||||
bool ll_remove_before(linkedlist *_owner_, linkedlist_node *_node_);
|
||||
linkedlist_node *ll_next_node(linkedlist_node *_node_);
|
||||
linkedlist_node *ll_prev_node(linkedlist_node *_node_);
|
||||
linkedlist_iter *ll_iter_new(linkedlist *target);
|
||||
void ll_iter_free(linkedlist_iter *iter);
|
||||
void ll_iter_init(linkedlist_iter *iter, linkedlist *target);
|
||||
bool ll_iter_start(linkedlist_iter *iter);
|
||||
bool ll_iter_end(linkedlist_iter *iter);
|
||||
void ll_iter_to_start(linkedlist_iter *iter);
|
||||
void ll_iter_to_end(linkedlist_iter *iter);
|
||||
bool ll_iter_next(linkedlist_iter *iter);
|
||||
bool ll_iter_prev(linkedlist_iter *iter);
|
||||
size_t ll_iter_value(linkedlist_iter *iter);
|
||||
size_t *ll_iter_rvalue(linkedlist_iter *iter);
|
||||
size_t ll_iter_index(linkedlist_iter *iter);
|
||||
linkedlist_node *ll_iter_node(linkedlist_iter *iter);
|
||||
static inline size_t ll_impl_default_value(void)
|
||||
{
|
||||
size_t _empty_value_;
|
||||
memset(&_empty_value_, 0, sizeof(size_t));
|
||||
return _empty_value_;
|
||||
}
|
||||
static linkedlist_iter ll_impl_it_start(linkedlist *_list_);
|
||||
static linkedlist_iter ll_impl_it_end(linkedlist *_list_);
|
||||
linkedlist *ll_new(void)
|
||||
{
|
||||
linkedlist *_list_ = malloc(sizeof(linkedlist));
|
||||
if (!_list_)
|
||||
return NULL;
|
||||
_list_->count = 0;
|
||||
_list_->head = NULL;
|
||||
_list_->tail = NULL;
|
||||
_list_->it_start = ll_impl_it_start;
|
||||
_list_->it_end = ll_impl_it_end;
|
||||
return _list_;
|
||||
}
|
||||
void ll_clear(linkedlist *_list_)
|
||||
{
|
||||
linkedlist_node *scan = _list_->head;
|
||||
while (_list_->head != NULL)
|
||||
{
|
||||
_list_->head = _list_->head->next;
|
||||
free(scan);
|
||||
scan = _list_->head;
|
||||
}
|
||||
_list_->count = 0;
|
||||
_list_->head = NULL;
|
||||
_list_->tail = NULL;
|
||||
}
|
||||
void ll_free(linkedlist *_list_)
|
||||
{
|
||||
ll_clear(_list_);
|
||||
free(_list_);
|
||||
}
|
||||
bool ll_push_front(linkedlist *_list_, size_t element)
|
||||
{
|
||||
linkedlist_node *_node_ = ll_new_node(element);
|
||||
if (!_node_)
|
||||
return false;
|
||||
if (ll_empty(_list_))
|
||||
{
|
||||
_list_->head = _node_;
|
||||
_list_->tail = _node_;
|
||||
}
|
||||
else
|
||||
{
|
||||
_node_->next = _list_->head;
|
||||
_list_->head->prev = _node_;
|
||||
_list_->head = _node_;
|
||||
}
|
||||
_list_->count++;
|
||||
return true;
|
||||
}
|
||||
bool ll_push(linkedlist *_list_, size_t element, size_t index)
|
||||
{
|
||||
if (index > _list_->count)
|
||||
return false;
|
||||
if (index == 0)
|
||||
{
|
||||
return ll_push_front(_list_, element);
|
||||
}
|
||||
else if (index == _list_->count)
|
||||
{
|
||||
return ll_push_back(_list_, element);
|
||||
}
|
||||
linkedlist_node *_node_ = ll_new_node(element);
|
||||
if (!_node_)
|
||||
return false;
|
||||
linkedlist_node *scan = ll_get_node(_list_, index - 1);
|
||||
_node_->next = scan->next;
|
||||
_node_->prev = scan;
|
||||
_node_->next->prev = _node_;
|
||||
_node_->prev->next = _node_;
|
||||
_list_->count++;
|
||||
return true;
|
||||
}
|
||||
bool ll_push_back(linkedlist *_list_, size_t element)
|
||||
{
|
||||
linkedlist_node *_node_ = ll_new_node(element);
|
||||
if (!_node_)
|
||||
return false;
|
||||
if (ll_empty(_list_))
|
||||
{
|
||||
_list_->head = _node_;
|
||||
_list_->tail = _node_;
|
||||
}
|
||||
else
|
||||
{
|
||||
_node_->prev = _list_->tail;
|
||||
_list_->tail->next = _node_;
|
||||
_list_->tail = _node_;
|
||||
}
|
||||
_list_->count++;
|
||||
return true;
|
||||
}
|
||||
bool ll_pop_front(linkedlist *_list_)
|
||||
{
|
||||
if (ll_empty(_list_))
|
||||
return false;
|
||||
linkedlist_node *_node_ = _list_->head;
|
||||
_list_->head = _list_->head->next;
|
||||
free(_node_);
|
||||
if (_list_->head == NULL)
|
||||
_list_->tail = NULL;
|
||||
else
|
||||
_list_->head->prev = NULL;
|
||||
_list_->count--;
|
||||
return true;
|
||||
}
|
||||
bool ll_pop(linkedlist *_list_, size_t index)
|
||||
{
|
||||
if (ll_empty(_list_))
|
||||
return false;
|
||||
if (index >= _list_->count)
|
||||
return false;
|
||||
if (index == 0)
|
||||
{
|
||||
return ll_pop_front(_list_);
|
||||
}
|
||||
else if (index == _list_->count - 1)
|
||||
{
|
||||
return ll_pop_back(_list_);
|
||||
}
|
||||
linkedlist_node *_node_ = ll_get_node(_list_, index);
|
||||
if (!_node_)
|
||||
return false;
|
||||
_node_->next->prev = _node_->prev;
|
||||
_node_->prev->next = _node_->next;
|
||||
free(_node_);
|
||||
_list_->count--;
|
||||
return true;
|
||||
}
|
||||
bool ll_pop_back(linkedlist *_list_)
|
||||
{
|
||||
if (ll_empty(_list_))
|
||||
return false;
|
||||
linkedlist_node *_node_ = _list_->tail;
|
||||
_list_->tail = _list_->tail->prev;
|
||||
free(_node_);
|
||||
if (_list_->tail == NULL)
|
||||
_list_->head = NULL;
|
||||
else
|
||||
_list_->tail->next = NULL;
|
||||
_list_->count--;
|
||||
return true;
|
||||
}
|
||||
bool ll_push_if(linkedlist *_list_, size_t element, size_t index, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return ll_push(_list_, element, index);
|
||||
return false;
|
||||
}
|
||||
bool ll_pop_if(linkedlist *_list_, size_t index, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return ll_pop(_list_, index);
|
||||
return false;
|
||||
}
|
||||
size_t ll_front(linkedlist *_list_)
|
||||
{
|
||||
if (ll_empty(_list_))
|
||||
ll_impl_default_value();
|
||||
return _list_->head->data;
|
||||
}
|
||||
size_t ll_get(linkedlist *_list_, size_t index)
|
||||
{
|
||||
if (index >= _list_->count || ll_empty(_list_))
|
||||
ll_impl_default_value();
|
||||
linkedlist_node *scan = ll_get_node(_list_, index);
|
||||
if (scan == NULL)
|
||||
return ll_impl_default_value();
|
||||
return scan->data;
|
||||
}
|
||||
size_t *ll_get_ref(linkedlist *_list_, size_t index)
|
||||
{
|
||||
if (index >= _list_->count)
|
||||
return NULL;
|
||||
if (ll_empty(_list_))
|
||||
return NULL;
|
||||
linkedlist_node *scan = ll_get_node(_list_, index);
|
||||
if (scan == NULL)
|
||||
return NULL;
|
||||
return &(scan->data);
|
||||
}
|
||||
size_t ll_back(linkedlist *_list_)
|
||||
{
|
||||
if (ll_empty(_list_))
|
||||
return ll_impl_default_value();
|
||||
return _list_->tail->data;
|
||||
}
|
||||
bool ll_contains(linkedlist *_list_, size_t element, int (*comparator)(size_t, size_t))
|
||||
{
|
||||
linkedlist_node *scan = _list_->head;
|
||||
while (scan != NULL)
|
||||
{
|
||||
if (comparator(scan->data, element) == 0)
|
||||
return true;
|
||||
scan = scan->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ll_empty(linkedlist *_list_) { return _list_->count == 0; }
|
||||
size_t ll_count(linkedlist *_list_) { return _list_->count; }
|
||||
linkedlist_node *ll_new_node(size_t element)
|
||||
{
|
||||
linkedlist_node *_node_ = malloc(sizeof(linkedlist_node));
|
||||
if (!_node_)
|
||||
return NULL;
|
||||
_node_->data = element;
|
||||
_node_->next = NULL;
|
||||
_node_->prev = NULL;
|
||||
return _node_;
|
||||
}
|
||||
void ll_free_node(linkedlist_node *_node_) { free(_node_); }
|
||||
linkedlist_node *ll_head(linkedlist *_list_) { return _list_->head; }
|
||||
linkedlist_node *ll_get_node(linkedlist *_list_, size_t index)
|
||||
{
|
||||
if (index >= _list_->count)
|
||||
return NULL;
|
||||
if (ll_empty(_list_))
|
||||
return NULL;
|
||||
linkedlist_node *_node_ = NULL;
|
||||
if (index <= _list_->count / 2)
|
||||
{
|
||||
_node_ = _list_->head;
|
||||
for (size_t i = 0; i < index; i++)
|
||||
{
|
||||
_node_ = _node_->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_node_ = _list_->tail;
|
||||
for (size_t i = _list_->count - 1; i > index; i--)
|
||||
{
|
||||
_node_ = _node_->prev;
|
||||
}
|
||||
}
|
||||
return _node_;
|
||||
}
|
||||
linkedlist_node *ll_tail(linkedlist *_list_) { return _list_->tail; }
|
||||
bool ll_insert_after(linkedlist *_owner_, linkedlist_node *_node_, size_t element)
|
||||
{
|
||||
linkedlist_node *new_node = ll_new_node(element);
|
||||
if (!new_node)
|
||||
return false;
|
||||
new_node->next = _node_->next;
|
||||
if (_node_->next != NULL)
|
||||
_node_->next->prev = new_node;
|
||||
else
|
||||
_owner_->tail = new_node;
|
||||
new_node->prev = _node_;
|
||||
_node_->next = new_node;
|
||||
_owner_->count++;
|
||||
return true;
|
||||
}
|
||||
bool ll_insert_before(linkedlist *_owner_, linkedlist_node *_node_, size_t element)
|
||||
{
|
||||
linkedlist_node *new_node = ll_new_node(element);
|
||||
if (!new_node)
|
||||
return false;
|
||||
new_node->prev = _node_->prev;
|
||||
if (_node_->prev != NULL)
|
||||
_node_->prev->next = new_node;
|
||||
else
|
||||
_owner_->head = new_node;
|
||||
new_node->next = _node_;
|
||||
_node_->prev = new_node;
|
||||
_owner_->count++;
|
||||
return true;
|
||||
}
|
||||
bool ll_remove_after(linkedlist *_owner_, linkedlist_node *_node_)
|
||||
{
|
||||
if (_node_->next == NULL)
|
||||
return false;
|
||||
linkedlist_node *tmp = _node_->next;
|
||||
if (tmp->next != NULL)
|
||||
{
|
||||
_node_->next = _node_->next->next;
|
||||
_node_->next->prev = _node_;
|
||||
}
|
||||
else
|
||||
_owner_->tail = _node_;
|
||||
free(tmp);
|
||||
_owner_->count--;
|
||||
return true;
|
||||
}
|
||||
bool ll_remove_current(linkedlist *_owner_, linkedlist_node *_node_)
|
||||
{
|
||||
if (_node_->prev != NULL)
|
||||
_node_->prev->next = _node_->next;
|
||||
else
|
||||
_owner_->head = _node_->next;
|
||||
if (_node_->next != NULL)
|
||||
_node_->next->prev = _node_->prev;
|
||||
else
|
||||
_owner_->tail = _node_->prev;
|
||||
free(_node_);
|
||||
_owner_->count--;
|
||||
return true;
|
||||
}
|
||||
bool ll_remove_before(linkedlist *_owner_, linkedlist_node *_node_)
|
||||
{
|
||||
if (_node_->prev == NULL)
|
||||
return false;
|
||||
linkedlist_node *tmp = _node_->prev;
|
||||
if (tmp->prev != NULL)
|
||||
{
|
||||
_node_->prev = _node_->prev->prev;
|
||||
_node_->prev->next = _node_;
|
||||
}
|
||||
else
|
||||
_owner_->head = _node_;
|
||||
free(tmp);
|
||||
_owner_->count--;
|
||||
return true;
|
||||
}
|
||||
linkedlist_node *ll_next_node(linkedlist_node *_node_) { return _node_->next; }
|
||||
linkedlist_node *ll_prev_node(linkedlist_node *_node_) { return _node_->prev; }
|
||||
linkedlist_iter *ll_iter_new(linkedlist *target)
|
||||
{
|
||||
linkedlist_iter *iter = malloc(sizeof(linkedlist_iter));
|
||||
if (!iter)
|
||||
return NULL;
|
||||
ll_iter_init(iter, target);
|
||||
return iter;
|
||||
}
|
||||
void ll_iter_free(linkedlist_iter *iter) { free(iter); }
|
||||
void ll_iter_init(linkedlist_iter *iter, linkedlist *target)
|
||||
{
|
||||
iter->target = target;
|
||||
iter->cursor = target->head;
|
||||
iter->index = 0;
|
||||
iter->start = true;
|
||||
iter->end = ll_empty(target);
|
||||
}
|
||||
bool ll_iter_start(linkedlist_iter *iter) { return ll_empty(iter->target) || iter->start; }
|
||||
bool ll_iter_end(linkedlist_iter *iter) { return ll_empty(iter->target) || iter->end; }
|
||||
void ll_iter_to_start(linkedlist_iter *iter)
|
||||
{
|
||||
iter->cursor = iter->target->head;
|
||||
iter->index = 0;
|
||||
iter->start = true;
|
||||
iter->end = ll_empty(iter->target);
|
||||
}
|
||||
void ll_iter_to_end(linkedlist_iter *iter)
|
||||
{
|
||||
iter->cursor = iter->target->tail;
|
||||
iter->index = iter->target->count - 1;
|
||||
iter->start = ll_empty(iter->target);
|
||||
iter->end = true;
|
||||
}
|
||||
bool ll_iter_next(linkedlist_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return false;
|
||||
iter->start = ll_empty(iter->target);
|
||||
if (iter->cursor->next == NULL)
|
||||
iter->end = true;
|
||||
else
|
||||
{
|
||||
iter->cursor = iter->cursor->next;
|
||||
iter->index++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool ll_iter_prev(linkedlist_iter *iter)
|
||||
{
|
||||
if (iter->start)
|
||||
return false;
|
||||
iter->end = ll_empty(iter->target);
|
||||
if (iter->cursor->prev == NULL)
|
||||
iter->start = true;
|
||||
else
|
||||
{
|
||||
iter->cursor = iter->cursor->prev;
|
||||
iter->index--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
size_t ll_iter_value(linkedlist_iter *iter)
|
||||
{
|
||||
if (ll_empty(iter->target))
|
||||
return ll_impl_default_value();
|
||||
return iter->cursor->data;
|
||||
}
|
||||
size_t *ll_iter_rvalue(linkedlist_iter *iter)
|
||||
{
|
||||
if (ll_empty(iter->target))
|
||||
return NULL;
|
||||
return &(iter->cursor->data);
|
||||
}
|
||||
size_t ll_iter_index(linkedlist_iter *iter) { return iter->index; }
|
||||
linkedlist_node *ll_iter_node(linkedlist_iter *iter) { return iter->cursor; }
|
||||
static linkedlist_iter ll_impl_it_start(linkedlist *_list_)
|
||||
{
|
||||
linkedlist_iter iter;
|
||||
ll_iter_init(&iter, _list_);
|
||||
ll_iter_to_start(&iter);
|
||||
return iter;
|
||||
}
|
||||
static linkedlist_iter ll_impl_it_end(linkedlist *_list_)
|
||||
{
|
||||
linkedlist_iter iter;
|
||||
ll_iter_init(&iter, _list_);
|
||||
ll_iter_to_end(&iter);
|
||||
return iter;
|
||||
}
|
||||
@@ -11,7 +11,7 @@ CMC_CREATE_UNIT(hashmap_test, true, {
|
||||
bool passed = (map->capacity >= (943722 / 0.6)) && map->count == 0 && map->buffer;
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, map);
|
||||
cmc_assert(hm_capacity(map) > (943722 / 0.6));
|
||||
cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "utl/assert.h"
|
||||
#include "utl/test.h"
|
||||
#include "../src/heap.c"
|
||||
|
||||
#include "utl.c"
|
||||
|
||||
CMC_CREATE_UNIT(heap_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
heap *h = h_new(1000000, MaxHeap, cmp);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, h);
|
||||
|
||||
bool passed = h->capacity == 1000000 && h->count == 0 && h->buffer;
|
||||
|
||||
cmc_assert_equals(size_t, 1000000, h->capacity);
|
||||
cmc_assert_equals(size_t, 0, h_count(h));
|
||||
cmc_assert_not_equals(ptr, NULL, h->buffer);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
h_free(h);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = 0], {
|
||||
heap *h = h_new(0, MaxHeap, cmp);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, h);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
heap *h = h_new(UINT64_MAX, MaxHeap, cmp);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, h);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
heap *h = h_new(100, MaxHeap, cmp);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, h);
|
||||
|
||||
for (size_t i = 0; i < 50; i++)
|
||||
h_insert(h, i);
|
||||
|
||||
cmc_assert_equals(size_t, 50, h_count(h));
|
||||
|
||||
h_clear(h);
|
||||
|
||||
cmc_assert_equals(size_t, 0, h_count(h));
|
||||
cmc_assert_equals(size_t, 100, h_capacity(h));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h_count(h) == 0 && h_capacity(h) == 100);
|
||||
|
||||
h_free(h);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(buffer_growth[edge_case:capacity = 1], {
|
||||
heap *h = h_new(1, MaxHeap, cmp);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, h);
|
||||
|
||||
for (size_t i = 0; i < 50; i++)
|
||||
h_insert(h, i);
|
||||
|
||||
cmc_assert_equals(size_t, 50, h_count(h));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h_count(h) == 50);
|
||||
|
||||
h_free(h);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "utl/assert.h"
|
||||
#include "utl/test.h"
|
||||
#include "../src/linkedlist.c"
|
||||
|
||||
CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
linkedlist *ll = ll_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
bool passed = ll->count == 0 && ll->head == NULL && ll->tail == NULL;
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
cmc_assert_equals(ptr, NULL, ll->head);
|
||||
cmc_assert_equals(ptr, NULL, ll->tail);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
linkedlist *ll = ll_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
for (size_t i = 0; i < 50; i++)
|
||||
ll_push_back(ll, i);
|
||||
|
||||
cmc_assert_equals(size_t, 50, ll_count(ll));
|
||||
|
||||
ll_clear(ll);
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ll_count(ll) == 0);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[edge_case:count = 0], {
|
||||
linkedlist *ll = ll_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
ll_clear(ll);
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ll_count(ll) == 0);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[count], {
|
||||
linkedlist *ll = ll_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
ll_push_front(ll, 1);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll->head);
|
||||
cmc_assert_not_equals(ptr, NULL, ll->tail);
|
||||
cmc_assert_equals(size_t, 1, ll_count(ll));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ll->head && ll->tail && ll_count(ll) == 1);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[item_preservation], {
|
||||
linkedlist *ll = ll_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
for (size_t i = 0; i < 200; i++)
|
||||
ll_push_front(ll, i);
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < ll_count(ll); i++)
|
||||
{
|
||||
passed = passed && ll_get(ll, i) == (ll_count(ll) - i - 1);
|
||||
|
||||
cmc_assert_equals(size_t, ll_get(ll, i), ll_count(ll) - i - 1);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && ll_count(ll) == 200);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
});
|
||||
+136
-22
@@ -118,13 +118,43 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[count capacity item_preservation grow], {
|
||||
CMC_CREATE_TEST(push_front[count], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 200; i++)
|
||||
l_push_front(l, i);
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_front(l, i));
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[capacity], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_front(l, i));
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) <= l_capacity(l));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[item_preservation], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_front(l, i));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
@@ -135,18 +165,57 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert_equals(size_t, l_get(l, i), l_count(l) - i - 1);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && l_count(l) == 200);
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push[count capacity item_preservation grow], {
|
||||
CMC_CREATE_TEST(push[count], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 200; i++)
|
||||
l_push(l, i, l_count(l));
|
||||
cmc_assert(l_push_back(l, 0));
|
||||
cmc_assert(l_push_back(l, 249));
|
||||
|
||||
for (size_t i = 1; i < 249; i++)
|
||||
cmc_assert(l_push(l, i, l_count(l) - 1));
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push[capacity], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
cmc_assert(l_push_back(l, 0));
|
||||
cmc_assert(l_push_back(l, 249));
|
||||
|
||||
for (size_t i = 1; i < 249; i++)
|
||||
cmc_assert(l_push(l, i, l_count(l) - 1));
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) <= l_capacity(l));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push[item_preservation], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
cmc_assert(l_push_back(l, 0));
|
||||
cmc_assert(l_push_back(l, 249));
|
||||
|
||||
for (size_t i = 1; i < 249; i++)
|
||||
cmc_assert(l_push(l, i, l_count(l) - 1));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
@@ -157,39 +226,84 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert_equals(size_t, l_get(l, i), i);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && l_count(l) == 200);
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_back[count capacity item_preservation grow], {
|
||||
CMC_CREATE_TEST(push_back[count], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 200; i++)
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_back(l, i));
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_back[capacity], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_back(l, i));
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) <= l_capacity(l));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_back[item_preservation], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_back(l, i));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
{
|
||||
passed = passed && l_get(l, i) == i;
|
||||
|
||||
cmc_assert_equals(size_t, l_get(l, i), i);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_front[count], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
l_push_back(l, i);
|
||||
|
||||
bool passed = true;
|
||||
cmc_assert(l_pop_front(l));
|
||||
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
{
|
||||
passed = passed && l_get(l, i) == i;
|
||||
|
||||
cmc_assert_equals(size_t, l_get(l, i), i);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && l_count(l) == 200);
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250 - 1);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_front[count item_preservation], {
|
||||
CMC_CREATE_TEST(pop_front[item_preservation], {
|
||||
list *l = l_new(100);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
for (size_t i = 0; i < 200; i++)
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
l_push_back(l, i);
|
||||
|
||||
bool passed = l_pop_front(l);
|
||||
@@ -201,7 +315,7 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert_equals(size_t, l_get(l, i), i + 1);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && l_count(l) == 199);
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user