Added flags to sortedlist

This commit is contained in:
Leonardo committed 2020-03-14 17:39:33 -03:00
1 parent db2de0b855
commit b3fa566725
2 files changed
+191 -24

No files matched your search

+101 -24
View File
@@ -223,12 +223,14 @@ struct cmc_callbacks_sortedlist
bool PFX##_full(struct SNAME *_list_); \
size_t PFX##_count(struct SNAME *_list_); \
size_t PFX##_capacity(struct SNAME *_list_); \
int PFX##_flag(struct SNAME *_list_); \
/* Collection Utility */ \
bool PFX##_resize(struct SNAME *_list_, size_t capacity); \
void PFX##_sort(struct SNAME *_list_); \
struct SNAME *PFX##_copy_of(struct SNAME *_list_); \
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \
struct cmc_string PFX##_to_string(struct SNAME *_list_); \
bool PFX##_print(struct SNAME *_list_, FILE *fptr); \
\
/* Iterator Functions */ \
/* Iterator Allocation and Deallocation */ \
@@ -352,6 +354,7 @@ struct cmc_callbacks_sortedlist
memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
\
_list_->count = 0; \
_list_->flag = cmc_flags.OK; \
} \
\
void PFX##_free(struct SNAME *_list_) \
@@ -374,6 +377,8 @@ struct cmc_callbacks_sortedlist
\
if (callbacks) \
_list_->callbacks = callbacks; \
\
_list_->flag = cmc_flags.OK; \
} \
\
bool PFX##_insert(struct SNAME *_list_, V element) \
@@ -387,31 +392,31 @@ struct cmc_callbacks_sortedlist
_list_->buffer[_list_->count++] = element; \
\
_list_->is_sorted = false; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
\
bool PFX##_remove(struct SNAME *_list_, size_t index) \
{ \
if (index >= _list_->count) \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return false; \
} \
\
if (index >= _list_->count) \
{ \
_list_->flag = cmc_flags.RANGE; \
return false; \
} \
\
memmove(_list_->buffer + index, _list_->buffer + index + 1, \
(_list_->count - index) * sizeof(V)); \
\
_list_->buffer[--_list_->count] = (V){ 0 }; \
\
return true; \
} \
\
bool PFX##_min(struct SNAME *_list_, V *result) \
{ \
if (PFX##_empty(_list_)) \
return false; \
\
PFX##_sort(_list_); \
\
*result = _list_->buffer[0]; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -419,27 +424,64 @@ struct cmc_callbacks_sortedlist
bool PFX##_max(struct SNAME *_list_, V *result) \
{ \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return false; \
} \
\
PFX##_sort(_list_); \
\
*result = _list_->buffer[_list_->count - 1]; \
if (result) \
*result = _list_->buffer[_list_->count - 1]; \
\
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
\
bool PFX##_min(struct SNAME *_list_, V *result) \
{ \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return false; \
} \
\
PFX##_sort(_list_); \
\
if (result) \
*result = _list_->buffer[0]; \
\
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
\
V PFX##_get(struct SNAME *_list_, size_t index) \
{ \
if (index >= _list_->count) \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return (V){ 0 }; \
} \
\
if (index >= _list_->count) \
{ \
_list_->flag = cmc_flags.RANGE; \
return (V){ 0 }; \
} \
\
PFX##_sort(_list_); \
\
_list_->flag = cmc_flags.OK; \
\
return _list_->buffer[index]; \
} \
\
size_t PFX##_index_of(struct SNAME *_list_, V element, bool from_start) \
{ \
_list_->flag = cmc_flags.OK; \
\
PFX##_sort(_list_); \
\
if (from_start) \
@@ -452,6 +494,8 @@ struct cmc_callbacks_sortedlist
\
bool PFX##_contains(struct SNAME *_list_, V element) \
{ \
_list_->flag = cmc_flags.OK; \
\
if (PFX##_empty(_list_)) \
return false; \
\
@@ -481,19 +525,32 @@ struct cmc_callbacks_sortedlist
return _list_->capacity; \
} \
\
int PFX##_flag(struct SNAME *_list_) \
{ \
return _list_->flag; \
} \
\
bool PFX##_resize(struct SNAME *_list_, size_t capacity) \
{ \
_list_->flag = cmc_flags.OK; \
\
if (_list_->capacity == capacity) \
return true; \
\
if (capacity < _list_->count) \
{ \
_list_->flag = cmc_flags.INVALID; \
return false; \
} \
\
V *new_buffer = \
_list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \
\
if (!new_buffer) \
{ \
_list_->flag = cmc_flags.ALLOC; \
return false; \
} \
\
/* TODO zero out remaining slots */ \
\
@@ -505,6 +562,8 @@ struct cmc_callbacks_sortedlist
\
void PFX##_sort(struct SNAME *_list_) \
{ \
_list_->flag = cmc_flags.OK; \
\
if (!_list_->is_sorted && _list_->count > 1) \
{ \
PFX##_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, \
@@ -521,7 +580,10 @@ struct cmc_callbacks_sortedlist
_list_->callbacks); \
\
if (!result) \
{ \
_list_->flag = cmc_flags.ERROR; \
return NULL; \
} \
\
if (_list_->f_val->cpy) \
{ \
@@ -533,25 +595,27 @@ struct cmc_callbacks_sortedlist
\
result->count = _list_->count; \
\
_list_->flag = cmc_flags.OK; \
\
return result; \
} \
\
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \
{ \
if (PFX##_count(_list1_) != PFX##_count(_list2_)) \
if (_list1_->count != _list2_->count) \
return false; \
\
PFX##_sort(_list1_); \
PFX##_sort(_list2_); \
\
for (size_t i = 0; i < PFX##_count(_list1_); i++) \
for (size_t i = 0; i < _list1_->count; i++) \
{ \
if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \
0) \
return false; \
} \
\
return false; \
return true; \
} \
\
struct cmc_string PFX##_to_string(struct SNAME *_list_) \
@@ -567,6 +631,19 @@ struct cmc_callbacks_sortedlist
return n >= 0 ? str : (struct cmc_string){ 0 }; \
} \
\
bool PFX##_print(struct SNAME *_list_, FILE *fptr) \
{ \
PFX##_sort(_list_); \
\
for (size_t i = 0; i < _list_->count; i++) \
{ \
if (!_list_->f_val->str(fptr, _list_->buffer[i])) \
return false; \
} \
\
return true; \
} \
\
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
{ \
struct SNAME##_iter *iter = \
@@ -631,7 +708,7 @@ struct cmc_callbacks_sortedlist
if (iter->end) \
return false; \
\
if (iter->cursor + 1 == PFX##_count(iter->target)) \
if (iter->cursor + 1 == iter->target->count) \
{ \
iter->end = true; \
return false; \
@@ -674,7 +751,7 @@ struct cmc_callbacks_sortedlist
return false; \
} \
\
if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \
if (steps == 0 || iter->cursor + steps >= iter->target->count) \
return false; \
\
iter->start = PFX##_empty(iter->target); \
@@ -710,7 +787,7 @@ struct cmc_callbacks_sortedlist
/* given index */ \
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
{ \
if (index >= PFX##_count(iter->target)) \
if (index >= iter->target->count) \
return false; \
\
if (iter->cursor > index) \
@@ -741,7 +818,7 @@ struct cmc_callbacks_sortedlist
return 1; \
\
size_t L = 0; \
size_t R = PFX##_count(_list_); \
size_t R = _list_->count; \
\
while (L < R) \
{ \
@@ -757,7 +834,7 @@ struct cmc_callbacks_sortedlist
return L; \
\
/* Not found */ \
return PFX##_count(_list_); \
return _list_->count; \
} \
\
static size_t PFX##_impl_binary_search_last(struct SNAME *_list_, V value) \
@@ -766,7 +843,7 @@ struct cmc_callbacks_sortedlist
return 1; \
\
size_t L = 0; \
size_t R = PFX##_count(_list_); \
size_t R = _list_->count; \
\
while (L < R) \
{ \
@@ -782,7 +859,7 @@ struct cmc_callbacks_sortedlist
return L - 1; \
\
/* Not found */ \
return PFX##_count(_list_); \
return _list_->count; \
} \
\
/* Characteristics of this quicksort implementation: */ \
+90
View File
@@ -145,4 +145,94 @@ CMC_CREATE_UNIT(sortedlist_test, true, {
sl_free(sl);
});
CMC_CREATE_TEST(flags, {
struct sortedlist *sl = sl_new(100, sl_ftab_val);
cmc_assert_not_equals(ptr, NULL, sl);
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// clear
sl->flag = cmc_flags.ERROR;
sl_clear(sl);
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// customize
sl->flag = cmc_flags.ERROR;
sl_customize(sl, NULL, NULL);
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// insert
sl->flag = cmc_flags.ERROR;
cmc_assert(sl_insert(sl, 10));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// remove
cmc_assert(!sl_remove(sl, 2));
cmc_assert_equals(int32_t, cmc_flags.RANGE, sl_flag(sl));
cmc_assert(sl_remove(sl, 0));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
cmc_assert(!sl_remove(sl, 0));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
// max min
sl->flag = cmc_flags.ERROR;
cmc_assert(!sl_max(sl, NULL));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
sl->flag = cmc_flags.ERROR;
cmc_assert(!sl_min(sl, NULL));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
cmc_assert(sl_insert(sl, 1));
sl->flag = cmc_flags.ERROR;
cmc_assert(sl_max(sl, NULL));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
sl->flag = cmc_flags.ERROR;
cmc_assert(sl_min(sl, NULL));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// get
sl->flag = cmc_flags.ERROR;
sl_get(sl, 1);
cmc_assert_equals(int32_t, cmc_flags.RANGE, sl_flag(sl));
sl_get(sl, 0);
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
cmc_assert(sl_remove(sl, 0));
sl_get(sl, 0);
cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
// index_of
cmc_assert(sl_insert(sl, 1));
sl_index_of(sl, 1, false);
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// contains
cmc_assert(sl_contains(sl, 1));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// sort
sl->flag = cmc_flags.ERROR;
sl_sort(sl);
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
// copy_of
sl->flag = cmc_flags.ERROR;
struct sortedlist *sl2 = sl_copy_of(sl);
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl2));
// equals
sl->flag = cmc_flags.ERROR;
sl2->flag = cmc_flags.ERROR;
cmc_assert(sl_equals(sl, sl2));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl2));
sl_free(sl);
sl_free(sl2);
});
});