Some fixes to treeset and flags

This commit is contained in:
Leonardo Vencovsky committed 2020-06-24 19:31:42 -03:00
1 parent fe056c1b06
commit 4d4f1256ee
5 files changed
+764 -747

No files matched your search

+1 -507
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{