From 77a7178857ffeab65bb55c770ec32d02aca1155b Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 27 May 2020 00:48:34 -0300 Subject: [PATCH] Added ./cor/ftable.h and fast forward changes --- src/cmc/deque.h | 1234 ++++++++++++++----------------------- src/cmc/hashmap.h | 32 - src/cor/core.h | 23 +- src/cor/ftable.h | 28 + src/ext/cmc/deque.h | 345 ++++++++++- src/ext/cmc/hashbidimap.h | 12 + src/ext/cmc/hashmap.h | 88 ++- src/macro_collections.h | 29 + 8 files changed, 961 insertions(+), 830 deletions(-) create mode 100644 src/cor/ftable.h diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 5b6dffa..ecbf4ae 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -70,769 +70,485 @@ static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Deque Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ - \ - /* Current circular array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the deque */ \ - size_t front; \ - \ - /* Index representing the back of the deque */ \ - size_t back; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* 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); \ - }; \ - \ - /* Deque Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target deque */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* 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 *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _deque_); \ - void CMC_(PFX, _free)(struct SNAME * _deque_); \ - void CMC_(PFX, _release)(struct SNAME _deque_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _deque_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _deque_); \ - V CMC_(PFX, _back)(struct SNAME * _deque_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ - bool CMC_(PFX, _full)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ - int CMC_(PFX, _flag)(struct SNAME * _deque_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ - bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _deque_); \ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Deque Structure */ \ + struct SNAME \ + { \ + /* Dynamic circular array of elements */ \ + V *buffer; \ + \ + /* Current circular array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Index representing the front of the deque */ \ + size_t front; \ + \ + /* Index representing the back of the deque */ \ + size_t back; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ + \ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ + \ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ + \ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ + \ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ + \ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _deque_); \ + void CMC_(PFX, _free)(struct SNAME * _deque_); \ + void CMC_(PFX, _release)(struct SNAME _deque_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _deque_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _deque_); \ + V CMC_(PFX, _back)(struct SNAME * _deque_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ + bool CMC_(PFX, _full)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ + int CMC_(PFX, _flag)(struct SNAME * _deque_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ + bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_deque_) \ - return NULL; \ - \ - _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_deque_->buffer) \ - { \ - alloc->free(_deque_); \ - return NULL; \ - } \ - \ - _deque_->capacity = capacity; \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - _deque_->flag = CMC_FLAG_OK; \ - _deque_->f_val = f_val; \ - _deque_->alloc = alloc; \ - _deque_->callbacks = callbacks; \ - \ - return _deque_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ - \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - _deque_->alloc->free(_deque_->buffer); \ - _deque_->alloc->free(_deque_); \ - } \ - \ - void CMC_(PFX, _release)(struct SNAME _deque_) \ - { \ - if (_deque_.f_val->free) \ - { \ - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ - { \ - _deque_.f_val->free(_deque_.buffer[i]); \ - \ - i = (i + 1) % _deque_.capacity; \ - } \ - } \ - \ - _deque_.alloc->free(_deque_.buffer); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _deque_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _deque_->alloc = &cmc_alloc_node_default; \ - else \ - _deque_->alloc = alloc; \ - \ - _deque_->callbacks = callbacks; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ - \ - _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 \ - : _deque_->front - 1; \ - \ - _deque_->buffer[_deque_->front] = value; \ - \ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->create) \ - _deque_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ - \ - _deque_->buffer[_deque_->back] = value; \ - \ - _deque_->back = \ - (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ - \ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->create) \ - _deque_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _deque_->buffer[_deque_->front] = (V){ 0 }; \ - \ - _deque_->front = (_deque_->front == _deque_->capacity - 1) \ - ? 0 \ - : _deque_->front + 1; \ - \ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->delete) \ - _deque_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _deque_->back = \ - (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ - \ - _deque_->buffer[_deque_->back] = (V){ 0 }; \ - \ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->delete) \ - _deque_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return _deque_->buffer[_deque_->front]; \ - } \ - \ - V CMC_(PFX, _back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 \ - : _deque_->back - 1]; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ - { \ - return _deque_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _deque_) \ - { \ - return _deque_->count >= _deque_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ - { \ - return _deque_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ - { \ - return _deque_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _deque_) \ - { \ - return _deque_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _deque_->count) \ - { \ - _deque_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _deque_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - new_buffer[j] = _deque_->buffer[i]; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - _deque_->alloc->free(_deque_->buffer); \ - \ - _deque_->buffer = new_buffer; \ - _deque_->capacity = capacity; \ - _deque_->front = 0; \ - _deque_->back = _deque_->count; \ - \ - success: \ - \ - if (_deque_->callbacks && _deque_->callbacks->resize) \ - _deque_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, \ - _deque_->alloc, _deque_->callbacks); \ - \ - if (!result) \ - { \ - _deque_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_deque_->f_val->cpy) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - else \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->buffer[i]; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - result->count = _deque_->count; \ - result->front = 0; \ - result->back = _deque_->count; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \ - { \ - _deque1_->flag = CMC_FLAG_OK; \ - _deque2_->flag = CMC_FLAG_OK; \ - \ - if (_deque1_->count != _deque2_->count) \ - return false; \ - \ - size_t i, j, k; \ - for (i = _deque1_->front, j = _deque2_->front, k = 0; \ - k < _deque1_->count; k++) \ - { \ - if (_deque1_->f_val->cmp(_deque1_->buffer[i], \ - _deque2_->buffer[j]) != 0) \ - return false; \ - \ - i = (i + 1) % _deque1_->capacity; \ - j = (j + 1) % _deque2_->capacity; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _deque_) \ - { \ - struct cmc_string str; \ - struct SNAME *d_ = _deque_; \ - \ - int n = \ - snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_deque, #SNAME, \ - #V, d_, d_->buffer, d_->capacity, d_->count, d_->front, \ - d_->back, d_->flag, d_->f_val, d_->alloc, d_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \ - return false; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->front; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - if (iter.target->back == 0) \ - iter.cursor = iter.target->capacity - 1; \ - else \ - iter.cursor = iter.target->back - 1; \ - \ - iter.index = iter.target->count - 1; \ - } \ - else \ - { \ - iter.cursor = 0; \ - iter.index = 0; \ - } \ - \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - 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 = false; \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(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 CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(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 CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * 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 = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index -= steps; \ - \ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += iter->target->capacity; \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ +#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ + \ + /* Implementation Detail Functions */ \ + /* None */ \ + \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ + \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ + \ + if (!f_val) \ + return NULL; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_deque_) \ + return NULL; \ + \ + _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \ + \ + if (!_deque_->buffer) \ + { \ + alloc->free(_deque_); \ + return NULL; \ + } \ + \ + _deque_->capacity = capacity; \ + _deque_->count = 0; \ + _deque_->front = 0; \ + _deque_->back = 0; \ + _deque_->flag = CMC_FLAG_OK; \ + _deque_->f_val = f_val; \ + _deque_->alloc = alloc; \ + _deque_->callbacks = callbacks; \ + \ + return _deque_; \ + } \ + \ + void CMC_(PFX, _clear)(struct SNAME * _deque_) \ + { \ + if (_deque_->f_val->free) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + _deque_->f_val->free(_deque_->buffer[i]); \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + \ + memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ + \ + _deque_->count = 0; \ + _deque_->front = 0; \ + _deque_->back = 0; \ + \ + _deque_->flag = CMC_FLAG_OK; \ + } \ + \ + void CMC_(PFX, _free)(struct SNAME * _deque_) \ + { \ + if (_deque_->f_val->free) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + _deque_->f_val->free(_deque_->buffer[i]); \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + \ + _deque_->alloc->free(_deque_->buffer); \ + _deque_->alloc->free(_deque_); \ + } \ + \ + void CMC_(PFX, _release)(struct SNAME _deque_) \ + { \ + if (_deque_.f_val->free) \ + { \ + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ + { \ + _deque_.f_val->free(_deque_.buffer[i]); \ + \ + i = (i + 1) % _deque_.capacity; \ + } \ + } \ + \ + _deque_.alloc->free(_deque_.buffer); \ + } \ + \ + void CMC_(PFX, _customize)(struct SNAME * _deque_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!alloc) \ + _deque_->alloc = &cmc_alloc_node_default; \ + else \ + _deque_->alloc = alloc; \ + \ + _deque_->callbacks = callbacks; \ + \ + _deque_->flag = CMC_FLAG_OK; \ + } \ + \ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ + { \ + if (CMC_(PFX, _full)(_deque_)) \ + { \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ + return false; \ + } \ + \ + _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 \ + : _deque_->front - 1; \ + \ + _deque_->buffer[_deque_->front] = value; \ + \ + _deque_->count++; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->create) \ + _deque_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ + { \ + if (CMC_(PFX, _full)(_deque_)) \ + { \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ + return false; \ + } \ + \ + _deque_->buffer[_deque_->back] = value; \ + \ + _deque_->back = \ + (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ + \ + _deque_->count++; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->create) \ + _deque_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + _deque_->buffer[_deque_->front] = (V){ 0 }; \ + \ + _deque_->front = (_deque_->front == _deque_->capacity - 1) \ + ? 0 \ + : _deque_->front + 1; \ + \ + _deque_->count--; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->delete) \ + _deque_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + _deque_->back = \ + (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ + \ + _deque_->buffer[_deque_->back] = (V){ 0 }; \ + \ + _deque_->count--; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->delete) \ + _deque_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _front)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->read) \ + _deque_->callbacks->read(); \ + \ + return _deque_->buffer[_deque_->front]; \ + } \ + \ + V CMC_(PFX, _back)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->read) \ + _deque_->callbacks->read(); \ + \ + return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 \ + : _deque_->back - 1]; \ + } \ + \ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ + { \ + _deque_->flag = CMC_FLAG_OK; \ + \ + bool result = false; \ + \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \ + { \ + result = true; \ + break; \ + } \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + \ + if (_deque_->callbacks && _deque_->callbacks->read) \ + _deque_->callbacks->read(); \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ + { \ + return _deque_->count == 0; \ + } \ + \ + bool CMC_(PFX, _full)(struct SNAME * _deque_) \ + { \ + return _deque_->count >= _deque_->capacity; \ + } \ + \ + size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ + { \ + return _deque_->count; \ + } \ + \ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ + { \ + return _deque_->capacity; \ + } \ + \ + int CMC_(PFX, _flag)(struct SNAME * _deque_) \ + { \ + return _deque_->flag; \ + } \ + \ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ + { \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->capacity == capacity) \ + goto success; \ + \ + if (capacity < _deque_->count) \ + { \ + _deque_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \ + \ + if (!new_buffer) \ + { \ + _deque_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ + \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + new_buffer[j] = _deque_->buffer[i]; \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + \ + _deque_->alloc->free(_deque_->buffer); \ + \ + _deque_->buffer = new_buffer; \ + _deque_->capacity = capacity; \ + _deque_->front = 0; \ + _deque_->back = _deque_->count; \ + \ + success: \ + \ + if (_deque_->callbacks && _deque_->callbacks->resize) \ + _deque_->callbacks->resize(); \ + \ + return true; \ + } \ + \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ + { \ + struct SNAME *result = \ + CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, \ + _deque_->alloc, _deque_->callbacks); \ + \ + if (!result) \ + { \ + _deque_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ + \ + if (_deque_->f_val->cpy) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + else \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + result->buffer[j] = _deque_->buffer[i]; \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + \ + result->count = _deque_->count; \ + result->front = 0; \ + result->back = _deque_->count; \ + \ + _deque_->flag = CMC_FLAG_OK; \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \ + { \ + _deque1_->flag = CMC_FLAG_OK; \ + _deque2_->flag = CMC_FLAG_OK; \ + \ + if (_deque1_->count != _deque2_->count) \ + return false; \ + \ + size_t i, j, k; \ + for (i = _deque1_->front, j = _deque2_->front, k = 0; \ + k < _deque1_->count; k++) \ + { \ + if (_deque1_->f_val->cmp(_deque1_->buffer[i], \ + _deque2_->buffer[j]) != 0) \ + return false; \ + \ + i = (i + 1) % _deque1_->capacity; \ + j = (j + 1) % _deque2_->capacity; \ + } \ + \ + return true; \ } #endif /* CMC_CMC_DEQUE_H */ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index d64dcaf..16b716a 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -220,8 +220,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ \ /* Iterator Functions */ \ /* Iterator Initialization */ \ @@ -860,36 +858,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmap, \ - #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ - m_->alloc, m_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_map_->f_key->str(fptr, entry->key) || \ - !_map_->f_val->str(fptr, entry->value)) \ - return false; \ - } \ - } \ - \ - return true; \ - } \ - \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ struct CMC_DEF_ITER(SNAME) iter; \ diff --git a/src/cor/core.h b/src/cor/core.h index 91e6460..375c597 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -32,6 +32,7 @@ #include "alloc.h" #include "callbacks.h" #include "flags.h" +#include "ftable.h" #define CMC__(A, B) A##B #define CMC_(A, B) CMC__(A, B) @@ -91,26 +92,4 @@ #define CMC_PARAM_K CMC_TUP_3 #define CMC_PARAM_V CMC_TUP_4 -/** - * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: - * - * CMC_NARG(HELLO) -> 0 - * CMC_NARG(HELLO,) -> 1 - * CMC_NARG(HELLO, WORLD,) -> 2 - */ -#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N()) -#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__) -#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ - _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ - _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ - _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ - _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ - _62, _63, N, ...) \ - N -#define CMC_SEQ_N() \ - 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \ - 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \ - 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - #endif /* CMC_COR_CORE_H */ diff --git a/src/cor/ftable.h b/src/cor/ftable.h new file mode 100644 index 0000000..23c29a7 --- /dev/null +++ b/src/cor/ftable.h @@ -0,0 +1,28 @@ +/** + * ftable.h + * + * Creation Date: 27/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * Type definitions for Functions Tables. + */ + +#ifndef CMC_COR_FTABLE_H +#define CMC_COR_FTABLE_H + +/** + * Where T can either be K or V + */ +#define CMC_DEF_FTAB_CMP(T) int (*cmp)(T, T) +#define CMC_DEF_FTAB_CPY(T) T (*cpy)(T) +#define CMC_DEF_FTAB_STR(T) bool (*str)(FILE *, T) +#define CMC_DEF_FTAB_FREE(T) void (*free)(T) +#define CMC_DEF_FTAB_HASH(T) size_t (*hash)(T) +#define CMC_DEF_FTAB_PRI(T) int (*pri)(T, T) + +#endif /* CMC_COR_FTABLE_H */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 9b91281..06cec26 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -8,24 +8,21 @@ * */ -/** - * Extensions to CMC - * - * - INIT - */ - #ifndef CMC_EXT_CMC_DEQUE_H #define CMC_EXT_CMC_DEQUE_H #include "../../cor/core.h" -#define CMC_EXT_CMC_DEQUE_PARTS INIT, +/** + * All the EXT parts of CMC Deque. + */ +#define CMC_EXT_CMC_DEQUE_PARTS INIT, ITER, STR /** * INIT * * The part 'INIT' gives a new way of initializing a collection. The collection - * struct is not heap allocated, only its internal structure (nodes, buffers) + * struct is not heap allocated, only its internal structure (nodes, buffers). */ #define CMC_EXT_CMC_DEQUE_INIT(BODY) \ CMC_EXT_CMC_DEQUE_INIT_HEADER(BODY) \ @@ -79,7 +76,7 @@ _deque_.count = 0; \ _deque_.front = 0; \ _deque_.back = 0; \ - _deque_.flag = cmc_flags.OK; \ + _deque_.flag = CMC_FLAG_OK; \ _deque_.f_val = f_val; \ _deque_.alloc = alloc; \ _deque_.callbacks = callbacks; \ @@ -87,4 +84,334 @@ return _deque_; \ } +/** + * ITER + */ +#define CMC_EXT_CMC_DEQUE_ITER(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY) + +#define CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ + /* Deque Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target deque */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = target->front; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + if (iter.target->back == 0) \ + iter.cursor = iter.target->capacity - 1; \ + else \ + iter.cursor = iter.target->back - 1; \ + \ + iter.index = iter.target->count - 1; \ + } \ + else \ + { \ + iter.cursor = 0; \ + iter.index = 0; \ + } \ + \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->front; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = false; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + 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 = false; \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ + iter->index++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(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 CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + iter->start = CMC_(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 CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * 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 = CMC_(PFX, _empty)(iter->target); \ + \ + iter->index -= steps; \ + \ + /* Prevent underflow */ \ + if (iter->cursor < steps) \ + iter->cursor += iter->target->capacity; \ + \ + iter->cursor -= steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor]; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->target->buffer[iter->cursor]); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_DEQUE_STR(BODY) \ + CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) + +#define CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) \ + CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \ + { \ + struct SNAME *d_ = _deque_; \ + \ + return 0 <= fprintf(fptr, cmc_cmc_string_fmt_deque, \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, \ + d_->buffer, d_->capacity, d_->count, d_->front, \ + d_->back, d_->flag, d_->f_val, d_->alloc, \ + d_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \ + return false; \ + \ + i = (i + 1) % _deque_->capacity; \ + \ + if (j + 1 < _deque_->count) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + #endif /* CMC_EXT_CMC_DEQUE_H */ diff --git a/src/ext/cmc/hashbidimap.h b/src/ext/cmc/hashbidimap.h index aa2cfa5..c3cd76a 100644 --- a/src/ext/cmc/hashbidimap.h +++ b/src/ext/cmc/hashbidimap.h @@ -7,3 +7,15 @@ * Leonardo Vencovsky (https://github.com/LeoVen) * */ + +#ifndef CMC_EXT_CMC_HASHBIDIMAP_H +#define CMC_EXT_CMC_HASHBIDIMAP_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC HashBidiMap. + */ +#define CMC_EXT_CMC_HASHBIDIMAP_PARTS + +#endif /* CMC_EXT_CMC_HASHBIDIMAP_H */ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 48e1987..9c462ae 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -8,18 +8,15 @@ * */ -/** - * Extensions to CMC - * - * - INIT - */ - #ifndef CMC_EXT_CMC_HASHMAP_H #define CMC_EXT_CMC_HASHMAP_H #include "../../cor/core.h" -#define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER +/** + * All the EXT parts of CMC HashMap. + */ +#define CMC_EXT_CMC_HASHMAP_PARTS INIT, STR /** * INIT @@ -91,7 +88,7 @@ _map_.count = 0; \ _map_.capacity = real_capacity; \ _map_.load = load; \ - _map_.flag = cmc_flags.OK; \ + _map_.flag = CMC_FLAG_OK; \ _map_.f_key = f_key; \ _map_.f_val = f_val; \ _map_.alloc = alloc; \ @@ -100,4 +97,79 @@ return _map_; \ } +/** + * STR + * + * The part 'STR' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#define CMC_EXT_CMC_HASHMAP_STR(BODY) \ + CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, V) \ + \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_, \ + FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) + +#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ + { \ + struct SNAME *m_ = _map_; \ + \ + return 0 <= fprintf(fptr, cmc_string_len, cmc_cmc_string_fmt_hashmap, \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(K), \ + CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \ + m_->count, m_->load, m_->flag, m_->f_key, \ + m_->f_val, m_->alloc, m_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + size_t last = 0; \ + for (size_t i = _map_->capacity; i > 0; i--) \ + { \ + if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ + \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \ + \ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_map_->f_key->str(fptr, entry->key) || \ + !_map_->f_val->str(fptr, entry->value)) \ + return false; \ + } \ + \ + if (i + 1 < last) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + #endif /* CMC_EXT_CMC_HASHMAP_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 35c7b5b..51495da 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -11,6 +11,7 @@ #ifndef CMC_MACRO_COLLECTIONS_H #define CMC_MACRO_COLLECTIONS_H +// clang-format off #include "cmc/bitset.h" /* Added in 30/04/2020 */ #include "cmc/deque.h" /* Added in 20/03/2019 */ #include "cmc/hashbidimap.h" /* Added in 26/09/2019 */ @@ -27,13 +28,18 @@ #include "cmc/stack.h" /* Added in 14/02/2019 */ #include "cmc/treemap.h" /* Added in 28/03/2019 */ #include "cmc/treeset.h" /* Added in 27/03/2019 */ + #include "cor/alloc.h" /* Added in 24/05/2020 */ #include "cor/bitset.h" /* Added in 20/05/2020 */ #include "cor/callbacks.h" /* Added in 24/05/2020 */ #include "cor/core.h" /* Added in 17/03/2020 */ #include "cor/flags.h" /* Added in 14/05/2020 */ +#include "cor/ftable.h" /* Added in 27/05/2020 */ #include "cor/hashtable.h" /* Added in 17/03/2020 */ + #include "ext/cmc/deque.h" /* Added in 25/05/2020 */ +#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ + #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ #include "utl/futils.h" /* Added in 15/04/2020 */ @@ -42,6 +48,7 @@ #include "utl/test.h" /* Added in 26/06/2019 */ #include "utl/thread.h" /* Added in 14/05/2020 */ #include "utl/timer.h" /* Added in 12/04/2019 */ +// clang-format on /** * Generate a specific part of a collection @@ -72,6 +79,28 @@ #define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \ CMC_EXT_##LIB##_##COLLECTION##_PARTS +/** + * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: + * + * CMC_NARG(HELLO) -> 0 + * CMC_NARG(HELLO,) -> 1 + * CMC_NARG(HELLO, WORLD,) -> 2 + */ +#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N()) +#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__) +#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ + _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ + _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ + _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ + _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ + _62, _63, N, ...) \ + N +#define CMC_SEQ_N() \ + 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \ + 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \ + 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 + #define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \ CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ (LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)