From 4d4f1256ee3b3bac82f18c379aa9ab6131fb81ed Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 24 Jun 2020 19:31:42 -0300 Subject: [PATCH] Some fixes to treeset and flags --- src/cmc/treeset.h | 508 +--------------------------------- src/cor/flags.h | 18 +- src/ext/cmc/treeset.h | 529 +++++++++++++++++++++++++++++++++++- tests/include/cmc/treeset.h | 38 +-- tests/src/cmc/treeset.c | 418 ++++++++++++++-------------- 5 files changed, 764 insertions(+), 747 deletions(-) diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 9b9ed6c..be3ffd4 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -130,31 +130,6 @@ /* Priority function */ \ CMC_DEF_FTAB_PRI(V); \ }; \ -\ - /* Treeset Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target treeset */ \ - struct SNAME *target; \ -\ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ -\ - /* The first node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * first; \ -\ - /* The last node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * last; \ -\ - /* 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 */ \ @@ -179,37 +154,7 @@ int CMC_(PFX, _flag)(struct SNAME * _set_); \ /* Collection Utility */ \ 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_); \ -\ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -663,457 +608,6 @@ \ return true; \ } \ -\ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_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)(_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)); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - /** TODO Should this compare count or capacity? */ \ - 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_node)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_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); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_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); \ -\ - if (CMC_(PFX, _impl_get_node)(_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_node)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _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_) \ - { \ - /* 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_node)(_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_) \ - { \ - /* 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_node)(_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_) \ - { \ - /* 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_node)(_set2_, value) != NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->left != NULL) \ - iter.cursor = iter.cursor->left; \ -\ - iter.first = iter.cursor; \ -\ - iter.last = target->root; \ - while (iter.last->right != NULL) \ - iter.last = iter.last->right; \ - } \ -\ - 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->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->right != NULL) \ - iter.cursor = iter.cursor->right; \ -\ - iter.last = iter.cursor; \ -\ - iter.first = target->root; \ - while (iter.first->left != NULL) \ - iter.first = iter.first->left; \ -\ - 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->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->first; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->cursor = iter->last; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->right != NULL) \ - { \ - iter->cursor = iter->cursor->right; \ -\ - while (iter->cursor->left != NULL) \ - iter->cursor = iter->cursor->left; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->left == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->left != NULL) \ - { \ - iter->cursor = iter->cursor->left; \ -\ - while (iter->cursor->right != NULL) \ - iter->cursor = iter->cursor->right; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->right == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - /* 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 == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - 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 == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - 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; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ \ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value) \ { \ diff --git a/src/cor/flags.h b/src/cor/flags.h index 0a39e02..a9b0407 100644 --- a/src/cor/flags.h +++ b/src/cor/flags.h @@ -22,15 +22,15 @@ enum cmc_flags { CMC_FLAG_OK = 0, // No errors - CMC_FLAG_ALLOC = 2, // Allocation failed - CMC_FLAG_EMPTY = 3, // The collection is empty when it should not - CMC_FLAG_NOT_FOUND = 4, // Key or value not found - CMC_FLAG_INVALID = 5, // Invalid argument or operation - CMC_FLAG_RANGE = 6, // Index out of range - CMC_FLAG_DUPLICATE = 7, // Duplicate key or value - CMC_FLAG_ERROR = 8, // Generic error, usually caused by algorithm error - CMC_FLAG_THREAD = 9, // Generic error regarding threads - CMC_FLAG_MUTEX = 10 // Generic error regarding mutexes + CMC_FLAG_ALLOC = 1, // Allocation failed + CMC_FLAG_EMPTY = 2, // The collection is empty when it should not + CMC_FLAG_NOT_FOUND = 3, // Key or value not found + CMC_FLAG_INVALID = 4, // Invalid argument or operation + CMC_FLAG_RANGE = 5, // Index out of range + CMC_FLAG_DUPLICATE = 6, // Duplicate key or value + CMC_FLAG_ERROR = 7, // Generic error, usually caused by algorithm error + CMC_FLAG_THREAD = 8, // Generic error regarding threads + CMC_FLAG_MUTEX = 9 // Generic error regarding mutexes }; // clang-format on diff --git a/src/ext/cmc/treeset.h b/src/ext/cmc/treeset.h index 1e4f32d..674fef4 100644 --- a/src/ext/cmc/treeset.h +++ b/src/ext/cmc/treeset.h @@ -16,7 +16,7 @@ /** * All the EXT parts of CMC TreeSet. */ -#define CMC_EXT_CMC_TREESET_PARTS ITER, STR +#define CMC_EXT_CMC_TREESET_PARTS ITER, SETF, STR /** * ITER @@ -31,9 +31,532 @@ #define CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS) \ CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) +#define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* Treeset Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target treeset */ \ + struct SNAME *target; \ +\ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ +\ + /* The first node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * first; \ +\ + /* The last node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * last; \ +\ + /* 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); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_TREESET_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->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->left != NULL) \ + iter.cursor = iter.cursor->left; \ +\ + iter.first = iter.cursor; \ +\ + iter.last = target->root; \ + while (iter.last->right != NULL) \ + iter.last = iter.last->right; \ + } \ +\ + 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->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->right != NULL) \ + iter.cursor = iter.cursor->right; \ +\ + iter.last = iter.cursor; \ +\ + iter.first = target->root; \ + while (iter.first->left != NULL) \ + iter.first = iter.first->left; \ +\ + 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->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->first; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->cursor = iter->last; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->right != NULL) \ + { \ + iter->cursor = iter->cursor->right; \ +\ + while (iter->cursor->left != NULL) \ + iter->cursor = iter->cursor->left; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->left == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->left != NULL) \ + { \ + iter->cursor = iter->cursor->left; \ +\ + while (iter->cursor->right != NULL) \ + iter->cursor = iter->cursor->right; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->right == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + /* 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 == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + 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 == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + 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; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * SETF + */ +#define CMC_EXT_CMC_TREESET_SETF(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS) + +#define CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_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_TREESET_SETF_SOURCE_(PFX, SNAME, V) \ +\ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_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)(_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)); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + /** TODO Should this compare count or capacity? */ \ + 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_node)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_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); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_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); \ +\ + if (CMC_(PFX, _impl_get_node)(_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_node)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _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_) \ + { \ + /* 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_node)(_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_) \ + { \ + /* 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_node)(_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_) \ + { \ + /* 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_node)(_set2_, value) != NULL) \ + return false; \ + } \ +\ + return true; \ + } -#define CMC_EXT_CMC_TREESET_ITER_SOURCE_(PFX, SNAME, V) /** * STR diff --git a/tests/include/cmc/treeset.h b/tests/include/cmc/treeset.h index 432f272..9bca697 100644 --- a/tests/include/cmc/treeset.h +++ b/tests/include/cmc/treeset.h @@ -30,16 +30,6 @@ struct treeset_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct treeset_iter -{ - struct treeset *target; - struct treeset_node *cursor; - struct treeset_node *first; - struct treeset_node *last; - size_t index; - _Bool start; - _Bool end; -}; struct treeset *ts_new(struct treeset_fval *f_val); struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -56,15 +46,16 @@ size_t ts_count(struct treeset *_set_); int ts_flag(struct treeset *_set_); struct treeset *ts_copy_of(struct treeset *_set_); _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); +struct treeset_iter +{ + struct treeset *target; + struct treeset_node *cursor; + struct treeset_node *first; + struct treeset_node *last; + size_t index; + _Bool start; + _Bool end; +}; struct treeset_iter ts_iter_start(struct treeset *target); struct treeset_iter ts_iter_end(struct treeset *target); _Bool ts_iter_at_start(struct treeset_iter *iter); @@ -78,6 +69,15 @@ _Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); _Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); size_t ts_iter_value(struct treeset_iter *iter); size_t ts_iter_index(struct treeset_iter *iter); +struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); _Bool ts_to_string(struct treeset *_set_, FILE *fptr); _Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); diff --git a/tests/src/cmc/treeset.c b/tests/src/cmc/treeset.c index 795a020..5216b54 100644 --- a/tests/src/cmc/treeset.c +++ b/tests/src/cmc/treeset.c @@ -360,133 +360,120 @@ _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) } return 1; } -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) +static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) + struct treeset_node *node = _set_->alloc->malloc(sizeof(struct treeset_node)); + if (!node) return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - ts_insert(_set_r_, ts_iter_value(&iter1)); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - ts_insert(_set_r_, ts_iter_value(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; + node->value = value; + node->right = ((void *)0); + node->left = ((void *)0); + node->parent = ((void *)0); + node->height = 0; + return node; } -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) +static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct treeset_iter iter = ts_iter_start(_set_A_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + struct treeset_node *scan = _set_->root; + while (scan != ((void *)0)) { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set_B_, value) != ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - size_t value = ts_iter_value(&iter1); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - size_t value = ts_iter_value(&iter2); - if (ts_impl_get_node(_set1_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count > _set2_->count) - return 0; - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_) -{ - return ts_is_subset(_set2_, _set1_); -} -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (ts_empty(_set1_)) - { - if (!ts_empty(_set2_)) - return 1; + if (_set_->f_val->cmp(scan->value, value) > 0) + scan = scan->left; + else if (_set_->f_val->cmp(scan->value, value) < 0) + scan = scan->right; else - return 0; + return scan; } - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; + return ((void *)0); } -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_) +static unsigned char ts_impl_h(struct treeset_node *node) { - return ts_is_proper_subset(_set2_, _set1_); + if (node == ((void *)0)) + return 0; + return node->height; } -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_) +static unsigned char ts_impl_hupdate(struct treeset_node *node) { - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + if (node == ((void *)0)) + return 0; + unsigned char h_l = ts_impl_h(node->left); + unsigned char h_r = ts_impl_h(node->right); + return 1 + (h_l > h_r ? h_l : h_r); +} +static void ts_impl_rotate_right(struct treeset_node **Z) +{ + struct treeset_node *root = *Z; + struct treeset_node *new_root = root->left; + if (root->parent != ((void *)0)) { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) != ((void *)0)) - return 0; + if (root->parent->left == root) + root->parent->left = new_root; + else + root->parent->right = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->left = new_root->right; + if (root->left) + root->left->parent = root; + new_root->right = root; + root->height = ts_impl_hupdate(root); + new_root->height = ts_impl_hupdate(new_root); + *Z = new_root; +} +static void ts_impl_rotate_left(struct treeset_node **Z) +{ + struct treeset_node *root = *Z; + struct treeset_node *new_root = root->right; + if (root->parent != ((void *)0)) + { + if (root->parent->right == root) + root->parent->right = new_root; + else + root->parent->left = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->right = new_root->left; + if (root->right) + root->right->parent = root; + new_root->left = root; + root->height = ts_impl_hupdate(root); + new_root->height = ts_impl_hupdate(new_root); + *Z = new_root; +} +static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) +{ + struct treeset_node *scan = node, *child = ((void *)0); + int balance; + _Bool is_root = 0; + while (scan != ((void *)0)) + { + if (scan->parent == ((void *)0)) + is_root = 1; + scan->height = ts_impl_hupdate(scan); + balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); + if (balance >= 2) + { + child = scan->right; + if (ts_impl_h(child->right) < ts_impl_h(child->left)) + ts_impl_rotate_right(&(scan->right)); + ts_impl_rotate_left(&scan); + } + else if (balance <= -2) + { + child = scan->left; + if (ts_impl_h(child->left) < ts_impl_h(child->right)) + ts_impl_rotate_left(&(scan->left)); + ts_impl_rotate_right(&scan); + } + if (is_root) + { + _set_->root = scan; + is_root = 0; + } + scan = scan->parent; } - return 1; } struct treeset_iter ts_iter_start(struct treeset *target) { @@ -671,120 +658,133 @@ size_t ts_iter_index(struct treeset_iter *iter) { return iter->index; } -static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value) +struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset_node *node = _set_->alloc->malloc(sizeof(struct treeset_node)); - if (!node) + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) return ((void *)0); - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; -} -static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) -{ - struct treeset_node *scan = _set_->root; - while (scan != ((void *)0)) + struct treeset_iter iter1 = ts_iter_start(_set1_); + struct treeset_iter iter2 = ts_iter_start(_set2_); + for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) { - if (_set_->f_val->cmp(scan->value, value) > 0) - scan = scan->left; - else if (_set_->f_val->cmp(scan->value, value) < 0) - scan = scan->right; - else - return scan; + ts_insert(_set_r_, ts_iter_value(&iter1)); } - return ((void *)0); + for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) + { + ts_insert(_set_r_, ts_iter_value(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static unsigned char ts_impl_h(struct treeset_node *node) +struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) { - if (node == ((void *)0)) + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct treeset_iter iter = ts_iter_start(_set_A_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set_B_, value) != ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset_iter iter1 = ts_iter_start(_set1_); + struct treeset_iter iter2 = ts_iter_start(_set2_); + for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) + { + size_t value = ts_iter_value(&iter1); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) + { + size_t value = ts_iter_value(&iter2); + if (ts_impl_get_node(_set1_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (_set1_->count > _set2_->count) return 0; - return node->height; + if (ts_empty(_set1_)) + return 1; + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + return 0; + } + return 1; } -static unsigned char ts_impl_hupdate(struct treeset_node *node) +_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_) { - if (node == ((void *)0)) + return ts_is_subset(_set2_, _set1_); +} +_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (_set1_->count >= _set2_->count) return 0; - unsigned char h_l = ts_impl_h(node->left); - unsigned char h_r = ts_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void ts_impl_rotate_right(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->left; - if (root->parent != ((void *)0)) + if (ts_empty(_set1_)) { - if (root->parent->left == root) - root->parent->left = new_root; + if (!ts_empty(_set2_)) + return 1; else - root->parent->right = new_root; + return 0; } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; -} -static void ts_impl_rotate_left(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->right; - if (root->parent != ((void *)0)) + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + return 0; } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; + return 1; } -static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) +_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) + return ts_is_proper_subset(_set2_, _set1_); +} +_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (ts_empty(_set1_)) + return 1; + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = ts_impl_hupdate(scan); - balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); - if (balance >= 2) - { - child = scan->right; - if (ts_impl_h(child->right) < ts_impl_h(child->left)) - ts_impl_rotate_right(&(scan->right)); - ts_impl_rotate_left(&scan); - } - else if (balance <= -2) - { - child = scan->left; - if (ts_impl_h(child->left) < ts_impl_h(child->right)) - ts_impl_rotate_left(&(scan->left)); - ts_impl_rotate_right(&scan); - } - if (is_root) - { - _set_->root = scan; - is_root = 0; - } - scan = scan->parent; + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) != ((void *)0)) + return 0; } + return 1; } _Bool ts_to_string(struct treeset *_set_, FILE *fptr) {