Added flags to linkedlist and renamed some functions

This commit is contained in:
Leonardo committed 2020-03-05 13:49:36 -03:00
1 parent 8bd297f4a3
commit 157aea6055
2 files changed
+287 -38

No files matched your search

+114 -38
View File
@@ -242,6 +242,7 @@ struct cmc_callbacks_linkedlist
bool PFX##_contains(struct SNAME *_list_, V element); \
bool PFX##_empty(struct SNAME *_list_); \
size_t PFX##_count(struct SNAME *_list_); \
int PFX##_flag(struct SNAME *_list_); \
/* Collection Utility */ \
struct SNAME *PFX##_copy_of(struct SNAME *_list_); \
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \
@@ -256,16 +257,13 @@ struct cmc_callbacks_linkedlist
struct SNAME##_node *PFX##_get_node(struct SNAME *_list_, size_t index); \
struct SNAME##_node *PFX##_tail(struct SNAME *_list_); \
/* Input and Output Relative to a Node */ \
bool PFX##_insert_after(struct SNAME *_owner_, \
struct SNAME##_node *_node_, V element); \
bool PFX##_insert_before(struct SNAME *_owner_, \
struct SNAME##_node *_node_, V element); \
bool PFX##_remove_after(struct SNAME *_owner_, \
struct SNAME##_node *_node_); \
bool PFX##_remove_current(struct SNAME *_owner_, \
struct SNAME##_node *_node_); \
bool PFX##_remove_before(struct SNAME *_owner_, \
struct SNAME##_node *_node_); \
bool PFX##_add_next(struct SNAME *_owner_, struct SNAME##_node *_node_, \
V element); \
bool PFX##_add_prev(struct SNAME *_owner_, struct SNAME##_node *_node_, \
V element); \
bool PFX##_del_next(struct SNAME *_owner_, struct SNAME##_node *_node_); \
bool PFX##_del_curr(struct SNAME *_owner_, struct SNAME##_node *_node_); \
bool PFX##_del_prev(struct SNAME *_owner_, struct SNAME##_node *_node_); \
/* Node Access Relative to a Linked List Node */ \
struct SNAME##_node *PFX##_next_node(struct SNAME##_node *_node_); \
struct SNAME##_node *PFX##_prev_node(struct SNAME##_node *_node_); \
@@ -376,6 +374,7 @@ struct cmc_callbacks_linkedlist
_list_->count = 0; \
_list_->head = NULL; \
_list_->tail = NULL; \
_list_->flag = cmc_flags.OK; \
} \
\
void PFX##_free(struct SNAME *_list_) \
@@ -393,6 +392,8 @@ struct cmc_callbacks_linkedlist
\
if (callbacks) \
_list_->callbacks = callbacks; \
\
_list_->flag = cmc_flags.OK; \
} \
\
bool PFX##_push_front(struct SNAME *_list_, V element) \
@@ -415,6 +416,7 @@ struct cmc_callbacks_linkedlist
} \
\
_list_->count++; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -422,7 +424,10 @@ struct cmc_callbacks_linkedlist
bool PFX##_push_at(struct SNAME *_list_, V element, size_t index) \
{ \
if (index > _list_->count) \
{ \
_list_->flag = cmc_flags.OUT_OF_RANGE; \
return false; \
} \
\
if (index == 0) \
{ \
@@ -446,6 +451,7 @@ struct cmc_callbacks_linkedlist
_node_->prev->next = _node_; \
\
_list_->count++; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -470,6 +476,7 @@ struct cmc_callbacks_linkedlist
} \
\
_list_->count++; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -477,7 +484,10 @@ struct cmc_callbacks_linkedlist
bool PFX##_pop_front(struct SNAME *_list_) \
{ \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return false; \
} \
\
struct SNAME##_node *_node_ = _list_->head; \
_list_->head = _list_->head->next; \
@@ -490,6 +500,7 @@ struct cmc_callbacks_linkedlist
_list_->head->prev = NULL; \
\
_list_->count--; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -497,10 +508,16 @@ struct cmc_callbacks_linkedlist
bool PFX##_pop_at(struct SNAME *_list_, size_t index) \
{ \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return false; \
} \
\
if (index >= _list_->count) \
{ \
_list_->flag = cmc_flags.OUT_OF_RANGE; \
return false; \
} \
\
if (index == 0) \
{ \
@@ -522,6 +539,7 @@ struct cmc_callbacks_linkedlist
_list_->alloc->free(_node_); \
\
_list_->count--; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -529,7 +547,10 @@ struct cmc_callbacks_linkedlist
bool PFX##_pop_back(struct SNAME *_list_) \
{ \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return false; \
} \
\
struct SNAME##_node *_node_ = _list_->tail; \
_list_->tail = _list_->tail->prev; \
@@ -542,6 +563,7 @@ struct cmc_callbacks_linkedlist
_list_->tail->next = NULL; \
\
_list_->count--; \
_list_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -549,15 +571,29 @@ struct cmc_callbacks_linkedlist
V PFX##_front(struct SNAME *_list_) \
{ \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return (V){ 0 }; \
} \
\
_list_->flag = cmc_flags.OK; \
\
return _list_->head->data; \
} \
\
V PFX##_get(struct SNAME *_list_, size_t index) \
{ \
if (index >= _list_->count || PFX##_empty(_list_)) \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return (V){ 0 }; \
} \
\
if (index >= _list_->count) \
{ \
_list_->flag = cmc_flags.OUT_OF_RANGE; \
return (V){ 0 }; \
} \
\
struct SNAME##_node *scan = PFX##_get_node(_list_, index); \
\
@@ -569,11 +605,17 @@ struct cmc_callbacks_linkedlist
\
V *PFX##_get_ref(struct SNAME *_list_, size_t index) \
{ \
if (index >= _list_->count) \
return NULL; \
\
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return NULL; \
} \
\
if (index >= _list_->count) \
{ \
_list_->flag = cmc_flags.OUT_OF_RANGE; \
return NULL; \
} \
\
struct SNAME##_node *scan = PFX##_get_node(_list_, index); \
\
@@ -586,13 +628,20 @@ struct cmc_callbacks_linkedlist
V PFX##_back(struct SNAME *_list_) \
{ \
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return (V){ 0 }; \
} \
\
_list_->flag = cmc_flags.OK; \
\
return _list_->tail->data; \
} \
\
bool PFX##_contains(struct SNAME *_list_, V element) \
{ \
_list_->flag = cmc_flags.OK; \
\
struct SNAME##_node *scan = _list_->head; \
\
while (scan != NULL) \
@@ -616,6 +665,11 @@ struct cmc_callbacks_linkedlist
return _list_->count; \
} \
\
int PFX##_flag(struct SNAME *_list_) \
{ \
return _list_->flag; \
} \
\
struct SNAME *PFX##_copy_of(struct SNAME *_list_) \
{ \
struct SNAME *result = \
@@ -655,12 +709,17 @@ struct cmc_callbacks_linkedlist
\
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_)) \
_list1_->flag = cmc_flags.OK; \
_list2_->flag = cmc_flags.OK; \
\
if (_list1_->count != _list2_->count) \
return false; \
\
struct SNAME##_node *scan1 = _list1_->head; \
@@ -696,7 +755,10 @@ struct cmc_callbacks_linkedlist
_list_->alloc->malloc(sizeof(struct SNAME##_node)); \
\
if (!_node_) \
{ \
_list_->flag = cmc_flags.ALLOC; \
return NULL; \
} \
\
_node_->data = element; \
_node_->next = NULL; \
@@ -717,11 +779,17 @@ struct cmc_callbacks_linkedlist
\
struct SNAME##_node *PFX##_get_node(struct SNAME *_list_, size_t index) \
{ \
if (index >= _list_->count) \
return NULL; \
\
if (PFX##_empty(_list_)) \
{ \
_list_->flag = cmc_flags.EMPTY; \
return NULL; \
} \
\
if (index >= _list_->count) \
{ \
_list_->flag = cmc_flags.OUT_OF_RANGE; \
return NULL; \
} \
\
struct SNAME##_node *_node_ = NULL; \
\
@@ -742,6 +810,8 @@ struct cmc_callbacks_linkedlist
} \
} \
\
_list_->flag = cmc_flags.OK; \
\
return _node_; \
} \
\
@@ -750,8 +820,8 @@ struct cmc_callbacks_linkedlist
return _list_->tail; \
} \
\
bool PFX##_insert_after(struct SNAME *_owner_, \
struct SNAME##_node *_node_, V element) \
bool PFX##_add_next(struct SNAME *_owner_, struct SNAME##_node *_node_, \
V element) \
{ \
struct SNAME##_node *new_node = PFX##_new_node(_owner_, element); \
\
@@ -769,12 +839,13 @@ struct cmc_callbacks_linkedlist
_node_->next = new_node; \
\
_owner_->count++; \
_owner_->flag = cmc_flags.OK; \
\
return true; \
} \
\
bool PFX##_insert_before(struct SNAME *_owner_, \
struct SNAME##_node *_node_, V element) \
bool PFX##_add_prev(struct SNAME *_owner_, struct SNAME##_node *_node_, \
V element) \
{ \
struct SNAME##_node *new_node = PFX##_new_node(_owner_, element); \
\
@@ -792,35 +863,37 @@ struct cmc_callbacks_linkedlist
_node_->prev = new_node; \
\
_owner_->count++; \
_owner_->flag = cmc_flags.OK; \
\
return true; \
} \
\
bool PFX##_remove_after(struct SNAME *_owner_, \
struct SNAME##_node *_node_) \
bool PFX##_del_next(struct SNAME *_owner_, struct SNAME##_node *_node_) \
{ \
if (_node_->next == NULL) \
{ \
_owner_->flag = cmc_flags.INVALID; \
return false; \
} \
\
struct SNAME##_node *tmp = _node_->next; \
\
_node_->next = _node_->next->next; \
\
if (tmp->next != NULL) \
{ \
_node_->next = _node_->next->next; \
_node_->next->prev = _node_; \
} \
tmp->next->prev = _node_; \
else \
_owner_->tail = _node_; \
\
_owner_->alloc->free(tmp); \
\
_owner_->count--; \
_owner_->flag = cmc_flags.OK; \
\
return true; \
} \
\
bool PFX##_remove_current(struct SNAME *_owner_, \
struct SNAME##_node *_node_) \
bool PFX##_del_curr(struct SNAME *_owner_, struct SNAME##_node *_node_) \
{ \
if (_node_->prev != NULL) \
_node_->prev->next = _node_->next; \
@@ -835,29 +908,32 @@ struct cmc_callbacks_linkedlist
_owner_->alloc->free(_node_); \
\
_owner_->count--; \
_owner_->flag = cmc_flags.OK; \
\
return true; \
} \
\
bool PFX##_remove_before(struct SNAME *_owner_, \
struct SNAME##_node *_node_) \
bool PFX##_del_prev(struct SNAME *_owner_, struct SNAME##_node *_node_) \
{ \
if (_node_->prev == NULL) \
{ \
_owner_->flag = cmc_flags.INVALID; \
return false; \
} \
\
struct SNAME##_node *tmp = _node_->prev; \
\
_node_->prev = _node_->prev->prev; \
\
if (tmp->prev != NULL) \
{ \
_node_->prev = _node_->prev->prev; \
_node_->prev->next = _node_; \
} \
tmp->prev->next = _node_; \
else \
_owner_->head = _node_; \
\
_owner_->alloc->free(tmp); \
\
_owner_->count--; \
_owner_->flag = cmc_flags.OK; \
\
return true; \
} \
@@ -981,7 +1057,7 @@ struct cmc_callbacks_linkedlist
return false; \
} \
\
if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \
if (steps == 0 || iter->index + steps >= iter->target->count) \
return false; \
\
iter->start = PFX##_empty(iter->target); \
@@ -1023,7 +1099,7 @@ struct cmc_callbacks_linkedlist
/* 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->index > index) \
+173
View File
@@ -83,4 +83,177 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
ll_free(ll);
});
CMC_CREATE_TEST(flags, {
struct linkedlist *ll = ll_new(ll_ftab_val);
cmc_assert_not_equals(ptr, NULL, ll);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// clear
ll->flag = cmc_flags.ERROR;
ll_clear(ll);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// customize
ll->flag = cmc_flags.ERROR;
ll_customize(ll, NULL, NULL);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// push_front
ll->flag = cmc_flags.ERROR;
cmc_assert(ll_push_front(ll, 10));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// push_at
ll->flag = cmc_flags.ERROR;
cmc_assert(ll_push_at(ll, 10, 1));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
cmc_assert(!ll_push_at(ll, 10, 300));
cmc_assert_equals(int32_t, cmc_flags.OUT_OF_RANGE, ll_flag(ll));
// push_back
ll->flag = cmc_flags.ERROR;
cmc_assert(ll_push_back(ll, 10));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
ll_clear(ll);
// pop_front
ll->flag = cmc_flags.ERROR;
cmc_assert(!ll_pop_front(ll));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
cmc_assert(ll_push_back(ll, 10));
cmc_assert(ll_pop_front(ll));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// pop_at
cmc_assert(!ll_pop_at(ll, 0));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
cmc_assert(ll_push_front(ll, 10));
cmc_assert(!ll_pop_at(ll, 1));
cmc_assert_equals(int32_t, cmc_flags.OUT_OF_RANGE, ll_flag(ll));
cmc_assert(ll_pop_at(ll, 0));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// pop_back
ll->flag = cmc_flags.ERROR;
cmc_assert(!ll_pop_front(ll));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
cmc_assert(ll_push_back(ll, 10));
cmc_assert(ll_pop_front(ll));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
ll_clear(ll);
// front
ll_front(ll);
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
cmc_assert(ll_push_front(ll, 10));
ll->flag = cmc_flags.ERROR;
ll_front(ll);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
ll_clear(ll);
// back
ll_back(ll);
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
cmc_assert(ll_push_front(ll, 10));
ll->flag = cmc_flags.ERROR;
ll_back(ll);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
ll_clear(ll);
// get get_ref
ll_get(ll, 0);
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
ll->flag = cmc_flags.ERROR;
ll_get_ref(ll, 0);
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
cmc_assert(ll_push_at(ll, 10, 0));
ll->flag = cmc_flags.ERROR;
ll_get(ll, 0);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
ll_get(ll, 1);
cmc_assert_equals(int32_t, cmc_flags.OUT_OF_RANGE, ll_flag(ll));
ll_get_ref(ll, 0);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
ll_get_ref(ll, 1);
cmc_assert_equals(int32_t, cmc_flags.OUT_OF_RANGE, ll_flag(ll));
// contains
cmc_assert(ll_contains(ll, 10));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// copy_of
ll->flag = cmc_flags.ERROR;
struct linkedlist *ll2 = ll_copy_of(ll);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll2));
// equals
ll->flag = cmc_flags.ERROR;
ll2->flag = cmc_flags.ERROR;
cmc_assert(ll_equals(ll, ll2));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll2));
ll_clear(ll);
// get_node
struct linkedlist_node *n = ll_get_node(ll, 0);
cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
cmc_assert(ll_push_at(ll, 10, 0));
n = ll_get_node(ll, 0);
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
n = ll_get_node(ll, 1);
cmc_assert_equals(int32_t, cmc_flags.OUT_OF_RANGE, ll_flag(ll));
// functions relative to node
ll_clear(ll);
cmc_assert(ll_push_front(ll, 10));
n = ll_get_node(ll, 0);
cmc_assert_not_equals(ptr, NULL, n);
// add_next
ll->flag = cmc_flags.ERROR;
cmc_assert(ll_add_next(ll, n, 11));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// add_prev
ll->flag = cmc_flags.ERROR;
cmc_assert(ll_add_prev(ll, n, 9));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// del_next
n = ll_next_node(n);
cmc_assert(!ll_del_next(ll, n));
cmc_assert_equals(int32_t, cmc_flags.INVALID, ll_flag(ll));
n = ll_prev_node(n);
cmc_assert(ll_del_next(ll, n));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// del_prev
n = ll_prev_node(n);
cmc_assert(!ll_del_prev(ll, n));
cmc_assert_equals(int32_t, cmc_flags.INVALID, ll_flag(ll));
n = ll_next_node(n);
cmc_assert(ll_del_prev(ll, n));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
// del_curr
ll->flag = cmc_flags.ERROR;
cmc_assert(ll_del_curr(ll, n));
cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
ll_free(ll);
ll_free(ll2);
});
});