Adding functions table to sortedlist and stack, and some fixes to queue

This commit is contained in:
Leonardo committed 2020-02-10 22:47:54 -03:00
1 parent aa7c5f775a
commit 7efc0e26e0
7 files changed
+875 -801

No files matched your search

+506 -505
View File
File diff suppressed because it is too large. Load diff
+170 -142
View File
@@ -90,7 +90,8 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> "
"capacity:%" PRIuMAX ", "
"count:%" PRIuMAX ", "
"is_sorted:%s, "
"cmp:%p, "
"flag:%d, "
"f_val:%p, "
"alloc:%p, "
"callbacks:%p }";
@@ -122,106 +123,132 @@ struct cmc_callbacks_sortedlist
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \
\
/* List Structure */ \
struct SNAME \
{ \
/* Dynamic array of elements */ \
V *buffer; \
\
/* Current array capacity */ \
size_t capacity; \
\
/* Current amount of elements */ \
size_t count; \
\
/* Flag if the list is sorted or not, used by lazy evaluation */ \
bool is_sorted; \
\
/* Element comparison function */ \
int (*cmp)(V, V); \
\
/* 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 *); \
\
/* Custom allocation functions */ \
struct cmc_alloc_node *alloc; \
\
/* Custom callback functions */ \
struct cmc_callbacks_sortedlist *callbacks; \
}; \
\
/* List Iterator */ \
struct SNAME##_iter \
{ \
/* Target list */ \
struct SNAME *target; \
\
/* Cursor's position (index) */ \
size_t cursor; \
\
/* If the iterator has reached the start of the iteration */ \
bool start; \
\
/* If the iterator has reached the end of the iteration */ \
bool end; \
}; \
\
/* Collection Functions */ \
/* Collection Allocation and Deallocation */ \
struct SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)); \
struct SNAME *PFX##_new_custom( \
size_t capacity, int (*compare)(V, V), struct cmc_alloc_node *alloc, \
struct cmc_callbacks_sortedlist *callbacks); \
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \
/* Customization of Allocation and Callbacks */ \
void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
struct cmc_callbacks_sortedlist *callbacks); \
/* Collection Input and Output */ \
bool PFX##_insert(struct SNAME *_list_, V element); \
bool PFX##_remove(struct SNAME *_list_, size_t index); \
/* Element Access */ \
bool PFX##_max(struct SNAME *_list_, V *result); \
bool PFX##_min(struct SNAME *_list_, V *result); \
V PFX##_get(struct SNAME *_list_, size_t index); \
size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start); \
/* Collection State */ \
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_); \
size_t PFX##_capacity(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_, V (*copy_func)(V)); \
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \
struct cmc_string PFX##_to_string(struct SNAME *_list_); \
\
/* Iterator Functions */ \
/* Iterator Allocation and Deallocation */ \
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
void PFX##_iter_free(struct SNAME##_iter *iter); \
/* Iterator Initialization */ \
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
/* Iterator State */ \
bool PFX##_iter_start(struct SNAME##_iter *iter); \
bool PFX##_iter_end(struct SNAME##_iter *iter); \
/* Iterator Movement */ \
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
bool PFX##_iter_next(struct SNAME##_iter *iter); \
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
/* Iterator Access */ \
V PFX##_iter_value(struct SNAME##_iter *iter); \
#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \
\
/* List Structure */ \
struct SNAME \
{ \
/* Dynamic array of elements */ \
V *buffer; \
\
/* Current array capacity */ \
size_t capacity; \
\
/* Current amount of elements */ \
size_t count; \
\
/* Flag if the list is sorted or not, used by lazy evaluation */ \
bool is_sorted; \
\
/* Flags indicating errors or success */ \
int flag; \
\
/* Value function table */ \
struct SNAME##_ftab_val *f_val; \
\
/* Custom allocation functions */ \
struct cmc_alloc_node *alloc; \
\
/* Custom callback functions */ \
struct cmc_callbacks_sortedlist *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 *); \
}; \
\
/* 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 \
{ \
/* Target list */ \
struct SNAME *target; \
\
/* Cursor's position (index) */ \
size_t cursor; \
\
/* If the iterator has reached the start of the iteration */ \
bool start; \
\
/* If the iterator has reached the end of the iteration */ \
bool end; \
}; \
\
/* Collection Functions */ \
/* Collection Allocation and Deallocation */ \
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_sortedlist *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_sortedlist *callbacks); \
/* Collection Input and Output */ \
bool PFX##_insert(struct SNAME *_list_, V element); \
bool PFX##_remove(struct SNAME *_list_, size_t index); \
/* Element Access */ \
bool PFX##_max(struct SNAME *_list_, V *result); \
bool PFX##_min(struct SNAME *_list_, V *result); \
V PFX##_get(struct SNAME *_list_, size_t index); \
size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start); \
/* Collection State */ \
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_); \
size_t PFX##_capacity(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_); \
\
/* Iterator Functions */ \
/* Iterator Allocation and Deallocation */ \
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
void PFX##_iter_free(struct SNAME##_iter *iter); \
/* Iterator Initialization */ \
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
/* Iterator State */ \
bool PFX##_iter_start(struct SNAME##_iter *iter); \
bool PFX##_iter_end(struct SNAME##_iter *iter); \
/* Iterator Movement */ \
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
bool PFX##_iter_next(struct SNAME##_iter *iter); \
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
/* Iterator Access */ \
V PFX##_iter_value(struct SNAME##_iter *iter); \
size_t PFX##_iter_index(struct SNAME##_iter *iter);
/* -------------------------------------------------------------------------
@@ -241,13 +268,16 @@ struct cmc_callbacks_sortedlist
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, int (*compare)(V, V)) \
struct SNAME *PFX##_new(size_t capacity, struct SNAME##_ftab_val *f_val) \
{ \
struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
\
if (capacity < 1) \
return NULL; \
\
if (!f_val) \
return NULL; \
\
struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
\
if (!_list_) \
@@ -263,19 +293,19 @@ struct cmc_callbacks_sortedlist
\
_list_->capacity = capacity; \
_list_->count = 0; \
_list_->cmp = compare; \
_list_->is_sorted = false; \
\
_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, int (*compare)(V, V), \
struct SNAME *PFX##_new_custom(size_t capacity, \
struct SNAME##_ftab_val *f_val, \
struct cmc_alloc_node *alloc, \
struct cmc_callbacks_sortedlist *callbacks) \
{ \
@@ -300,24 +330,23 @@ struct cmc_callbacks_sortedlist
\
_list_->capacity = capacity; \
_list_->count = 0; \
_list_->cmp = compare; \
_list_->is_sorted = false; \
\
_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); \
@@ -325,12 +354,12 @@ struct cmc_callbacks_sortedlist
_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); \
@@ -351,7 +380,7 @@ struct cmc_callbacks_sortedlist
{ \
if (PFX##_full(_list_)) \
{ \
if (!PFX##_resize(_list_, PFX##_capacity(_list_) * 2)) \
if (!PFX##_resize(_list_, _list_->capacity * 2)) \
return false; \
} \
\
@@ -429,7 +458,7 @@ struct cmc_callbacks_sortedlist
PFX##_sort(_list_); \
\
return PFX##_impl_binary_search_first(_list_, element) < \
PFX##_count(_list_); \
_list_->count; \
} \
\
bool PFX##_empty(struct SNAME *_list_) \
@@ -454,10 +483,10 @@ struct cmc_callbacks_sortedlist
\
bool PFX##_resize(struct SNAME *_list_, size_t capacity) \
{ \
if (PFX##_capacity(_list_) == capacity) \
if (_list_->capacity == capacity) \
return true; \
\
if (capacity < PFX##_count(_list_)) \
if (capacity < _list_->count) \
return false; \
\
V *new_buffer = \
@@ -466,6 +495,8 @@ struct cmc_callbacks_sortedlist
if (!new_buffer) \
return false; \
\
/* TODO zero out remaining slots */ \
\
_list_->buffer = new_buffer; \
_list_->capacity = capacity; \
\
@@ -476,25 +507,26 @@ struct cmc_callbacks_sortedlist
{ \
if (!_list_->is_sorted && _list_->count > 1) \
{ \
PFX##_impl_sort_quicksort(_list_->buffer, _list_->cmp, 0, \
PFX##_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, \
_list_->count - 1); \
\
_list_->is_sorted = 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_->cmp, _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); \
@@ -514,7 +546,8 @@ struct cmc_callbacks_sortedlist
\
for (size_t i = 0; i < PFX##_count(_list1_); i++) \
{ \
if (_list1_->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) \
if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \
0) \
return false; \
} \
\
@@ -528,15 +561,10 @@ struct cmc_callbacks_sortedlist
\
int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_sortedlist, \
#SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \
l_->is_sorted ? "true" : "false", l_->cmp, l_->alloc, \
l_->callbacks); \
l_->is_sorted ? "true" : "false", 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) \
@@ -719,13 +747,13 @@ struct cmc_callbacks_sortedlist
{ \
size_t M = L + (R - L) / 2; \
\
if (_list_->cmp(_list_->buffer[M], value) < 0) \
if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) \
L = M + 1; \
else \
R = M; \
} \
\
if (_list_->cmp(_list_->buffer[L], value) == 0) \
if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) \
return L; \
\
/* Not found */ \
@@ -744,13 +772,13 @@ struct cmc_callbacks_sortedlist
{ \
size_t M = L + (R - L) / 2; \
\
if (_list_->cmp(_list_->buffer[M], value) > 0) \
if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) \
R = M; \
else \
L = M + 1; \
} \
\
if (_list_->cmp(_list_->buffer[L - 1], value) == 0) \
if (_list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) \
return L - 1; \
\
/* Not found */ \
+84 -56
View File
@@ -95,6 +95,8 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> "
"buffer:%p, "
"capacity:%" PRIuMAX ", "
"count:%" PRIuMAX ", "
"flag:%d, "
"f_val:%p, "
"alloc:%p, "
"callbacks:%p }";
@@ -140,17 +142,45 @@ struct cmc_callbacks_stack
/* Current amount of elements */ \
size_t count; \
\
/* Function that returns an iterator to the start of the stack */ \
struct SNAME##_iter (*it_start)(struct SNAME *); \
/* Flags indicating errors or success */ \
int flag; \
\
/* Function that returns an iterator to the end of the stack */ \
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_stack *callbacks; \
\
/* Function that returns an iterator to the start of the stack */ \
struct SNAME##_iter (*it_start)(struct SNAME *); \
\
/* Function that returns an iterator to the end of the stack */ \
struct SNAME##_iter (*it_end)(struct SNAME *); \
}; \
\
/* 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); \
}; \
\
/* Stack Iterator */ \
@@ -171,12 +201,12 @@ struct cmc_callbacks_stack
\
/* 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_stack *callbacks); \
void PFX##_clear(struct SNAME *_stack_, void (*deallocator)(V)); \
void PFX##_free(struct SNAME *_stack_, 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_stack *callbacks); \
void PFX##_clear(struct SNAME *_stack_); \
void PFX##_free(struct SNAME *_stack_); \
/* Customization of Allocation and Callbacks */ \
void PFX##_customize(struct SNAME *_stack_, struct cmc_alloc_node *alloc, \
struct cmc_callbacks_stack *callbacks); \
@@ -186,17 +216,15 @@ struct cmc_callbacks_stack
/* Element Access */ \
V PFX##_top(struct SNAME *_stack_); \
/* Collection State */ \
bool PFX##_contains(struct SNAME *_stack_, V element, \
int (*comparator)(V, V)); \
bool PFX##_contains(struct SNAME *_stack_, V element); \
bool PFX##_empty(struct SNAME *_stack_); \
bool PFX##_full(struct SNAME *_stack_); \
size_t PFX##_count(struct SNAME *_stack_); \
size_t PFX##_capacity(struct SNAME *_stack_); \
/* Collection Utility */ \
bool PFX##_resize(struct SNAME *_stack_, size_t capacity); \
struct SNAME *PFX##_copy_of(struct SNAME *_stack_, V (*copy_func)(V)); \
bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_, \
int (*comparator)(V, V)); \
struct SNAME *PFX##_copy_of(struct SNAME *_stack_); \
bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_); \
struct cmc_string PFX##_to_string(struct SNAME *_stack_); \
\
/* Iterator Functions */ \
@@ -230,13 +258,16 @@ struct cmc_callbacks_stack
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_stack_); \
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_stack_); \
\
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; \
\
if (capacity < 1) \
return NULL; \
\
if (!f_val) \
return NULL; \
\
struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \
\
if (!_stack_) \
@@ -252,21 +283,23 @@ struct cmc_callbacks_stack
\
_stack_->capacity = capacity; \
_stack_->count = 0; \
\
_stack_->it_start = PFX##_impl_it_start; \
_stack_->it_end = PFX##_impl_it_end; \
\
_stack_->flag = cmc_flags.OK; \
_stack_->f_val = f_val; \
_stack_->alloc = alloc; \
_stack_->callbacks = NULL; \
_stack_->it_start = PFX##_impl_it_start; \
_stack_->it_end = PFX##_impl_it_end; \
\
return _stack_; \
} \
\
struct SNAME *PFX##_new_custom(size_t capacity, \
struct cmc_alloc_node *alloc, \
struct cmc_callbacks_stack *callbacks) \
struct SNAME *PFX##_new_custom( \
size_t capacity, struct SNAME##_ftab_val *f_val, \
struct cmc_alloc_node *alloc, struct cmc_callbacks_stack *callbacks) \
{ \
if (capacity < 1) \
return NULL; \
if (!f_val) \
return NULL; \
\
if (!alloc) \
@@ -287,22 +320,22 @@ struct cmc_callbacks_stack
\
_stack_->capacity = capacity; \
_stack_->count = 0; \
\
_stack_->it_start = PFX##_impl_it_start; \
_stack_->it_end = PFX##_impl_it_end; \
\
_stack_->flag = cmc_flags.OK; \
_stack_->f_val = f_val; \
_stack_->alloc = alloc; \
_stack_->callbacks = callbacks; \
_stack_->it_start = PFX##_impl_it_start; \
_stack_->it_end = PFX##_impl_it_end; \
\
return _stack_; \
} \
\
void PFX##_clear(struct SNAME *_stack_, void (*deallocator)(V)) \
void PFX##_clear(struct SNAME *_stack_) \
{ \
if (deallocator) \
if (_stack_->f_val->free) \
{ \
for (size_t i = 0; i < _stack_->count; i++) \
deallocator(_stack_->buffer[i]); \
_stack_->f_val->free(_stack_->buffer[i]); \
} \
\
memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
@@ -310,12 +343,12 @@ struct cmc_callbacks_stack
_stack_->count = 0; \
} \
\
void PFX##_free(struct SNAME *_stack_, void (*deallocator)(V)) \
void PFX##_free(struct SNAME *_stack_) \
{ \
if (deallocator) \
if (_stack_->f_val->free) \
{ \
for (size_t i = 0; i < _stack_->count; i++) \
deallocator(_stack_->buffer[i]); \
_stack_->f_val->free(_stack_->buffer[i]); \
} \
\
_stack_->alloc->free(_stack_->buffer); \
@@ -336,7 +369,7 @@ struct cmc_callbacks_stack
{ \
if (PFX##_full(_stack_)) \
{ \
if (!PFX##_resize(_stack_, PFX##_capacity(_stack_) * 2)) \
if (!PFX##_resize(_stack_, _stack_->capacity * 2)) \
return false; \
} \
\
@@ -363,12 +396,11 @@ struct cmc_callbacks_stack
return _stack_->buffer[_stack_->count - 1]; \
} \
\
bool PFX##_contains(struct SNAME *_stack_, V element, \
int (*comparator)(V, V)) \
bool PFX##_contains(struct SNAME *_stack_, V element) \
{ \
for (size_t i = 0; i < _stack_->count; i++) \
{ \
if (comparator(_stack_->buffer[i], element) == 0) \
if (_stack_->f_val->cmp(_stack_->buffer[i], element) == 0) \
return true; \
} \
\
@@ -397,10 +429,10 @@ struct cmc_callbacks_stack
\
bool PFX##_resize(struct SNAME *_stack_, size_t capacity) \
{ \
if (PFX##_capacity(_stack_) == capacity) \
if (_stack_->capacity == capacity) \
return true; \
\
if (capacity < PFX##_count(_stack_)) \
if (capacity < _stack_->count) \
return false; \
\
V *new_buffer = \
@@ -415,18 +447,19 @@ struct cmc_callbacks_stack
return true; \
} \
\
struct SNAME *PFX##_copy_of(struct SNAME *_stack_, V (*copy_func)(V)) \
struct SNAME *PFX##_copy_of(struct SNAME *_stack_) \
{ \
struct SNAME *result = PFX##_new_custom( \
_stack_->capacity, _stack_->alloc, _stack_->callbacks); \
struct SNAME *result = \
PFX##_new_custom(_stack_->capacity, _stack_->f_val, \
_stack_->alloc, _stack_->callbacks); \
\
if (!result) \
return NULL; \
\
if (copy_func) \
if (_stack_->f_val->cpy) \
{ \
for (size_t i = 0; i < _stack_->count; i++) \
result->buffer[i] = copy_func(_stack_->buffer[i]); \
result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); \
} \
else \
memcpy(result->buffer, _stack_->buffer, \
@@ -437,15 +470,15 @@ struct cmc_callbacks_stack
return result; \
} \
\
bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_, \
int (*comparator)(V, V)) \
bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_) \
{ \
if (PFX##_count(_stack1_) != PFX##_count(_stack2_)) \
if (_stack1_->count != _stack2_->count) \
return false; \
\
for (size_t i = 0; i < PFX##_count(_stack1_); i++) \
for (size_t i = 0; i < _stack1_->count; i++) \
{ \
if (comparator(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \
if (_stack1_->f_val->cmp(_stack1_->buffer[i], \
_stack2_->buffer[i]) != 0) \
return false; \
} \
\
@@ -459,14 +492,9 @@ struct cmc_callbacks_stack
\
int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, #SNAME, \
#V, s_, s_->buffer, s_->capacity, s_->count, \
s_->alloc, s_->callbacks); \
s_->f_val, s_->alloc, s_->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) \