diff --git a/src/cmc/queue.h b/src/cmc/queue.h index 33c8bf8..52e7292 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -112,6 +112,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " "count:%" PRIuMAX ", " "front:%" PRIuMAX ", " "back:%" PRIuMAX ", " + "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }"; @@ -277,511 +278,511 @@ struct cmc_callbacks_queue /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_queue_); \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_queue_); \ - \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_queue_) \ - return NULL; \ - \ - _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_queue_->buffer) \ - { \ - alloc->free(_queue_); \ - return NULL; \ - } \ - \ - _queue_->capacity = capacity; \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - _queue_->flag = cmc_flags.OK; \ - _queue_->f_val = f_val; \ - _queue_->alloc = alloc; \ - _queue_->callbacks = NULL; \ - _queue_->it_start = PFX##_impl_it_start; \ - _queue_->it_end = PFX##_impl_it_end; \ - \ - return _queue_; \ - } \ - \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_ftab_val *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks_queue *callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_queue_) \ - return NULL; \ - \ - _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_queue_->buffer) \ - { \ - alloc->free(_queue_); \ - return NULL; \ - } \ - \ - _queue_->capacity = capacity; \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - _queue_->flag = cmc_flags.OK; \ - _queue_->f_val = f_val; \ - _queue_->alloc = alloc; \ - _queue_->callbacks = callbacks; \ - _queue_->it_start = PFX##_impl_it_start; \ - _queue_->it_end = PFX##_impl_it_end; \ - \ - return _queue_; \ - } \ - \ - void PFX##_clear(struct SNAME *_queue_) \ - { \ - if (_queue_->f_val->free) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - _queue_->f_val->free(_queue_->buffer[i]); \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - \ - memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \ - \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - } \ - \ - void PFX##_free(struct SNAME *_queue_) \ - { \ - if (_queue_->f_val->free) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - _queue_->f_val->free(_queue_->buffer[i]); \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - \ - _queue_->alloc->free(_queue_->buffer); \ - _queue_->alloc->free(_queue_); \ - } \ - \ - void PFX##_customize(struct SNAME *_queue_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks_queue *callbacks) \ - { \ - if (alloc) \ - _queue_->alloc = alloc; \ - \ - if (callbacks) \ - _queue_->callbacks = callbacks; \ - } \ - \ - bool PFX##_enqueue(struct SNAME *_queue_, V element) \ - { \ - if (PFX##_full(_queue_)) \ - { \ - if (!PFX##_resize(_queue_, PFX##_capacity(_queue_) * 2)) \ - return false; \ - } \ - \ - _queue_->buffer[_queue_->back] = element; \ - \ - _queue_->back = \ - (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \ - _queue_->count++; \ - \ - return true; \ - } \ - \ - bool PFX##_dequeue(struct SNAME *_queue_) \ - { \ - if (PFX##_empty(_queue_)) \ - return false; \ - \ - _queue_->buffer[_queue_->front] = (V){ 0 }; \ - \ - _queue_->front = (_queue_->front == _queue_->capacity - 1) \ - ? 0 \ - : _queue_->front + 1; \ - _queue_->count--; \ - \ - return true; \ - } \ - \ - V PFX##_peek(struct SNAME *_queue_) \ - { \ - if (PFX##_empty(_queue_)) \ - return (V){ 0 }; \ - \ - return _queue_->buffer[_queue_->front]; \ - } \ - \ - bool PFX##_contains(struct SNAME *_queue_, V element) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - if (_queue_->f_val->cmp(_queue_->buffer[i], element) == 0) \ - return true; \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - \ - return false; \ - } \ - \ - bool PFX##_empty(struct SNAME *_queue_) \ - { \ - return _queue_->count == 0; \ - } \ - \ - bool PFX##_full(struct SNAME *_queue_) \ - { \ - return _queue_->count >= _queue_->capacity; \ - } \ - \ - size_t PFX##_count(struct SNAME *_queue_) \ - { \ - return _queue_->count; \ - } \ - \ - size_t PFX##_capacity(struct SNAME *_queue_) \ - { \ - return _queue_->capacity; \ - } \ - \ - bool PFX##_resize(struct SNAME *_queue_, size_t capacity) \ - { \ - if (PFX##_capacity(_queue_) == capacity) \ - return true; \ - \ - if (capacity < PFX##_count(_queue_)) \ - return false; \ - \ - V *new_buffer = _queue_->alloc->malloc(sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - return false; \ - \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - new_buffer[j] = _queue_->buffer[i]; \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - \ - _queue_->alloc->free(_queue_->buffer); \ - \ - _queue_->buffer = new_buffer; \ - _queue_->capacity = capacity; \ - _queue_->front = 0; \ - _queue_->back = _queue_->count; \ - \ - return true; \ - } \ - \ - struct SNAME *PFX##_copy_of(struct SNAME *_queue_) \ - { \ - struct SNAME *result = \ - PFX##_new_custom(_queue_->capacity, _queue_->f_val, \ - _queue_->alloc, _queue_->callbacks); \ - \ - if (!result) \ - return NULL; \ - \ - if (_queue_->f_val->cpy) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - else \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - result->buffer[j] = _queue_->buffer[i]; \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - \ - result->count = _queue_->count; \ - result->front = 0; \ - result->back = _queue_->count; \ - \ - return result; \ - } \ - \ - bool PFX##_equals(struct SNAME *_queue1_, struct SNAME *_queue2_) \ - { \ - if (PFX##_count(_queue1_) != PFX##_count(_queue2_)) \ - return false; \ - \ - size_t i, j, k; \ - for (i = _queue1_->front, j = _queue2_->front, k = 0; \ - k < PFX##_count(_queue1_); k++) \ - { \ - if (_queue1_->f_val->cmp(_queue1_->buffer[i], \ - _queue2_->buffer[j]) != 0) \ - return false; \ - \ - i = (i + 1) % _queue1_->capacity; \ - j = (j + 1) % _queue2_->capacity; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string PFX##_to_string(struct SNAME *_queue_) \ - { \ - struct cmc_string str; \ - struct SNAME *q_ = _queue_; \ - \ - int n = \ - snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, #SNAME, #V, \ - q_, q_->buffer, q_->capacity, q_->count, q_->front, \ - q_->back, q_->f_val, q_->alloc, q_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ - { \ - struct SNAME##_iter *iter = \ - target->alloc->malloc(sizeof(struct SNAME##_iter)); \ - \ - if (!iter) \ - return NULL; \ - \ - PFX##_iter_init(iter, target); \ - \ - return iter; \ - } \ - \ - void PFX##_iter_free(struct SNAME##_iter *iter) \ - { \ - iter->target->alloc->free(iter); \ - } \ - \ - void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \ - { \ - iter->target = target; \ - iter->cursor = target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(target); \ - } \ - \ - bool PFX##_iter_start(struct SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->start; \ - } \ - \ - bool PFX##_iter_end(struct SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->end; \ - } \ - \ - void PFX##_iter_to_start(struct SNAME##_iter *iter) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ - } \ - \ - void PFX##_iter_to_end(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - iter->cursor = 0; \ - else \ - { \ - if (iter->target->back == 0) \ - iter->cursor = iter->target->capacity - 1; \ - else \ - iter->cursor = iter->target->back - 1; \ - } \ - \ - iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ - iter->end = true; \ - } \ - \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == PFX##_count(iter->target)) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ - : iter->cursor - 1; \ - iter->index--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == PFX##_count(iter->target)) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \ - return false; \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - iter->index += steps; \ - iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - iter->index -= steps; \ - \ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += PFX##_capacity(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(struct SNAME##_iter *iter, size_t index) \ - { \ - if (index >= PFX##_count(iter->target)) \ - return false; \ - \ - if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ - else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ - { \ - return iter->index; \ - } \ - \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_queue_) \ - { \ - struct SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _queue_); \ - PFX##_iter_to_start(&iter); \ - \ - return iter; \ - } \ - \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_queue_) \ - { \ - struct SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _queue_); \ - PFX##_iter_to_end(&iter); \ - \ - return iter; \ +#define CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) \ + \ + /* Implementation Detail Functions */ \ + static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_queue_); \ + static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_queue_); \ + \ + struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val) \ + { \ + struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ + \ + if (capacity < 1) \ + return NULL; \ + \ + if (!f_val) \ + return NULL; \ + \ + struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_queue_) \ + return NULL; \ + \ + _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ + \ + if (!_queue_->buffer) \ + { \ + alloc->free(_queue_); \ + return NULL; \ + } \ + \ + _queue_->capacity = capacity; \ + _queue_->count = 0; \ + _queue_->front = 0; \ + _queue_->back = 0; \ + _queue_->flag = cmc_flags.OK; \ + _queue_->f_val = f_val; \ + _queue_->alloc = alloc; \ + _queue_->callbacks = NULL; \ + _queue_->it_start = PFX##_impl_it_start; \ + _queue_->it_end = PFX##_impl_it_end; \ + \ + return _queue_; \ + } \ + \ + struct SNAME *PFX##_new_custom( \ + size_t capacity, struct SNAME##_ftab_val *f_val, \ + struct cmc_alloc_node *alloc, struct cmc_callbacks_queue *callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ + \ + if (!f_val) \ + return NULL; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_queue_) \ + return NULL; \ + \ + _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ + \ + if (!_queue_->buffer) \ + { \ + alloc->free(_queue_); \ + return NULL; \ + } \ + \ + _queue_->capacity = capacity; \ + _queue_->count = 0; \ + _queue_->front = 0; \ + _queue_->back = 0; \ + _queue_->flag = cmc_flags.OK; \ + _queue_->f_val = f_val; \ + _queue_->alloc = alloc; \ + _queue_->callbacks = callbacks; \ + _queue_->it_start = PFX##_impl_it_start; \ + _queue_->it_end = PFX##_impl_it_end; \ + \ + return _queue_; \ + } \ + \ + void PFX##_clear(struct SNAME *_queue_) \ + { \ + if (_queue_->f_val->free) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + _queue_->f_val->free(_queue_->buffer[i]); \ + \ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ + \ + memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \ + \ + _queue_->count = 0; \ + _queue_->front = 0; \ + _queue_->back = 0; \ + } \ + \ + void PFX##_free(struct SNAME *_queue_) \ + { \ + if (_queue_->f_val->free) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + _queue_->f_val->free(_queue_->buffer[i]); \ + \ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ + \ + _queue_->alloc->free(_queue_->buffer); \ + _queue_->alloc->free(_queue_); \ + } \ + \ + void PFX##_customize(struct SNAME *_queue_, struct cmc_alloc_node *alloc, \ + struct cmc_callbacks_queue *callbacks) \ + { \ + if (alloc) \ + _queue_->alloc = alloc; \ + \ + if (callbacks) \ + _queue_->callbacks = callbacks; \ + } \ + \ + bool PFX##_enqueue(struct SNAME *_queue_, V element) \ + { \ + if (PFX##_full(_queue_)) \ + { \ + if (!PFX##_resize(_queue_, PFX##_capacity(_queue_) * 2)) \ + return false; \ + } \ + \ + _queue_->buffer[_queue_->back] = element; \ + \ + _queue_->back = \ + (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \ + _queue_->count++; \ + \ + return true; \ + } \ + \ + bool PFX##_dequeue(struct SNAME *_queue_) \ + { \ + if (PFX##_empty(_queue_)) \ + return false; \ + \ + _queue_->buffer[_queue_->front] = (V){ 0 }; \ + \ + _queue_->front = (_queue_->front == _queue_->capacity - 1) \ + ? 0 \ + : _queue_->front + 1; \ + _queue_->count--; \ + \ + return true; \ + } \ + \ + V PFX##_peek(struct SNAME *_queue_) \ + { \ + if (PFX##_empty(_queue_)) \ + return (V){ 0 }; \ + \ + return _queue_->buffer[_queue_->front]; \ + } \ + \ + bool PFX##_contains(struct SNAME *_queue_, V element) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + if (_queue_->f_val->cmp(_queue_->buffer[i], element) == 0) \ + return true; \ + \ + i = (i + 1) % _queue_->capacity; \ + } \ + \ + return false; \ + } \ + \ + bool PFX##_empty(struct SNAME *_queue_) \ + { \ + return _queue_->count == 0; \ + } \ + \ + bool PFX##_full(struct SNAME *_queue_) \ + { \ + return _queue_->count >= _queue_->capacity; \ + } \ + \ + size_t PFX##_count(struct SNAME *_queue_) \ + { \ + return _queue_->count; \ + } \ + \ + size_t PFX##_capacity(struct SNAME *_queue_) \ + { \ + return _queue_->capacity; \ + } \ + \ + bool PFX##_resize(struct SNAME *_queue_, size_t capacity) \ + { \ + if (PFX##_capacity(_queue_) == capacity) \ + return true; \ + \ + if (capacity < PFX##_count(_queue_)) \ + return false; \ + \ + V *new_buffer = _queue_->alloc->malloc(sizeof(V) * capacity); \ + \ + if (!new_buffer) \ + return false; \ + \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + new_buffer[j] = _queue_->buffer[i]; \ + \ + i = (i + 1) % _queue_->capacity; \ + } \ + \ + _queue_->alloc->free(_queue_->buffer); \ + \ + _queue_->buffer = new_buffer; \ + _queue_->capacity = capacity; \ + _queue_->front = 0; \ + _queue_->back = _queue_->count; \ + \ + return true; \ + } \ + \ + struct SNAME *PFX##_copy_of(struct SNAME *_queue_) \ + { \ + struct SNAME *result = \ + PFX##_new_custom(_queue_->capacity, _queue_->f_val, \ + _queue_->alloc, _queue_->callbacks); \ + \ + if (!result) \ + return NULL; \ + \ + if (_queue_->f_val->cpy) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); \ + \ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ + else \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + result->buffer[j] = _queue_->buffer[i]; \ + \ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ + \ + result->count = _queue_->count; \ + result->front = 0; \ + result->back = _queue_->count; \ + \ + return result; \ + } \ + \ + bool PFX##_equals(struct SNAME *_queue1_, struct SNAME *_queue2_) \ + { \ + if (PFX##_count(_queue1_) != PFX##_count(_queue2_)) \ + return false; \ + \ + size_t i, j, k; \ + for (i = _queue1_->front, j = _queue2_->front, k = 0; \ + k < PFX##_count(_queue1_); k++) \ + { \ + if (_queue1_->f_val->cmp(_queue1_->buffer[i], \ + _queue2_->buffer[j]) != 0) \ + return false; \ + \ + i = (i + 1) % _queue1_->capacity; \ + j = (j + 1) % _queue2_->capacity; \ + } \ + \ + return true; \ + } \ + \ + struct cmc_string PFX##_to_string(struct SNAME *_queue_) \ + { \ + struct cmc_string str; \ + struct SNAME *q_ = _queue_; \ + \ + int n = \ + snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, #SNAME, #V, \ + q_, q_->buffer, q_->capacity, q_->count, q_->front, \ + q_->back, q_->flag, q_->f_val, q_->alloc, q_->callbacks); \ + \ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ + \ + struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ + { \ + struct SNAME##_iter *iter = \ + target->alloc->malloc(sizeof(struct SNAME##_iter)); \ + \ + if (!iter) \ + return NULL; \ + \ + PFX##_iter_init(iter, target); \ + \ + return iter; \ + } \ + \ + void PFX##_iter_free(struct SNAME##_iter *iter) \ + { \ + iter->target->alloc->free(iter); \ + } \ + \ + void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \ + { \ + iter->target = target; \ + iter->cursor = target->front; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = PFX##_empty(target); \ + } \ + \ + bool PFX##_iter_start(struct SNAME##_iter *iter) \ + { \ + return PFX##_empty(iter->target) || iter->start; \ + } \ + \ + bool PFX##_iter_end(struct SNAME##_iter *iter) \ + { \ + return PFX##_empty(iter->target) || iter->end; \ + } \ + \ + void PFX##_iter_to_start(struct SNAME##_iter *iter) \ + { \ + iter->cursor = iter->target->front; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = PFX##_empty(iter->target); \ + } \ + \ + void PFX##_iter_to_end(struct SNAME##_iter *iter) \ + { \ + if (PFX##_empty(iter->target)) \ + iter->cursor = 0; \ + else \ + { \ + if (iter->target->back == 0) \ + iter->cursor = iter->target->capacity - 1; \ + else \ + iter->cursor = iter->target->back - 1; \ + } \ + \ + iter->index = iter->target->count - 1; \ + iter->start = PFX##_empty(iter->target); \ + iter->end = true; \ + } \ + \ + bool PFX##_iter_next(struct SNAME##_iter *iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == PFX##_count(iter->target)) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = PFX##_empty(iter->target); \ + \ + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ + iter->index++; \ + \ + return true; \ + } \ + \ + bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = PFX##_empty(iter->target); \ + \ + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ + : iter->cursor - 1; \ + iter->index--; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == PFX##_count(iter->target)) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \ + return false; \ + \ + iter->start = PFX##_empty(iter->target); \ + \ + iter->index += steps; \ + iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + iter->end = PFX##_empty(iter->target); \ + \ + iter->index -= steps; \ + \ + /* Prevent underflow */ \ + if (iter->cursor < steps) \ + iter->cursor += PFX##_capacity(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(struct SNAME##_iter *iter, size_t index) \ + { \ + if (index >= PFX##_count(iter->target)) \ + return false; \ + \ + if (iter->index > index) \ + return PFX##_iter_rewind(iter, iter->index - index); \ + else if (iter->index < index) \ + return PFX##_iter_advance(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + V PFX##_iter_value(struct SNAME##_iter *iter) \ + { \ + if (PFX##_empty(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor]; \ + } \ + \ + V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ + { \ + if (PFX##_empty(iter->target)) \ + return NULL; \ + \ + return &(iter->target->buffer[iter->cursor]); \ + } \ + \ + size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + { \ + return iter->index; \ + } \ + \ + static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_queue_) \ + { \ + struct SNAME##_iter iter; \ + \ + PFX##_iter_init(&iter, _queue_); \ + PFX##_iter_to_start(&iter); \ + \ + return iter; \ + } \ + \ + static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_queue_) \ + { \ + struct SNAME##_iter iter; \ + \ + PFX##_iter_init(&iter, _queue_); \ + PFX##_iter_to_end(&iter); \ + \ + return iter; \ } #endif /* CMC_QUEUE_H */ diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index 381ed2e..aa9d7cb 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -90,7 +90,8 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " "capacity:%" PRIuMAX ", " "count:%" PRIuMAX ", " "is_sorted:%s, " - "cmp:%p, " + "flag:%d, " + "f_val:%p, " "alloc:%p, " "callbacks:%p }"; @@ -122,106 +123,132 @@ struct cmc_callbacks_sortedlist /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \ - \ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flag if the list is sorted or not, used by lazy evaluation */ \ - bool is_sorted; \ - \ - /* Element comparison function */ \ - int (*cmp)(V, V); \ - \ - /* Function that returns an iterator to the start of the list */ \ - struct SNAME##_iter (*it_start)(struct SNAME *); \ - \ - /* Function that returns an iterator to the end of the list */ \ - struct SNAME##_iter (*it_end)(struct SNAME *); \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks_sortedlist *callbacks; \ - }; \ - \ - /* List Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target list */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, int (*compare)(V, V), struct cmc_alloc_node *alloc, \ - struct cmc_callbacks_sortedlist *callbacks); \ - void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \ - void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks_sortedlist *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_list_, V element); \ - bool PFX##_remove(struct SNAME *_list_, size_t index); \ - /* Element Access */ \ - bool PFX##_max(struct SNAME *_list_, V *result); \ - bool PFX##_min(struct SNAME *_list_, V *result); \ - V PFX##_get(struct SNAME *_list_, size_t index); \ - size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_list_, V element); \ - bool PFX##_empty(struct SNAME *_list_); \ - bool PFX##_full(struct SNAME *_list_); \ - size_t PFX##_count(struct SNAME *_list_); \ - size_t PFX##_capacity(struct SNAME *_list_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_list_, size_t capacity); \ - void PFX##_sort(struct SNAME *_list_); \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)); \ - bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_list_); \ - \ - /* Iterator Functions */ \ - /* Iterator Allocation and Deallocation */ \ - struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \ - void PFX##_iter_free(struct SNAME##_iter *iter); \ - /* Iterator Initialization */ \ - void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - void PFX##_iter_to_start(struct SNAME##_iter *iter); \ - void PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ +#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \ + \ + /* List Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Flag if the list is sorted or not, used by lazy evaluation */ \ + bool is_sorted; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct SNAME##_ftab_val *f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks_sortedlist *callbacks; \ + \ + /* Function that returns an iterator to the start of the list */ \ + struct SNAME##_iter (*it_start)(struct SNAME *); \ + \ + /* Function that returns an iterator to the end of the list */ \ + struct SNAME##_iter (*it_end)(struct SNAME *); \ + }; \ + \ + /* Value struct function table */ \ + struct SNAME##_ftab_val \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* List Iterator */ \ + struct SNAME##_iter \ + { \ + /* Target list */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val); \ + struct SNAME *PFX##_new_custom( \ + size_t capacity, struct SNAME##_ftab_val *f_val, \ + struct cmc_alloc_node *alloc, \ + struct cmc_callbacks_sortedlist *callbacks); \ + void PFX##_clear(struct SNAME *_list_); \ + void PFX##_free(struct SNAME *_list_); \ + /* Customization of Allocation and Callbacks */ \ + void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ + struct cmc_callbacks_sortedlist *callbacks); \ + /* Collection Input and Output */ \ + bool PFX##_insert(struct SNAME *_list_, V element); \ + bool PFX##_remove(struct SNAME *_list_, size_t index); \ + /* Element Access */ \ + bool PFX##_max(struct SNAME *_list_, V *result); \ + bool PFX##_min(struct SNAME *_list_, V *result); \ + V PFX##_get(struct SNAME *_list_, size_t index); \ + size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start); \ + /* Collection State */ \ + bool PFX##_contains(struct SNAME *_list_, V element); \ + bool PFX##_empty(struct SNAME *_list_); \ + bool PFX##_full(struct SNAME *_list_); \ + size_t PFX##_count(struct SNAME *_list_); \ + size_t PFX##_capacity(struct SNAME *_list_); \ + /* Collection Utility */ \ + bool PFX##_resize(struct SNAME *_list_, size_t capacity); \ + void PFX##_sort(struct SNAME *_list_); \ + struct SNAME *PFX##_copy_of(struct SNAME *_list_); \ + bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \ + struct cmc_string PFX##_to_string(struct SNAME *_list_); \ + \ + /* Iterator Functions */ \ + /* Iterator Allocation and Deallocation */ \ + struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \ + void PFX##_iter_free(struct SNAME##_iter *iter); \ + /* Iterator Initialization */ \ + void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \ + /* Iterator State */ \ + bool PFX##_iter_start(struct SNAME##_iter *iter); \ + bool PFX##_iter_end(struct SNAME##_iter *iter); \ + /* Iterator Movement */ \ + void PFX##_iter_to_start(struct SNAME##_iter *iter); \ + void PFX##_iter_to_end(struct SNAME##_iter *iter); \ + bool PFX##_iter_next(struct SNAME##_iter *iter); \ + bool PFX##_iter_prev(struct SNAME##_iter *iter); \ + bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ + bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ + bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ + /* Iterator Access */ \ + V PFX##_iter_value(struct SNAME##_iter *iter); \ size_t PFX##_iter_index(struct SNAME##_iter *iter); /* ------------------------------------------------------------------------- @@ -241,13 +268,16 @@ struct cmc_callbacks_sortedlist static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_list_); \ static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_list_); \ \ - struct SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)) \ + struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ if (capacity < 1) \ return NULL; \ \ + if (!f_val) \ + return NULL; \ + \ struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ \ if (!_list_) \ @@ -263,19 +293,19 @@ struct cmc_callbacks_sortedlist \ _list_->capacity = capacity; \ _list_->count = 0; \ - _list_->cmp = compare; \ _list_->is_sorted = false; \ - \ - _list_->it_start = PFX##_impl_it_start; \ - _list_->it_end = PFX##_impl_it_end; \ - \ + _list_->flag = cmc_flags.OK; \ + _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = NULL; \ + _list_->it_start = PFX##_impl_it_start; \ + _list_->it_end = PFX##_impl_it_end; \ \ return _list_; \ } \ \ - struct SNAME *PFX##_new_custom(size_t capacity, int (*compare)(V, V), \ + struct SNAME *PFX##_new_custom(size_t capacity, \ + struct SNAME##_ftab_val *f_val, \ struct cmc_alloc_node *alloc, \ struct cmc_callbacks_sortedlist *callbacks) \ { \ @@ -300,24 +330,23 @@ struct cmc_callbacks_sortedlist \ _list_->capacity = capacity; \ _list_->count = 0; \ - _list_->cmp = compare; \ _list_->is_sorted = false; \ - \ - _list_->it_start = PFX##_impl_it_start; \ - _list_->it_end = PFX##_impl_it_end; \ - \ + _list_->flag = cmc_flags.OK; \ + _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = callbacks; \ + _list_->it_start = PFX##_impl_it_start; \ + _list_->it_end = PFX##_impl_it_end; \ \ return _list_; \ } \ \ - void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)) \ + void PFX##_clear(struct SNAME *_list_) \ { \ - if (deallocator) \ + if (_list_->f_val->free) \ { \ for (size_t i = 0; i < _list_->count; i++) \ - deallocator(_list_->buffer[i]); \ + _list_->f_val->free(_list_->buffer[i]); \ } \ \ memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ @@ -325,12 +354,12 @@ struct cmc_callbacks_sortedlist _list_->count = 0; \ } \ \ - void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)) \ + void PFX##_free(struct SNAME *_list_) \ { \ - if (deallocator) \ + if (_list_->f_val->free) \ { \ for (size_t i = 0; i < _list_->count; i++) \ - deallocator(_list_->buffer[i]); \ + _list_->f_val->free(_list_->buffer[i]); \ } \ \ _list_->alloc->free(_list_->buffer); \ @@ -351,7 +380,7 @@ struct cmc_callbacks_sortedlist { \ if (PFX##_full(_list_)) \ { \ - if (!PFX##_resize(_list_, PFX##_capacity(_list_) * 2)) \ + if (!PFX##_resize(_list_, _list_->capacity * 2)) \ return false; \ } \ \ @@ -429,7 +458,7 @@ struct cmc_callbacks_sortedlist PFX##_sort(_list_); \ \ return PFX##_impl_binary_search_first(_list_, element) < \ - PFX##_count(_list_); \ + _list_->count; \ } \ \ bool PFX##_empty(struct SNAME *_list_) \ @@ -454,10 +483,10 @@ struct cmc_callbacks_sortedlist \ bool PFX##_resize(struct SNAME *_list_, size_t capacity) \ { \ - if (PFX##_capacity(_list_) == capacity) \ + if (_list_->capacity == capacity) \ return true; \ \ - if (capacity < PFX##_count(_list_)) \ + if (capacity < _list_->count) \ return false; \ \ V *new_buffer = \ @@ -466,6 +495,8 @@ struct cmc_callbacks_sortedlist if (!new_buffer) \ return false; \ \ + /* TODO zero out remaining slots */ \ + \ _list_->buffer = new_buffer; \ _list_->capacity = capacity; \ \ @@ -476,25 +507,26 @@ struct cmc_callbacks_sortedlist { \ if (!_list_->is_sorted && _list_->count > 1) \ { \ - PFX##_impl_sort_quicksort(_list_->buffer, _list_->cmp, 0, \ + PFX##_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, \ _list_->count - 1); \ \ _list_->is_sorted = true; \ } \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)) \ + struct SNAME *PFX##_copy_of(struct SNAME *_list_) \ { \ - struct SNAME *result = PFX##_new_custom( \ - _list_->capacity, _list_->cmp, _list_->alloc, _list_->callbacks); \ + struct SNAME *result = \ + PFX##_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, \ + _list_->callbacks); \ \ if (!result) \ return NULL; \ \ - if (copy_func) \ + if (_list_->f_val->cpy) \ { \ for (size_t i = 0; i < _list_->count; i++) \ - result->buffer[i] = copy_func(_list_->buffer[i]); \ + result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ } \ else \ memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ @@ -514,7 +546,8 @@ struct cmc_callbacks_sortedlist \ for (size_t i = 0; i < PFX##_count(_list1_); i++) \ { \ - if (_list1_->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) \ + if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \ + 0) \ return false; \ } \ \ @@ -528,15 +561,10 @@ struct cmc_callbacks_sortedlist \ int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_sortedlist, \ #SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \ - l_->is_sorted ? "true" : "false", l_->cmp, l_->alloc, \ - l_->callbacks); \ + l_->is_sorted ? "true" : "false", l_->flag, \ + l_->f_val, l_->alloc, l_->callbacks); \ \ - if (n < 0 || n == (int)cmc_string_len) \ - return (struct cmc_string){ 0 }; \ - \ - str.s[n] = '\0'; \ - \ - return str; \ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ @@ -719,13 +747,13 @@ struct cmc_callbacks_sortedlist { \ size_t M = L + (R - L) / 2; \ \ - if (_list_->cmp(_list_->buffer[M], value) < 0) \ + if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) \ L = M + 1; \ else \ R = M; \ } \ \ - if (_list_->cmp(_list_->buffer[L], value) == 0) \ + if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) \ return L; \ \ /* Not found */ \ @@ -744,13 +772,13 @@ struct cmc_callbacks_sortedlist { \ size_t M = L + (R - L) / 2; \ \ - if (_list_->cmp(_list_->buffer[M], value) > 0) \ + if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) \ R = M; \ else \ L = M + 1; \ } \ \ - if (_list_->cmp(_list_->buffer[L - 1], value) == 0) \ + if (_list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) \ return L - 1; \ \ /* Not found */ \ diff --git a/src/cmc/stack.h b/src/cmc/stack.h index de0d49f..7cb9a88 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -95,6 +95,8 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " "buffer:%p, " "capacity:%" PRIuMAX ", " "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " "alloc:%p, " "callbacks:%p }"; @@ -140,17 +142,45 @@ struct cmc_callbacks_stack /* Current amount of elements */ \ size_t count; \ \ - /* Function that returns an iterator to the start of the stack */ \ - struct SNAME##_iter (*it_start)(struct SNAME *); \ + /* Flags indicating errors or success */ \ + int flag; \ \ - /* Function that returns an iterator to the end of the stack */ \ - struct SNAME##_iter (*it_end)(struct SNAME *); \ + /* Value function table */ \ + struct SNAME##_ftab_val *f_val; \ \ /* Custom allocation functions */ \ struct cmc_alloc_node *alloc; \ \ /* Custom callback functions */ \ struct cmc_callbacks_stack *callbacks; \ + \ + /* Function that returns an iterator to the start of the stack */ \ + struct SNAME##_iter (*it_start)(struct SNAME *); \ + \ + /* Function that returns an iterator to the end of the stack */ \ + struct SNAME##_iter (*it_end)(struct SNAME *); \ + }; \ + \ + /* Value struct function table */ \ + struct SNAME##_ftab_val \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ }; \ \ /* Stack Iterator */ \ @@ -171,12 +201,12 @@ struct cmc_callbacks_stack \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity); \ - struct SNAME *PFX##_new_custom(size_t capacity, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks_stack *callbacks); \ - void PFX##_clear(struct SNAME *_stack_, void (*deallocator)(V)); \ - void PFX##_free(struct SNAME *_stack_, void (*deallocator)(V)); \ + struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val); \ + struct SNAME *PFX##_new_custom( \ + size_t capacity, struct SNAME##_ftab_val *f_val, \ + struct cmc_alloc_node *alloc, struct cmc_callbacks_stack *callbacks); \ + void PFX##_clear(struct SNAME *_stack_); \ + void PFX##_free(struct SNAME *_stack_); \ /* Customization of Allocation and Callbacks */ \ void PFX##_customize(struct SNAME *_stack_, struct cmc_alloc_node *alloc, \ struct cmc_callbacks_stack *callbacks); \ @@ -186,17 +216,15 @@ struct cmc_callbacks_stack /* Element Access */ \ V PFX##_top(struct SNAME *_stack_); \ /* Collection State */ \ - bool PFX##_contains(struct SNAME *_stack_, V element, \ - int (*comparator)(V, V)); \ + bool PFX##_contains(struct SNAME *_stack_, V element); \ bool PFX##_empty(struct SNAME *_stack_); \ bool PFX##_full(struct SNAME *_stack_); \ size_t PFX##_count(struct SNAME *_stack_); \ size_t PFX##_capacity(struct SNAME *_stack_); \ /* Collection Utility */ \ bool PFX##_resize(struct SNAME *_stack_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_stack_, V (*copy_func)(V)); \ - bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_, \ - int (*comparator)(V, V)); \ + struct SNAME *PFX##_copy_of(struct SNAME *_stack_); \ + bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_); \ struct cmc_string PFX##_to_string(struct SNAME *_stack_); \ \ /* Iterator Functions */ \ @@ -230,13 +258,16 @@ struct cmc_callbacks_stack static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_stack_); \ static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_stack_); \ \ - struct SNAME *PFX##_new(size_t capacity) \ + struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ if (capacity < 1) \ return NULL; \ \ + if (!f_val) \ + return NULL; \ + \ struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \ \ if (!_stack_) \ @@ -252,21 +283,23 @@ struct cmc_callbacks_stack \ _stack_->capacity = capacity; \ _stack_->count = 0; \ - \ - _stack_->it_start = PFX##_impl_it_start; \ - _stack_->it_end = PFX##_impl_it_end; \ - \ + _stack_->flag = cmc_flags.OK; \ + _stack_->f_val = f_val; \ _stack_->alloc = alloc; \ _stack_->callbacks = NULL; \ + _stack_->it_start = PFX##_impl_it_start; \ + _stack_->it_end = PFX##_impl_it_end; \ \ return _stack_; \ } \ \ - struct SNAME *PFX##_new_custom(size_t capacity, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks_stack *callbacks) \ + struct SNAME *PFX##_new_custom( \ + size_t capacity, struct SNAME##_ftab_val *f_val, \ + struct cmc_alloc_node *alloc, struct cmc_callbacks_stack *callbacks) \ { \ if (capacity < 1) \ + return NULL; \ + if (!f_val) \ return NULL; \ \ if (!alloc) \ @@ -287,22 +320,22 @@ struct cmc_callbacks_stack \ _stack_->capacity = capacity; \ _stack_->count = 0; \ - \ - _stack_->it_start = PFX##_impl_it_start; \ - _stack_->it_end = PFX##_impl_it_end; \ - \ + _stack_->flag = cmc_flags.OK; \ + _stack_->f_val = f_val; \ _stack_->alloc = alloc; \ _stack_->callbacks = callbacks; \ + _stack_->it_start = PFX##_impl_it_start; \ + _stack_->it_end = PFX##_impl_it_end; \ \ return _stack_; \ } \ \ - void PFX##_clear(struct SNAME *_stack_, void (*deallocator)(V)) \ + void PFX##_clear(struct SNAME *_stack_) \ { \ - if (deallocator) \ + if (_stack_->f_val->free) \ { \ for (size_t i = 0; i < _stack_->count; i++) \ - deallocator(_stack_->buffer[i]); \ + _stack_->f_val->free(_stack_->buffer[i]); \ } \ \ memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \ @@ -310,12 +343,12 @@ struct cmc_callbacks_stack _stack_->count = 0; \ } \ \ - void PFX##_free(struct SNAME *_stack_, void (*deallocator)(V)) \ + void PFX##_free(struct SNAME *_stack_) \ { \ - if (deallocator) \ + if (_stack_->f_val->free) \ { \ for (size_t i = 0; i < _stack_->count; i++) \ - deallocator(_stack_->buffer[i]); \ + _stack_->f_val->free(_stack_->buffer[i]); \ } \ \ _stack_->alloc->free(_stack_->buffer); \ @@ -336,7 +369,7 @@ struct cmc_callbacks_stack { \ if (PFX##_full(_stack_)) \ { \ - if (!PFX##_resize(_stack_, PFX##_capacity(_stack_) * 2)) \ + if (!PFX##_resize(_stack_, _stack_->capacity * 2)) \ return false; \ } \ \ @@ -363,12 +396,11 @@ struct cmc_callbacks_stack return _stack_->buffer[_stack_->count - 1]; \ } \ \ - bool PFX##_contains(struct SNAME *_stack_, V element, \ - int (*comparator)(V, V)) \ + bool PFX##_contains(struct SNAME *_stack_, V element) \ { \ for (size_t i = 0; i < _stack_->count; i++) \ { \ - if (comparator(_stack_->buffer[i], element) == 0) \ + if (_stack_->f_val->cmp(_stack_->buffer[i], element) == 0) \ return true; \ } \ \ @@ -397,10 +429,10 @@ struct cmc_callbacks_stack \ bool PFX##_resize(struct SNAME *_stack_, size_t capacity) \ { \ - if (PFX##_capacity(_stack_) == capacity) \ + if (_stack_->capacity == capacity) \ return true; \ \ - if (capacity < PFX##_count(_stack_)) \ + if (capacity < _stack_->count) \ return false; \ \ V *new_buffer = \ @@ -415,18 +447,19 @@ struct cmc_callbacks_stack return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_stack_, V (*copy_func)(V)) \ + struct SNAME *PFX##_copy_of(struct SNAME *_stack_) \ { \ - struct SNAME *result = PFX##_new_custom( \ - _stack_->capacity, _stack_->alloc, _stack_->callbacks); \ + struct SNAME *result = \ + PFX##_new_custom(_stack_->capacity, _stack_->f_val, \ + _stack_->alloc, _stack_->callbacks); \ \ if (!result) \ return NULL; \ \ - if (copy_func) \ + if (_stack_->f_val->cpy) \ { \ for (size_t i = 0; i < _stack_->count; i++) \ - result->buffer[i] = copy_func(_stack_->buffer[i]); \ + result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); \ } \ else \ memcpy(result->buffer, _stack_->buffer, \ @@ -437,15 +470,15 @@ struct cmc_callbacks_stack return result; \ } \ \ - bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_, \ - int (*comparator)(V, V)) \ + bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_) \ { \ - if (PFX##_count(_stack1_) != PFX##_count(_stack2_)) \ + if (_stack1_->count != _stack2_->count) \ return false; \ \ - for (size_t i = 0; i < PFX##_count(_stack1_); i++) \ + for (size_t i = 0; i < _stack1_->count; i++) \ { \ - if (comparator(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \ + if (_stack1_->f_val->cmp(_stack1_->buffer[i], \ + _stack2_->buffer[i]) != 0) \ return false; \ } \ \ @@ -459,14 +492,9 @@ struct cmc_callbacks_stack \ int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, #SNAME, \ #V, s_, s_->buffer, s_->capacity, s_->count, \ - s_->alloc, s_->callbacks); \ + s_->f_val, s_->alloc, s_->callbacks); \ \ - if (n < 0 || n == (int)cmc_string_len) \ - return (struct cmc_string){ 0 }; \ - \ - str.s[n] = '\0'; \ - \ - return str; \ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ diff --git a/tests/main/unt/multimap.c b/tests/main/unt/multimap.c index df3def0..a718a4c 100644 --- a/tests/main/unt/multimap.c +++ b/tests/main/unt/multimap.c @@ -42,7 +42,8 @@ CMC_CREATE_UNIT(multimap_test, true, { }); CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct multimap *map = mm_new(UINT64_MAX, 0.99, mm_ftab_key, mm_ftab_val); + struct multimap *map = + mm_new(UINT64_MAX, 0.99, mm_ftab_key, mm_ftab_val); cmc_assert_equals(ptr, NULL, map); }); diff --git a/tests/main/unt/queue.c b/tests/main/unt/queue.c index 31df9be..e84a7f9 100644 --- a/tests/main/unt/queue.c +++ b/tests/main/unt/queue.c @@ -9,11 +9,11 @@ CMC_GENERATE_QUEUE(q, queue, size_t) struct queue_ftab_val *q_ftab_val = &(struct queue_ftab_val){ .cmp = cmp, - .cpy = copy, - .str = str, - .free = custom_free, - .hash = hash, - .pri = pri }; + .cpy = copy, + .str = str, + .free = custom_free, + .hash = hash, + .pri = pri }; CMC_CREATE_UNIT(queue_test, true, { CMC_CREATE_TEST(new, { diff --git a/tests/main/unt/sortedlist.c b/tests/main/unt/sortedlist.c index d609675..329f3cc 100644 --- a/tests/main/unt/sortedlist.c +++ b/tests/main/unt/sortedlist.c @@ -7,9 +7,17 @@ CMC_GENERATE_SORTEDLIST(sl, sortedlist, size_t) +struct sortedlist_ftab_val *sl_ftab_val = + &(struct sortedlist_ftab_val){ .cmp = cmp, + .cpy = copy, + .str = str, + .free = custom_free, + .hash = hash, + .pri = pri }; + CMC_CREATE_UNIT(sortedlist_test, true, { CMC_CREATE_TEST(new, { - struct sortedlist *sl = sl_new(1000000, cmp); + struct sortedlist *sl = sl_new(1000000, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); cmc_assert_not_equals(ptr, NULL, sl->buffer); @@ -17,23 +25,23 @@ CMC_CREATE_UNIT(sortedlist_test, true, { cmc_assert_equals(size_t, 0, sl_count(sl)); cmc_assert_not_equals(ptr, NULL, sl->buffer); - sl_free(sl, NULL); + sl_free(sl); }); CMC_CREATE_TEST(new[capacity = 0], { - struct sortedlist *sl = sl_new(0, cmp); + struct sortedlist *sl = sl_new(0, sl_ftab_val); cmc_assert_equals(ptr, NULL, sl); }); CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct sortedlist *sl = sl_new(UINT64_MAX, cmp); + struct sortedlist *sl = sl_new(UINT64_MAX, sl_ftab_val); cmc_assert_equals(ptr, NULL, sl); }); CMC_CREATE_TEST(clear[count capacity], { - struct sortedlist *sl = sl_new(100, cmp); + struct sortedlist *sl = sl_new(100, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); @@ -42,16 +50,16 @@ CMC_CREATE_UNIT(sortedlist_test, true, { cmc_assert_equals(size_t, 50, sl_count(sl)); - sl_clear(sl, NULL); + sl_clear(sl); cmc_assert_equals(size_t, 0, sl_count(sl)); cmc_assert_equals(size_t, 100, sl_capacity(sl)); - sl_free(sl, NULL); + sl_free(sl); }); CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct sortedlist *sl = sl_new(1, cmp); + struct sortedlist *sl = sl_new(1, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); @@ -63,21 +71,21 @@ CMC_CREATE_UNIT(sortedlist_test, true, { cmc_assert_equals(size_t, 50, sl_count(sl)); cmc_assert_array_sorted_any(size_t, sl->buffer, cmp, 0, sl->count - 1); - sl_free(sl, NULL); + sl_free(sl); }); CMC_CREATE_TEST(insert, { - struct sortedlist *sl = sl_new(100, cmp); + struct sortedlist *sl = sl_new(100, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); cmc_assert(sl_insert(sl, 1)); - sl_free(sl, NULL); + sl_free(sl); }); CMC_CREATE_TEST(remove, { - struct sortedlist *sl = sl_new(100, cmp); + struct sortedlist *sl = sl_new(100, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); @@ -85,21 +93,21 @@ CMC_CREATE_UNIT(sortedlist_test, true, { cmc_assert(sl_remove(sl, 0)); - sl_free(sl, NULL); + sl_free(sl); }); CMC_CREATE_TEST(remove[count = 0], { - struct sortedlist *sl = sl_new(100, cmp); + struct sortedlist *sl = sl_new(100, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); cmc_assert(!sl_remove(sl, 0)); - sl_free(sl, NULL); + sl_free(sl); }); CMC_CREATE_TEST(remove[out of range], { - struct sortedlist *sl = sl_new(100, cmp); + struct sortedlist *sl = sl_new(100, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); @@ -107,11 +115,11 @@ CMC_CREATE_UNIT(sortedlist_test, true, { cmc_assert(!sl_remove(sl, 2)); - sl_free(sl, NULL); + sl_free(sl); }); CMC_CREATE_TEST(indexof, { - struct sortedlist *sl = sl_new(1, cmp); + struct sortedlist *sl = sl_new(1, sl_ftab_val); cmc_assert_not_equals(ptr, NULL, sl); @@ -135,6 +143,6 @@ CMC_CREATE_UNIT(sortedlist_test, true, { cmc_assert_equals(size_t, sl_count(sl), sl_indexof(sl, 0, true)); cmc_assert_equals(size_t, sl_count(sl), sl_indexof(sl, 0, false)); - sl_free(sl, NULL); + sl_free(sl); }); }); diff --git a/tests/main/unt/stack.c b/tests/main/unt/stack.c index d98feed..ba44772 100644 --- a/tests/main/unt/stack.c +++ b/tests/main/unt/stack.c @@ -7,9 +7,17 @@ CMC_GENERATE_STACK(s, stack, size_t) +struct stack_ftab_val *s_ftab_val = + &(struct stack_ftab_val){ .cmp = cmp, + .cpy = copy, + .str = str, + .free = custom_free, + .hash = hash, + .pri = pri }; + CMC_CREATE_UNIT(stack_test, true, { CMC_CREATE_TEST(new, { - struct stack *s = s_new(1000000); + struct stack *s = s_new(1000000, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); cmc_assert_not_equals(ptr, NULL, s->buffer); @@ -17,23 +25,23 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 0, s_count(s)); cmc_assert_not_equals(ptr, NULL, s->buffer); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(new[capacity = 0], { - struct stack *s = s_new(0); + struct stack *s = s_new(0, s_ftab_val); cmc_assert_equals(ptr, NULL, s); }); CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct stack *s = s_new(UINT64_MAX); + struct stack *s = s_new(UINT64_MAX, s_ftab_val); cmc_assert_equals(ptr, NULL, s); }); CMC_CREATE_TEST(clear[count capacity], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -42,16 +50,16 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 50, s_count(s)); - s_clear(s, NULL); + s_clear(s); cmc_assert_equals(size_t, 0, s_count(s)); cmc_assert_equals(size_t, 100, s_capacity(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct stack *s = s_new(1); + struct stack *s = s_new(1, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -61,11 +69,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 50, s_count(s)); cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(push[count], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -74,11 +82,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 250, s_count(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(push[capacity], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -87,11 +95,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(push[item preservation], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -101,11 +109,11 @@ CMC_CREATE_UNIT(stack_test, true, { for (size_t i = 0; i < s_count(s); i++) cmc_assert_equals(size_t, i, s->buffer[i]); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(pop[count], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -116,11 +124,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 249, s_count(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(pop[capacity], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -131,11 +139,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(pop[item preservation], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -148,21 +156,21 @@ CMC_CREATE_UNIT(stack_test, true, { for (size_t i = 0; i < s_count(s); i++) cmc_assert_equals(size_t, i, s->buffer[i]); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(pop[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); cmc_assert_equals(bool, false, s_pop(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(top, { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -174,11 +182,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 247, s_top(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(top[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -188,11 +196,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, (size_t){ 0 }, s_top(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(top[count = 1], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -200,11 +208,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 1, s_count(s)); cmc_assert_equals(size_t, 10, s_top(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(contains, { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -212,33 +220,33 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert(s_push(s, i)); for (size_t i = 0; i < 150; i++) - cmc_assert(s_contains(s, i, cmp)); + cmc_assert(s_contains(s, i)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(contains[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); - cmc_assert_equals(bool, false, s_contains(s, 10, cmp)); + cmc_assert_equals(bool, false, s_contains(s, 10)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(empty, { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); cmc_assert(s_empty(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(empty[after_io], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -246,11 +254,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert(s_pop(s)); cmc_assert(s_empty(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(full, { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -259,11 +267,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert(s_full(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(full[capacity = 1], { - struct stack *s = s_new(1); + struct stack *s = s_new(1, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -271,11 +279,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert(s_full(s)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iter_alloc, { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -284,11 +292,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_not_equals(ptr, NULL, iter); s_iter_free(iter); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iter_init[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -301,11 +309,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert(iter.start); cmc_assert(iter.end); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iter_start[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -315,11 +323,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert(s_iter_start(&iter)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iter_end[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -329,11 +337,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert(s_iter_end(&iter)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iteration, { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -358,11 +366,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 40200, total); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iteration[while loop], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -388,11 +396,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 40200, total); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iteration[count = 1], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); cmc_assert(s_push(s, 10)); @@ -413,11 +421,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 20, total); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iteration[count = capacity], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -444,11 +452,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 2000, total); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iteration[to_start = it_start and to_end = it_end], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -479,11 +487,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(bool, it1.start, it2.start); cmc_assert_equals(bool, it1.end, it2.end); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iteration[boundaries count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -498,11 +506,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(bool, false, s_iter_prev(&iter)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iteration[boundaries count > 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -520,11 +528,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(bool, false, s_iter_prev(&iter)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iter_value[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -534,11 +542,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, (size_t){ 0 }, s_iter_value(&iter)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(iter_rvalue[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -548,11 +556,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(ptr, NULL, s_iter_rvalue(&iter)); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(index, { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -589,11 +597,11 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 90, total); - s_free(s, NULL); + s_free(s); }); CMC_CREATE_TEST(index[count = 0], { - struct stack *s = s_new(100); + struct stack *s = s_new(100, s_ftab_val); cmc_assert_not_equals(ptr, NULL, s); @@ -602,6 +610,6 @@ CMC_CREATE_UNIT(stack_test, true, { cmc_assert_equals(size_t, 0, s_iter_index(&iter)); - s_free(s, NULL); + s_free(s); }); });