Added callbacks to heap and intervaheap, and reworked some min and max functions
This commit is contained in:
1 parent
cf5ceb9c48
commit
5b8f64b421
11 files changed
+237
-130
No files matched your search
+34
-33
@@ -168,7 +168,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
struct cmc_callbacks *callbacks); \
|
struct cmc_callbacks *callbacks); \
|
||||||
/* Collection Input and Output */ \
|
/* Collection Input and Output */ \
|
||||||
bool PFX##_insert(struct SNAME *_heap_, V element); \
|
bool PFX##_insert(struct SNAME *_heap_, V element); \
|
||||||
bool PFX##_remove(struct SNAME *_heap_, V *result); \
|
bool PFX##_remove(struct SNAME *_heap_); \
|
||||||
/* Element Access */ \
|
/* Element Access */ \
|
||||||
V PFX##_peek(struct SNAME *_heap_); \
|
V PFX##_peek(struct SNAME *_heap_); \
|
||||||
/* Collection State */ \
|
/* Collection State */ \
|
||||||
@@ -212,8 +212,8 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
#define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \
|
#define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \
|
||||||
\
|
\
|
||||||
/* Implementation Detail Functions */ \
|
/* Implementation Detail Functions */ \
|
||||||
static bool PFX##_impl_float_up(struct SNAME *_heap_, size_t index); \
|
static void PFX##_impl_float_up(struct SNAME *_heap_, size_t index); \
|
||||||
static bool PFX##_impl_float_down(struct SNAME *_heap_, size_t index); \
|
static void PFX##_impl_float_down(struct SNAME *_heap_, size_t index); \
|
||||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_); \
|
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_); \
|
||||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_heap_); \
|
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_heap_); \
|
||||||
\
|
\
|
||||||
@@ -350,29 +350,22 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (PFX##_empty(_heap_)) \
|
|
||||||
{ \
|
|
||||||
_heap_->buffer[_heap_->count++] = element; \
|
|
||||||
\
|
|
||||||
_heap_->flag = cmc_flags.OK; \
|
|
||||||
\
|
|
||||||
return true; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
_heap_->buffer[_heap_->count++] = element; \
|
_heap_->buffer[_heap_->count++] = element; \
|
||||||
\
|
\
|
||||||
if (!PFX##_impl_float_up(_heap_, _heap_->count - 1)) \
|
if (!PFX##_empty(_heap_)) \
|
||||||
{ \
|
{ \
|
||||||
_heap_->flag = cmc_flags.ERROR; \
|
PFX##_impl_float_up(_heap_, _heap_->count - 1); \
|
||||||
return false; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->create) \
|
||||||
|
_heap_->callbacks->create(); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_remove(struct SNAME *_heap_, V *result) \
|
bool PFX##_remove(struct SNAME *_heap_) \
|
||||||
{ \
|
{ \
|
||||||
if (PFX##_empty(_heap_)) \
|
if (PFX##_empty(_heap_)) \
|
||||||
{ \
|
{ \
|
||||||
@@ -380,22 +373,18 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (result) \
|
|
||||||
*result = _heap_->buffer[0]; \
|
|
||||||
\
|
|
||||||
_heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \
|
_heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \
|
||||||
_heap_->buffer[_heap_->count - 1] = (V){ 0 }; \
|
_heap_->buffer[_heap_->count - 1] = (V){ 0 }; \
|
||||||
\
|
\
|
||||||
_heap_->count--; \
|
_heap_->count--; \
|
||||||
\
|
\
|
||||||
if (!PFX##_impl_float_down(_heap_, 0)) \
|
PFX##_impl_float_down(_heap_, 0); \
|
||||||
{ \
|
|
||||||
_heap_->flag = cmc_flags.ERROR; \
|
|
||||||
return false; \
|
|
||||||
} \
|
|
||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->delete) \
|
||||||
|
_heap_->callbacks->delete (); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -409,6 +398,9 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||||
|
_heap_->callbacks->read(); \
|
||||||
|
\
|
||||||
return _heap_->buffer[0]; \
|
return _heap_->buffer[0]; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -416,13 +408,21 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
{ \
|
{ \
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
|
bool result = false; \
|
||||||
|
\
|
||||||
for (size_t i = 0; i < _heap_->count; i++) \
|
for (size_t i = 0; i < _heap_->count; i++) \
|
||||||
{ \
|
{ \
|
||||||
if (_heap_->f_val->cmp(_heap_->buffer[i], element) == 0) \
|
if (_heap_->f_val->cmp(_heap_->buffer[i], element) == 0) \
|
||||||
return true; \
|
{ \
|
||||||
|
result = true; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
return false; \
|
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||||
|
_heap_->callbacks->read(); \
|
||||||
|
\
|
||||||
|
return result; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_empty(struct SNAME *_heap_) \
|
bool PFX##_empty(struct SNAME *_heap_) \
|
||||||
@@ -455,7 +455,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
if (_heap_->capacity == capacity) \
|
if (_heap_->capacity == capacity) \
|
||||||
return true; \
|
goto success; \
|
||||||
\
|
\
|
||||||
if (capacity < _heap_->count) \
|
if (capacity < _heap_->count) \
|
||||||
{ \
|
{ \
|
||||||
@@ -477,6 +477,11 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
_heap_->buffer = new_buffer; \
|
_heap_->buffer = new_buffer; \
|
||||||
_heap_->capacity = capacity; \
|
_heap_->capacity = capacity; \
|
||||||
\
|
\
|
||||||
|
success: \
|
||||||
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->resize) \
|
||||||
|
_heap_->callbacks->resize(); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -716,7 +721,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
return iter->cursor; \
|
return iter->cursor; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool PFX##_impl_float_up(struct SNAME *_heap_, size_t index) \
|
static void PFX##_impl_float_up(struct SNAME *_heap_, size_t index) \
|
||||||
{ \
|
{ \
|
||||||
/* Current index */ \
|
/* Current index */ \
|
||||||
size_t C = index; \
|
size_t C = index; \
|
||||||
@@ -738,11 +743,9 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
child = _heap_->buffer[C]; \
|
child = _heap_->buffer[C]; \
|
||||||
parent = _heap_->buffer[(C - 1) / 2]; \
|
parent = _heap_->buffer[(C - 1) / 2]; \
|
||||||
} \
|
} \
|
||||||
\
|
|
||||||
return true; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool PFX##_impl_float_down(struct SNAME *_heap_, size_t index) \
|
static void PFX##_impl_float_down(struct SNAME *_heap_, size_t index) \
|
||||||
{ \
|
{ \
|
||||||
int mod = _heap_->HO; \
|
int mod = _heap_->HO; \
|
||||||
\
|
\
|
||||||
@@ -781,8 +784,6 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
|||||||
else \
|
else \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
\
|
|
||||||
return true; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_) \
|
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_) \
|
||||||
|
|||||||
+78
-41
@@ -155,8 +155,8 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
bool PFX##_update_max(struct SNAME *_heap_, V element); \
|
bool PFX##_update_max(struct SNAME *_heap_, V element); \
|
||||||
bool PFX##_update_min(struct SNAME *_heap_, V element); \
|
bool PFX##_update_min(struct SNAME *_heap_, V element); \
|
||||||
/* Element Access */ \
|
/* Element Access */ \
|
||||||
bool PFX##_max(struct SNAME *_heap_, V *value); \
|
V PFX##_max(struct SNAME *_heap_); \
|
||||||
bool PFX##_min(struct SNAME *_heap_, V *value); \
|
V PFX##_min(struct SNAME *_heap_); \
|
||||||
/* Collection State */ \
|
/* Collection State */ \
|
||||||
bool PFX##_contains(struct SNAME *_heap_, V element); \
|
bool PFX##_contains(struct SNAME *_heap_, V element); \
|
||||||
bool PFX##_empty(struct SNAME *_heap_); \
|
bool PFX##_empty(struct SNAME *_heap_); \
|
||||||
@@ -250,7 +250,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
size_t capacity, struct SNAME##_ftab_val *f_val, \
|
size_t capacity, struct SNAME##_ftab_val *f_val, \
|
||||||
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
|
struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
|
||||||
{ \
|
{ \
|
||||||
if (capacity == 0 || capacity == UINT64_MAX) \
|
if (capacity == 0 || capacity == UINTMAX_MAX) \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
\
|
\
|
||||||
if (!f_val) \
|
if (!f_val) \
|
||||||
@@ -371,18 +371,22 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
_heap_->count++; \
|
_heap_->count++; \
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
if (_heap_->count <= 2) \
|
if (_heap_->count > 2) \
|
||||||
return true; \
|
{ \
|
||||||
|
/* Determine wheather to do a MaxHeap insert or a MinHeap insert \
|
||||||
|
*/ \
|
||||||
|
struct SNAME##_node *parent = \
|
||||||
|
&(_heap_->buffer[(_heap_->size - 1) / 2]); \
|
||||||
\
|
\
|
||||||
/* Determine wheather to do a MaxHeap insert or a MinHeap insert */ \
|
if (_heap_->f_val->cmp(parent->data[0], element) > 0) \
|
||||||
struct SNAME##_node *parent = \
|
PFX##_impl_float_up_min(_heap_); \
|
||||||
&(_heap_->buffer[(_heap_->size - 1) / 2]); \
|
else if (_heap_->f_val->cmp(parent->data[1], element) < 0) \
|
||||||
|
PFX##_impl_float_up_max(_heap_); \
|
||||||
|
/* else no float up required */ \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
if (_heap_->f_val->cmp(parent->data[0], element) > 0) \
|
if (_heap_->callbacks && _heap_->callbacks->create) \
|
||||||
PFX##_impl_float_up_min(_heap_); \
|
_heap_->callbacks->create(); \
|
||||||
else if (_heap_->f_val->cmp(parent->data[1], element) < 0) \
|
|
||||||
PFX##_impl_float_up_max(_heap_); \
|
|
||||||
/* else no float up required */ \
|
|
||||||
\
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
@@ -402,9 +406,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
_heap_->count--; \
|
_heap_->count--; \
|
||||||
_heap_->size--; \
|
_heap_->size--; \
|
||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
goto success; \
|
||||||
\
|
|
||||||
return true; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* Swap the result with the last element in the MaxHeap and float */ \
|
/* Swap the result with the last element in the MaxHeap and float */ \
|
||||||
@@ -428,11 +430,17 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
_heap_->count--; \
|
_heap_->count--; \
|
||||||
_heap_->flag = cmc_flags.OK; \
|
|
||||||
\
|
\
|
||||||
/* FLoat Down on the MaxHeap */ \
|
/* FLoat Down on the MaxHeap */ \
|
||||||
PFX##_impl_float_down_max(_heap_); \
|
PFX##_impl_float_down_max(_heap_); \
|
||||||
\
|
\
|
||||||
|
success: \
|
||||||
|
\
|
||||||
|
_heap_->flag = cmc_flags.OK; \
|
||||||
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->delete) \
|
||||||
|
_heap_->callbacks->delete (); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -451,9 +459,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
_heap_->count--; \
|
_heap_->count--; \
|
||||||
_heap_->size--; \
|
_heap_->size--; \
|
||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
goto success; \
|
||||||
\
|
|
||||||
return true; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* Swap the result with the last element in the MinHeap and float */ \
|
/* Swap the result with the last element in the MinHeap and float */ \
|
||||||
@@ -477,11 +483,17 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
_heap_->count--; \
|
_heap_->count--; \
|
||||||
_heap_->flag = cmc_flags.OK; \
|
|
||||||
\
|
\
|
||||||
/* FLoat Down on the MinHeap */ \
|
/* FLoat Down on the MinHeap */ \
|
||||||
PFX##_impl_float_down_min(_heap_); \
|
PFX##_impl_float_down_min(_heap_); \
|
||||||
\
|
\
|
||||||
|
success: \
|
||||||
|
\
|
||||||
|
_heap_->flag = cmc_flags.OK; \
|
||||||
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->delete) \
|
||||||
|
_heap_->callbacks->delete (); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -516,6 +528,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->update) \
|
||||||
|
_heap_->callbacks->update(); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -550,56 +565,69 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->update) \
|
||||||
|
_heap_->callbacks->update(); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_max(struct SNAME *_heap_, V *value) \
|
V PFX##_max(struct SNAME *_heap_) \
|
||||||
{ \
|
{ \
|
||||||
if (PFX##_empty(_heap_)) \
|
if (PFX##_empty(_heap_)) \
|
||||||
{ \
|
{ \
|
||||||
_heap_->flag = cmc_flags.EMPTY; \
|
_heap_->flag = cmc_flags.EMPTY; \
|
||||||
return false; \
|
return (V){ 0 }; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
_heap_->flag = cmc_flags.OK; \
|
||||||
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||||
|
_heap_->callbacks->read(); \
|
||||||
|
\
|
||||||
/* If there is only one element, then the maximum element is the */ \
|
/* If there is only one element, then the maximum element is the */ \
|
||||||
/* same as the one in the MinHeap */ \
|
/* same as the one in the MinHeap */ \
|
||||||
if (_heap_->count == 1) \
|
if (_heap_->count == 1) \
|
||||||
*value = _heap_->buffer[0].data[0]; \
|
return _heap_->buffer[0].data[0]; \
|
||||||
else \
|
|
||||||
*value = _heap_->buffer[0].data[1]; \
|
|
||||||
\
|
\
|
||||||
_heap_->flag = cmc_flags.OK; \
|
return _heap_->buffer[0].data[1]; \
|
||||||
\
|
|
||||||
return true; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_min(struct SNAME *_heap_, V *value) \
|
V PFX##_min(struct SNAME *_heap_) \
|
||||||
{ \
|
{ \
|
||||||
if (PFX##_empty(_heap_)) \
|
if (PFX##_empty(_heap_)) \
|
||||||
{ \
|
{ \
|
||||||
_heap_->flag = cmc_flags.EMPTY; \
|
_heap_->flag = cmc_flags.EMPTY; \
|
||||||
return false; \
|
return (V){ 0 }; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
*value = _heap_->buffer[0].data[0]; \
|
|
||||||
\
|
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
return true; \
|
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||||
|
_heap_->callbacks->read(); \
|
||||||
|
\
|
||||||
|
return _heap_->buffer[0].data[0]; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_contains(struct SNAME *_heap_, V element) \
|
bool PFX##_contains(struct SNAME *_heap_, V element) \
|
||||||
{ \
|
{ \
|
||||||
_heap_->flag = cmc_flags.OK; \
|
_heap_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
|
bool result = false; \
|
||||||
|
\
|
||||||
for (size_t i = 0; i < _heap_->count; i++) \
|
for (size_t i = 0; i < _heap_->count; i++) \
|
||||||
{ \
|
{ \
|
||||||
if (_heap_->f_val->cmp(_heap_->buffer[i / 2].data[i % 2], \
|
if (_heap_->f_val->cmp(_heap_->buffer[i / 2].data[i % 2], \
|
||||||
element) == 0) \
|
element) == 0) \
|
||||||
return true; \
|
{ \
|
||||||
|
result = true; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
return false; \
|
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||||
|
_heap_->callbacks->read(); \
|
||||||
|
\
|
||||||
|
return result; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_empty(struct SNAME *_heap_) \
|
bool PFX##_empty(struct SNAME *_heap_) \
|
||||||
@@ -630,10 +658,8 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
\
|
\
|
||||||
bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \
|
bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \
|
||||||
{ \
|
{ \
|
||||||
_heap_->flag = cmc_flags.OK; \
|
|
||||||
\
|
|
||||||
if (_heap_->capacity == capacity) \
|
if (_heap_->capacity == capacity) \
|
||||||
return true; \
|
goto success; \
|
||||||
\
|
\
|
||||||
if (capacity < _heap_->count) \
|
if (capacity < _heap_->count) \
|
||||||
{ \
|
{ \
|
||||||
@@ -659,12 +685,23 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
memset(new_buffer + _heap_->capacity, 0, \
|
if (capacity > _heap_->capacity) \
|
||||||
sizeof(struct SNAME##_node) * _heap_->capacity); \
|
{ \
|
||||||
|
memset(new_buffer + _heap_->capacity, 0, \
|
||||||
|
sizeof(struct SNAME##_node) * \
|
||||||
|
(capacity - _heap_->capacity)); \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
_heap_->buffer = new_buffer; \
|
_heap_->buffer = new_buffer; \
|
||||||
_heap_->capacity = capacity; \
|
_heap_->capacity = capacity; \
|
||||||
\
|
\
|
||||||
|
success: \
|
||||||
|
\
|
||||||
|
_heap_->flag = cmc_flags.OK; \
|
||||||
|
\
|
||||||
|
if (_heap_->callbacks && _heap_->callbacks->resize) \
|
||||||
|
_heap_->callbacks->resize(); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
|||||||
+8
-14
@@ -144,8 +144,8 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> "
|
|||||||
bool PFX##_insert(struct SNAME *_list_, V element); \
|
bool PFX##_insert(struct SNAME *_list_, V element); \
|
||||||
bool PFX##_remove(struct SNAME *_list_, size_t index); \
|
bool PFX##_remove(struct SNAME *_list_, size_t index); \
|
||||||
/* Element Access */ \
|
/* Element Access */ \
|
||||||
bool PFX##_max(struct SNAME *_list_, V *result); \
|
V PFX##_max(struct SNAME *_list_); \
|
||||||
bool PFX##_min(struct SNAME *_list_, V *result); \
|
V PFX##_min(struct SNAME *_list_); \
|
||||||
V PFX##_get(struct SNAME *_list_, size_t index); \
|
V PFX##_get(struct SNAME *_list_, size_t index); \
|
||||||
size_t PFX##_index_of(struct SNAME *_list_, V element, bool from_start); \
|
size_t PFX##_index_of(struct SNAME *_list_, V element, bool from_start); \
|
||||||
/* Collection State */ \
|
/* Collection State */ \
|
||||||
@@ -351,40 +351,34 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> "
|
|||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_max(struct SNAME *_list_, V *result) \
|
V PFX##_max(struct SNAME *_list_) \
|
||||||
{ \
|
{ \
|
||||||
if (PFX##_empty(_list_)) \
|
if (PFX##_empty(_list_)) \
|
||||||
{ \
|
{ \
|
||||||
_list_->flag = cmc_flags.EMPTY; \
|
_list_->flag = cmc_flags.EMPTY; \
|
||||||
return false; \
|
return (V){ 0 }; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
PFX##_sort(_list_); \
|
PFX##_sort(_list_); \
|
||||||
\
|
\
|
||||||
if (result) \
|
|
||||||
*result = _list_->buffer[_list_->count - 1]; \
|
|
||||||
\
|
|
||||||
_list_->flag = cmc_flags.OK; \
|
_list_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
return true; \
|
return _list_->buffer[_list_->count - 1]; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_min(struct SNAME *_list_, V *result) \
|
V PFX##_min(struct SNAME *_list_) \
|
||||||
{ \
|
{ \
|
||||||
if (PFX##_empty(_list_)) \
|
if (PFX##_empty(_list_)) \
|
||||||
{ \
|
{ \
|
||||||
_list_->flag = cmc_flags.EMPTY; \
|
_list_->flag = cmc_flags.EMPTY; \
|
||||||
return false; \
|
return (V){ 0 }; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
PFX##_sort(_list_); \
|
PFX##_sort(_list_); \
|
||||||
\
|
\
|
||||||
if (result) \
|
|
||||||
*result = _list_->buffer[0]; \
|
|
||||||
\
|
|
||||||
_list_->flag = cmc_flags.OK; \
|
_list_->flag = cmc_flags.OK; \
|
||||||
\
|
\
|
||||||
return true; \
|
return _list_->buffer[0]; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
V PFX##_get(struct SNAME *_list_, size_t index) \
|
V PFX##_get(struct SNAME *_list_, size_t index) \
|
||||||
|
|||||||
@@ -512,7 +512,8 @@ CMC_CREATE_UNIT(bidimap_test, true, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
CMC_CREATE_TEST(callbacks, {
|
CMC_CREATE_TEST(callbacks, {
|
||||||
struct bidimap *map = bm_new_custom(100, 0.7, bm_ftab_key, bm_ftab_val, NULL, callbacks);
|
struct bidimap *map =
|
||||||
|
bm_new_custom(100, 0.7, bm_ftab_key, bm_ftab_val, NULL, callbacks);
|
||||||
|
|
||||||
cmc_assert_not_equals(ptr, NULL, map);
|
cmc_assert_not_equals(ptr, NULL, map);
|
||||||
cmc_assert_equals(ptr, callbacks, map->callbacks);
|
cmc_assert_equals(ptr, callbacks, map->callbacks);
|
||||||
|
|||||||
@@ -660,8 +660,7 @@ CMC_CREATE_UNIT(deque_test, true, {
|
|||||||
|
|
||||||
// customize
|
// customize
|
||||||
d->flag = cmc_flags.ERROR;
|
d->flag = cmc_flags.ERROR;
|
||||||
d_customize(d, &cmc_alloc_node_default,
|
d_customize(d, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 });
|
||||||
&(struct cmc_callbacks){ 0 });
|
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
|
cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
|
||||||
|
|
||||||
// push_front
|
// push_front
|
||||||
|
|||||||
@@ -604,7 +604,8 @@ CMC_CREATE_UNIT(hashmap_test, true, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
CMC_CREATE_TEST(callbacks, {
|
CMC_CREATE_TEST(callbacks, {
|
||||||
struct hashmap *map = hm_new_custom(100, 0.6, hm_ftab_key, hm_ftab_val, NULL, callbacks);
|
struct hashmap *map =
|
||||||
|
hm_new_custom(100, 0.6, hm_ftab_key, hm_ftab_val, NULL, callbacks);
|
||||||
|
|
||||||
total_create = 0;
|
total_create = 0;
|
||||||
total_read = 0;
|
total_read = 0;
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ CMC_CREATE_UNIT(hashset_test, true, {
|
|||||||
cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
|
cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
|
||||||
|
|
||||||
// copy
|
// copy
|
||||||
set->flag = cmc_flags.ERROR;\
|
set->flag = cmc_flags.ERROR;
|
||||||
struct hashset *set2 = hs_copy_of(set);
|
struct hashset *set2 = hs_copy_of(set);
|
||||||
|
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
|
cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
|
||||||
@@ -483,7 +483,8 @@ CMC_CREATE_UNIT(hashset_test, true, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
CMC_CREATE_TEST(callbacks, {
|
CMC_CREATE_TEST(callbacks, {
|
||||||
struct hashset *set = hs_new_custom(100, 0.6, hs_ftab_val, NULL, callbacks);
|
struct hashset *set =
|
||||||
|
hs_new_custom(100, 0.6, hs_ftab_val, NULL, callbacks);
|
||||||
|
|
||||||
total_create = 0;
|
total_create = 0;
|
||||||
total_read = 0;
|
total_read = 0;
|
||||||
|
|||||||
+43
-12
@@ -104,10 +104,9 @@ CMC_CREATE_UNIT(heap_test, true, {
|
|||||||
for (size_t i = 0; i <= 100; i++)
|
for (size_t i = 0; i <= 100; i++)
|
||||||
cmc_assert(h_insert(h, i));
|
cmc_assert(h_insert(h, i));
|
||||||
|
|
||||||
size_t r;
|
cmc_assert_equals(size_t, 100, h_peek(h));
|
||||||
cmc_assert(h_remove(h, &r));
|
cmc_assert(h_remove(h));
|
||||||
|
cmc_assert_equals(size_t, 99, h_peek(h));
|
||||||
cmc_assert_equals(size_t, 100, r);
|
|
||||||
|
|
||||||
h_free(h);
|
h_free(h);
|
||||||
});
|
});
|
||||||
@@ -117,8 +116,7 @@ CMC_CREATE_UNIT(heap_test, true, {
|
|||||||
|
|
||||||
cmc_assert_not_equals(ptr, NULL, h);
|
cmc_assert_not_equals(ptr, NULL, h);
|
||||||
|
|
||||||
size_t _;
|
cmc_assert(!h_remove(h));
|
||||||
cmc_assert(!h_remove(h, &_));
|
|
||||||
|
|
||||||
h_free(h);
|
h_free(h);
|
||||||
});
|
});
|
||||||
@@ -136,9 +134,8 @@ CMC_CREATE_UNIT(heap_test, true, {
|
|||||||
size_t arr[100];
|
size_t arr[100];
|
||||||
while (!h_empty(h))
|
while (!h_empty(h))
|
||||||
{
|
{
|
||||||
cmc_assert(h_remove(h, &r));
|
arr[i++] = h_peek(h);
|
||||||
|
cmc_assert(h_remove(h));
|
||||||
arr[i++] = r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmc_assert_array_sorted_any(size_t, arr, cmp, 0, 99);
|
cmc_assert_array_sorted_any(size_t, arr, cmp, 0, 99);
|
||||||
@@ -184,17 +181,17 @@ CMC_CREATE_UNIT(heap_test, true, {
|
|||||||
h->flag = cmc_flags.ERROR;
|
h->flag = cmc_flags.ERROR;
|
||||||
|
|
||||||
// remove
|
// remove
|
||||||
cmc_assert(h_remove(h, NULL));
|
cmc_assert(h_remove(h));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
|
cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
|
||||||
|
|
||||||
cmc_assert(!h_remove(h, NULL));
|
cmc_assert(!h_remove(h));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h));
|
cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h));
|
||||||
|
|
||||||
// peek
|
// peek
|
||||||
cmc_assert(h_insert(h, 10));
|
cmc_assert(h_insert(h, 10));
|
||||||
h_peek(h);
|
h_peek(h);
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
|
cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
|
||||||
cmc_assert(h_remove(h, NULL));
|
cmc_assert(h_remove(h));
|
||||||
h_peek(h);
|
h_peek(h);
|
||||||
cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h));
|
cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h));
|
||||||
|
|
||||||
@@ -226,4 +223,38 @@ CMC_CREATE_UNIT(heap_test, true, {
|
|||||||
h_free(h);
|
h_free(h);
|
||||||
h_free(h2);
|
h_free(h2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CMC_CREATE_TEST(callbacks, {
|
||||||
|
struct heap *h =
|
||||||
|
h_new_custom(100, cmc_max_heap, h_ftab_val, NULL, callbacks);
|
||||||
|
|
||||||
|
total_create = 0;
|
||||||
|
total_read = 0;
|
||||||
|
total_update = 0;
|
||||||
|
total_delete = 0;
|
||||||
|
total_resize = 0;
|
||||||
|
|
||||||
|
cmc_assert(h_insert(h, 10));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_create);
|
||||||
|
|
||||||
|
cmc_assert(h_remove(h));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_delete);
|
||||||
|
|
||||||
|
cmc_assert(h_insert(h, 10));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_create);
|
||||||
|
|
||||||
|
cmc_assert_equals(size_t, 10, h_peek(h));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_read);
|
||||||
|
|
||||||
|
cmc_assert(h_contains(h, 10));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_read);
|
||||||
|
|
||||||
|
cmc_assert(h_resize(h, 1000));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_resize);
|
||||||
|
|
||||||
|
cmc_assert(h_resize(h, 100));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_resize);
|
||||||
|
|
||||||
|
h_free(h);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@@ -127,10 +127,7 @@ CMC_CREATE_UNIT(intervalheap_test, true, {
|
|||||||
cmc_assert(ih_insert(ih, 1));
|
cmc_assert(ih_insert(ih, 1));
|
||||||
cmc_assert(ih_insert(ih, 2));
|
cmc_assert(ih_insert(ih, 2));
|
||||||
|
|
||||||
size_t r;
|
cmc_assert_equals(size_t, 2, ih_max(ih));
|
||||||
cmc_assert(ih_max(ih, &r));
|
|
||||||
|
|
||||||
cmc_assert_equals(size_t, 2, r);
|
|
||||||
|
|
||||||
ih_free(ih);
|
ih_free(ih);
|
||||||
});
|
});
|
||||||
@@ -142,10 +139,7 @@ CMC_CREATE_UNIT(intervalheap_test, true, {
|
|||||||
cmc_assert(ih_insert(ih, 1));
|
cmc_assert(ih_insert(ih, 1));
|
||||||
cmc_assert(ih_insert(ih, 2));
|
cmc_assert(ih_insert(ih, 2));
|
||||||
|
|
||||||
size_t r;
|
cmc_assert_equals(size_t, 0, ih_min(ih));
|
||||||
cmc_assert(ih_min(ih, &r));
|
|
||||||
|
|
||||||
cmc_assert_equals(size_t, 0, r);
|
|
||||||
|
|
||||||
ih_free(ih);
|
ih_free(ih);
|
||||||
});
|
});
|
||||||
@@ -228,22 +222,21 @@ CMC_CREATE_UNIT(intervalheap_test, true, {
|
|||||||
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
|
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
|
||||||
|
|
||||||
// max min
|
// max min
|
||||||
size_t r;
|
|
||||||
ih->flag = cmc_flags.ERROR;
|
ih->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(!ih_max(ih, &r));
|
cmc_assert_equals(size_t, (size_t){ 0 }, ih_max(ih));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
|
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
|
||||||
|
|
||||||
ih->flag = cmc_flags.ERROR;
|
ih->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(!ih_min(ih, &r));
|
cmc_assert_equals(size_t, (size_t){ 0 }, ih_min(ih));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
|
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
|
||||||
|
|
||||||
cmc_assert(ih_insert(ih, 10));
|
cmc_assert(ih_insert(ih, 10));
|
||||||
ih->flag = cmc_flags.ERROR;
|
ih->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(ih_max(ih, &r));
|
cmc_assert_equals(size_t, 10, ih_max(ih));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
|
cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
|
||||||
|
|
||||||
ih->flag = cmc_flags.ERROR;
|
ih->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(ih_max(ih, &r));
|
cmc_assert_equals(size_t, 10, ih_min(ih));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
|
cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
|
||||||
|
|
||||||
// contains
|
// contains
|
||||||
@@ -267,4 +260,54 @@ CMC_CREATE_UNIT(intervalheap_test, true, {
|
|||||||
ih_free(ih);
|
ih_free(ih);
|
||||||
ih_free(ih2);
|
ih_free(ih2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CMC_CREATE_TEST(callbacks, {
|
||||||
|
struct intervalheap *ih =
|
||||||
|
ih_new_custom(100, ih_ftab_val, NULL, callbacks);
|
||||||
|
|
||||||
|
total_create = 0;
|
||||||
|
total_read = 0;
|
||||||
|
total_update = 0;
|
||||||
|
total_delete = 0;
|
||||||
|
total_resize = 0;
|
||||||
|
|
||||||
|
cmc_assert(ih_insert(ih, 10));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_create);
|
||||||
|
|
||||||
|
cmc_assert(ih_remove_max(ih));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_delete);
|
||||||
|
|
||||||
|
cmc_assert(ih_insert(ih, 10));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_create);
|
||||||
|
|
||||||
|
cmc_assert(ih_remove_min(ih));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_delete);
|
||||||
|
|
||||||
|
cmc_assert(ih_insert(ih, 1));
|
||||||
|
cmc_assert(ih_insert(ih, 2));
|
||||||
|
cmc_assert_equals(int32_t, 4, total_create);
|
||||||
|
|
||||||
|
cmc_assert(ih_update_max(ih, 1));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_update);
|
||||||
|
|
||||||
|
cmc_assert(ih_update_min(ih, 2));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_update);
|
||||||
|
|
||||||
|
cmc_assert_equals(size_t, 2, ih_max(ih));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_read);
|
||||||
|
|
||||||
|
cmc_assert_equals(size_t, 1, ih_min(ih));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_read);
|
||||||
|
|
||||||
|
cmc_assert(ih_contains(ih, 1));
|
||||||
|
cmc_assert_equals(int32_t, 3, total_read);
|
||||||
|
|
||||||
|
cmc_assert(ih_resize(ih, 1000));
|
||||||
|
cmc_assert_equals(int32_t, 1, total_resize);
|
||||||
|
|
||||||
|
cmc_assert(ih_resize(ih, 50));
|
||||||
|
cmc_assert_equals(int32_t, 2, total_resize);
|
||||||
|
|
||||||
|
ih_free(ih);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@@ -179,18 +179,18 @@ CMC_CREATE_UNIT(sortedlist_test, true, {
|
|||||||
|
|
||||||
// max min
|
// max min
|
||||||
sl->flag = cmc_flags.ERROR;
|
sl->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(!sl_max(sl, NULL));
|
cmc_assert_equals(size_t, (size_t){ 0 }, sl_max(sl));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
|
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
|
||||||
sl->flag = cmc_flags.ERROR;
|
sl->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(!sl_min(sl, NULL));
|
cmc_assert_equals(size_t, (size_t){ 0 }, sl_min(sl));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
|
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
|
||||||
|
|
||||||
cmc_assert(sl_insert(sl, 1));
|
cmc_assert(sl_insert(sl, 1));
|
||||||
sl->flag = cmc_flags.ERROR;
|
sl->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(sl_max(sl, NULL));
|
cmc_assert_equals(size_t, 1, sl_max(sl));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
|
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
|
||||||
sl->flag = cmc_flags.ERROR;
|
sl->flag = cmc_flags.ERROR;
|
||||||
cmc_assert(sl_min(sl, NULL));
|
cmc_assert_equals(size_t, 1, sl_min(sl));
|
||||||
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
|
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
|
||||||
|
|
||||||
// get
|
// get
|
||||||
|
|||||||
@@ -98,12 +98,11 @@ void callback_resize(void)
|
|||||||
total_resize++;
|
total_resize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmc_callbacks *callbacks = &(struct cmc_callbacks) {
|
struct cmc_callbacks *callbacks =
|
||||||
.create = callback_create,
|
&(struct cmc_callbacks){ .create = callback_create,
|
||||||
.read = callback_read,
|
.read = callback_read,
|
||||||
.update = callback_update,
|
.update = callback_update,
|
||||||
.delete = callback_delete,
|
.delete = callback_delete,
|
||||||
.resize = callback_resize
|
.resize = callback_resize };
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* CMC_UNIT_TEST_UTL__ */
|
#endif /* CMC_UNIT_TEST_UTL__ */
|
||||||
Reference in new issue
Block a user