Moving more things to EXT

This commit is contained in:
Leonardo Vencovsky committed 2020-06-03 18:38:49 -03:00
1 parent 97f46b3a81
commit 63eb525406
10 files changed
+1902 -1814

No files matched your search

+1 -298
View File
@@ -161,28 +161,7 @@
/* Collection Utility */ \
bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \
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, _summation)(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_);
bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_);
/* -------------------------------------------------------------------------
* Source
@@ -810,282 +789,6 @@
return true; \
} \
\
struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
size_t max_ = m1 > m2 ? m1 : m2; \
\
CMC_(PFX, _update)(_set_r_, value, max_); \
} \
\
for (; !CMC_(PFX, _iter_at_end)(&iter2); \
CMC_(PFX, _iter_next)(&iter2)) \
{ \
V value = CMC_(PFX, _iter_value)(&iter2); \
\
size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \
size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \
size_t max_ = m1 > m2 ? m1 : m2; \
\
CMC_(PFX, _update)(_set_r_, value, max_); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
return NULL; \
\
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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \
size_t max_ = m1 < m2 ? m1 : m2; \
\
CMC_(PFX, _update)(_set_r_, value, max_); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 > m2) \
CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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_many) \
(_set_r_, CMC_(PFX, _iter_value)(&iter1), \
CMC_(PFX, _iter_multiplicity)(&iter1)); \
} \
\
for (; !CMC_(PFX, _iter_at_end)(&iter2); \
CMC_(PFX, _iter_next)(&iter2)) \
{ \
CMC_(PFX, _insert_many) \
(_set_r_, CMC_(PFX, _iter_value)(&iter2), \
CMC_(PFX, _iter_multiplicity)(&iter2)); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 != m2) \
{ \
if (m1 > m2) \
CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
else \
CMC_(PFX, _update)(_set_r_, value, m2 - m1); \
} \
} \
\
for (; !CMC_(PFX, _iter_at_end)(&iter2); \
CMC_(PFX, _iter_next)(&iter2)) \
{ \
V value = CMC_(PFX, _iter_value)(&iter2); \
\
size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \
size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \
\
if (m1 != m2) \
{ \
if (m1 > m2) \
CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
else \
CMC_(PFX, _update)(_set_r_, value, m2 - m1); \
} \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
{ \
if (_set1_->count > _set2_->count) \
return false; \
\
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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 > m2) \
return false; \
} \
\
return true; \
} \
\
bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
{ \
return CMC_(PFX, _is_subset)(_set2_, _set1_); \
} \
\
bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
if (_set1_->count >= _set2_->count) \
return false; \
\
if (CMC_(PFX, _empty)(_set1_)) \
{ \
if (!CMC_(PFX, _empty)(_set2_)) \
return true; \
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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 >= m2) \
return false; \
} \
\
return true; \
} \
\
bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \
} \
\
bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
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_entry)(_set2_, value) != NULL) \
return false; \
} \
\
return true; \
} \
\
static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \
V value) \
{ \
+96 -369
View File
@@ -47,121 +47,102 @@
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \
\
/* Hashset Structure */ \
struct SNAME \
{ \
/* Array of Entries */ \
struct CMC_DEF_ENTRY(SNAME) * buffer; \
\
/* Current Array Capcity */ \
size_t capacity; \
\
/* Current amount of elements */ \
size_t count; \
\
/* Load factor in range (0.0, 1.0) */ \
double load; \
\
/* Flags indicating errors or success */ \
int flag; \
\
/* Value function table */ \
struct CMC_DEF_FVAL(SNAME) * f_val; \
\
/* Custom allocation functions */ \
struct cmc_alloc_node *alloc; \
\
/* Custom callback functions */ \
struct cmc_callbacks *callbacks; \
}; \
\
struct CMC_DEF_ENTRY(SNAME) \
{ \
/* Entry value */ \
V value; \
\
/* The distance of this node to its original position, used by */ \
/* robin-hood hashing */ \
size_t dist; \
\
/* The sate of this node (DELETED, EMPTY, FILLED) */ \
enum cmc_entry_state state; \
}; \
\
/* Value struct function table */ \
struct CMC_DEF_FVAL(SNAME) \
{ \
/* Comparator function */ \
CMC_DEF_FTAB_CMP(V); \
\
/* Copy function */ \
CMC_DEF_FTAB_CPY(V); \
\
/* To string function */ \
CMC_DEF_FTAB_STR(V); \
\
/* Free from memory function */ \
CMC_DEF_FTAB_FREE(V); \
\
/* Hash function */ \
CMC_DEF_FTAB_HASH(V); \
\
/* Priority function */ \
CMC_DEF_FTAB_PRI(V); \
}; \
\
/* Collection Functions */ \
/* Collection Allocation and Deallocation */ \
struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \
struct CMC_DEF_FVAL(SNAME) * f_val); \
struct SNAME *CMC_(PFX, _new_custom)( \
size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \
void CMC_(PFX, _clear)(struct SNAME * _set_); \
void CMC_(PFX, _free)(struct SNAME * _set_); \
/* Customization of Allocation and Callbacks */ \
void CMC_(PFX, _customize)(struct SNAME * _set_, \
struct cmc_alloc_node * alloc, \
struct cmc_callbacks * callbacks); \
/* Collection Input and Output */ \
bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \
bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \
/* Element Access */ \
bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \
bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \
/* Collection State */ \
bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \
bool CMC_(PFX, _empty)(struct SNAME * _set_); \
bool CMC_(PFX, _full)(struct SNAME * _set_); \
size_t CMC_(PFX, _count)(struct SNAME * _set_); \
size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \
double CMC_(PFX, _load)(struct SNAME * _set_); \
int CMC_(PFX, _flag)(struct SNAME * _set_); \
/* Collection Utility */ \
bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \
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_);
#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \
\
/* Hashset Structure */ \
struct SNAME \
{ \
/* Array of Entries */ \
struct CMC_DEF_ENTRY(SNAME) * buffer; \
\
/* Current Array Capcity */ \
size_t capacity; \
\
/* Current amount of elements */ \
size_t count; \
\
/* Load factor in range (0.0, 1.0) */ \
double load; \
\
/* Flags indicating errors or success */ \
int flag; \
\
/* Value function table */ \
struct CMC_DEF_FVAL(SNAME) * f_val; \
\
/* Custom allocation functions */ \
struct cmc_alloc_node *alloc; \
\
/* Custom callback functions */ \
struct cmc_callbacks *callbacks; \
}; \
\
struct CMC_DEF_ENTRY(SNAME) \
{ \
/* Entry value */ \
V value; \
\
/* The distance of this node to its original position, used by */ \
/* robin-hood hashing */ \
size_t dist; \
\
/* The sate of this node (DELETED, EMPTY, FILLED) */ \
enum cmc_entry_state state; \
}; \
\
/* Value struct function table */ \
struct CMC_DEF_FVAL(SNAME) \
{ \
/* Comparator function */ \
CMC_DEF_FTAB_CMP(V); \
\
/* Copy function */ \
CMC_DEF_FTAB_CPY(V); \
\
/* To string function */ \
CMC_DEF_FTAB_STR(V); \
\
/* Free from memory function */ \
CMC_DEF_FTAB_FREE(V); \
\
/* Hash function */ \
CMC_DEF_FTAB_HASH(V); \
\
/* Priority function */ \
CMC_DEF_FTAB_PRI(V); \
}; \
\
/* Collection Functions */ \
/* Collection Allocation and Deallocation */ \
struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \
struct CMC_DEF_FVAL(SNAME) * f_val); \
struct SNAME *CMC_(PFX, _new_custom)( \
size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \
void CMC_(PFX, _clear)(struct SNAME * _set_); \
void CMC_(PFX, _free)(struct SNAME * _set_); \
/* Customization of Allocation and Callbacks */ \
void CMC_(PFX, _customize)(struct SNAME * _set_, \
struct cmc_alloc_node * alloc, \
struct cmc_callbacks * callbacks); \
/* Collection Input and Output */ \
bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \
bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \
/* Element Access */ \
bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \
bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \
/* Collection State */ \
bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \
bool CMC_(PFX, _empty)(struct SNAME * _set_); \
bool CMC_(PFX, _full)(struct SNAME * _set_); \
size_t CMC_(PFX, _count)(struct SNAME * _set_); \
size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \
double CMC_(PFX, _load)(struct SNAME * _set_); \
int CMC_(PFX, _flag)(struct SNAME * _set_); \
/* Collection Utility */ \
bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \
bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_);
/* -------------------------------------------------------------------------
* Source
@@ -669,260 +650,6 @@
return true; \
} \
\
struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
return NULL; \
} \
\
struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
\
/* TODO turn this into a normal loop and check for errors */ \
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)); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
return NULL; \
} \
\
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_entry)(_set_B_, value) != NULL) \
CMC_(PFX, _insert)(_set_r_, value); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
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_entry)(_set2_, value) == NULL) \
CMC_(PFX, _insert)(_set_r_, value); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
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_entry)(_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_entry)(_set1_, value) == NULL) \
CMC_(PFX, _insert)(_set_r_, value); \
} \
\
_set_r_->callbacks = _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_) \
{ \
_set1_->flag = CMC_FLAG_OK; \
_set2_->flag = CMC_FLAG_OK; \
\
/* 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_entry)(_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_) \
{ \
_set1_->flag = CMC_FLAG_OK; \
_set2_->flag = CMC_FLAG_OK; \
\
/* 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_entry)(_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_) \
{ \
_set1_->flag = CMC_FLAG_OK; \
_set2_->flag = CMC_FLAG_OK; \
\
/* 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_entry)(_set2_, value) != NULL) \
return false; \
} \
\
return true; \
} \
\
static struct CMC_DEF_ENTRY(SNAME) * \
CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \
{ \
+577 -1103
View File
File diff suppressed because it is too large. Load diff
+317 -1
View File
@@ -16,7 +16,7 @@
/**
* All the EXT parts of CMC HashMultiSet.
*/
#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, STR
#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, SETF, STR
/**
* ITER
@@ -342,6 +342,322 @@
return iter->index; \
}
/**
* SETF
*/
#define CMC_EXT_CMC_HASHMULTISET_SETF(PARAMS) \
CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \
CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS)
#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \
CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) \
CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_HASHMULTISET_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, _summation)(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_HASHMULTISET_SETF_SOURCE_(PFX, SNAME, V) \
\
struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
size_t max_ = m1 > m2 ? m1 : m2; \
\
CMC_(PFX, _update)(_set_r_, value, max_); \
} \
\
for (; !CMC_(PFX, _iter_at_end)(&iter2); \
CMC_(PFX, _iter_next)(&iter2)) \
{ \
V value = CMC_(PFX, _iter_value)(&iter2); \
\
size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \
size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \
size_t max_ = m1 > m2 ? m1 : m2; \
\
CMC_(PFX, _update)(_set_r_, value, max_); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
return NULL; \
\
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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \
size_t max_ = m1 < m2 ? m1 : m2; \
\
CMC_(PFX, _update)(_set_r_, value, max_); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 > m2) \
CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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_many) \
(_set_r_, CMC_(PFX, _iter_value)(&iter1), \
CMC_(PFX, _iter_multiplicity)(&iter1)); \
} \
\
for (; !CMC_(PFX, _iter_at_end)(&iter2); \
CMC_(PFX, _iter_next)(&iter2)) \
{ \
CMC_(PFX, _insert_many) \
(_set_r_, CMC_(PFX, _iter_value)(&iter2), \
CMC_(PFX, _iter_multiplicity)(&iter2)); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 != m2) \
{ \
if (m1 > m2) \
CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
else \
CMC_(PFX, _update)(_set_r_, value, m2 - m1); \
} \
} \
\
for (; !CMC_(PFX, _iter_at_end)(&iter2); \
CMC_(PFX, _iter_next)(&iter2)) \
{ \
V value = CMC_(PFX, _iter_value)(&iter2); \
\
size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \
size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \
\
if (m1 != m2) \
{ \
if (m1 > m2) \
CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
else \
CMC_(PFX, _update)(_set_r_, value, m2 - m1); \
} \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
{ \
if (_set1_->count > _set2_->count) \
return false; \
\
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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 > m2) \
return false; \
} \
\
return true; \
} \
\
bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
{ \
return CMC_(PFX, _is_subset)(_set2_, _set1_); \
} \
\
bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
if (_set1_->count >= _set2_->count) \
return false; \
\
if (CMC_(PFX, _empty)(_set1_)) \
{ \
if (!CMC_(PFX, _empty)(_set2_)) \
return true; \
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); \
\
size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
\
if (m1 >= m2) \
return false; \
} \
\
return true; \
} \
\
bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \
} \
\
bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
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_entry)(_set2_, value) != NULL) \
return false; \
} \
\
return true; \
}
/**
* STR
*/
+293 -1
View File
@@ -16,7 +16,7 @@
/**
* All the EXT parts of CMC HashSet.
*/
#define CMC_EXT_CMC_HASHSET_PARTS ITER, STR
#define CMC_EXT_CMC_HASHSET_PARTS ITER, SETF, STR
/**
* ITER
@@ -333,6 +333,298 @@
return iter->index; \
}
/**
* SETF
*/
#define CMC_EXT_CMC_HASHSET_SETF(PARAMS) \
CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \
CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS)
#define CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \
CMC_EXT_CMC_HASHSET_SETF_HEADER_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) \
CMC_EXT_CMC_HASHSET_SETF_SOURCE_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_HASHSET_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_HASHSET_SETF_SOURCE_(PFX, SNAME, V) \
\
struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
return NULL; \
} \
\
struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
\
/* TODO turn this into a normal loop and check for errors */ \
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)); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
return NULL; \
} \
\
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_entry)(_set_B_, value) != NULL) \
CMC_(PFX, _insert)(_set_r_, value); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
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_entry)(_set2_, value) == NULL) \
CMC_(PFX, _insert)(_set_r_, value); \
} \
\
_set_r_->callbacks = _set1_->callbacks; \
\
return _set_r_; \
} \
\
struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
/* Callbacks are added later */ \
struct SNAME *_set_r_ = \
CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \
_set1_->f_val, _set1_->alloc, NULL); \
\
if (!_set_r_) \
{ \
_set1_->flag = CMC_FLAG_ALLOC; \
_set2_->flag = CMC_FLAG_ALLOC; \
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_entry)(_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_entry)(_set1_, value) == NULL) \
CMC_(PFX, _insert)(_set_r_, value); \
} \
\
_set_r_->callbacks = _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_) \
{ \
_set1_->flag = CMC_FLAG_OK; \
_set2_->flag = CMC_FLAG_OK; \
\
/* 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_entry)(_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_) \
{ \
_set1_->flag = CMC_FLAG_OK; \
_set2_->flag = CMC_FLAG_OK; \
\
/* 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_entry)(_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_) \
{ \
_set1_->flag = CMC_FLAG_OK; \
_set2_->flag = CMC_FLAG_OK; \
\
/* 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_entry)(_set2_, value) != NULL) \
return false; \
} \
\
return true; \
}
/**
* STR
*/
+607
View File
@@ -0,0 +1,607 @@
/**
* ext/cmc/linkedlist.h
*
* Creation Date: 26/05/2020
*
* Authors:
* Leonardo Vencovsky (https://github.com/LeoVen)
*
*/
#ifndef CMC_EXT_CMC_LINKEDLIST_H
#define CMC_EXT_CMC_LINKEDLIST_H
#include "../../cor/core.h"
/**
* All the EXT parts of CMC LinkedList.
*/
#define CMC_EXT_CMC_LINKEDLIST_PARTS ITER, NODE, STR
/**
* ITER
*/
#define CMC_EXT_CMC_LINKEDLIST_ITER(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS)
#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \
\
/* LinkedList Iterator */ \
struct CMC_DEF_ITER(SNAME) \
{ \
/* Target Linked List */ \
struct SNAME *target; \
\
/* Cursor's current node */ \
struct CMC_DEF_NODE(SNAME) * cursor; \
\
/* 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); \
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter);
#define CMC_EXT_CMC_LINKEDLIST_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->head; \
iter.index = 0; \
iter.start = true; \
iter.end = CMC_(PFX, _empty)(target); \
\
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->tail; \
iter.index = 0; \
iter.start = CMC_(PFX, _empty)(target); \
iter.end = true; \
\
if (!CMC_(PFX, _empty)(target)) \
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->cursor = iter->target->head; \
iter->index = 0; \
iter->start = true; \
iter->end = CMC_(PFX, _empty)(iter->target); \
\
return true; \
} \
\
return false; \
} \
\
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
if (!CMC_(PFX, _empty)(iter->target)) \
{ \
iter->cursor = iter->target->tail; \
iter->index = iter->target->count - 1; \
iter->start = CMC_(PFX, _empty)(iter->target); \
iter->end = true; \
\
return true; \
} \
\
return false; \
} \
\
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
if (iter->end) \
return false; \
\
if (iter->cursor->next == NULL) \
{ \
iter->end = true; \
return false; \
} \
\
iter->start = CMC_(PFX, _empty)(iter->target); \
\
iter->cursor = iter->cursor->next; \
iter->index++; \
\
return true; \
} \
\
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
if (iter->start) \
return false; \
\
if (iter->cursor->prev == NULL) \
{ \
iter->start = true; \
return false; \
} \
\
iter->end = CMC_(PFX, _empty)(iter->target); \
\
iter->cursor = iter->cursor->prev; \
iter->index--; \
\
return true; \
} \
\
/* 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->next == NULL) \
{ \
iter->end = true; \
return false; \
} \
\
if (steps == 0 || iter->index + steps >= iter->target->count) \
return false; \
\
iter->start = CMC_(PFX, _empty)(iter->target); \
\
iter->index += steps; \
\
for (size_t i = 0; i < steps; i++) \
iter->cursor = iter->cursor->next; \
\
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->prev == NULL) \
{ \
iter->start = true; \
return false; \
} \
\
if (steps == 0 || iter->index < steps) \
return false; \
\
iter->end = CMC_(PFX, _empty)(iter->target); \
\
iter->index -= steps; \
\
for (size_t i = 0; i < steps; i++) \
iter->cursor = iter->cursor->prev; \
\
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; \
} \
\
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
if (CMC_(PFX, _empty)(iter->target)) \
return NULL; \
\
return &(iter->cursor->value); \
} \
\
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
return iter->index; \
} \
\
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
return iter->cursor; \
}
/**
* NODE
*/
#define CMC_EXT_CMC_LINKEDLIST_NODE(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS)
#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \
\
/* Node Allocation and Deallocation */ \
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \
void CMC_(PFX, _free_node)(struct SNAME * _list_, \
struct CMC_DEF_NODE(SNAME) * _node_); \
/* Node Access Relative to a Linked List */ \
struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \
struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \
/* Input and Output Relative to a Node */ \
bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_, V value); \
bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_, V value); \
bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_); \
bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_); \
bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_); \
/* Node Access Relative to a Linked List Node */ \
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_);
#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(PFX, SNAME, V) \
\
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \
{ \
struct CMC_DEF_NODE(SNAME) *_node_ = \
_list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \
\
if (!_node_) \
{ \
_list_->flag = CMC_FLAG_ALLOC; \
return NULL; \
} \
\
_node_->value = value; \
_node_->next = NULL; \
_node_->prev = NULL; \
\
return _node_; \
} \
\
void CMC_(PFX, _free_node)(struct SNAME * _list_, \
struct CMC_DEF_NODE(SNAME) * _node_) \
{ \
_list_->alloc->free(_node_); \
} \
\
struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \
{ \
return _list_->head; \
} \
\
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \
{ \
if (CMC_(PFX, _empty)(_list_)) \
{ \
_list_->flag = CMC_FLAG_EMPTY; \
return NULL; \
} \
\
if (index >= _list_->count) \
{ \
_list_->flag = CMC_FLAG_RANGE; \
return NULL; \
} \
\
struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \
\
if (index <= _list_->count / 2) \
{ \
_node_ = _list_->head; \
for (size_t i = 0; i < index; i++) \
{ \
_node_ = _node_->next; \
} \
} \
else \
{ \
_node_ = _list_->tail; \
for (size_t i = _list_->count - 1; i > index; i--) \
{ \
_node_ = _node_->prev; \
} \
} \
\
_list_->flag = CMC_FLAG_OK; \
\
return _node_; \
} \
\
struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \
{ \
return _list_->tail; \
} \
\
bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_, V value) \
{ \
struct CMC_DEF_NODE(SNAME) *new_node = \
CMC_(PFX, _new_node)(_owner_, value); \
\
if (!new_node) \
return false; \
\
new_node->next = _node_->next; \
\
if (_node_->next != NULL) \
_node_->next->prev = new_node; \
else \
_owner_->tail = new_node; \
\
new_node->prev = _node_; \
_node_->next = new_node; \
\
_owner_->count++; \
_owner_->flag = CMC_FLAG_OK; \
\
return true; \
} \
\
bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_, V value) \
{ \
struct CMC_DEF_NODE(SNAME) *new_node = \
CMC_(PFX, _new_node)(_owner_, value); \
\
if (!new_node) \
return false; \
\
new_node->prev = _node_->prev; \
\
if (_node_->prev != NULL) \
_node_->prev->next = new_node; \
else \
_owner_->head = new_node; \
\
new_node->next = _node_; \
_node_->prev = new_node; \
\
_owner_->count++; \
_owner_->flag = CMC_FLAG_OK; \
\
return true; \
} \
\
bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_) \
{ \
if (_node_->next == NULL) \
{ \
_owner_->flag = CMC_FLAG_INVALID; \
return false; \
} \
\
struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \
\
_node_->next = _node_->next->next; \
\
if (tmp->next != NULL) \
tmp->next->prev = _node_; \
else \
_owner_->tail = _node_; \
\
_owner_->alloc->free(tmp); \
\
_owner_->count--; \
_owner_->flag = CMC_FLAG_OK; \
\
return true; \
} \
\
bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_) \
{ \
if (_node_->prev != NULL) \
_node_->prev->next = _node_->next; \
else \
_owner_->head = _node_->next; \
\
if (_node_->next != NULL) \
_node_->next->prev = _node_->prev; \
else \
_owner_->tail = _node_->prev; \
\
_owner_->alloc->free(_node_); \
\
_owner_->count--; \
_owner_->flag = CMC_FLAG_OK; \
\
return true; \
} \
\
bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \
struct CMC_DEF_NODE(SNAME) * _node_) \
{ \
if (_node_->prev == NULL) \
{ \
_owner_->flag = CMC_FLAG_INVALID; \
return false; \
} \
\
struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \
\
_node_->prev = _node_->prev->prev; \
\
if (tmp->prev != NULL) \
tmp->prev->next = _node_; \
else \
_owner_->head = _node_; \
\
_owner_->alloc->free(tmp); \
\
_owner_->count--; \
_owner_->flag = CMC_FLAG_OK; \
\
return true; \
} \
\
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \
{ \
return _node_->next; \
} \
\
struct CMC_DEF_NODE(SNAME) * \
CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \
{ \
return _node_->prev; \
}
/**
* STR
*/
#define CMC_EXT_CMC_LINKEDLIST_STR(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS)
#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_STR_HEADER_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) \
CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_( \
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(PFX, SNAME, V) \
\
bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \
bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \
const char *start, const char *separator, \
const char *end);
#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(PFX, SNAME, V) \
\
bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \
{ \
struct SNAME *l_ = _list_; \
\
return 0 <= fprintf(fptr, \
"struct %s<%s> " \
"at %p { " \
"count:%" PRIuMAX ", " \
"head:%p, " \
"tail:%p, " \
"flag:%d, " \
"f_val:%p, " \
"alloc:%p, " \
"callbacks:%p }", \
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \
l_->count, l_->head, l_->tail, l_->flag, \
l_->f_val, l_->alloc, l_->callbacks); \
} \
\
bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \
const char *start, const char *separator, \
const char *end) \
{ \
fprintf(fptr, "%s", start); \
\
struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \
\
while (scan != NULL) \
{ \
if (!_list_->f_val->str(fptr, scan->value)) \
return false; \
\
scan = scan->next; \
\
if (scan) \
fprintf(fptr, "%s", separator); \
} \
\
fprintf(fptr, "%s", end); \
\
return true; \
}
#endif /* CMC_EXT_CMC_LINKEDLIST_H */
+1
View File
@@ -60,6 +60,7 @@
#include "ext/cmc/hashset.h" /* Added in 31/05/2020 */
#include "ext/cmc/heap.h" /* Added in 01/06/2020 */
#include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */
#include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */
#include "utl/assert.h" /* Added in 27/06/2019 */
#include "utl/foreach.h" /* Added in 25/02/2019 */