More migrations to EXT
This commit is contained in:
1 parent
90a6b4ef0d
commit
770ec1c4c7
5 files changed
+631
-535
No files matched your search
+90
-534
@@ -48,20 +48,6 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
#include "../cor/core.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* List specific
|
||||
* ------------------------------------------------------------------------- */
|
||||
/* to_string format */
|
||||
static const char *cmc_cmc_string_fmt_list = "struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%" PRIuMAX ", "
|
||||
"count:%" PRIuMAX ", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }";
|
||||
|
||||
/**
|
||||
* Core List implementation
|
||||
*/
|
||||
@@ -80,146 +66,94 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> "
|
||||
/* -------------------------------------------------------------------------
|
||||
* Header
|
||||
* ------------------------------------------------------------------------- */
|
||||
#define CMC_CMC_LIST_CORE_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; \
|
||||
\
|
||||
/* Flags indicating errors or success */ \
|
||||
int flag; \
|
||||
\
|
||||
/* Value function table */ \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val; \
|
||||
\
|
||||
/* Custom allocation functions */ \
|
||||
struct cmc_alloc_node *alloc; \
|
||||
\
|
||||
/* Custom callback functions */ \
|
||||
struct cmc_callbacks *callbacks; \
|
||||
}; \
|
||||
\
|
||||
/* Value struct function table */ \
|
||||
struct CMC_DEF_FVAL(SNAME) \
|
||||
{ \
|
||||
/* Comparator function */ \
|
||||
CMC_DEF_FTAB_CMP(V); \
|
||||
\
|
||||
/* Copy function */ \
|
||||
CMC_DEF_FTAB_CPY(V); \
|
||||
\
|
||||
/* To string function */ \
|
||||
CMC_DEF_FTAB_STR(V); \
|
||||
\
|
||||
/* Free from memory function */ \
|
||||
CMC_DEF_FTAB_FREE(V); \
|
||||
\
|
||||
/* Hash function */ \
|
||||
CMC_DEF_FTAB_HASH(V); \
|
||||
\
|
||||
/* Priority function */ \
|
||||
CMC_DEF_FTAB_PRI(V); \
|
||||
}; \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* 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 *CMC_(PFX, _new)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME *CMC_(PFX, _new_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \
|
||||
void CMC_(PFX, _clear)(struct SNAME * _list_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _list_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _list_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks); \
|
||||
/* Collection Input and Output */ \
|
||||
bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \
|
||||
bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \
|
||||
bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \
|
||||
bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \
|
||||
bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \
|
||||
/* Collection Sequence Input and Output */ \
|
||||
bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \
|
||||
size_t size); \
|
||||
bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \
|
||||
size_t size, size_t index); \
|
||||
bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \
|
||||
size_t size); \
|
||||
bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \
|
||||
size_t to); \
|
||||
struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \
|
||||
size_t to); \
|
||||
/* Element Access */ \
|
||||
V CMC_(PFX, _front)(struct SNAME * _list_); \
|
||||
V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \
|
||||
V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \
|
||||
V CMC_(PFX, _back)(struct SNAME * _list_); \
|
||||
size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \
|
||||
bool from_start); \
|
||||
/* Collection State */ \
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _full)(struct SNAME * _list_); \
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \
|
||||
int CMC_(PFX, _flag)(struct SNAME * _list_); \
|
||||
/* Collection Utility */ \
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \
|
||||
struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Initialization */ \
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \
|
||||
/* Iterator State */ \
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
/* Iterator Movement */ \
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps); \
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps); \
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
#define CMC_CMC_LIST_CORE_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; \
|
||||
\
|
||||
/* Flags indicating errors or success */ \
|
||||
int flag; \
|
||||
\
|
||||
/* Value function table */ \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val; \
|
||||
\
|
||||
/* Custom allocation functions */ \
|
||||
struct cmc_alloc_node *alloc; \
|
||||
\
|
||||
/* Custom callback functions */ \
|
||||
struct cmc_callbacks *callbacks; \
|
||||
}; \
|
||||
\
|
||||
/* Value struct function table */ \
|
||||
struct CMC_DEF_FVAL(SNAME) \
|
||||
{ \
|
||||
/* Comparator function */ \
|
||||
CMC_DEF_FTAB_CMP(V); \
|
||||
\
|
||||
/* Copy function */ \
|
||||
CMC_DEF_FTAB_CPY(V); \
|
||||
\
|
||||
/* To string function */ \
|
||||
CMC_DEF_FTAB_STR(V); \
|
||||
\
|
||||
/* Free from memory function */ \
|
||||
CMC_DEF_FTAB_FREE(V); \
|
||||
\
|
||||
/* Hash function */ \
|
||||
CMC_DEF_FTAB_HASH(V); \
|
||||
\
|
||||
/* Priority function */ \
|
||||
CMC_DEF_FTAB_PRI(V); \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *CMC_(PFX, _new)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME *CMC_(PFX, _new_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \
|
||||
void CMC_(PFX, _clear)(struct SNAME * _list_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _list_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _list_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks); \
|
||||
/* Collection Input and Output */ \
|
||||
bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \
|
||||
bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \
|
||||
bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \
|
||||
bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \
|
||||
bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \
|
||||
/* Element Access */ \
|
||||
V CMC_(PFX, _front)(struct SNAME * _list_); \
|
||||
V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \
|
||||
V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \
|
||||
V CMC_(PFX, _back)(struct SNAME * _list_); \
|
||||
size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \
|
||||
bool from_start); \
|
||||
/* Collection State */ \
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _full)(struct SNAME * _list_); \
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \
|
||||
int CMC_(PFX, _flag)(struct SNAME * _list_); \
|
||||
/* Collection Utility */ \
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Source
|
||||
@@ -465,177 +399,6 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> "
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \
|
||||
size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (!CMC_(PFX, _fits)(_list_, size)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
memmove(_list_->buffer + size, _list_->buffer, \
|
||||
_list_->count * sizeof(V)); \
|
||||
\
|
||||
memcpy(_list_->buffer, values, size * sizeof(V)); \
|
||||
\
|
||||
_list_->count += size; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->create) \
|
||||
_list_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \
|
||||
size_t size, size_t index) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (index > _list_->count) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_RANGE; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (index == 0) \
|
||||
return CMC_(PFX, _seq_push_front)(_list_, values, size); \
|
||||
else if (index == _list_->count) \
|
||||
return CMC_(PFX, _seq_push_back)(_list_, values, size); \
|
||||
\
|
||||
if (!CMC_(PFX, _fits)(_list_, size)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
memmove(_list_->buffer + index + size, _list_->buffer + index, \
|
||||
(_list_->count - index) * sizeof(V)); \
|
||||
\
|
||||
memcpy(_list_->buffer + index, values, size * sizeof(V)); \
|
||||
\
|
||||
_list_->count += size; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->create) \
|
||||
_list_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \
|
||||
size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (!CMC_(PFX, _fits)(_list_, size)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \
|
||||
\
|
||||
_list_->count += size; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->create) \
|
||||
_list_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (to >= _list_->count) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_RANGE; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
size_t length = (to - from + 1); \
|
||||
\
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, \
|
||||
(_list_->count - to - 1) * sizeof(V)); \
|
||||
\
|
||||
memset(_list_->buffer + _list_->count - length, 0, \
|
||||
length * sizeof(V)); \
|
||||
\
|
||||
_list_->count -= to - from + 1; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->delete) \
|
||||
_list_->callbacks->delete (); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \
|
||||
size_t to) \
|
||||
{ \
|
||||
if (from > to) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
if (to >= _list_->count) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_RANGE; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
size_t length = to - from + 1; \
|
||||
\
|
||||
struct SNAME *result = CMC_(PFX, _new_custom)( \
|
||||
length, _list_->f_val, _list_->alloc, _list_->callbacks); \
|
||||
\
|
||||
if (!result) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_ALLOC; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \
|
||||
\
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, \
|
||||
(_list_->count - to - 1) * sizeof(V)); \
|
||||
\
|
||||
memset(_list_->buffer + _list_->count - length, 0, \
|
||||
length * sizeof(V)); \
|
||||
\
|
||||
_list_->count -= length; \
|
||||
result->count = length; \
|
||||
\
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->delete) \
|
||||
_list_->callbacks->delete (); \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _front)(struct SNAME * _list_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_list_)) \
|
||||
@@ -869,219 +632,12 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> "
|
||||
\
|
||||
for (size_t i = 0; i < _list1_->count; i++) \
|
||||
{ \
|
||||
if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \
|
||||
0) \
|
||||
if (0 != \
|
||||
_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \
|
||||
{ \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *l_ = _list_; \
|
||||
\
|
||||
int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_list, \
|
||||
#SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \
|
||||
l_->flag, l_->f_val, l_->alloc, l_->callbacks); \
|
||||
\
|
||||
return n >= 0 ? str : (struct cmc_string){ 0 }; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
if (!_list_->f_val->str(fptr, _list_->buffer[i])) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.cursor = 0; \
|
||||
iter.start = true; \
|
||||
iter.end = CMC_(PFX, _empty)(target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.cursor = 0; \
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
iter.cursor = target->count - 1; \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->end = true; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor += steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor < steps) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor -= steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the */ \
|
||||
/* given index */ \
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t index) \
|
||||
{ \
|
||||
if (index >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \
|
||||
else if (iter->cursor < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (V){ 0 }; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
}
|
||||
|
||||
#endif /* CMC_CMC_LIST_H */
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* ext/cmc/linkedlist.h
|
||||
*
|
||||
* Creation Date: 26/05/2020
|
||||
* Creation Date: 03/06/2020
|
||||
*
|
||||
* Authors:
|
||||
* Leonardo Vencovsky (https://github.com/LeoVen)
|
||||
|
||||
@@ -0,0 +1,527 @@
|
||||
/**
|
||||
* ext/cmc/list.h
|
||||
*
|
||||
* Creation Date: 04/06/2020
|
||||
*
|
||||
* Authors:
|
||||
* Leonardo Vencovsky (https://github.com/LeoVen)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CMC_EXT_CMC_LIST_H
|
||||
#define CMC_EXT_CMC_LIST_H
|
||||
|
||||
#include "../../cor/core.h"
|
||||
|
||||
/**
|
||||
* All the EXT parts of CMC List.
|
||||
*/
|
||||
#define CMC_EXT_CMC_LIST_PARTS ITER, SEQ, STR
|
||||
|
||||
/**
|
||||
* ITER
|
||||
*/
|
||||
#define CMC_EXT_CMC_LIST_ITER(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_ITER_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_ITER_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* 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; \
|
||||
}; \
|
||||
\
|
||||
/* Iterator Initialization */ \
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \
|
||||
/* Iterator State */ \
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
/* Iterator Movement */ \
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps); \
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps); \
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
|
||||
#define CMC_EXT_CMC_LIST_ITER_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.cursor = 0; \
|
||||
iter.start = true; \
|
||||
iter.end = CMC_(PFX, _empty)(target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.cursor = 0; \
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
iter.cursor = target->count - 1; \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->end = true; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor += steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor < steps) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor -= steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the */ \
|
||||
/* given index */ \
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \
|
||||
size_t index) \
|
||||
{ \
|
||||
if (index >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \
|
||||
else if (iter->cursor < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (V){ 0 }; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
}
|
||||
|
||||
/**
|
||||
* SEQ
|
||||
*/
|
||||
#define CMC_EXT_CMC_LIST_SEQ(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_LIST_SEQ_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* List Sequence Input and Output */ \
|
||||
bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \
|
||||
size_t size); \
|
||||
bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \
|
||||
size_t size, size_t index); \
|
||||
bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \
|
||||
size_t size); \
|
||||
bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \
|
||||
size_t to); \
|
||||
struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \
|
||||
size_t to);
|
||||
|
||||
#define CMC_EXT_CMC_LIST_SEQ_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \
|
||||
size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (!CMC_(PFX, _fits)(_list_, size)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
memmove(_list_->buffer + size, _list_->buffer, \
|
||||
_list_->count * sizeof(V)); \
|
||||
\
|
||||
memcpy(_list_->buffer, values, size * sizeof(V)); \
|
||||
\
|
||||
_list_->count += size; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->create) \
|
||||
_list_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \
|
||||
size_t size, size_t index) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (index > _list_->count) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_RANGE; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (index == 0) \
|
||||
return CMC_(PFX, _seq_push_front)(_list_, values, size); \
|
||||
else if (index == _list_->count) \
|
||||
return CMC_(PFX, _seq_push_back)(_list_, values, size); \
|
||||
\
|
||||
if (!CMC_(PFX, _fits)(_list_, size)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
memmove(_list_->buffer + index + size, _list_->buffer + index, \
|
||||
(_list_->count - index) * sizeof(V)); \
|
||||
\
|
||||
memcpy(_list_->buffer + index, values, size * sizeof(V)); \
|
||||
\
|
||||
_list_->count += size; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->create) \
|
||||
_list_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \
|
||||
size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (!CMC_(PFX, _fits)(_list_, size)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \
|
||||
\
|
||||
_list_->count += size; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->create) \
|
||||
_list_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (to >= _list_->count) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_RANGE; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
size_t length = (to - from + 1); \
|
||||
\
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, \
|
||||
(_list_->count - to - 1) * sizeof(V)); \
|
||||
\
|
||||
memset(_list_->buffer + _list_->count - length, 0, \
|
||||
length * sizeof(V)); \
|
||||
\
|
||||
_list_->count -= to - from + 1; \
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->delete) \
|
||||
_list_->callbacks->delete (); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \
|
||||
size_t to) \
|
||||
{ \
|
||||
if (from > to) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_INVALID; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
if (to >= _list_->count) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_RANGE; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
size_t length = to - from + 1; \
|
||||
\
|
||||
struct SNAME *result = CMC_(PFX, _new_custom)( \
|
||||
length, _list_->f_val, _list_->alloc, _list_->callbacks); \
|
||||
\
|
||||
if (!result) \
|
||||
{ \
|
||||
_list_->flag = CMC_FLAG_ALLOC; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \
|
||||
\
|
||||
memmove(_list_->buffer + from, _list_->buffer + to + 1, \
|
||||
(_list_->count - to - 1) * sizeof(V)); \
|
||||
\
|
||||
memset(_list_->buffer + _list_->count - length, 0, \
|
||||
length * sizeof(V)); \
|
||||
\
|
||||
_list_->count -= length; \
|
||||
result->count = length; \
|
||||
\
|
||||
_list_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_list_->callbacks && _list_->callbacks->delete) \
|
||||
_list_->callbacks->delete (); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*/
|
||||
#define CMC_EXT_CMC_LIST_STR(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_LIST_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end);
|
||||
|
||||
#define CMC_EXT_CMC_LIST_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *l_ = _list_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"flag:%d, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \
|
||||
l_->buffer, l_->capacity, l_->count, l_->flag, \
|
||||
l_->f_val, l_->alloc, l_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
if (!_list_->f_val->str(fptr, _list_->buffer[i])) \
|
||||
return false; \
|
||||
\
|
||||
if (i + 1 < _list_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_LIST_H */
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "ext/cmc/heap.h" /* Added in 01/06/2020 */
|
||||
#include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */
|
||||
#include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */
|
||||
#include "ext/cmc/list.h" /* Added in 04/06/2020 */
|
||||
|
||||
#include "utl/assert.h" /* Added in 27/06/2019 */
|
||||
#include "utl/foreach.h" /* Added in 25/02/2019 */
|
||||
|
||||
Reference in new issue
Block a user