Some fixes to treeset and flags
This commit is contained in:
1 parent
fe056c1b06
commit
4d4f1256ee
5 files changed
+764
-747
No files matched your search
+1
-507
@@ -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) \
|
||||
{ \
|
||||
|
||||
+9
-9
@@ -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
|
||||
|
||||
|
||||
+526
-3
@@ -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
|
||||
|
||||
+19
-19
@@ -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);
|
||||
|
||||
|
||||
+209
-209
@@ -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)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user