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
|
||||
|
||||
Reference in new issue
Block a user