Adding functions table to linkedlist and list and some minor fixes from previous commit
This commit is contained in:
1 parent
64c3a99922
commit
683decfa64
6 files changed
+233
-160
No files matched your search
+2
-1
@@ -112,6 +112,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> "
|
||||
"capacity:%" PRIuMAX ", "
|
||||
"count:%" PRIuMAX ", "
|
||||
"type:%s, "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks: %p}";
|
||||
@@ -547,7 +548,7 @@ struct cmc_callbacks_heap
|
||||
\
|
||||
int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_heap, #SNAME, \
|
||||
#V, h_, h_->buffer, h_->capacity, h_->count, t, \
|
||||
h_->f_val, h_->alloc, h_->callbacks); \
|
||||
h_->flag, h_->f_val, h_->alloc, h_->callbacks); \
|
||||
\
|
||||
return n >= 0 ? str : (struct cmc_string){ 0 }; \
|
||||
} \
|
||||
|
||||
@@ -89,6 +89,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
"capacity:%" PRIuMAX ", "
|
||||
"size:%" PRIuMAX ", "
|
||||
"count:%" PRIuMAX ", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }";
|
||||
@@ -739,7 +740,8 @@ struct cmc_callbacks_intervalheap
|
||||
\
|
||||
int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_intervalheap, \
|
||||
#SNAME, #V, h_, h_->buffer, h_->capacity, h_->size, \
|
||||
h_->count, h_->f_val, h_->alloc, h_->callbacks); \
|
||||
h_->count, h_->flag, h_->f_val, h_->alloc, \
|
||||
h_->callbacks); \
|
||||
\
|
||||
return n >= 0 ? str : (struct cmc_string){ 0 }; \
|
||||
} \
|
||||
|
||||
+74
-45
@@ -95,6 +95,8 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> "
|
||||
"count:%" PRIuMAX ", "
|
||||
"head:%p, "
|
||||
"tail:%p, "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }";
|
||||
|
||||
@@ -140,17 +142,23 @@ struct cmc_callbacks_linkedlist
|
||||
/* Current amount of elements in the list */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
/* Flags indicating errors or success */ \
|
||||
int flag; \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the list */ \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
/* Value function table */ \
|
||||
struct SNAME##_ftab_val *f_val; \
|
||||
\
|
||||
/* Custom allocation functions */ \
|
||||
struct cmc_alloc_node *alloc; \
|
||||
\
|
||||
/* Custom callback functions */ \
|
||||
struct cmc_callbacks_linkedlist *callbacks; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the list */ \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
/* Doubly-linked list node */ \
|
||||
@@ -166,6 +174,28 @@ struct cmc_callbacks_linkedlist
|
||||
struct SNAME##_node *prev; \
|
||||
}; \
|
||||
\
|
||||
/* Value struct function table */ \
|
||||
struct SNAME##_ftab_val \
|
||||
{ \
|
||||
/* Comparator function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Copy function */ \
|
||||
V (*cpy)(V); \
|
||||
\
|
||||
/* To string function */ \
|
||||
bool (*str)(FILE *, V); \
|
||||
\
|
||||
/* Free from memory function */ \
|
||||
void (*free)(V); \
|
||||
\
|
||||
/* Hash function */ \
|
||||
size_t (*hash)(V); \
|
||||
\
|
||||
/* Priority function */ \
|
||||
int (*pri)(V, V); \
|
||||
}; \
|
||||
\
|
||||
/* Linked List Iterator */ \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
@@ -187,12 +217,12 @@ struct cmc_callbacks_linkedlist
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *PFX##_new(void); \
|
||||
struct SNAME *PFX##_new(struct SNAME##_ftab_val *f_val); \
|
||||
struct SNAME *PFX##_new_custom( \
|
||||
struct cmc_alloc_node *alloc, \
|
||||
struct SNAME##_ftab_val *f_val, struct cmc_alloc_node *alloc, \
|
||||
struct cmc_callbacks_linkedlist *callbacks); \
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_clear(struct SNAME *_list_); \
|
||||
void PFX##_free(struct SNAME *_list_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
|
||||
struct cmc_callbacks_linkedlist *callbacks); \
|
||||
@@ -209,14 +239,12 @@ struct cmc_callbacks_linkedlist
|
||||
V *PFX##_get_ref(struct SNAME *_list_, size_t index); \
|
||||
V PFX##_back(struct SNAME *_list_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element, \
|
||||
int (*comparator)(V, V)); \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element); \
|
||||
bool PFX##_empty(struct SNAME *_list_); \
|
||||
size_t PFX##_count(struct SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_, \
|
||||
int (*comparator)(V, V)); \
|
||||
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_); \
|
||||
\
|
||||
/* Node Related Functions */ \
|
||||
@@ -274,8 +302,11 @@ struct cmc_callbacks_linkedlist
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_list_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_list_); \
|
||||
\
|
||||
struct SNAME *PFX##_new(void) \
|
||||
struct SNAME *PFX##_new(struct SNAME##_ftab_val *f_val) \
|
||||
{ \
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
|
||||
@@ -286,19 +317,23 @@ struct cmc_callbacks_linkedlist
|
||||
_list_->count = 0; \
|
||||
_list_->head = NULL; \
|
||||
_list_->tail = NULL; \
|
||||
\
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
_list_->flag = cmc_flags.OK; \
|
||||
_list_->f_val = f_val; \
|
||||
_list_->alloc = alloc; \
|
||||
_list_->callbacks = NULL; \
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *PFX##_new_custom(struct cmc_alloc_node *alloc, \
|
||||
struct SNAME *PFX##_new_custom(struct SNAME##_ftab_val *f_val, \
|
||||
struct cmc_alloc_node *alloc, \
|
||||
struct cmc_callbacks_linkedlist *callbacks) \
|
||||
{ \
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
@@ -310,17 +345,17 @@ struct cmc_callbacks_linkedlist
|
||||
_list_->count = 0; \
|
||||
_list_->head = NULL; \
|
||||
_list_->tail = NULL; \
|
||||
\
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
_list_->flag = cmc_flags.OK; \
|
||||
_list_->f_val = f_val; \
|
||||
_list_->alloc = alloc; \
|
||||
_list_->callbacks = callbacks; \
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_list_) \
|
||||
{ \
|
||||
struct SNAME##_node *scan = _list_->head; \
|
||||
\
|
||||
@@ -328,9 +363,9 @@ struct cmc_callbacks_linkedlist
|
||||
{ \
|
||||
_list_->head = _list_->head->next; \
|
||||
\
|
||||
if (deallocator) \
|
||||
if (_list_->f_val->free) \
|
||||
{ \
|
||||
deallocator(scan->data); \
|
||||
_list_->f_val->free(scan->data); \
|
||||
} \
|
||||
\
|
||||
_list_->alloc->free(scan); \
|
||||
@@ -343,9 +378,9 @@ struct cmc_callbacks_linkedlist
|
||||
_list_->tail = NULL; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_list_) \
|
||||
{ \
|
||||
PFX##_clear(_list_, deallocator); \
|
||||
PFX##_clear(_list_); \
|
||||
\
|
||||
_list_->alloc->free(_list_); \
|
||||
} \
|
||||
@@ -556,14 +591,13 @@ struct cmc_callbacks_linkedlist
|
||||
return _list_->tail->data; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(struct SNAME *_list_, V element, \
|
||||
int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element) \
|
||||
{ \
|
||||
struct SNAME##_node *scan = _list_->head; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (comparator(scan->data, element) == 0) \
|
||||
if (_list_->f_val->cmp(scan->data, element) == 0) \
|
||||
return true; \
|
||||
\
|
||||
scan = scan->next; \
|
||||
@@ -582,10 +616,10 @@ struct cmc_callbacks_linkedlist
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_) \
|
||||
{ \
|
||||
struct SNAME *result = \
|
||||
PFX##_new_custom(_list_->alloc, _list_->callbacks); \
|
||||
PFX##_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -598,8 +632,9 @@ struct cmc_callbacks_linkedlist
|
||||
/* possible to recover from it. That is why it isn't checked */ \
|
||||
struct SNAME##_node *new_node; \
|
||||
\
|
||||
if (copy_func) \
|
||||
new_node = PFX##_new_node(_list_, copy_func(scan->data)); \
|
||||
if (_list_->f_val->cpy) \
|
||||
new_node = \
|
||||
PFX##_new_node(_list_, _list_->f_val->cpy(scan->data)); \
|
||||
else \
|
||||
new_node = PFX##_new_node(_list_, scan->data); \
|
||||
\
|
||||
@@ -623,8 +658,7 @@ struct cmc_callbacks_linkedlist
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_, \
|
||||
int (*comparator)(V, V)) \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \
|
||||
{ \
|
||||
if (PFX##_count(_list1_) != PFX##_count(_list2_)) \
|
||||
return false; \
|
||||
@@ -634,7 +668,7 @@ struct cmc_callbacks_linkedlist
|
||||
\
|
||||
while (scan1 != NULL && scan2 != NULL) \
|
||||
{ \
|
||||
if (comparator(scan1->data, scan2->data) != 0) \
|
||||
if (_list1_->f_val->cmp(scan1->data, scan2->data) != 0) \
|
||||
return false; \
|
||||
\
|
||||
scan1 = scan1->next; \
|
||||
@@ -651,14 +685,9 @@ struct cmc_callbacks_linkedlist
|
||||
\
|
||||
int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_linkedlist, \
|
||||
#SNAME, #V, l_, l_->count, l_->head, l_->tail, \
|
||||
l_->alloc, l_->callbacks); \
|
||||
l_->flag, l_->f_val, l_->alloc, l_->callbacks); \
|
||||
\
|
||||
if (n < 0 || n == (int)cmc_string_len) \
|
||||
return (struct cmc_string){ 0 }; \
|
||||
\
|
||||
str.s[n] = '\0'; \
|
||||
\
|
||||
return str; \
|
||||
return n >= 0 ? str : (struct cmc_string){ 0 }; \
|
||||
} \
|
||||
\
|
||||
struct SNAME##_node *PFX##_new_node(struct SNAME *_list_, V element) \
|
||||
|
||||
+80
-54
@@ -110,6 +110,8 @@ static const char *cmc_string_fmt_list = "struct %s<%s> "
|
||||
"buffer:%p, "
|
||||
"capacity:%" PRIuMAX ", "
|
||||
"count:%" PRIuMAX ", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }";
|
||||
|
||||
@@ -155,6 +157,12 @@ struct cmc_callbacks_list
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Flags indicating errors or success */ \
|
||||
int flag; \
|
||||
\
|
||||
/* Value function table */ \
|
||||
struct SNAME##_ftab_val *f_val; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
@@ -168,6 +176,28 @@ struct cmc_callbacks_list
|
||||
struct cmc_callbacks_list *callbacks; \
|
||||
}; \
|
||||
\
|
||||
/* Value struct function table */ \
|
||||
struct SNAME##_ftab_val \
|
||||
{ \
|
||||
/* Comparator function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Copy function */ \
|
||||
V (*cpy)(V); \
|
||||
\
|
||||
/* To string function */ \
|
||||
bool (*str)(FILE *, V); \
|
||||
\
|
||||
/* Free from memory function */ \
|
||||
void (*free)(V); \
|
||||
\
|
||||
/* Hash function */ \
|
||||
size_t (*hash)(V); \
|
||||
\
|
||||
/* Priority function */ \
|
||||
int (*pri)(V, V); \
|
||||
}; \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
@@ -186,12 +216,12 @@ struct cmc_callbacks_list
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *PFX##_new(size_t capacity); \
|
||||
struct SNAME *PFX##_new_custom(size_t capacity, \
|
||||
struct cmc_alloc_node *alloc, \
|
||||
struct cmc_callbacks_list *callbacks); \
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val); \
|
||||
struct SNAME *PFX##_new_custom( \
|
||||
size_t capacity, struct SNAME##_ftab_val *f_val, \
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks_list *callbacks); \
|
||||
void PFX##_clear(struct SNAME *_list_); \
|
||||
void PFX##_free(struct SNAME *_list_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
|
||||
struct cmc_callbacks_list *callbacks); \
|
||||
@@ -215,11 +245,9 @@ struct cmc_callbacks_list
|
||||
V PFX##_get(struct SNAME *_list_, size_t index); \
|
||||
V *PFX##_get_ref(struct SNAME *_list_, size_t index); \
|
||||
V PFX##_back(struct SNAME *_list_); \
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, \
|
||||
int (*comparator)(V, V), bool from_start); \
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element, \
|
||||
int (*comparator)(V, V)); \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element); \
|
||||
bool PFX##_empty(struct SNAME *_list_); \
|
||||
bool PFX##_full(struct SNAME *_list_); \
|
||||
size_t PFX##_count(struct SNAME *_list_); \
|
||||
@@ -227,9 +255,8 @@ struct cmc_callbacks_list
|
||||
size_t PFX##_capacity(struct SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(struct SNAME *_list_, size_t capacity); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_, \
|
||||
int (*comparator)(V, V)); \
|
||||
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_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
@@ -263,7 +290,7 @@ struct cmc_callbacks_list
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_list_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_list_); \
|
||||
\
|
||||
struct SNAME *PFX##_new(size_t capacity) \
|
||||
struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val) \
|
||||
{ \
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
@@ -285,23 +312,26 @@ struct cmc_callbacks_list
|
||||
\
|
||||
_list_->capacity = capacity; \
|
||||
_list_->count = 0; \
|
||||
\
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
_list_->flag = cmc_flags.OK; \
|
||||
_list_->f_val = f_val; \
|
||||
_list_->alloc = alloc; \
|
||||
_list_->callbacks = NULL; \
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *PFX##_new_custom(size_t capacity, \
|
||||
struct cmc_alloc_node *alloc, \
|
||||
struct cmc_callbacks_list *callbacks) \
|
||||
struct SNAME *PFX##_new_custom( \
|
||||
size_t capacity, struct SNAME##_ftab_val *f_val, \
|
||||
struct cmc_alloc_node *alloc, struct cmc_callbacks_list *callbacks) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
@@ -320,22 +350,22 @@ struct cmc_callbacks_list
|
||||
\
|
||||
_list_->capacity = capacity; \
|
||||
_list_->count = 0; \
|
||||
\
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
_list_->flag = cmc_flags.OK; \
|
||||
_list_->f_val = f_val; \
|
||||
_list_->alloc = alloc; \
|
||||
_list_->callbacks = callbacks; \
|
||||
_list_->it_start = PFX##_impl_it_start; \
|
||||
_list_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_list_) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
if (_list_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
deallocator(_list_->buffer[i]); \
|
||||
_list_->f_val->free(_list_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
|
||||
@@ -343,12 +373,12 @@ struct cmc_callbacks_list
|
||||
_list_->count = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_list_) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
if (_list_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
deallocator(_list_->buffer[i]); \
|
||||
_list_->f_val->free(_list_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
_list_->alloc->free(_list_->buffer); \
|
||||
@@ -549,7 +579,7 @@ struct cmc_callbacks_list
|
||||
\
|
||||
size_t length = to - from + 1; \
|
||||
\
|
||||
struct SNAME *result = PFX##_new(length); \
|
||||
struct SNAME *result = PFX##_new(length, _list_->f_val); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -603,14 +633,13 @@ struct cmc_callbacks_list
|
||||
return _list_->buffer[_list_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, \
|
||||
int (*comparator)(V, V), bool from_start) \
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start) \
|
||||
{ \
|
||||
if (from_start) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
if (comparator(_list_->buffer[i], element) == 0) \
|
||||
if (_list_->f_val->cmp(_list_->buffer[i], element) == 0) \
|
||||
return i; \
|
||||
} \
|
||||
} \
|
||||
@@ -618,7 +647,7 @@ struct cmc_callbacks_list
|
||||
{ \
|
||||
for (size_t i = _list_->count; i > 0; i--) \
|
||||
{ \
|
||||
if (comparator(_list_->buffer[i - 1], element) == 0) \
|
||||
if (_list_->f_val->cmp(_list_->buffer[i - 1], element) == 0) \
|
||||
return i - 1; \
|
||||
} \
|
||||
} \
|
||||
@@ -626,12 +655,11 @@ struct cmc_callbacks_list
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(struct SNAME *_list_, V element, \
|
||||
int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
if (comparator(_list_->buffer[i], element) == 0) \
|
||||
if (_list_->f_val->cmp(_list_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
@@ -677,24 +705,27 @@ struct cmc_callbacks_list
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
/* TODO zero out new slots */ \
|
||||
\
|
||||
_list_->buffer = new_buffer; \
|
||||
_list_->capacity = capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_) \
|
||||
{ \
|
||||
struct SNAME *result = PFX##_new_custom( \
|
||||
_list_->capacity, _list_->alloc, _list_->callbacks); \
|
||||
struct SNAME *result = \
|
||||
PFX##_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, \
|
||||
_list_->callbacks); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
if (_list_->f_val->cpy) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
result->buffer[i] = copy_func(_list_->buffer[i]); \
|
||||
result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \
|
||||
@@ -704,15 +735,15 @@ struct cmc_callbacks_list
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_, \
|
||||
int (*comparator)(V, V)) \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \
|
||||
{ \
|
||||
if (PFX##_count(_list1_) != PFX##_count(_list2_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < PFX##_count(_list1_); i++) \
|
||||
{ \
|
||||
if (comparator(_list1_->buffer[i], _list2_->buffer[i]) != 0) \
|
||||
if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \
|
||||
0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
@@ -726,14 +757,9 @@ struct cmc_callbacks_list
|
||||
\
|
||||
int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_list, #SNAME, \
|
||||
#V, l_, l_->buffer, l_->capacity, l_->count, \
|
||||
l_->alloc, l_->callbacks); \
|
||||
l_->flag, l_->f_val, l_->alloc, l_->callbacks); \
|
||||
\
|
||||
if (n < 0 || n == (int)cmc_string_len) \
|
||||
return (struct cmc_string){ 0 }; \
|
||||
\
|
||||
str.s[n] = '\0'; \
|
||||
\
|
||||
return str; \
|
||||
return n >= 0 ? str : (struct cmc_string){ 0 }; \
|
||||
} \
|
||||
\
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
|
||||
+20
-12
@@ -7,20 +7,28 @@
|
||||
|
||||
CMC_GENERATE_LINKEDLIST(ll, linkedlist, size_t)
|
||||
|
||||
struct linkedlist_ftab_val *ll_ftab_val =
|
||||
&(struct linkedlist_ftab_val){ .cmp = cmp,
|
||||
.cpy = copy,
|
||||
.str = str,
|
||||
.free = custom_free,
|
||||
.hash = hash,
|
||||
.pri = pri };
|
||||
|
||||
CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
struct linkedlist *ll = ll_new();
|
||||
struct linkedlist *ll = ll_new(ll_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
cmc_assert_equals(ptr, NULL, ll->head);
|
||||
cmc_assert_equals(ptr, NULL, ll->tail);
|
||||
|
||||
ll_free(ll, NULL);
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
struct linkedlist *ll = ll_new();
|
||||
struct linkedlist *ll = ll_new(ll_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
@@ -29,27 +37,27 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 50, ll_count(ll));
|
||||
|
||||
ll_clear(ll, NULL);
|
||||
ll_clear(ll);
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
|
||||
ll_free(ll, NULL);
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count = 0], {
|
||||
struct linkedlist *ll = ll_new();
|
||||
struct linkedlist *ll = ll_new(ll_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
ll_clear(ll, NULL);
|
||||
ll_clear(ll);
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
|
||||
ll_free(ll, NULL);
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[count], {
|
||||
struct linkedlist *ll = ll_new();
|
||||
struct linkedlist *ll = ll_new(ll_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
@@ -59,11 +67,11 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
cmc_assert_not_equals(ptr, NULL, ll->tail);
|
||||
cmc_assert_equals(size_t, 1, ll_count(ll));
|
||||
|
||||
ll_free(ll, NULL);
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[item preservation], {
|
||||
struct linkedlist *ll = ll_new();
|
||||
struct linkedlist *ll = ll_new(ll_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
@@ -73,6 +81,6 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
for (size_t i = 0; i < ll_count(ll); i++)
|
||||
cmc_assert_equals(size_t, ll_get(ll, i), ll_count(ll) - i - 1);
|
||||
|
||||
ll_free(ll, NULL);
|
||||
ll_free(ll);
|
||||
});
|
||||
});
|
||||
+54
-47
@@ -7,32 +7,39 @@
|
||||
|
||||
CMC_GENERATE_LIST(l, list, size_t)
|
||||
|
||||
struct list_ftab_val *l_ftab_val = &(struct list_ftab_val){ .cmp = cmp,
|
||||
.cpy = copy,
|
||||
.str = str,
|
||||
.free = custom_free,
|
||||
.hash = hash,
|
||||
.pri = pri };
|
||||
|
||||
CMC_CREATE_UNIT(list_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
struct list *l = l_new(1000000);
|
||||
struct list *l = l_new(1000000, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert_not_equals(ptr, NULL, l->buffer);
|
||||
cmc_assert_equals(size_t, 1000000, l_capacity(l));
|
||||
cmc_assert_equals(size_t, 0, l_count(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[capacity = 0], {
|
||||
struct list *l = l_new(0);
|
||||
struct list *l = l_new(0, l_ftab_val);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[capacity = UINT64_MAX], {
|
||||
struct list *l = l_new(UINT64_MAX);
|
||||
struct list *l = l_new(UINT64_MAX, l_ftab_val);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -41,16 +48,16 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 50, l_count(l));
|
||||
|
||||
l_clear(l, NULL);
|
||||
l_clear(l);
|
||||
|
||||
cmc_assert_equals(size_t, 0, l_count(l));
|
||||
cmc_assert_equals(size_t, 100, l_capacity(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(buffer_growth[capacity = 1], {
|
||||
struct list *l = l_new(1);
|
||||
struct list *l = l_new(1, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -62,11 +69,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
cmc_assert_equals(size_t, i, l_get(l, i));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[count], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -75,11 +82,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[capacity], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -88,11 +95,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_front[item preservation], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -102,11 +109,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
cmc_assert_equals(size_t, l_get(l, i), l_count(l) - i - 1);
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_at[count], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -118,11 +125,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_at[capacity], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -134,11 +141,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_at[item preservation], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -151,11 +158,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
cmc_assert_equals(size_t, l_get(l, i), i);
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_back[count], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -164,11 +171,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_back[capacity], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -177,11 +184,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(push_back[item preservation], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -191,11 +198,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
cmc_assert_equals(size_t, l_get(l, i), i);
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_front[count], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -204,11 +211,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert(l_pop_front(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_front[item preservation], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
@@ -220,30 +227,30 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
cmc_assert_equals(size_t, l_get(l, i), i + 1);
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_front[count = 0], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(!l_pop_front(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_front[count = 1], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(l_push_back(l, 10));
|
||||
cmc_assert(l_pop_front(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_front[buffer_clear], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(l_push_back(l, 1));
|
||||
@@ -253,20 +260,20 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, l->buffer[1]);
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_at[count = 0], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(!l_pop_at(l, 1));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_at[count = 1], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(l_push_back(l, 1));
|
||||
@@ -274,11 +281,11 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, l->buffer[0]);
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_at[buffer_clear], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(l_push_back(l, 1));
|
||||
@@ -286,25 +293,25 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert(l_push_back(l, 3));
|
||||
cmc_assert(l_pop_at(l, 1));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_back[count = 0], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(!l_pop_back(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(pop_back[count = 1], {
|
||||
struct list *l = l_new(100);
|
||||
struct list *l = l_new(100, l_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(l_push_back(l, 10));
|
||||
cmc_assert(l_pop_back(l));
|
||||
|
||||
l_free(l, NULL);
|
||||
l_free(l);
|
||||
});
|
||||
})
|
||||
Reference in new issue
Block a user