diff --git a/src/cmc/list.h b/src/cmc/list.h index d0254cd..1353481 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -48,20 +48,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * List specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core List implementation */ @@ -80,146 +66,94 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_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; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - 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); \ - }; \ - \ - /* List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* 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 *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 * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Collection Sequence Input and Output */ \ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ - size_t size); \ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ - size_t size, size_t index); \ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ - size_t size); \ - bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \ - size_t to); \ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ - size_t to); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ - bool from_start); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - bool CMC_(PFX, _full)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, 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_LIST_CORE_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; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + 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 * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ + V CMC_(PFX, _back)(struct SNAME * _list_); \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ + bool from_start); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + bool CMC_(PFX, _full)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- * Source @@ -465,177 +399,6 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ - size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + size, _list_->buffer, \ - _list_->count * sizeof(V)); \ - \ - memcpy(_list_->buffer, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ - size_t size, size_t index) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - return CMC_(PFX, _seq_push_front)(_list_, values, size); \ - else if (index == _list_->count) \ - return CMC_(PFX, _seq_push_back)(_list_, values, size); \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + index + size, _list_->buffer + index, \ - (_list_->count - index) * sizeof(V)); \ - \ - memcpy(_list_->buffer + index, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ - size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - size_t length = (to - from + 1); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, \ - (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, \ - length * sizeof(V)); \ - \ - _list_->count -= to - from + 1; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ - size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return NULL; \ - } \ - \ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - size_t length = to - from + 1; \ - \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - length, _list_->f_val, _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, \ - (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, \ - length * sizeof(V)); \ - \ - _list_->count -= length; \ - result->count = length; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return result; \ - } \ - \ V CMC_(PFX, _front)(struct SNAME * _list_) \ { \ if (CMC_(PFX, _empty)(_list_)) \ @@ -869,219 +632,12 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " \ for (size_t i = 0; i < _list1_->count; i++) \ { \ - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \ - 0) \ + if (0 != \ + _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \ return false; \ } \ \ return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ - { \ - struct cmc_string str; \ - struct SNAME *l_ = _list_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_list, \ - #SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \ - l_->flag, l_->f_val, l_->alloc, l_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ - return false; \ - } \ - \ - 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 = 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; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - 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 = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->target->count - 1; \ - 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->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - 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->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - 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->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - 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->cursor; \ } #endif /* CMC_CMC_LIST_H */ diff --git a/src/ext/cmc/linkedlist.h b/src/ext/cmc/linkedlist.h index 15d1f3a..bb1f18e 100644 --- a/src/ext/cmc/linkedlist.h +++ b/src/ext/cmc/linkedlist.h @@ -1,7 +1,7 @@ /** * ext/cmc/linkedlist.h * - * Creation Date: 26/05/2020 + * Creation Date: 03/06/2020 * * Authors: * Leonardo Vencovsky (https://github.com/LeoVen) diff --git a/src/ext/cmc/list.h b/src/ext/cmc/list.h new file mode 100644 index 0000000..155d6d7 --- /dev/null +++ b/src/ext/cmc/list.h @@ -0,0 +1,527 @@ +/** + * ext/cmc/list.h + * + * Creation Date: 04/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_LIST_H +#define CMC_EXT_CMC_LIST_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC List. + */ +#define CMC_EXT_CMC_LIST_PARTS ITER, SEQ, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_LIST_ITER(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* 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; \ + }; \ + \ + /* 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_LIST_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 = 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; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ + \ + 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 = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->target->count - 1; \ + 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->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor--; \ + \ + 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->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor += steps; \ + \ + 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->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor < steps) \ + return false; \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor -= steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ + \ + 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->cursor; \ + } + +/** + * SEQ + */ +#define CMC_EXT_CMC_LIST_SEQ(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_SEQ_HEADER_(PFX, SNAME, V) \ + \ + /* List Sequence Input and Output */ \ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ + size_t size); \ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ + size_t size, size_t index); \ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ + size_t size); \ + bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \ + size_t to); \ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ + size_t to); + +#define CMC_EXT_CMC_LIST_SEQ_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ + size_t size) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ + \ + memmove(_list_->buffer + size, _list_->buffer, \ + _list_->count * sizeof(V)); \ + \ + memcpy(_list_->buffer, values, size * sizeof(V)); \ + \ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ + size_t size, size_t index) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (index > _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + if (index == 0) \ + return CMC_(PFX, _seq_push_front)(_list_, values, size); \ + else if (index == _list_->count) \ + return CMC_(PFX, _seq_push_back)(_list_, values, size); \ + \ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ + \ + memmove(_list_->buffer + index + size, _list_->buffer + index, \ + (_list_->count - index) * sizeof(V)); \ + \ + memcpy(_list_->buffer + index, values, size * sizeof(V)); \ + \ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ + size_t size) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ + \ + memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ + \ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \ + { \ + if (from > to) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (to >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + size_t length = (to - from + 1); \ + \ + memmove(_list_->buffer + from, _list_->buffer + to + 1, \ + (_list_->count - to - 1) * sizeof(V)); \ + \ + memset(_list_->buffer + _list_->count - length, 0, \ + length * sizeof(V)); \ + \ + _list_->count -= to - from + 1; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ + size_t to) \ + { \ + if (from > to) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return NULL; \ + } \ + \ + if (to >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ + \ + size_t length = to - from + 1; \ + \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + length, _list_->f_val, _list_->alloc, _list_->callbacks); \ + \ + if (!result) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \ + \ + memmove(_list_->buffer + from, _list_->buffer + to + 1, \ + (_list_->count - to - 1) * sizeof(V)); \ + \ + memset(_list_->buffer + _list_->count - length, 0, \ + length * sizeof(V)); \ + \ + _list_->count -= length; \ + result->count = length; \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return result; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_LIST_STR(PARAMS) \ + CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_LIST_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ + { \ + struct SNAME *l_ = _list_; \ + \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \ + l_->buffer, l_->capacity, l_->count, l_->flag, \ + l_->f_val, l_->alloc, l_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ + return false; \ + \ + if (i + 1 < _list_->count) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_LIST_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 6ad0562..50bb4a2 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -61,6 +61,7 @@ #include "ext/cmc/heap.h" /* Added in 01/06/2020 */ #include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */ #include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */ +#include "ext/cmc/list.h" /* Added in 04/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/to_string.c b/tests/to_string.c index 1aad044..72dd3fd 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -11,6 +11,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) struct { @@ -37,6 +38,7 @@ int main(void) struct heap *h = h_new(100, CMC_MAX_HEAP, (struct heap_fval *)&int_ftab); struct intervalheap *ih = ih_new(100, (struct intervalheap_fval *)&int_ftab); struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab); + struct list *l = l_new(100, (struct list_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -54,6 +56,8 @@ int main(void) ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); ll_to_string(ll, stdout); ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); + l_to_string(l, stdout); + l_print(l, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -65,6 +69,7 @@ int main(void) h_insert(h, 0); ih_insert(ih, 0); ll_push_back(ll, 0); + l_push_back(l, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -82,6 +87,8 @@ int main(void) ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); ll_to_string(ll, stdout); ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); + l_to_string(l, stdout); + l_print(l, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -93,6 +100,7 @@ int main(void) h_insert(h, i); ih_insert(ih, i); ll_push_back(ll, i); + l_push_back(l, i); } fprintf(stdout, "\n"); @@ -113,6 +121,8 @@ int main(void) ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); ll_to_string(ll, stdout); ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); + l_to_string(l, stdout); + l_print(l, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); @@ -121,6 +131,8 @@ int main(void) hs_free(hs); h_free(h); ih_free(ih); + ll_free(ll); + l_free(l); } // clang-format on