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