diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 5bb3b3d..0cb968d 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -346,26 +346,10 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI if (PFX##_capacity(_deque_) == capacity) \ return true; \ \ - size_t new_capacity = 0; \ + if (capacity < PFX##_count(_deque_)) \ + return false; \ \ - if (capacity < PFX##_capacity(_deque_)) \ - { \ - /* Shrink */ \ - if (capacity < PFX##_count(_deque_)) \ - return false; \ - \ - new_capacity = capacity; \ - } \ - else \ - { \ - /* Grow */ \ - if (PFX##_capacity(_deque_) * 2 < capacity) \ - new_capacity = capacity; \ - else \ - new_capacity = PFX##_capacity(_deque_) * 2; \ - } \ - \ - V *new_buffer = malloc(sizeof(V) * new_capacity); \ + V *new_buffer = malloc(sizeof(V) * capacity); \ \ if (!new_buffer) \ return false; \ @@ -380,7 +364,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI free(_deque_->buffer); \ \ _deque_->buffer = new_buffer; \ - _deque_->capacity = new_capacity; \ + _deque_->capacity = capacity; \ _deque_->front = 0; \ _deque_->back = _deque_->count; \ \ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index a3bfac8..59de0da 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -112,7 +112,6 @@ typedef enum cmc_heap_order_e bool PFX##_remove(SNAME *_heap_, V *result); \ /* Element Access */ \ V PFX##_peek(SNAME *_heap_); \ - V *PFX##_peek_ref(SNAME *_heap_); \ /* Collection State */ \ bool PFX##_contains(SNAME *_heap_, V element); \ bool PFX##_empty(SNAME *_heap_); \ @@ -120,6 +119,7 @@ typedef enum cmc_heap_order_e size_t PFX##_count(SNAME *_heap_); \ size_t PFX##_capacity(SNAME *_heap_); \ /* Collection Utility */ \ + bool PFX##_resize(SNAME *_heap_, size_t capacity); \ SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)); \ bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_); \ cmc_string PFX##_to_string(SNAME *_heap_); \ @@ -159,7 +159,6 @@ typedef enum cmc_heap_order_e #define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static bool PFX##_impl_grow(SNAME *_heap_); \ static bool PFX##_impl_float_up(SNAME *_heap_, size_t index); \ static bool PFX##_impl_float_down(SNAME *_heap_, size_t index); \ static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \ @@ -232,7 +231,7 @@ typedef enum cmc_heap_order_e { \ if (PFX##_full(_heap_)) \ { \ - if (!PFX##_impl_grow(_heap_)) \ + if (!PFX##_resize(_heap_, PFX##_count(_heap_) * 2)) \ return false; \ } \ \ @@ -275,14 +274,6 @@ typedef enum cmc_heap_order_e return _heap_->buffer[0]; \ } \ \ - V *PFX##_peek_ref(SNAME *_heap_) \ - { \ - if (PFX##_empty(_heap_)) \ - return NULL; \ - \ - return &(_heap_->buffer[0]); \ - } \ - \ bool PFX##_contains(SNAME *_heap_, V element) \ { \ for (size_t i = 0; i < _heap_->count; i++) \ @@ -314,6 +305,22 @@ typedef enum cmc_heap_order_e return _heap_->capacity; \ } \ \ + bool PFX##_resize(SNAME *_heap_, size_t capacity) \ + { \ + if (capacity < PFX##_count(_heap_)) \ + return false; \ + \ + V *new_buffer = realloc(_heap_->buffer, sizeof(V) * capacity); \ + \ + if (!new_buffer) \ + return false; \ + \ + _heap_->buffer = new_buffer; \ + _heap_->capacity = capacity; \ + \ + return true; \ + } \ + \ SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \ { \ SNAME *result = PFX##_new(_heap_->capacity, _heap_->HO, _heap_->cmp); \ @@ -526,21 +533,6 @@ typedef enum cmc_heap_order_e return iter->cursor; \ } \ \ - static bool PFX##_impl_grow(SNAME *_heap_) \ - { \ - size_t new_capacity = _heap_->capacity * 2; \ - \ - V *new_buffer = realloc(_heap_->buffer, sizeof(V) * new_capacity); \ - \ - if (!new_buffer) \ - return false; \ - \ - _heap_->buffer = new_buffer; \ - _heap_->capacity = new_capacity; \ - \ - return true; \ - } \ - \ static bool PFX##_impl_float_up(SNAME *_heap_, size_t index) \ { \ /* Current index */ \ diff --git a/src/cmc/list.h b/src/cmc/list.h index 3271eed..7903e0f 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -136,6 +136,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu bool PFX##_fits(SNAME *_list_, size_t size); \ size_t PFX##_capacity(SNAME *_list_); \ /* Collection Utility */ \ + bool PFX##_resize(SNAME *_list_, size_t capacity); \ SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)); \ bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)); \ cmc_string PFX##_to_string(SNAME *_list_); \ @@ -173,630 +174,622 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu } \ \ /* SOURCE ********************************************************************/ -#define CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static bool PFX##_impl_grow(SNAME *_list_, size_t required); \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \ - \ - SNAME *PFX##_new(size_t capacity) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - SNAME *_list_ = malloc(sizeof(SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->buffer = malloc(capacity * sizeof(V)); \ - \ - if (!_list_->buffer) \ - { \ - free(_list_); \ - return NULL; \ - } \ - \ - memset(_list_->buffer, 0, capacity * sizeof(V)); \ - \ - _list_->capacity = capacity; \ - _list_->count = 0; \ - \ - _list_->it_start = PFX##_impl_it_start; \ - _list_->it_end = PFX##_impl_it_end; \ - \ - return _list_; \ - } \ - \ - SNAME *PFX##_new_from(V *elements, size_t size) \ - { \ - if (size == 0) \ - return NULL; \ - \ - SNAME *_list_ = PFX##_new(size + size / 2); \ - \ - if (!_list_) \ - return NULL; \ - \ - memcpy(_list_->buffer, elements, size * sizeof(V)); \ - \ - _list_->count = size; \ - \ - return _list_; \ - } \ - \ - void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \ - { \ - if (deallocator) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - deallocator(_list_->buffer[i]); \ - } \ - \ - memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ - \ - _list_->count = 0; \ - } \ - \ - void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \ - { \ - if (deallocator) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - deallocator(_list_->buffer[i]); \ - } \ - \ - free(_list_->buffer); \ - free(_list_); \ - } \ - \ - bool PFX##_push_front(SNAME *_list_, V element) \ - { \ - if (PFX##_full(_list_)) \ - { \ - if (!PFX##_impl_grow(_list_, _list_->count + 1)) \ - return false; \ - } \ - \ - if (!PFX##_empty(_list_)) \ - { \ - memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(V)); \ - } \ - \ - _list_->buffer[0] = element; \ - \ - _list_->count++; \ - \ - return true; \ - } \ - \ - bool PFX##_push_at(SNAME *_list_, V element, size_t index) \ - { \ - if (index > _list_->count) \ - return false; \ - \ - if (index == 0) \ - { \ - return PFX##_push_front(_list_, element); \ - } \ - else if (index == _list_->count) \ - { \ - return PFX##_push_back(_list_, element); \ - } \ - \ - if (PFX##_full(_list_)) \ - { \ - if (!PFX##_impl_grow(_list_, _list_->count + 1)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \ - \ - _list_->buffer[index] = element; \ - \ - _list_->count++; \ - \ - return true; \ - } \ - \ - bool PFX##_push_back(SNAME *_list_, V element) \ - { \ - if (PFX##_full(_list_)) \ - { \ - if (!PFX##_impl_grow(_list_, _list_->count + 1)) \ - return false; \ - } \ - \ - _list_->buffer[_list_->count++] = element; \ - \ - return true; \ - } \ - \ - bool PFX##_pop_front(SNAME *_list_) \ - { \ - if (PFX##_empty(_list_)) \ - return false; \ - \ - memmove(_list_->buffer, _list_->buffer + 1, _list_->count * sizeof(V)); \ - \ - _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ - \ - return true; \ - } \ - \ - bool PFX##_pop_at(SNAME *_list_, size_t index) \ - { \ - if (index >= _list_->count) \ - return false; \ - \ - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(V)); \ - \ - _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ - \ - return true; \ - } \ - \ - bool PFX##_pop_back(SNAME *_list_) \ - { \ - if (PFX##_empty(_list_)) \ - return false; \ - \ - _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ - \ - return true; \ - } \ - \ - bool PFX##_seq_push_front(SNAME *_list_, V *elements, size_t size) \ - { \ - if (size == 0) \ - return false; \ - \ - if (!PFX##_fits(_list_, size)) \ - { \ - if (!PFX##_impl_grow(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(V)); \ - \ - memcpy(_list_->buffer, elements, size * sizeof(V)); \ - \ - _list_->count += size; \ - \ - return true; \ - } \ - \ - bool PFX##_seq_push_at(SNAME *_list_, V *elements, size_t size, size_t index) \ - { \ - if (size == 0 || index > _list_->count) \ - return false; \ - \ - if (index == 0) \ - return PFX##_seq_push_front(_list_, elements, size); \ - else if (index == _list_->count) \ - return PFX##_seq_push_back(_list_, elements, size); \ - else \ - { \ - if (!PFX##_fits(_list_, size)) \ - { \ - if (!PFX##_impl_grow(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \ - \ - memcpy(_list_->buffer + index, elements, size * sizeof(V)); \ - \ - _list_->count += size; \ - } \ - \ - return true; \ - } \ - \ - bool PFX##_seq_push_back(SNAME *_list_, V *elements, size_t size) \ - { \ - if (size == 0) \ - return false; \ - \ - if (!PFX##_fits(_list_, size)) \ - { \ - if (!PFX##_impl_grow(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memcpy(_list_->buffer + _list_->count, elements, size * sizeof(V)); \ - \ - _list_->count += size; \ - \ - return true; \ - } \ - \ - bool PFX##_seq_pop_at(SNAME *_list_, size_t from, size_t to) \ - { \ - if (from > to || to >= _list_->count) \ - return false; \ - \ - size_t length = (to - from + 1); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ - \ - _list_->count -= to - from + 1; \ - \ - return true; \ - } \ - \ - SNAME *PFX##_seq_sublist(SNAME *_list_, size_t from, size_t to) \ - { \ - if (from > to || to >= _list_->count) \ - return false; \ - \ - size_t length = to - from + 1; \ - \ - SNAME *result = PFX##_new(length); \ - \ - if (!result) \ - return NULL; \ - \ - memcpy(result->buffer, _list_->buffer, _list_->count * sizeof(V)); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ - \ - _list_->count -= length; \ - result->count = length; \ - \ - return result; \ - } \ - \ - V PFX##_front(SNAME *_list_) \ - { \ - if (PFX##_empty(_list_)) \ - return PFX##_impl_default_value(); \ - \ - return _list_->buffer[0]; \ - } \ - \ - V PFX##_get(SNAME *_list_, size_t index) \ - { \ - if (index >= _list_->count || PFX##_empty(_list_)) \ - return PFX##_impl_default_value(); \ - \ - return _list_->buffer[index]; \ - } \ - \ - V *PFX##_get_ref(SNAME *_list_, size_t index) \ - { \ - if (index >= _list_->count) \ - return NULL; \ - \ - if (PFX##_empty(_list_)) \ - return NULL; \ - \ - return &(_list_->buffer[index]); \ - } \ - \ - V PFX##_back(SNAME *_list_) \ - { \ - if (PFX##_empty(_list_)) \ - return PFX##_impl_default_value(); \ - \ - return _list_->buffer[_list_->count - 1]; \ - } \ - \ - size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start) \ - { \ - if (from_start) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (comparator(_list_->buffer[i], element) == 0) \ - return i; \ - } \ - } \ - else \ - { \ - for (size_t i = _list_->count; i > 0; i--) \ - { \ - if (comparator(_list_->buffer[i - 1], element) == 0) \ - return i - 1; \ - } \ - } \ - \ - return _list_->count; \ - } \ - \ - bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (comparator(_list_->buffer[i], element) == 0) \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool PFX##_empty(SNAME *_list_) \ - { \ - return _list_->count == 0; \ - } \ - \ - bool PFX##_full(SNAME *_list_) \ - { \ - return _list_->count >= _list_->capacity; \ - } \ - \ - size_t PFX##_count(SNAME *_list_) \ - { \ - return _list_->count; \ - } \ - \ - bool PFX##_fits(SNAME *_list_, size_t size) \ - { \ - return _list_->count + size <= _list_->capacity; \ - } \ - \ - size_t PFX##_capacity(SNAME *_list_) \ - { \ - return _list_->capacity; \ - } \ - \ - SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)) \ - { \ - SNAME *result = PFX##_new(_list_->capacity); \ - \ - if (!result) \ - return NULL; \ - \ - if (copy_func) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - result->buffer[i] = copy_func(_list_->buffer[i]); \ - } \ - else \ - memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ - \ - result->count = _list_->count; \ - \ - return result; \ - } \ - \ - bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)) \ - { \ - if (PFX##_count(_list1_) != PFX##_count(_list2_)) \ - return false; \ - \ - for (size_t i = 0; i < PFX##_count(_list1_); i++) \ - { \ - if (comparator(_list1_->buffer[i], _list2_->buffer[i]) != 0) \ - return false; \ - } \ - \ - return false; \ - } \ - \ - cmc_string PFX##_to_string(SNAME *_list_) \ - { \ - cmc_string str; \ - SNAME *l_ = _list_; \ - const char *name = #SNAME; \ - \ - snprintf(str.s, cmc_string_len, cmc_string_fmt_list, \ - name, l_, l_->buffer, l_->capacity, l_->count); \ - \ - return str; \ - } \ - \ - SNAME##_iter *PFX##_iter_new(SNAME *target) \ - { \ - SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \ - \ - if (!iter) \ - return NULL; \ - \ - PFX##_iter_init(iter, target); \ - \ - return iter; \ - } \ - \ - void PFX##_iter_free(SNAME##_iter *iter) \ - { \ - free(iter); \ - } \ - \ - void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \ - { \ - iter->target = target; \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(target); \ - } \ - \ - bool PFX##_iter_start(SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->start; \ - } \ - \ - bool PFX##_iter_end(SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->end; \ - } \ - \ - void PFX##_iter_to_start(SNAME##_iter *iter) \ - { \ - if (!PFX##_empty(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ - } \ - } \ - \ - void PFX##_iter_to_end(SNAME##_iter *iter) \ - { \ - if (!PFX##_empty(iter->target)) \ - { \ - iter->start = PFX##_empty(iter->target); \ - iter->cursor = PFX##_empty(iter->target) ? 0 : iter->target->count - 1; \ - iter->end = true; \ - } \ - } \ - \ - bool PFX##_iter_next(SNAME##_iter *iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == PFX##_count(iter->target)) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool PFX##_iter_prev(SNAME##_iter *iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \ - return false; \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the given index */ \ - bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \ - { \ - if (index >= PFX##_count(iter->target)) \ - return false; \ - \ - if (iter->cursor > index) \ - return PFX##_iter_rewind(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return PFX##_iter_advance(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V PFX##_iter_value(SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return PFX##_impl_default_value(); \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *PFX##_iter_rvalue(SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t PFX##_iter_index(SNAME##_iter *iter) \ - { \ - return iter->cursor; \ - } \ - \ - static bool PFX##_impl_grow(SNAME *_list_, size_t required) \ - { \ - size_t new_capacity = _list_->capacity * 2; \ - \ - if (new_capacity < required) \ - new_capacity = required; \ - \ - V *new_buffer = realloc(_list_->buffer, sizeof(V) * new_capacity); \ - \ - if (!new_buffer) \ - return false; \ - \ - _list_->buffer = new_buffer; \ - _list_->capacity = new_capacity; \ - \ - return true; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _list_); \ - PFX##_iter_to_start(&iter); \ - \ - return iter; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _list_); \ - PFX##_iter_to_end(&iter); \ - \ - return iter; \ +#define CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) \ + \ + /* Implementation Detail Functions */ \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \ + \ + SNAME *PFX##_new(size_t capacity) \ + { \ + if (capacity < 1) \ + return NULL; \ + \ + SNAME *_list_ = malloc(sizeof(SNAME)); \ + \ + if (!_list_) \ + return NULL; \ + \ + _list_->buffer = malloc(capacity * sizeof(V)); \ + \ + if (!_list_->buffer) \ + { \ + free(_list_); \ + return NULL; \ + } \ + \ + memset(_list_->buffer, 0, capacity * sizeof(V)); \ + \ + _list_->capacity = capacity; \ + _list_->count = 0; \ + \ + _list_->it_start = PFX##_impl_it_start; \ + _list_->it_end = PFX##_impl_it_end; \ + \ + return _list_; \ + } \ + \ + SNAME *PFX##_new_from(V *elements, size_t size) \ + { \ + if (size == 0) \ + return NULL; \ + \ + SNAME *_list_ = PFX##_new(size + size / 2); \ + \ + if (!_list_) \ + return NULL; \ + \ + memcpy(_list_->buffer, elements, size * sizeof(V)); \ + \ + _list_->count = size; \ + \ + return _list_; \ + } \ + \ + void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \ + { \ + if (deallocator) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + deallocator(_list_->buffer[i]); \ + } \ + \ + memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ + \ + _list_->count = 0; \ + } \ + \ + void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \ + { \ + if (deallocator) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + deallocator(_list_->buffer[i]); \ + } \ + \ + free(_list_->buffer); \ + free(_list_); \ + } \ + \ + bool PFX##_push_front(SNAME *_list_, V element) \ + { \ + if (PFX##_full(_list_)) \ + { \ + if (!PFX##_resize(_list_, PFX##_count(_list_) * 2)) \ + return false; \ + } \ + \ + if (!PFX##_empty(_list_)) \ + { \ + memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(V)); \ + } \ + \ + _list_->buffer[0] = element; \ + \ + _list_->count++; \ + \ + return true; \ + } \ + \ + bool PFX##_push_at(SNAME *_list_, V element, size_t index) \ + { \ + if (index > _list_->count) \ + return false; \ + \ + if (PFX##_full(_list_)) \ + { \ + if (!PFX##_resize(_list_, PFX##_count(_list_) * 2)) \ + return false; \ + } \ + \ + memmove(_list_->buffer + index + 1, _list_->buffer + index, \ + (_list_->count - index) * sizeof(V)); \ + \ + _list_->buffer[index] = element; \ + _list_->count++; \ + \ + return true; \ + } \ + \ + bool PFX##_push_back(SNAME *_list_, V element) \ + { \ + if (PFX##_full(_list_)) \ + { \ + if (!PFX##_resize(_list_, PFX##_count(_list_) * 2)) \ + return false; \ + } \ + \ + _list_->buffer[_list_->count++] = element; \ + \ + return true; \ + } \ + \ + bool PFX##_pop_front(SNAME *_list_) \ + { \ + if (PFX##_empty(_list_)) \ + return false; \ + \ + memmove(_list_->buffer, _list_->buffer + 1, _list_->count * sizeof(V)); \ + \ + _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ + \ + return true; \ + } \ + \ + bool PFX##_pop_at(SNAME *_list_, size_t index) \ + { \ + if (index >= _list_->count) \ + return false; \ + \ + memmove(_list_->buffer + index, _list_->buffer + index + 1, \ + (_list_->count - index) * sizeof(V)); \ + \ + _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ + \ + return true; \ + } \ + \ + bool PFX##_pop_back(SNAME *_list_) \ + { \ + if (PFX##_empty(_list_)) \ + return false; \ + \ + _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ + \ + return true; \ + } \ + \ + bool PFX##_seq_push_front(SNAME *_list_, V *elements, size_t size) \ + { \ + if (size == 0) \ + return false; \ + \ + if (!PFX##_fits(_list_, size)) \ + { \ + if (!PFX##_resize(_list_, PFX##_count(_list_) + size)) \ + return false; \ + } \ + \ + memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(V)); \ + \ + memcpy(_list_->buffer, elements, size * sizeof(V)); \ + \ + _list_->count += size; \ + \ + return true; \ + } \ + \ + bool PFX##_seq_push_at(SNAME *_list_, V *elements, size_t size, size_t index) \ + { \ + if (size == 0 || index > _list_->count) \ + return false; \ + \ + if (index == 0) \ + return PFX##_seq_push_front(_list_, elements, size); \ + else if (index == _list_->count) \ + return PFX##_seq_push_back(_list_, elements, size); \ + else \ + { \ + if (!PFX##_fits(_list_, size)) \ + { \ + if (!PFX##_resize(_list_, PFX##_count(_list_) + size)) \ + return false; \ + } \ + \ + memmove(_list_->buffer + index + size, _list_->buffer + index, \ + (_list_->count - index) * sizeof(V)); \ + \ + memcpy(_list_->buffer + index, elements, size * sizeof(V)); \ + \ + _list_->count += size; \ + } \ + \ + return true; \ + } \ + \ + bool PFX##_seq_push_back(SNAME *_list_, V *elements, size_t size) \ + { \ + if (size == 0) \ + return false; \ + \ + if (!PFX##_fits(_list_, size)) \ + { \ + if (!PFX##_resize(_list_, _list_->count + size)) \ + return false; \ + } \ + \ + memcpy(_list_->buffer + _list_->count, elements, size * sizeof(V)); \ + \ + _list_->count += size; \ + \ + return true; \ + } \ + \ + bool PFX##_seq_pop_at(SNAME *_list_, size_t from, size_t to) \ + { \ + if (from > to || to >= _list_->count) \ + return false; \ + \ + size_t length = (to - from + 1); \ + \ + memmove(_list_->buffer + from, _list_->buffer + to + 1, \ + (_list_->count - to - 1) * sizeof(V)); \ + \ + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ + \ + _list_->count -= to - from + 1; \ + \ + return true; \ + } \ + \ + SNAME *PFX##_seq_sublist(SNAME *_list_, size_t from, size_t to) \ + { \ + if (from > to || to >= _list_->count) \ + return false; \ + \ + size_t length = to - from + 1; \ + \ + SNAME *result = PFX##_new(length); \ + \ + if (!result) \ + return NULL; \ + \ + memcpy(result->buffer, _list_->buffer, _list_->count * sizeof(V)); \ + \ + memmove(_list_->buffer + from, _list_->buffer + to + 1, \ + (_list_->count - to - 1) * sizeof(V)); \ + \ + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ + \ + _list_->count -= length; \ + result->count = length; \ + \ + return result; \ + } \ + \ + V PFX##_front(SNAME *_list_) \ + { \ + if (PFX##_empty(_list_)) \ + return PFX##_impl_default_value(); \ + \ + return _list_->buffer[0]; \ + } \ + \ + V PFX##_get(SNAME *_list_, size_t index) \ + { \ + if (index >= _list_->count || PFX##_empty(_list_)) \ + return PFX##_impl_default_value(); \ + \ + return _list_->buffer[index]; \ + } \ + \ + V *PFX##_get_ref(SNAME *_list_, size_t index) \ + { \ + if (index >= _list_->count) \ + return NULL; \ + \ + if (PFX##_empty(_list_)) \ + return NULL; \ + \ + return &(_list_->buffer[index]); \ + } \ + \ + V PFX##_back(SNAME *_list_) \ + { \ + if (PFX##_empty(_list_)) \ + return PFX##_impl_default_value(); \ + \ + return _list_->buffer[_list_->count - 1]; \ + } \ + \ + size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start) \ + { \ + if (from_start) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (comparator(_list_->buffer[i], element) == 0) \ + return i; \ + } \ + } \ + else \ + { \ + for (size_t i = _list_->count; i > 0; i--) \ + { \ + if (comparator(_list_->buffer[i - 1], element) == 0) \ + return i - 1; \ + } \ + } \ + \ + return _list_->count; \ + } \ + \ + bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (comparator(_list_->buffer[i], element) == 0) \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool PFX##_empty(SNAME *_list_) \ + { \ + return _list_->count == 0; \ + } \ + \ + bool PFX##_full(SNAME *_list_) \ + { \ + return _list_->count >= _list_->capacity; \ + } \ + \ + size_t PFX##_count(SNAME *_list_) \ + { \ + return _list_->count; \ + } \ + \ + bool PFX##_fits(SNAME *_list_, size_t size) \ + { \ + return _list_->count + size <= _list_->capacity; \ + } \ + \ + size_t PFX##_capacity(SNAME *_list_) \ + { \ + return _list_->capacity; \ + } \ + \ + bool PFX##_resize(SNAME *_list_, size_t capacity) \ + { \ + if (capacity < PFX##_count(_list_)) \ + return false; \ + \ + V *new_buffer = realloc(_list_->buffer, sizeof(V) * capacity); \ + \ + if (!new_buffer) \ + return false; \ + \ + _list_->buffer = new_buffer; \ + _list_->capacity = capacity; \ + \ + return true; \ + } \ + \ + SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)) \ + { \ + SNAME *result = PFX##_new(_list_->capacity); \ + \ + if (!result) \ + return NULL; \ + \ + if (copy_func) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + result->buffer[i] = copy_func(_list_->buffer[i]); \ + } \ + else \ + memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ + \ + result->count = _list_->count; \ + \ + return result; \ + } \ + \ + bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)) \ + { \ + if (PFX##_count(_list1_) != PFX##_count(_list2_)) \ + return false; \ + \ + for (size_t i = 0; i < PFX##_count(_list1_); i++) \ + { \ + if (comparator(_list1_->buffer[i], _list2_->buffer[i]) != 0) \ + return false; \ + } \ + \ + return false; \ + } \ + \ + cmc_string PFX##_to_string(SNAME *_list_) \ + { \ + cmc_string str; \ + SNAME *l_ = _list_; \ + const char *name = #SNAME; \ + \ + snprintf(str.s, cmc_string_len, cmc_string_fmt_list, \ + name, l_, l_->buffer, l_->capacity, l_->count); \ + \ + return str; \ + } \ + \ + SNAME##_iter *PFX##_iter_new(SNAME *target) \ + { \ + SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \ + \ + if (!iter) \ + return NULL; \ + \ + PFX##_iter_init(iter, target); \ + \ + return iter; \ + } \ + \ + void PFX##_iter_free(SNAME##_iter *iter) \ + { \ + free(iter); \ + } \ + \ + void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \ + { \ + iter->target = target; \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = PFX##_empty(target); \ + } \ + \ + bool PFX##_iter_start(SNAME##_iter *iter) \ + { \ + return PFX##_empty(iter->target) || iter->start; \ + } \ + \ + bool PFX##_iter_end(SNAME##_iter *iter) \ + { \ + return PFX##_empty(iter->target) || iter->end; \ + } \ + \ + void PFX##_iter_to_start(SNAME##_iter *iter) \ + { \ + if (!PFX##_empty(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = PFX##_empty(iter->target); \ + } \ + } \ + \ + void PFX##_iter_to_end(SNAME##_iter *iter) \ + { \ + if (!PFX##_empty(iter->target)) \ + { \ + iter->start = PFX##_empty(iter->target); \ + iter->cursor = PFX##_empty(iter->target) ? 0 : iter->target->count - 1; \ + iter->end = true; \ + } \ + } \ + \ + bool PFX##_iter_next(SNAME##_iter *iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == PFX##_count(iter->target)) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = PFX##_empty(iter->target); \ + \ + iter->cursor++; \ + \ + return true; \ + } \ + \ + bool PFX##_iter_prev(SNAME##_iter *iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = PFX##_empty(iter->target); \ + \ + iter->cursor--; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \ + return false; \ + \ + iter->start = PFX##_empty(iter->target); \ + \ + iter->cursor += steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor < steps) \ + return false; \ + \ + iter->end = PFX##_empty(iter->target); \ + \ + iter->cursor -= steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the given index */ \ + bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \ + { \ + if (index >= PFX##_count(iter->target)) \ + return false; \ + \ + if (iter->cursor > index) \ + return PFX##_iter_rewind(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return PFX##_iter_advance(iter, index - iter->cursor); \ + \ + return true; \ + } \ + \ + V PFX##_iter_value(SNAME##_iter *iter) \ + { \ + if (PFX##_empty(iter->target)) \ + return PFX##_impl_default_value(); \ + \ + return iter->target->buffer[iter->cursor]; \ + } \ + \ + V *PFX##_iter_rvalue(SNAME##_iter *iter) \ + { \ + if (PFX##_empty(iter->target)) \ + return NULL; \ + \ + return &(iter->target->buffer[iter->cursor]); \ + } \ + \ + size_t PFX##_iter_index(SNAME##_iter *iter) \ + { \ + return iter->cursor; \ + } \ + \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \ + { \ + SNAME##_iter iter; \ + \ + PFX##_iter_init(&iter, _list_); \ + PFX##_iter_to_start(&iter); \ + \ + return iter; \ + } \ + \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \ + { \ + SNAME##_iter iter; \ + \ + PFX##_iter_init(&iter, _list_); \ + PFX##_iter_to_end(&iter); \ + \ + return iter; \ } #endif /* CMC_LIST_H */ diff --git a/tests/main/unt/deque.c b/tests/main/unt/deque.c index b1bb3c5..4b65f55 100644 --- a/tests/main/unt/deque.c +++ b/tests/main/unt/deque.c @@ -19,13 +19,13 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { deque *d = d_new(0); cmc_assert_equals(ptr, NULL, d); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { deque *d = d_new(UINT64_MAX); cmc_assert_equals(ptr, NULL, d); @@ -49,7 +49,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { + CMC_CREATE_TEST(buffer_growth[capacity = 1], { deque *d = d_new(1); cmc_assert_not_equals(ptr, NULL, d); @@ -63,7 +63,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(buffer_growth[item_preservation], { + CMC_CREATE_TEST(buffer_growth[item preservation], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -100,7 +100,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(push_front[item_preservation], { + CMC_CREATE_TEST(push_front[item preservation], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -134,7 +134,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(push_back[item_preservation], { + CMC_CREATE_TEST(push_back[item preservation], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -172,7 +172,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(pop_front[item_preservation], { + CMC_CREATE_TEST(pop_front[item preservation], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -213,7 +213,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(pop_back[item_preservation], { + CMC_CREATE_TEST(pop_back[item preservation], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -300,7 +300,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(front[edge_case count = 0], { + CMC_CREATE_TEST(front[count = 0], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -341,7 +341,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(back[edge_case count = 0], { + CMC_CREATE_TEST(back[count = 0], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -404,7 +404,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(contains[edge_case count = 0], { + CMC_CREATE_TEST(contains[count = 0], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -414,7 +414,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(contains[edge_case count = 1], { + CMC_CREATE_TEST(contains[count = 1], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -509,7 +509,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d, NULL); }); - CMC_CREATE_TEST(resize[item_preservation], { + CMC_CREATE_TEST(resize[item preservation], { deque *d = d_new(100); cmc_assert_not_equals(ptr, NULL, d); @@ -616,7 +616,7 @@ CMC_CREATE_UNIT(deque_test, true, { d_free(d2, NULL); }); - CMC_CREATE_TEST(equals[edge_case count = 0], { + CMC_CREATE_TEST(equals[count = 0], { deque *d1 = d_new(100); cmc_assert_not_equals(ptr, NULL, d1); diff --git a/tests/main/unt/hashmap.c b/tests/main/unt/hashmap.c index 7fe20be..b020096 100644 --- a/tests/main/unt/hashmap.c +++ b/tests/main/unt/hashmap.c @@ -19,13 +19,13 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { hashmap *map = hm_new(0, 0.6, cmp, hash); cmc_assert_equals(ptr, NULL, map); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { hashmap *map = hm_new(UINT64_MAX, 0.99, cmp, hash); cmc_assert_equals(ptr, NULL, map); @@ -59,7 +59,7 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); - CMC_CREATE_TEST(insert[edge_case smallest capacity], { + CMC_CREATE_TEST(insert[smallest capacity], { hashmap *map = hm_new(1, 0.99, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -190,7 +190,7 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); - CMC_CREATE_TEST(remove[edge_case count = 0], { + CMC_CREATE_TEST(remove[count = 0], { hashmap *map = hm_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -233,7 +233,7 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); - CMC_CREATE_TEST(max[edge_case count = 0], { + CMC_CREATE_TEST(max[count = 0], { hashmap *map = hm_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -261,7 +261,7 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); - CMC_CREATE_TEST(min[edge_case count = 0], { + CMC_CREATE_TEST(min[count = 0], { hashmap *map = hm_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -283,7 +283,7 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); - CMC_CREATE_TEST(get[edge_case count = 0], { + CMC_CREATE_TEST(get[count = 0], { hashmap *map = hm_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -308,7 +308,7 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); - CMC_CREATE_TEST(get_ref[edge_case count = 0], { + CMC_CREATE_TEST(get_ref[count = 0], { hashmap *map = hm_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -330,6 +330,16 @@ CMC_CREATE_UNIT(hashmap_test, true, { hm_free(map, NULL); }); + CMC_CREATE_TEST(contains[count = 0], { + hashmap *map = hm_new(100, 0.6, cmp, hash); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert(!hm_contains(map, 987654321)); + + hm_free(map, NULL); + }); + CMC_CREATE_TEST(contains[sum], { hashmap *map = hm_new(100, 0.6, cmp, hash); diff --git a/tests/main/unt/hashset.c b/tests/main/unt/hashset.c index a3d8d48..2bb3991 100644 --- a/tests/main/unt/hashset.c +++ b/tests/main/unt/hashset.c @@ -19,13 +19,13 @@ CMC_CREATE_UNIT(hashset_test, true, { hs_free(set, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { hashset *set = hs_new(0, 0.6, cmp, hash); cmc_assert_equals(ptr, NULL, set); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { hashset *set = hs_new(UINT64_MAX, 0.99, cmp, hash); cmc_assert_equals(ptr, NULL, set); @@ -59,7 +59,7 @@ CMC_CREATE_UNIT(hashset_test, true, { hs_free(set, NULL); }); - CMC_CREATE_TEST(insert[edge_case smallest capacity], { + CMC_CREATE_TEST(insert[smallest capacity], { hashset *set = hs_new(1, 0.99, cmp, hash); cmc_assert_not_equals(ptr, NULL, set); @@ -162,7 +162,7 @@ CMC_CREATE_UNIT(hashset_test, true, { hs_free(set, NULL); }); - CMC_CREATE_TEST(remove[edge_case count = 0], { + CMC_CREATE_TEST(remove[count = 0], { hashset *set = hs_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, set); @@ -203,7 +203,7 @@ CMC_CREATE_UNIT(hashset_test, true, { hs_free(set, NULL); }); - CMC_CREATE_TEST(max[edge_case count = 0], { + CMC_CREATE_TEST(max[count = 0], { hashset *set = hs_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, set); @@ -229,7 +229,7 @@ CMC_CREATE_UNIT(hashset_test, true, { hs_free(set, NULL); }); - CMC_CREATE_TEST(min[edge_case count = 0], { + CMC_CREATE_TEST(min[count = 0], { hashset *set = hs_new(100, 0.6, cmp, hash); cmc_assert_not_equals(ptr, NULL, set); @@ -251,6 +251,16 @@ CMC_CREATE_UNIT(hashset_test, true, { hs_free(set, NULL); }); + CMC_CREATE_TEST(contains[count = 0], { + hashset *set = hs_new(100, 0.6, cmp, hash); + + cmc_assert_not_equals(ptr, NULL, set); + + cmc_assert(!hs_contains(set, 987654321)); + + hs_free(set, NULL); + }); + CMC_CREATE_TEST(contains[sum], { hashset *set = hs_new(100, 0.6, cmp, hash); diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index 365ef89..8eebd44 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -55,10 +55,110 @@ CMC_CREATE_UNIT(heap_test, true, { cmc_assert_not_equals(ptr, NULL, h); for (size_t i = 0; i < 50; i++) - h_insert(h, i); + cmc_assert(h_insert(h, i)); cmc_assert_equals(size_t, 50, h_count(h)); h_free(h, NULL); }); + + CMC_CREATE_TEST(insert, { + heap *h = h_new(100, cmc_max_heap, cmp); + + cmc_assert_not_equals(ptr, NULL, h); + + cmc_assert(h_insert(h, 10)); + + h_free(h, NULL); + }); + + CMC_CREATE_TEST(insert[item preservation], { + heap *h = h_new(50, cmc_max_heap, cmp); + + cmc_assert_not_equals(ptr, NULL, h); + + for (size_t i = 0; i <= 100; i++) + cmc_assert(h_insert(h, i)); + + size_t sum = 0; + for (size_t i = 0; i < h_count(h); i++) + sum += h->buffer[i]; + + cmc_assert_equals(size_t, 5050, sum); + + h_free(h, NULL); + }); + + CMC_CREATE_TEST(remove, { + heap *h = h_new(50, cmc_max_heap, cmp); + + cmc_assert_not_equals(ptr, NULL, h); + + for (size_t i = 0; i <= 100; i++) + cmc_assert(h_insert(h, i)); + + size_t r; + cmc_assert(h_remove(h, &r)); + + cmc_assert_equals(size_t, 100, r); + + h_free(h, NULL); + }); + + CMC_CREATE_TEST(remove[count = 0], { + heap *h = h_new(100, cmc_max_heap, cmp); + + cmc_assert_not_equals(ptr, NULL, h); + + size_t _; + cmc_assert(!h_remove(h, &_)); + + h_free(h, NULL); + }); + + CMC_CREATE_TEST(remove[sorted], { + heap *h = h_new(100, cmc_min_heap, cmp); + + cmc_assert_not_equals(ptr, NULL, h); + + for (size_t i = 1; i <= 100; i++) + cmc_assert(h_insert(h, i)); + + size_t r; + size_t i = 0; + size_t arr[100]; + while (!h_empty(h)) + { + cmc_assert(h_remove(h, &r)); + + arr[i++] = r; + } + + cmc_assert_array_sorted_any(size_t, arr, cmp, 0, 99); + + h_free(h, NULL); + }); + + CMC_CREATE_TEST(peek, { + heap *h = h_new(100, cmc_max_heap, cmp); + + cmc_assert_not_equals(ptr, NULL, h); + + for (size_t i = 1; i <= 100; i++) + cmc_assert(h_insert(h, i)); + + cmc_assert_equals(size_t, 100, h_peek(h)); + + h_free(h, NULL); + }); + + CMC_CREATE_TEST(peek[count = 0], { + heap *h = h_new(100, cmc_max_heap, cmp); + + cmc_assert_not_equals(ptr, NULL, h); + + cmc_assert_equals(size_t, h_impl_default_value(), h_peek(h)); + + h_free(h, NULL); + }); }); diff --git a/tests/main/unt/intervalheap.c b/tests/main/unt/intervalheap.c index 0dd3e14..4fefced 100644 --- a/tests/main/unt/intervalheap.c +++ b/tests/main/unt/intervalheap.c @@ -19,7 +19,7 @@ CMC_CREATE_UNIT(intervalheap_test, true, { ih_free(ih, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { intervalheap *ih = ih_new(0, cmp); cmc_assert_equals(ptr, NULL, ih); @@ -28,7 +28,7 @@ CMC_CREATE_UNIT(intervalheap_test, true, { ih_free(ih, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { intervalheap *ih = ih_new(UINT64_MAX, cmp); cmc_assert_equals(ptr, NULL, ih); @@ -55,7 +55,7 @@ CMC_CREATE_UNIT(intervalheap_test, true, { ih_free(ih, NULL); }); - CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { + CMC_CREATE_TEST(buffer_growth[capacity = 1], { intervalheap *ih = ih_new(1, cmp); cmc_assert_not_equals(ptr, NULL, ih); diff --git a/tests/main/unt/linkedlist.c b/tests/main/unt/linkedlist.c index bb45f8c..f377165 100644 --- a/tests/main/unt/linkedlist.c +++ b/tests/main/unt/linkedlist.c @@ -36,7 +36,7 @@ CMC_CREATE_UNIT(linkedlist_test, true, { ll_free(ll, NULL); }); - CMC_CREATE_TEST(clear[edge_case count = 0], { + CMC_CREATE_TEST(clear[count = 0], { linkedlist *ll = ll_new(); cmc_assert_not_equals(ptr, NULL, ll); @@ -62,7 +62,7 @@ CMC_CREATE_UNIT(linkedlist_test, true, { ll_free(ll, NULL); }); - CMC_CREATE_TEST(push_front[item_preservation], { + CMC_CREATE_TEST(push_front[item preservation], { linkedlist *ll = ll_new(); cmc_assert_not_equals(ptr, NULL, ll); diff --git a/tests/main/unt/list.c b/tests/main/unt/list.c index 69dcab5..2740e03 100644 --- a/tests/main/unt/list.c +++ b/tests/main/unt/list.c @@ -19,19 +19,19 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { list *l = l_new(0); cmc_assert_equals(ptr, NULL, l); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { list *l = l_new(UINT64_MAX); cmc_assert_equals(ptr, NULL, l); }); - CMC_CREATE_TEST(new_from[count item_preservation], { + CMC_CREATE_TEST(new_from[count and item preservation], { size_t v[5]; for (size_t i = 0; i < 5; i++) @@ -49,7 +49,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(new_from[edge_case size = 1], { + CMC_CREATE_TEST(new_from[size = 1], { size_t a = 10; size_t *values = &a; @@ -79,7 +79,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { + CMC_CREATE_TEST(buffer_growth[capacity = 1], { list *l = l_new(1); cmc_assert_not_equals(ptr, NULL, l); @@ -121,7 +121,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(push_front[item_preservation], { + CMC_CREATE_TEST(push_front[item preservation], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -135,7 +135,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(push[count], { + CMC_CREATE_TEST(push_at[count], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -151,7 +151,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(push[capacity], { + CMC_CREATE_TEST(push_at[capacity], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -167,7 +167,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(push[item_preservation], { + CMC_CREATE_TEST(push_at[item preservation], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -210,7 +210,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(push_back[item_preservation], { + CMC_CREATE_TEST(push_back[item preservation], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -237,7 +237,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(pop_front[item_preservation], { + CMC_CREATE_TEST(pop_front[item preservation], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -253,7 +253,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(pop_front[edge_case count = 0], { + CMC_CREATE_TEST(pop_front[count = 0], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -262,7 +262,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(pop_front[edge_case count = 1], { + CMC_CREATE_TEST(pop_front[count = 1], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -286,7 +286,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(pop_at[edge_case count = 0], { + CMC_CREATE_TEST(pop_at[count = 0], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -295,7 +295,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(pop_at[edge_case count = 1], { + CMC_CREATE_TEST(pop_at[count = 1], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -319,7 +319,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(pop_back[edge_case count = 0], { + CMC_CREATE_TEST(pop_back[count = 0], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); @@ -328,7 +328,7 @@ CMC_CREATE_UNIT(list_test, true, { l_free(l, NULL); }); - CMC_CREATE_TEST(pop_back[edge_case count = 1], { + CMC_CREATE_TEST(pop_back[count = 1], { list *l = l_new(100); cmc_assert_not_equals(ptr, NULL, l); diff --git a/tests/main/unt/multimap.c b/tests/main/unt/multimap.c index 6ccb049..1581953 100644 --- a/tests/main/unt/multimap.c +++ b/tests/main/unt/multimap.c @@ -19,13 +19,13 @@ CMC_CREATE_UNIT(multimap_test, true, { mm_free(map, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { multimap *map = mm_new(0, 0.8, cmp, hash); cmc_assert_equals(ptr, NULL, map); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { multimap *map = mm_new(UINT64_MAX, 0.99, cmp, hash); cmc_assert_equals(ptr, NULL, map); @@ -79,7 +79,7 @@ CMC_CREATE_UNIT(multimap_test, true, { mm_free(map, NULL); }); - CMC_CREATE_TEST(remove[edge_case count = 0], { + CMC_CREATE_TEST(remove[count = 0], { multimap *map = mm_new(100, 0.8, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -91,7 +91,7 @@ CMC_CREATE_UNIT(multimap_test, true, { mm_free(map, NULL); }); - CMC_CREATE_TEST(remove[edge_case count = 1], { + CMC_CREATE_TEST(remove[count = 1], { multimap *map = mm_new(100, 0.8, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); @@ -104,7 +104,7 @@ CMC_CREATE_UNIT(multimap_test, true, { mm_free(map, NULL); }); - CMC_CREATE_TEST(get[key_ordering], { + CMC_CREATE_TEST(get[key ordering], { multimap *map = mm_new(100, 0.8, cmp, hash); cmc_assert_not_equals(ptr, NULL, map); diff --git a/tests/main/unt/multiset.c b/tests/main/unt/multiset.c index 98e2083..262ce69 100644 --- a/tests/main/unt/multiset.c +++ b/tests/main/unt/multiset.c @@ -19,13 +19,13 @@ CMC_CREATE_UNIT(multiset_test, true, { ms_free(set, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { multiset *set = ms_new(0, 0.6, cmp, hash); cmc_assert_equals(ptr, NULL, set); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { multiset *set = ms_new(UINT64_MAX, 0.99, cmp, hash); cmc_assert_equals(ptr, NULL, set); diff --git a/tests/main/unt/queue.c b/tests/main/unt/queue.c index 1938460..165482e 100644 --- a/tests/main/unt/queue.c +++ b/tests/main/unt/queue.c @@ -20,13 +20,13 @@ CMC_CREATE_UNIT(queue_test, true, { q_free(q, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { queue *q = q_new(0); cmc_assert_equals(ptr, NULL, q); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { queue *q = q_new(UINT64_MAX); cmc_assert_equals(ptr, NULL, q); @@ -50,7 +50,7 @@ CMC_CREATE_UNIT(queue_test, true, { q_free(q, NULL); }); - CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { + CMC_CREATE_TEST(buffer_growth[capacity = 1], { queue *q = q_new(1); cmc_assert_not_equals(ptr, NULL, q); diff --git a/tests/main/unt/sortedlist.c b/tests/main/unt/sortedlist.c index cb3a565..21eda65 100644 --- a/tests/main/unt/sortedlist.c +++ b/tests/main/unt/sortedlist.c @@ -20,13 +20,13 @@ CMC_CREATE_UNIT(sortedlist_test, true, { sl_free(sl, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { sortedlist *sl = sl_new(0, cmp); cmc_assert_equals(ptr, NULL, sl); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { sortedlist *sl = sl_new(UINT64_MAX, cmp); cmc_assert_equals(ptr, NULL, sl); @@ -50,7 +50,7 @@ CMC_CREATE_UNIT(sortedlist_test, true, { sl_free(sl, NULL); }); - CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { + CMC_CREATE_TEST(buffer_growth[capacity = 1], { sortedlist *sl = sl_new(1, cmp); cmc_assert_not_equals(ptr, NULL, sl); diff --git a/tests/main/unt/stack.c b/tests/main/unt/stack.c index f60b04b..e9df04b 100644 --- a/tests/main/unt/stack.c +++ b/tests/main/unt/stack.c @@ -20,13 +20,13 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(new[edge_case capacity = 0], { + CMC_CREATE_TEST(new[capacity = 0], { stack *s = s_new(0); cmc_assert_equals(ptr, NULL, s); }); - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { stack *s = s_new(UINT64_MAX); cmc_assert_equals(ptr, NULL, s); @@ -50,7 +50,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { + CMC_CREATE_TEST(buffer_growth[capacity = 1], { stack *s = s_new(1); cmc_assert_not_equals(ptr, NULL, s); @@ -90,7 +90,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(push[item_preservation], { + CMC_CREATE_TEST(push[item preservation], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -134,7 +134,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(pop[item_preservation], { + CMC_CREATE_TEST(pop[item preservation], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -151,7 +151,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(pop[edge_case count = 0], { + CMC_CREATE_TEST(pop[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -177,7 +177,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(top[edge_case count = 0], { + CMC_CREATE_TEST(top[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -191,7 +191,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(top[edge_case count = 1], { + CMC_CREATE_TEST(top[count = 1], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -217,7 +217,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(contains[edge_case count = 0], { + CMC_CREATE_TEST(contains[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -262,7 +262,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(full[edge_case capacity = 1], { + CMC_CREATE_TEST(full[capacity = 1], { stack *s = s_new(1); cmc_assert_not_equals(ptr, NULL, s); @@ -287,7 +287,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(iter_init[edge_case count = 0], { + CMC_CREATE_TEST(iter_init[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -304,7 +304,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(iter_start[edge_case count = 0], { + CMC_CREATE_TEST(iter_start[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -318,7 +318,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(iter_end[edge_case count = 0], { + CMC_CREATE_TEST(iter_end[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -389,7 +389,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(iteration[edge_case count = 1], { + CMC_CREATE_TEST(iteration[count = 1], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -412,7 +412,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(iteration[edge_case count = capacity], { + CMC_CREATE_TEST(iteration[count = capacity], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -517,7 +517,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(iter_value[edge_case count = 0], { + CMC_CREATE_TEST(iter_value[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -531,7 +531,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(iter_rvalue[edge_case count = 0], { + CMC_CREATE_TEST(iter_rvalue[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s); @@ -584,7 +584,7 @@ CMC_CREATE_UNIT(stack_test, true, { s_free(s, NULL); }); - CMC_CREATE_TEST(index[edge_case count = 0], { + CMC_CREATE_TEST(index[count = 0], { stack *s = s_new(100); cmc_assert_not_equals(ptr, NULL, s);