diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index a1e23ea..0c05769 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -26,21 +26,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * IntervalHeap specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "size:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core IntervalHeap implementation */ @@ -59,133 +44,93 @@ static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Heap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ - V (*buffer)[2]; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of pairs of values in the array */ \ - size_t size; \ - \ - /* Current amount of elements in the heap */ \ - 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); \ - }; \ - \ - /* Heap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target heap */ \ - 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 * _heap_); \ - void CMC_(PFX, _free)(struct SNAME * _heap_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ - bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ - /* Collection Update */ \ - bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ - /* Element Access */ \ - V CMC_(PFX, _max)(struct SNAME * _heap_); \ - V CMC_(PFX, _min)(struct SNAME * _heap_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ - bool CMC_(PFX, _full)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ - int CMC_(PFX, _flag)(struct SNAME * _heap_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_); \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, 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); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* IntervalHeap Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ + V (*buffer)[2]; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of pairs of values in the array */ \ + size_t size; \ + \ + /* Current amount of elements in the heap */ \ + 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 * _heap_); \ + void CMC_(PFX, _free)(struct SNAME * _heap_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ + bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ + /* Collection Update */ \ + bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ + /* Element Access */ \ + V CMC_(PFX, _max)(struct SNAME * _heap_); \ + V CMC_(PFX, _min)(struct SNAME * _heap_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ + bool CMC_(PFX, _full)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ + int CMC_(PFX, _flag)(struct SNAME * _heap_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); /* ------------------------------------------------------------------------- * Source @@ -754,209 +699,6 @@ static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_) \ - { \ - struct cmc_string str; \ - struct SNAME *h_ = _heap_; \ - \ - int n = snprintf(str.s, cmc_string_len, \ - cmc_cmc_string_fmt_intervalheap, #SNAME, #V, h_, \ - h_->buffer, h_->capacity, h_->size, h_->count, \ - h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \ - 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->cursor = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - 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; \ - \ - if (iter->end) \ - 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 / 2][iter->cursor % 2]; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } \ - \ static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_) \ { \ size_t index = _heap_->size - 1; \ diff --git a/src/ext/cmc/intervalheap.h b/src/ext/cmc/intervalheap.h new file mode 100644 index 0000000..a5d5992 --- /dev/null +++ b/src/ext/cmc/intervalheap.h @@ -0,0 +1,320 @@ +/** + * ext/cmc/intervalheap.h + * + * Creation Date: 02/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_INTERVALHEAP_H +#define CMC_EXT_CMC_INTERVALHEAP_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC IntervalHeap. + */ +#define CMC_EXT_CMC_INTERVALHEAP_PARTS ITER, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_INTERVALHEAP_ITER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* IntervalHeap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target IntervalHeap */ \ + 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); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_INTERVALHEAP_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->cursor = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + 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; \ + \ + if (iter->end) \ + 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 / 2][iter->cursor % 2]; \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_INTERVALHEAP_STR(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ + { \ + struct SNAME *h_ = _heap_; \ + \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "size:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \ + h_->buffer, h_->capacity, h_->size, h_->count, \ + h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \ + return false; \ + \ + if (i + 1 < _heap_->count) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_INTERVALHEAP_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index a49ba68..730561d 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -59,6 +59,7 @@ #include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */ #include "ext/cmc/hashset.h" /* Added in 31/05/2020 */ #include "ext/cmc/heap.h" /* Added in 01/06/2020 */ +#include "ext/cmc/intervalheap.h" /* Added in 02/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 3c0365c..74357d4 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -9,6 +9,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) 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)) struct { @@ -33,6 +34,7 @@ int main(void) struct hashset *hs = hs_new(100, 0.6, (struct hashset_fval *)&int_ftab); 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); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -46,8 +48,35 @@ int main(void) hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); h_to_string(h, stdout); h_print(h, stdout, "\n[ ", ", ", " ]\n"); + ih_to_string(ih, stdout); + ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); - for (int i = 0; i < 20; i++) + fprintf(stdout, "\n"); + + d_push_back(d, 0); + hm_insert(hm, 0, 0); + hmm_insert(hmm, 0, 0); + hms_insert(hms, 0); + hs_insert(hs, 0); + h_insert(h, 0); + ih_insert(ih, 0); + + d_to_string(d, stdout); + d_print(d, stdout, "\n[ ", ", ", " ]\n"); + hm_to_string(hm, stdout); + hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hmm_to_string(hmm, stdout); + hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hms_to_string(hms, stdout); + hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hs_to_string(hs, stdout); + hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); + h_to_string(h, stdout); + h_print(h, stdout, "\n[ ", ", ", " ]\n"); + ih_to_string(ih, stdout); + ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + + for (int i = 1; i < 20; i++) { d_push_back(d, i); hm_insert(hm, i, i); @@ -55,6 +84,7 @@ int main(void) hms_insert(hms, i); hs_insert(hs, i); h_insert(h, i); + ih_insert(ih, i); } fprintf(stdout, "\n"); @@ -71,12 +101,16 @@ int main(void) hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); h_to_string(h, stdout); h_print(h, stdout, "\n[ ", ", ", " ]\n"); + ih_to_string(ih, stdout); + ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); hmm_free(hmm); hms_free(hms); hs_free(hs); + h_free(h); + ih_free(ih); } // clang-format on