Adding and fixing things, documenting code and moving more stuff to EXT

This commit is contained in:
Leonardo Vencovsky committed 2020-05-31 00:50:55 -03:00
1 parent b85f3d1f81
commit 624d1613f0
8 files changed
+514 -355

No files matched your search

+1 -319
View File
@@ -29,21 +29,6 @@
* ------------------------------------------------------------------------- */
#include "../cor/hashtable.h"
/* -------------------------------------------------------------------------
* HashSet specific
* ------------------------------------------------------------------------- */
/* to_string format */
static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> "
"at %p { "
"buffer:%p, "
"capacity:%" PRIuMAX ", "
"count:%" PRIuMAX ", "
"load:%lf, "
"flag:%d, "
"f_val:%p, "
"alloc:%p, "
"callbacks: %p }";
/**
* Core HashSet implementation
*/
@@ -183,8 +168,6 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> "
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_); \
struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \
bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \
\
/* Set Operations */ \
struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \
@@ -203,29 +186,7 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> "
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);
struct SNAME * _set2_);
/* -------------------------------------------------------------------------
* Source
@@ -737,35 +698,6 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> "
return true; \
} \
\
struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \
{ \
struct cmc_string str; \
struct SNAME *s_ = _set_; \
\
int n = \
snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashset, \
#SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \
s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); \
\
return n >= 0 ? str : (struct cmc_string){ 0 }; \
} \
\
bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \
{ \
for (size_t i = 0; i < _set_->capacity; i++) \
{ \
struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
\
if (entry->state == CMC_ES_FILLED) \
{ \
if (!_set_->f_val->str(fptr, entry->value)) \
return false; \
} \
} \
\
return true; \
} \
\
struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \
struct SNAME * _set2_) \
{ \
@@ -1020,256 +952,6 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> "
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 = 0; \
iter.index = 0; \
iter.first = 0; \
iter.last = 0; \
iter.start = true; \
iter.end = CMC_(PFX, _empty)(target); \
\
if (!CMC_(PFX, _empty)(target)) \
{ \
for (size_t i = 0; i < target->capacity; i++) \
{ \
if (target->buffer[i].state == CMC_ES_FILLED) \
{ \
iter.first = i; \
break; \
} \
} \
\
iter.cursor = iter.first; \
\
for (size_t i = target->capacity; i > 0; i--) \
{ \
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
{ \
iter.last = i - 1; \
break; \
} \
} \
} \
\
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 = 0; \
iter.index = 0; \
iter.first = 0; \
iter.last = 0; \
iter.start = CMC_(PFX, _empty)(target); \
iter.end = true; \
\
if (!CMC_(PFX, _empty)(target)) \
{ \
for (size_t i = 0; i < target->capacity; i++) \
{ \
if (target->buffer[i].state == CMC_ES_FILLED) \
{ \
iter.first = i; \
break; \
} \
} \
\
for (size_t i = target->capacity; i > 0; i--) \
{ \
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
{ \
iter.last = i - 1; \
break; \
} \
} \
\
iter.cursor = iter.last; \
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->first; \
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->last; \
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->index + 1 == iter->target->count) \
{ \
iter->end = true; \
return false; \
} \
\
iter->start = CMC_(PFX, _empty)(iter->target); \
\
struct CMC_DEF_ENTRY(SNAME) *scan = \
&(iter->target->buffer[iter->cursor]); \
\
iter->index++; \
\
while (1) \
{ \
iter->cursor++; \
scan = &(iter->target->buffer[iter->cursor]); \
\
if (scan->state == CMC_ES_FILLED) \
break; \
} \
\
return true; \
} \
\
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
if (iter->start) \
return false; \
\
if (iter->index == 0) \
{ \
iter->start = true; \
return false; \
} \
\
iter->end = CMC_(PFX, _empty)(iter->target); \
\
struct CMC_DEF_ENTRY(SNAME) *scan = \
&(iter->target->buffer[iter->cursor]); \
\
iter->index--; \
\
while (1) \
{ \
iter->cursor--; \
scan = &(iter->target->buffer[iter->cursor]); \
\
if (scan->state == CMC_ES_FILLED) \
break; \
} \
\
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->index + 1 == iter->target->count) \
{ \
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->index == 0) \
{ \
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->target->buffer[iter->cursor].value; \
} \
\
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
return iter->index; \
} \
\
static struct CMC_DEF_ENTRY(SNAME) * \
CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \
{ \
+1 -1
View File
@@ -84,7 +84,7 @@
* K - Key type
* V - Value type
*
* PARAM := (PFX, SNAME, SIZE, K, V)
* PARAMS := (PFX, SNAME, SIZE, K, V)
*/
#define CMC_PARAM_PFX CMC_TUP_0
#define CMC_PARAM_SNAME CMC_TUP_1
-3
View File
@@ -449,9 +449,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> "
/**
* STR
*
* The part 'STR' gives a new way of initializing a collection. The collection
* struct is not heap allocated, only its internal structure (nodes, buffers).
*/
#define CMC_EXT_CMC_HASHMAP_STR(BODY) \
CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \
-3
View File
@@ -358,9 +358,6 @@ static const char *cmc_cmc_string_fmt_hashmultiset =
/**
* STR
*
* The part 'STR' gives a new way of initializing a collection. The collection
* struct is not heap allocated, only its internal structure (nodes, buffers).
*/
#define CMC_EXT_CMC_HASHMULTISET_STR(BODY) \
CMC_EXT_CMC_HASHMULTISET_STR_HEADER(BODY) \
+397 -1
View File
@@ -16,6 +16,402 @@
/**
* All the EXT parts of CMC HashSet.
*/
#define CMC_EXT_CMC_HASHSET_PARTS
#define CMC_EXT_CMC_HASHSET_PARTS ITER, STR
/* Used by STR */
static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> "
"at %p { "
"buffer:%p, "
"capacity:%" PRIuMAX ", "
"count:%" PRIuMAX ", "
"load:%lf, "
"flag:%d, "
"f_val:%p, "
"alloc:%p, "
"callbacks: %p }";
/**
* ITER
*/
#define CMC_EXT_CMC_HASHSET_ITER(BODY) \
CMC_EXT_CMC_HASHSET_ITER_HEADER(BODY) \
CMC_EXT_CMC_HASHSET_ITER_SOURCE(BODY)
#define CMC_EXT_CMC_HASHSET_ITER_HEADER(BODY) \
CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(BODY), \
CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY))
#define CMC_EXT_CMC_HASHSET_ITER_SOURCE(BODY) \
CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(BODY), \
CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY))
#define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \
\
/* HashSet Iterator */ \
struct CMC_DEF_ITER(SNAME) \
{ \
/* Target HashSet */ \
struct SNAME *target; \
\
/* Cursor's position (index) */ \
size_t cursor; \
\
/* Keeps track of relative index to the iteration of elements */ \
size_t index; \
\
/* The index of the first element */ \
size_t first; \
\
/* The index of the last element */ \
size_t last; \
\
/* 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_HASHSET_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 = 0; \
iter.index = 0; \
iter.first = 0; \
iter.last = 0; \
iter.start = true; \
iter.end = CMC_(PFX, _empty)(target); \
\
if (!CMC_(PFX, _empty)(target)) \
{ \
for (size_t i = 0; i < target->capacity; i++) \
{ \
if (target->buffer[i].state == CMC_ES_FILLED) \
{ \
iter.first = i; \
break; \
} \
} \
\
iter.cursor = iter.first; \
\
for (size_t i = target->capacity; i > 0; i--) \
{ \
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
{ \
iter.last = i - 1; \
break; \
} \
} \
} \
\
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 = 0; \
iter.index = 0; \
iter.first = 0; \
iter.last = 0; \
iter.start = CMC_(PFX, _empty)(target); \
iter.end = true; \
\
if (!CMC_(PFX, _empty)(target)) \
{ \
for (size_t i = 0; i < target->capacity; i++) \
{ \
if (target->buffer[i].state == CMC_ES_FILLED) \
{ \
iter.first = i; \
break; \
} \
} \
\
for (size_t i = target->capacity; i > 0; i--) \
{ \
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
{ \
iter.last = i - 1; \
break; \
} \
} \
\
iter.cursor = iter.last; \
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->first; \
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->last; \
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->index + 1 == iter->target->count) \
{ \
iter->end = true; \
return false; \
} \
\
iter->start = CMC_(PFX, _empty)(iter->target); \
\
struct CMC_DEF_ENTRY(SNAME) *scan = \
&(iter->target->buffer[iter->cursor]); \
\
iter->index++; \
\
while (1) \
{ \
iter->cursor++; \
scan = &(iter->target->buffer[iter->cursor]); \
\
if (scan->state == CMC_ES_FILLED) \
break; \
} \
\
return true; \
} \
\
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
if (iter->start) \
return false; \
\
if (iter->index == 0) \
{ \
iter->start = true; \
return false; \
} \
\
iter->end = CMC_(PFX, _empty)(iter->target); \
\
struct CMC_DEF_ENTRY(SNAME) *scan = \
&(iter->target->buffer[iter->cursor]); \
\
iter->index--; \
\
while (1) \
{ \
iter->cursor--; \
scan = &(iter->target->buffer[iter->cursor]); \
\
if (scan->state == CMC_ES_FILLED) \
break; \
} \
\
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->index + 1 == iter->target->count) \
{ \
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->index == 0) \
{ \
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->target->buffer[iter->cursor].value; \
} \
\
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
{ \
return iter->index; \
}
/**
* STR
*/
#define CMC_EXT_CMC_HASHSET_STR(BODY) \
CMC_EXT_CMC_HASHSET_STR_HEADER(BODY) \
CMC_EXT_CMC_HASHSET_STR_SOURCE(BODY)
#define CMC_EXT_CMC_HASHSET_STR_HEADER(BODY) \
CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(BODY), \
CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY))
#define CMC_EXT_CMC_HASHSET_STR_SOURCE(BODY) \
CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(BODY), \
CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY))
#define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \
\
bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \
bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \
const char *start, const char *separator, \
const char *end);
#define CMC_EXT_CMC_HASHSET_STR_SOURCE_(PFX, SNAME, V) \
\
bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \
{ \
struct SNAME *s_ = _set_; \
\
return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashset, \
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, \
s_->buffer, s_->capacity, s_->count, s_->load, \
s_->flag, s_->f_val, s_->alloc, s_->callbacks); \
} \
\
bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \
const char *start, const char *separator, \
const char *end) \
{ \
fprintf(fptr, "%s", start); \
\
size_t last = 0; \
for (size_t i = _set_->capacity; i > 0; i--) \
{ \
if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \
{ \
last = i - 1; \
break; \
} \
} \
\
for (size_t i = 0; i < _set_->capacity; i++) \
{ \
struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
\
if (entry->state == CMC_ES_FILLED) \
{ \
if (!_set_->f_val->str(fptr, entry->value)) \
return false; \
\
if (i + 1 < last) \
fprintf(fptr, "%s", separator); \
} \
} \
\
fprintf(fptr, "%s", end); \
\
return true; \
}
#endif /* CMC_EXT_CMC_HASHSET_H */
+104 -3
View File
@@ -8,6 +8,21 @@
*
*/
/**
* This file provides everything from the C Macro Collections library.
*
* Every data structure and features are available through this header. There is
* also three macros that can help you generate whichever Collection you need
* from any given sub-library. They are:
*
* - C_MACRO_COLLECTIONS
* - C_MACRO_COLLECTIONS_GEN
* - C_MACRO_COLLECTIONS_GEN_HEADER
* - C_MACRO_COLLECTIONS_GEN_SOURCE
* - C_MACRO_COLLECTIONS_ALL
* - C_MACRO_COLLECTIONS_ALL_HEADER
* - C_MACRO_COLLECTIONS_ALL_SOURCE
*/
#ifndef CMC_MACRO_COLLECTIONS_H
#define CMC_MACRO_COLLECTIONS_H
@@ -41,6 +56,7 @@
#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */
#include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */
#include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */
#include "ext/cmc/hashset.h" /* Added in 31/05/2020 */
#include "utl/assert.h" /* Added in 27/06/2019 */
#include "utl/foreach.h" /* Added in 25/02/2019 */
@@ -53,7 +69,15 @@
// clang-format on
/**
* Generate a specific part of a collection
* C_MACRO_COLLECTIONS
*
* Generate a specific part of a specific collection from a specific library.
*
* \param LIB The collection's sub-library
* \param COLLECTION The name of the collection in all uppercase
* \param PART The part of the collection (either CORE or one available at EXT)
* \param FILE Either HEADER or SOURCE
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
*/
#define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE)(PARAMS)
@@ -61,26 +85,102 @@
CMC_##LIB##_##COLLECTION##_##PART##_##FILE
/**
* Generate everything provided by a collection included in ext
* C_MACRO_COLLECTIONS_GEN
*
* Generate the CORE of a collection along with one or more part from EXT. The
* headers are generated first, then the source code.
*
* \param LIB The collection's sub-library
* \param COLLECTION The name of the collection in all uppercase
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
* \param PARTS A non-empty tuple of all desired EXT parts
*/
#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \
C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \
C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS)
/**
* C_MACRO_COLLECTIONS_GEN_HEADER
*
* Generate all headers of CORE and the specified header parts of a collection.
*
* \param LIB The collection's sub-library
* \param COLLECTION The name of the collection in all uppercase
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
* \param PARTS A non-empty tuple of all desired EXT parts
*/
#define C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, CMC_EVAL PARTS)
/**
* C_MACRO_COLLECTIONS_GEN_SOURCE
*
* Generate all sources of CORE and the specified source parts of a collection.
*
* \param LIB The collection's sub-library
* \param COLLECTION The name of the collection in all uppercase
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
* \param PARTS A non-empty tuple of all desired EXT parts
*/
#define C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) \
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, CMC_EVAL PARTS)
/**
* C_MACRO_COLLECTIONS_ALL
*
* Generate everything provided by a collection included in the EXT library. The
* headers are generated first, then the source code.
*
* \param LIB The collection's library
* \param COLLECTION The name of the collection in all uppercase
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
*/
#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \
C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \
C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS)
/**
* C_MACRO_COLLECTIONS_ALL_HEADER
*
* Generates all headers (CORE and those at EXT) from a given collection.
*
* \param LIB The collection's library
* \param COLLECTION The name of the collection in all uppercase
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
*/
#define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, \
C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
/**
* C_MACRO_COLLECTIONS_ALL_SOURCE
*
* Generates all sources (CORE and those at EXT) from a given collection.
*
* \param LIB The collection's library
* \param COLLECTION The name of the collection in all uppercase
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
*/
#define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) \
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, \
C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
/* Gets the macro with all EXT parts of a collection */
/**
* C_MACRO_COLLECTIONS_PARTS
*
* Gets the macro with all EXT parts of a collection. Every collection has this
* macro defined in the EXT libraries.
*/
#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \
CMC_EXT_##LIB##_##COLLECTION##_PARTS,
/* Evaluates a tuple so that (A, B) -> A, B, */
#define CMC_EVAL(...) __VA_ARGS__,
/**
* A __VA_ARGS__ argument counter. This argument counter is slightly shifted:
*
@@ -103,6 +203,7 @@
28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
/* Generates the FILE for each part (__VA_ARGS__) of a collection */
#define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \
CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \
(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
-24
View File
@@ -455,30 +455,6 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_)
}
return 1;
}
struct cmc_string hs_to_string(struct hashset *_set_)
{
struct cmc_string str;
struct hashset *s_ = _set_;
int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashset,
"CMC_PARAM_SNAME((hs, hashset, , , size_t))",
"CMC_PARAM_V((hs, hashset, , , size_t))", s_, s_->buffer,
s_->capacity, s_->count, s_->load, s_->flag, s_->f_val,
s_->alloc, s_->callbacks);
return n >= 0 ? str : (struct cmc_string){ 0 };
}
_Bool hs_print(struct hashset *_set_, FILE *fptr)
{
for (size_t i = 0; i < _set_->capacity; i++)
{
struct hashset_entry *entry = &(_set_->buffer[i]);
if (entry->state == CMC_ES_FILLED)
{
if (!_set_->f_val->str(fptr, entry->value))
return 0;
}
}
return 1;
}
struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_)
{
struct hashset *_set_r_ =
+11 -1
View File
@@ -7,6 +7,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int))
C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int))
C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int))
C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int))
C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int))
struct
{
@@ -26,7 +27,10 @@ int main(void)
struct hashmultimap *hmm = hmm_new(100, 0.8,
(struct hashmultimap_fkey *)&int_ftab,
(struct hashmultimap_fval *)&int_ftab);
struct hashmultiset *hms = hms_new(100, 0.6, (struct hashmultiset_fval *)&int_ftab);
struct hashmultiset *hms = hms_new(100, 0.6,
(struct hashmultiset_fval *)&int_ftab);
struct hashset *hs = hs_new(100, 0.6,
(struct hashset_fval *)&int_ftab);
d_to_string(d, stdout);
d_print(d, stdout, "\n[ ", ", ", " ]\n");
@@ -36,6 +40,8 @@ int main(void)
hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
hms_to_string(hms, stdout);
hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : ");
hs_to_string(hs, stdout);
hs_print(hs, stdout, "\n[ ", ", ", " ]\n");
for (int i = 0; i < 20; i++)
{
@@ -43,6 +49,7 @@ int main(void)
hm_insert(hm, i, i);
hmm_insert(hmm, i, i);
hms_insert(hms, i);
hs_insert(hs, i);
}
fprintf(stdout, "\n");
@@ -55,11 +62,14 @@ int main(void)
hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
hms_to_string(hms, stdout);
hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : ");
hs_to_string(hs, stdout);
hs_print(hs, stdout, "\n[ ", ", ", " ]\n");
d_free(d);
hm_free(hm);
hmm_free(hmm);
hms_free(hms);
hs_free(hs);
}
// clang-format on