From 63eb52540699341729fff620a89104d146a0ab3c Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 3 Jun 2020 18:38:49 -0300 Subject: [PATCH] Moving more things to EXT --- src/cmc/hashmultiset.h | 299 +----- src/cmc/hashset.h | 465 ++------- src/cmc/linkedlist.h | 1680 +++++++++++---------------------- src/ext/cmc/hashmultiset.h | 318 ++++++- src/ext/cmc/hashset.h | 294 +++++- src/ext/cmc/linkedlist.h | 607 ++++++++++++ src/macro_collections.h | 1 + tests/main/src/intervalheap.c | 20 - tests/main/src/linkedlist.c | 22 - tests/to_string.c | 10 + 10 files changed, 1902 insertions(+), 1814 deletions(-) create mode 100644 src/ext/cmc/linkedlist.h diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index daaa563..91d80de 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -161,28 +161,7 @@ /* Collection Utility */ \ bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - \ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -810,282 +789,6 @@ return true; \ } \ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - size_t max_ = m1 > m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ - size_t max_ = m1 > m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct SNAME *_set_A_ = \ - _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ - size_t max_ = m1 < m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter1), \ - CMC_(PFX, _iter_multiplicity)(&iter1)); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter2), \ - CMC_(PFX, _iter_multiplicity)(&iter2)); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ - \ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - if (_set1_->count > _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 > m2) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ - \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - if (_set1_->count >= _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - else \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 >= m2) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ - \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \ V value) \ { \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 4b230da..08ac2af 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -47,121 +47,102 @@ /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Hashset Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ - \ - /* Current Array Capcity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* 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; \ - }; \ - \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry value */ \ - V value; \ - \ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ - \ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; \ - \ - /* 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, double load, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - bool CMC_(PFX, _full)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ - double CMC_(PFX, _load)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - \ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); +#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Hashset Structure */ \ + struct SNAME \ + { \ + /* Array of Entries */ \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ + \ + /* Current Array Capcity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ + \ + /* 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; \ + }; \ + \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry value */ \ + V value; \ + \ + /* The distance of this node to its original position, used by */ \ + /* robin-hood hashing */ \ + size_t dist; \ + \ + /* The sate of this node (DELETED, EMPTY, FILLED) */ \ + enum cmc_entry_state state; \ + }; \ + \ + /* 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, double load, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + bool CMC_(PFX, _full)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ + double CMC_(PFX, _load)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -669,260 +650,6 @@ return true; \ } \ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - /* TODO turn this into a normal loop and check for errors */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct SNAME *_set_A_ = \ - _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - /* Is _set1_ a subset of _set2_ ? */ \ - /* A set X is a subset of a set Y when: X <= Y */ \ - /* If X is a subset of Y, then Y is a superset of X */ \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* If the cardinality of _set1_ is greater than that of _set2_, */ \ - /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ - if (_set1_->count > _set2_->count) \ - return false; \ - \ - /* The empty set is a subset of all sets */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a superset of _set2_ ? */ \ - /* A set X is a superset of a set Y when: X >= Y */ \ - /* If X is a superset of Y, then Y is a subset of X */ \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a proper subset of _set2_ ? */ \ - /* A set X is a proper subset of a set Y when: X < Y */ \ - /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* If the cardinality of _set1_ is greater than or equal to that of */ \ - /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ - /* subset of _set2_ */ \ - if (_set1_->count >= _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - /* The empty set is a proper subset of all non-empty sets */ \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - /* The empty set is not a proper subset of itself (this is true */ \ - /* for any set) */ \ - else \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a proper superset of _set2_ ? */ \ - /* A set X is a proper superset of a set Y when: X > Y */ \ - /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a disjointset of _set2_ ? */ \ - /* A set X is a disjointset of a set Y if their intersection is empty, */ \ - /* that is, if there are no elements in common between the two */ \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* The intersection of an empty set with any other set will result */ \ - /* in an empty set */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ static struct CMC_DEF_ENTRY(SNAME) * \ CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ { \ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index 7d76647..b332033 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -33,20 +33,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * LinkedList specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_linkedlist = "struct %s<%s> " - "at %p { " - "count:%" PRIuMAX ", " - "head:%p, " - "tail:%p, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core LinkedList implementation */ @@ -65,1099 +51,587 @@ static const char *cmc_cmc_string_fmt_linkedlist = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Linked List Structure */ \ - struct SNAME \ - { \ - /* First node in the list */ \ - struct CMC_DEF_NODE(SNAME) * head; \ - \ - /* Last node in the list */ \ - struct CMC_DEF_NODE(SNAME) * tail; \ - \ - /* Current amount of elements in the list */ \ - 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; \ - }; \ - \ - /* Doubly-linked list node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node's value */ \ - V value; \ - \ - /* Pointer to the next node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * next; \ - \ - /* Pointer to the previous node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * prev; \ - }; \ - \ - /* 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); \ - }; \ - \ - /* Linked List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target Linked List */ \ - struct SNAME *target; \ - \ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * 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)(struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(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_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - 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); \ - \ - /* Node Related Functions */ \ - /* Node Allocation and Deallocation */ \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ - void CMC_(PFX, _free_node)(struct SNAME * _list_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List */ \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ - /* Input and Output Relative to a Node */ \ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List Node */ \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ - \ - /* 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); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Linked List Structure */ \ + struct SNAME \ + { \ + /* First node in the list */ \ + struct CMC_DEF_NODE(SNAME) * head; \ + \ + /* Last node in the list */ \ + struct CMC_DEF_NODE(SNAME) * tail; \ + \ + /* Current amount of elements in the list */ \ + 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; \ + }; \ + \ + /* Doubly-linked list node */ \ + struct CMC_DEF_NODE(SNAME) \ + { \ + /* Node's value */ \ + V value; \ + \ + /* Pointer to the next node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * next; \ + \ + /* Pointer to the previous node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * prev; \ + }; \ + \ + /* 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)(struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(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_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - if (!f_val) \ - return NULL; \ - \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = NULL; \ - \ - return _list_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = callbacks; \ - \ - return _list_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (_list_->head != NULL) \ - { \ - _list_->head = _list_->head->next; \ - \ - if (_list_->f_val->free) \ - { \ - _list_->f_val->free(scan->value); \ - } \ - \ - _list_->alloc->free(scan); \ - \ - scan = _list_->head; \ - } \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - CMC_(PFX, _clear)(_list_); \ - \ - _list_->alloc->free(_list_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ - \ - _list_->callbacks = callbacks; \ - \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->next = _list_->head; \ - _list_->head->prev = _node_; \ - _list_->head = _node_; \ - } \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ - { \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - { \ - return CMC_(PFX, _push_front)(_list_, value); \ - } \ - else if (index == _list_->count) \ - { \ - return CMC_(PFX, _push_back)(_list_, value); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index - 1); \ - \ - _node_->next = scan->next; \ - _node_->prev = scan; \ - _node_->next->prev = _node_; \ - _node_->prev->next = _node_; \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->prev = _list_->tail; \ - _list_->tail->next = _node_; \ - _list_->tail = _node_; \ - } \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ - _list_->head = _list_->head->next; \ - \ - _list_->alloc->free(_node_); \ - \ - if (_list_->head == NULL) \ - _list_->tail = NULL; \ - else \ - _list_->head->prev = NULL; \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - { \ - return CMC_(PFX, _pop_front)(_list_); \ - } \ - else if (index == _list_->count - 1) \ - { \ - return CMC_(PFX, _pop_back)(_list_); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (!_node_) \ - return false; \ - \ - _node_->next->prev = _node_->prev; \ - _node_->prev->next = _node_->next; \ - \ - _list_->alloc->free(_node_); \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ - _list_->tail = _list_->tail->prev; \ - \ - _list_->alloc->free(_node_); \ - \ - if (_list_->tail == NULL) \ - _list_->head = NULL; \ - else \ - _list_->tail->next = NULL; \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->head->value; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (scan == NULL) \ - return (V){ 0 }; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return scan->value; \ - } \ - \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (scan == NULL) \ - return NULL; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return &(scan->value); \ - } \ - \ - V CMC_(PFX, _back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->tail->value; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - if (_list_->f_val->cmp(scan->value, value) == 0) \ - { \ - result = true; \ - break; \ - } \ - \ - scan = scan->next; \ - } \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _list_->f_val, _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - return NULL; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - /* This allocation should never fail since it might not be */ \ - /* possible to recover from it. That is why it isn't checked */ \ - struct CMC_DEF_NODE(SNAME) * new_node; \ - \ - if (_list_->f_val->cpy) \ - new_node = CMC_(PFX, _new_node)( \ - _list_, _list_->f_val->cpy(scan->value)); \ - else \ - new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ - \ - if (!result->head) \ - { \ - result->head = new_node; \ - result->tail = new_node; \ - } \ - else \ - { \ - new_node->prev = result->tail; \ - result->tail->next = new_node; \ - result->tail = new_node; \ - } \ - \ - scan = scan->next; \ - } \ - \ - result->count = _list_->count; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - _list1_->flag = CMC_FLAG_OK; \ - _list2_->flag = CMC_FLAG_OK; \ - \ - if (_list1_->count != _list2_->count) \ - return false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ - struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ - \ - while (scan1 != NULL && scan2 != NULL) \ - { \ - if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \ - return false; \ - \ - scan1 = scan1->next; \ - scan2 = scan2->next; \ - } \ - \ - 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_linkedlist, \ - #SNAME, #V, l_, l_->count, l_->head, l_->tail, \ - 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) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - if (!_list_->f_val->str(fptr, scan->value)) \ - return false; \ - \ - scan = scan->next; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ - \ - if (!_node_) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - _node_->value = value; \ - _node_->next = NULL; \ - _node_->prev = NULL; \ - \ - return _node_; \ - } \ - \ - void CMC_(PFX, _free_node)(struct SNAME * _list_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - _list_->alloc->free(_node_); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ - { \ - return _list_->head; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ - \ - if (index <= _list_->count / 2) \ - { \ - _node_ = _list_->head; \ - for (size_t i = 0; i < index; i++) \ - { \ - _node_ = _node_->next; \ - } \ - } \ - else \ - { \ - _node_ = _list_->tail; \ - for (size_t i = _list_->count - 1; i > index; i--) \ - { \ - _node_ = _node_->prev; \ - } \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return _node_; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ - { \ - return _list_->tail; \ - } \ - \ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = \ - CMC_(PFX, _new_node)(_owner_, value); \ - \ - if (!new_node) \ - return false; \ - \ - new_node->next = _node_->next; \ - \ - if (_node_->next != NULL) \ - _node_->next->prev = new_node; \ - else \ - _owner_->tail = new_node; \ - \ - new_node->prev = _node_; \ - _node_->next = new_node; \ - \ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = \ - CMC_(PFX, _new_node)(_owner_, value); \ - \ - if (!new_node) \ - return false; \ - \ - new_node->prev = _node_->prev; \ - \ - if (_node_->prev != NULL) \ - _node_->prev->next = new_node; \ - else \ - _owner_->head = new_node; \ - \ - new_node->next = _node_; \ - _node_->prev = new_node; \ - \ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->next == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ - \ - _node_->next = _node_->next->next; \ - \ - if (tmp->next != NULL) \ - tmp->next->prev = _node_; \ - else \ - _owner_->tail = _node_; \ - \ - _owner_->alloc->free(tmp); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev != NULL) \ - _node_->prev->next = _node_->next; \ - else \ - _owner_->head = _node_->next; \ - \ - if (_node_->next != NULL) \ - _node_->next->prev = _node_->prev; \ - else \ - _owner_->tail = _node_->prev; \ - \ - _owner_->alloc->free(_node_); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ - \ - _node_->prev = _node_->prev->prev; \ - \ - if (tmp->prev != NULL) \ - tmp->prev->next = _node_; \ - else \ - _owner_->head = _node_; \ - \ - _owner_->alloc->free(tmp); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->next; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->prev; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->head; \ - 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; \ - iter.cursor = target->tail; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.index = 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 = iter->target->head; \ - iter->index = 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->tail; \ - iter->index = 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->next == NULL) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = iter->cursor->next; \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = iter->cursor->prev; \ - 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->cursor->next == NULL) \ - { \ - 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; \ - \ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->next; \ - \ - 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->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index -= steps; \ - \ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->prev; \ - \ - 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->cursor->value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->cursor->value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ +#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ + \ + /* Implementation Detail Functions */ \ + /* None */ \ + \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + if (!f_val) \ + return NULL; \ + \ + struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_list_) \ + return NULL; \ + \ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + _list_->callbacks = NULL; \ + \ + return _list_; \ + } \ + \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!f_val) \ + return NULL; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_list_) \ + return NULL; \ + \ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + _list_->callbacks = callbacks; \ + \ + return _list_; \ + } \ + \ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (_list_->head != NULL) \ + { \ + _list_->head = _list_->head->next; \ + \ + if (_list_->f_val->free) \ + { \ + _list_->f_val->free(scan->value); \ + } \ + \ + _list_->alloc->free(scan); \ + \ + scan = _list_->head; \ + } \ + \ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + } \ + \ + void CMC_(PFX, _free)(struct SNAME * _list_) \ + { \ + CMC_(PFX, _clear)(_list_); \ + \ + _list_->alloc->free(_list_); \ + } \ + \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!alloc) \ + _list_->alloc = &cmc_alloc_node_default; \ + else \ + _list_->alloc = alloc; \ + \ + _list_->callbacks = callbacks; \ + \ + _list_->flag = CMC_FLAG_OK; \ + } \ + \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ + \ + if (!_node_) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->head = _node_; \ + _list_->tail = _node_; \ + } \ + else \ + { \ + _node_->next = _list_->head; \ + _list_->head->prev = _node_; \ + _list_->head = _node_; \ + } \ + \ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ + { \ + if (index > _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + if (index == 0) \ + { \ + return CMC_(PFX, _push_front)(_list_, value); \ + } \ + else if (index == _list_->count) \ + { \ + return CMC_(PFX, _push_back)(_list_, value); \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ + \ + if (!_node_) \ + return false; \ + \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index - 1); \ + \ + _node_->next = scan->next; \ + _node_->prev = scan; \ + _node_->next->prev = _node_; \ + _node_->prev->next = _node_; \ + \ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ + \ + if (!_node_) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->head = _node_; \ + _list_->tail = _node_; \ + } \ + else \ + { \ + _node_->prev = _list_->tail; \ + _list_->tail->next = _node_; \ + _list_->tail = _node_; \ + } \ + \ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ + _list_->head = _list_->head->next; \ + \ + _list_->alloc->free(_node_); \ + \ + if (_list_->head == NULL) \ + _list_->tail = NULL; \ + else \ + _list_->head->prev = NULL; \ + \ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + if (index == 0) \ + { \ + return CMC_(PFX, _pop_front)(_list_); \ + } \ + else if (index == _list_->count - 1) \ + { \ + return CMC_(PFX, _pop_back)(_list_); \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _get_node)(_list_, index); \ + \ + if (!_node_) \ + return false; \ + \ + _node_->next->prev = _node_->prev; \ + _node_->prev->next = _node_->next; \ + \ + _list_->alloc->free(_node_); \ + \ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ + _list_->tail = _list_->tail->prev; \ + \ + _list_->alloc->free(_node_); \ + \ + if (_list_->tail == NULL) \ + _list_->head = NULL; \ + else \ + _list_->tail->next = NULL; \ + \ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return _list_->head->value; \ + } \ + \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return (V){ 0 }; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index); \ + \ + if (scan == NULL) \ + return (V){ 0 }; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return scan->value; \ + } \ + \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return NULL; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index); \ + \ + if (scan == NULL) \ + return NULL; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return &(scan->value); \ + } \ + \ + V CMC_(PFX, _back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return _list_->tail->value; \ + } \ + \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ + { \ + _list_->flag = CMC_FLAG_OK; \ + \ + bool result = false; \ + \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (scan != NULL) \ + { \ + if (_list_->f_val->cmp(scan->value, value) == 0) \ + { \ + result = true; \ + break; \ + } \ + \ + scan = scan->next; \ + } \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ + { \ + return _list_->count == 0; \ + } \ + \ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ + { \ + return _list_->count; \ + } \ + \ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ + { \ + return _list_->flag; \ + } \ + \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _list_->f_val, _list_->alloc, _list_->callbacks); \ + \ + if (!result) \ + return NULL; \ + \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (scan != NULL) \ + { \ + /* This allocation should never fail since it might not be */ \ + /* possible to recover from it. That is why it isn't checked */ \ + struct CMC_DEF_NODE(SNAME) * new_node; \ + \ + if (_list_->f_val->cpy) \ + new_node = CMC_(PFX, _new_node)( \ + _list_, _list_->f_val->cpy(scan->value)); \ + else \ + new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ + \ + if (!result->head) \ + { \ + result->head = new_node; \ + result->tail = new_node; \ + } \ + else \ + { \ + new_node->prev = result->tail; \ + result->tail->next = new_node; \ + result->tail = new_node; \ + } \ + \ + scan = scan->next; \ + } \ + \ + result->count = _list_->count; \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ + { \ + _list1_->flag = CMC_FLAG_OK; \ + _list2_->flag = CMC_FLAG_OK; \ + \ + if (_list1_->count != _list2_->count) \ + return false; \ + \ + struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ + struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ + \ + while (scan1 != NULL && scan2 != NULL) \ + { \ + if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \ + return false; \ + \ + scan1 = scan1->next; \ + scan2 = scan2->next; \ + } \ + \ + return true; \ } #endif /* CMC_CMC_LINKEDLIST_H */ diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index 518eea0..af1b848 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -16,7 +16,7 @@ /** * All the EXT parts of CMC HashMultiSet. */ -#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, STR +#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, SETF, STR /** * ITER @@ -342,6 +342,322 @@ return iter->index; \ } +/** + * SETF + */ +#define CMC_EXT_CMC_HASHMULTISET_SETF(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(PFX, SNAME, V) \ + \ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); + +#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + size_t max_ = m1 > m2 ? m1 : m2; \ + \ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ + \ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ + size_t max_ = m1 > m2 ? m1 : m2; \ + \ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct SNAME *_set_A_ = \ + _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ + size_t max_ = m1 < m2 ? m1 : m2; \ + \ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter1), \ + CMC_(PFX, _iter_multiplicity)(&iter1)); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter2), \ + CMC_(PFX, _iter_multiplicity)(&iter2)); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 != m2) \ + { \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + else \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ + } \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ + \ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ + \ + if (m1 != m2) \ + { \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + else \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ + } \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + if (_set1_->count > _set2_->count) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 > m2) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ + \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + if (_set1_->count >= _set2_->count) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ + else \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 >= m2) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ + \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ + return false; \ + } \ + \ + return true; \ + } + /** * STR */ diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index 933ce46..cdb627e 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -16,7 +16,7 @@ /** * All the EXT parts of CMC HashSet. */ -#define CMC_EXT_CMC_HASHSET_PARTS ITER, STR +#define CMC_EXT_CMC_HASHSET_PARTS ITER, SETF, STR /** * ITER @@ -333,6 +333,298 @@ return iter->index; \ } +/** + * SETF + */ +#define CMC_EXT_CMC_HASHSET_SETF(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) + +#define CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_SETF_HEADER_(PFX, SNAME, V) \ + \ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); + +#define CMC_EXT_CMC_HASHSET_SETF_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + /* TODO turn this into a normal loop and check for errors */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct SNAME *_set_A_ = \ + _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + /* Is _set1_ a subset of _set2_ ? */ \ + /* A set X is a subset of a set Y when: X <= Y */ \ + /* If X is a subset of Y, then Y is a superset of X */ \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ + \ + /* If the cardinality of _set1_ is greater than that of _set2_, */ \ + /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ + if (_set1_->count > _set2_->count) \ + return false; \ + \ + /* The empty set is a subset of all sets */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + /* Is _set1_ a superset of _set2_ ? */ \ + /* A set X is a superset of a set Y when: X >= Y */ \ + /* If X is a superset of Y, then Y is a subset of X */ \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ + \ + /* Is _set1_ a proper subset of _set2_ ? */ \ + /* A set X is a proper subset of a set Y when: X < Y */ \ + /* If X is a proper subset of Y, then Y is a proper superset of X */ \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ + \ + /* If the cardinality of _set1_ is greater than or equal to that of */ \ + /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ + /* subset of _set2_ */ \ + if (_set1_->count >= _set2_->count) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + /* The empty set is a proper subset of all non-empty sets */ \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ + /* The empty set is not a proper subset of itself (this is true */ \ + /* for any set) */ \ + else \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + /* Is _set1_ a proper superset of _set2_ ? */ \ + /* A set X is a proper superset of a set Y when: X > Y */ \ + /* If X is a proper superset of Y, then Y is a proper subset of X */ \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ + \ + /* Is _set1_ a disjointset of _set2_ ? */ \ + /* A set X is a disjointset of a set Y if their intersection is empty, */ \ + /* that is, if there are no elements in common between the two */ \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ + \ + /* The intersection of an empty set with any other set will result */ \ + /* in an empty set */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ + return false; \ + } \ + \ + return true; \ + } + /** * STR */ diff --git a/src/ext/cmc/linkedlist.h b/src/ext/cmc/linkedlist.h new file mode 100644 index 0000000..15d1f3a --- /dev/null +++ b/src/ext/cmc/linkedlist.h @@ -0,0 +1,607 @@ +/** + * ext/cmc/linkedlist.h + * + * Creation Date: 26/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_LINKEDLIST_H +#define CMC_EXT_CMC_LINKEDLIST_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC LinkedList. + */ +#define CMC_EXT_CMC_LINKEDLIST_PARTS ITER, NODE, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_LINKEDLIST_ITER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* LinkedList Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target Linked List */ \ + struct SNAME *target; \ + \ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * 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); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_LINKEDLIST_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->head; \ + 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; \ + iter.cursor = target->tail; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + iter.index = 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 = iter->target->head; \ + iter->index = 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->tail; \ + iter->index = 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->next == NULL) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor = iter->cursor->next; \ + iter->index++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor->prev == NULL) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor = iter->cursor->prev; \ + 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->cursor->next == NULL) \ + { \ + 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; \ + \ + for (size_t i = 0; i < steps; i++) \ + iter->cursor = iter->cursor->next; \ + \ + 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->prev == NULL) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->index -= steps; \ + \ + for (size_t i = 0; i < steps; i++) \ + iter->cursor = iter->cursor->prev; \ + \ + 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->cursor->value; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->cursor->value); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } + +/** + * NODE + */ +#define CMC_EXT_CMC_LINKEDLIST_NODE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \ + \ + /* Node Allocation and Deallocation */ \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ + void CMC_(PFX, _free_node)(struct SNAME * _list_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List */ \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ + /* Input and Output Relative to a Node */ \ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List Node */ \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); + +#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ + \ + if (!_node_) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + _node_->value = value; \ + _node_->next = NULL; \ + _node_->prev = NULL; \ + \ + return _node_; \ + } \ + \ + void CMC_(PFX, _free_node)(struct SNAME * _list_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + _list_->alloc->free(_node_); \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ + { \ + return _list_->head; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return NULL; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ + \ + if (index <= _list_->count / 2) \ + { \ + _node_ = _list_->head; \ + for (size_t i = 0; i < index; i++) \ + { \ + _node_ = _node_->next; \ + } \ + } \ + else \ + { \ + _node_ = _list_->tail; \ + for (size_t i = _list_->count - 1; i > index; i--) \ + { \ + _node_ = _node_->prev; \ + } \ + } \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + return _node_; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ + { \ + return _list_->tail; \ + } \ + \ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *new_node = \ + CMC_(PFX, _new_node)(_owner_, value); \ + \ + if (!new_node) \ + return false; \ + \ + new_node->next = _node_->next; \ + \ + if (_node_->next != NULL) \ + _node_->next->prev = new_node; \ + else \ + _owner_->tail = new_node; \ + \ + new_node->prev = _node_; \ + _node_->next = new_node; \ + \ + _owner_->count++; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *new_node = \ + CMC_(PFX, _new_node)(_owner_, value); \ + \ + if (!new_node) \ + return false; \ + \ + new_node->prev = _node_->prev; \ + \ + if (_node_->prev != NULL) \ + _node_->prev->next = new_node; \ + else \ + _owner_->head = new_node; \ + \ + new_node->next = _node_; \ + _node_->prev = new_node; \ + \ + _owner_->count++; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->next == NULL) \ + { \ + _owner_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ + \ + _node_->next = _node_->next->next; \ + \ + if (tmp->next != NULL) \ + tmp->next->prev = _node_; \ + else \ + _owner_->tail = _node_; \ + \ + _owner_->alloc->free(tmp); \ + \ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->prev != NULL) \ + _node_->prev->next = _node_->next; \ + else \ + _owner_->head = _node_->next; \ + \ + if (_node_->next != NULL) \ + _node_->next->prev = _node_->prev; \ + else \ + _owner_->tail = _node_->prev; \ + \ + _owner_->alloc->free(_node_); \ + \ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->prev == NULL) \ + { \ + _owner_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ + \ + _node_->prev = _node_->prev->prev; \ + \ + if (tmp->prev != NULL) \ + tmp->prev->next = _node_; \ + else \ + _owner_->head = _node_; \ + \ + _owner_->alloc->free(tmp); \ + \ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + return _node_->next; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + return _node_->prev; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_LINKEDLIST_STR(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_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_LINKEDLIST_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 { " \ + "count:%" PRIuMAX ", " \ + "head:%p, " \ + "tail:%p, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \ + l_->count, l_->head, l_->tail, 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); \ + \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (scan != NULL) \ + { \ + if (!_list_->f_val->str(fptr, scan->value)) \ + return false; \ + \ + scan = scan->next; \ + \ + if (scan) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_LINKEDLIST_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 730561d..6ad0562 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -60,6 +60,7 @@ #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 "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index ddcce5b..62522f1 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -477,26 +477,6 @@ _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) } return 1; } -struct cmc_string ih_to_string(struct intervalheap *_heap_) -{ - struct cmc_string str; - struct intervalheap *h_ = _heap_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_intervalheap, - "CMC_PARAM_SNAME((ih, intervalheap, , , size_t))", - "CMC_PARAM_V((ih, intervalheap, , , size_t))", 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 ih_print(struct intervalheap *_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 0; - } - return 1; -} struct intervalheap_iter ih_iter_start(struct intervalheap *target) { struct intervalheap_iter iter; diff --git a/tests/main/src/linkedlist.c b/tests/main/src/linkedlist.c index acf7384..2fe8dbd 100644 --- a/tests/main/src/linkedlist.c +++ b/tests/main/src/linkedlist.c @@ -446,28 +446,6 @@ _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) } return 1; } -struct cmc_string ll_to_string(struct linkedlist *_list_) -{ - struct cmc_string str; - struct linkedlist *l_ = _list_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_linkedlist, - "CMC_PARAM_SNAME((ll, linkedlist, , , size_t))", - "CMC_PARAM_V((ll, linkedlist, , , size_t))", l_, l_->count, - l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, - l_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool ll_print(struct linkedlist *_list_, FILE *fptr) -{ - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - if (!_list_->f_val->str(fptr, scan->value)) - return 0; - scan = scan->next; - } - return 1; -} struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) { struct linkedlist_node *_node_ = diff --git a/tests/to_string.c b/tests/to_string.c index 74357d4..1aad044 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -10,6 +10,7 @@ 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)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) struct { @@ -35,6 +36,7 @@ int main(void) (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); + struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -50,6 +52,8 @@ int main(void) h_print(h, stdout, "\n[ ", ", ", " ]\n"); ih_to_string(ih, stdout); ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + ll_to_string(ll, stdout); + ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -60,6 +64,7 @@ int main(void) hs_insert(hs, 0); h_insert(h, 0); ih_insert(ih, 0); + ll_push_back(ll, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -75,6 +80,8 @@ int main(void) h_print(h, stdout, "\n[ ", ", ", " ]\n"); ih_to_string(ih, stdout); ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + ll_to_string(ll, stdout); + ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -85,6 +92,7 @@ int main(void) hs_insert(hs, i); h_insert(h, i); ih_insert(ih, i); + ll_push_back(ll, i); } fprintf(stdout, "\n"); @@ -103,6 +111,8 @@ int main(void) h_print(h, stdout, "\n[ ", ", ", " ]\n"); ih_to_string(ih, stdout); ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + ll_to_string(ll, stdout); + ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm);