Massive changes, unit tests halted
Code format changes that significantly reduce file sizes Working towards many new features at the same time Callbacks are going to be optional Everything is still breaking
This commit is contained in:
1 parent
770ec1c4c7
commit
aa033b0316
71 files changed
+19023
-21074
No files matched your search
+486
-521
File diff suppressed because it is too large.
Load diff
+440
-464
@@ -43,484 +43,460 @@
|
||||
/**
|
||||
* Core Deque implementation
|
||||
*/
|
||||
#define CMC_CMC_DEQUE_CORE(PARAMS) \
|
||||
#define CMC_CMC_DEQUE_CORE(PARAMS) \
|
||||
CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \
|
||||
CMC_CMC_DEQUE_CORE_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \
|
||||
CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \
|
||||
CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) \
|
||||
CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) \
|
||||
CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Header
|
||||
* ------------------------------------------------------------------------- */
|
||||
#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Deque Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic circular array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current circular array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Index representing the front of the deque */ \
|
||||
size_t front; \
|
||||
\
|
||||
/* Index representing the back of the deque */ \
|
||||
size_t back; \
|
||||
\
|
||||
/* Flags indicating errors or success */ \
|
||||
int flag; \
|
||||
\
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val; \
|
||||
\
|
||||
/* Custom allocation functions */ \
|
||||
struct cmc_alloc_node *alloc; \
|
||||
\
|
||||
/* Custom callback functions */ \
|
||||
struct cmc_callbacks *callbacks; \
|
||||
}; \
|
||||
\
|
||||
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 * _deque_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _deque_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _deque_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks); \
|
||||
/* Collection Input and Output */ \
|
||||
bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \
|
||||
bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \
|
||||
bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \
|
||||
bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \
|
||||
/* Element Access */ \
|
||||
V CMC_(PFX, _front)(struct SNAME * _deque_); \
|
||||
V CMC_(PFX, _back)(struct SNAME * _deque_); \
|
||||
/* Collection State */ \
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _deque_); \
|
||||
bool CMC_(PFX, _full)(struct SNAME * _deque_); \
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _deque_); \
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \
|
||||
int CMC_(PFX, _flag)(struct SNAME * _deque_); \
|
||||
/* Collection Utility */ \
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \
|
||||
#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Deque Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic circular array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current circular array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Index representing the front of the deque */ \
|
||||
size_t front; \
|
||||
\
|
||||
/* Index representing the back of the deque */ \
|
||||
size_t back; \
|
||||
\
|
||||
/* Flags indicating errors or success */ \
|
||||
int flag; \
|
||||
\
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val; \
|
||||
\
|
||||
/* Custom allocation functions */ \
|
||||
struct CMC_ALLOC_NODE_NAME *alloc; \
|
||||
\
|
||||
/* Custom callback functions */ \
|
||||
CMC_CALLBACKS_DECL; \
|
||||
}; \
|
||||
\
|
||||
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_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \
|
||||
void CMC_(PFX, _clear)(struct SNAME * _deque_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _deque_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \
|
||||
struct CMC_CALLBACKS_NAME * callbacks); \
|
||||
/* Collection Input and Output */ \
|
||||
bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \
|
||||
bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \
|
||||
bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \
|
||||
bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \
|
||||
/* Element Access */ \
|
||||
V CMC_(PFX, _front)(struct SNAME * _deque_); \
|
||||
V CMC_(PFX, _back)(struct SNAME * _deque_); \
|
||||
/* Collection State */ \
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _deque_); \
|
||||
bool CMC_(PFX, _full)(struct SNAME * _deque_); \
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _deque_); \
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \
|
||||
int CMC_(PFX, _flag)(struct SNAME * _deque_); \
|
||||
/* Collection Utility */ \
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Source
|
||||
* ------------------------------------------------------------------------- */
|
||||
#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
/* None */ \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _new)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
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) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_deque_) \
|
||||
return NULL; \
|
||||
\
|
||||
_deque_->buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_deque_->buffer) \
|
||||
{ \
|
||||
alloc->free(_deque_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
_deque_->capacity = capacity; \
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
_deque_->f_val = f_val; \
|
||||
_deque_->alloc = alloc; \
|
||||
_deque_->callbacks = callbacks; \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _clear)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (_deque_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
_deque_->f_val->free(_deque_->buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
|
||||
\
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _free)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (_deque_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
_deque_->f_val->free(_deque_->buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_deque_->alloc->free(_deque_->buffer); \
|
||||
_deque_->alloc->free(_deque_); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _customize)(struct SNAME * _deque_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks) \
|
||||
{ \
|
||||
if (!alloc) \
|
||||
_deque_->alloc = &cmc_alloc_node_default; \
|
||||
else \
|
||||
_deque_->alloc = alloc; \
|
||||
\
|
||||
_deque_->callbacks = callbacks; \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \
|
||||
{ \
|
||||
if (CMC_(PFX, _full)(_deque_)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 \
|
||||
: _deque_->front - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = value; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->create) \
|
||||
_deque_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \
|
||||
{ \
|
||||
if (CMC_(PFX, _full)(_deque_)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = value; \
|
||||
\
|
||||
_deque_->back = \
|
||||
(_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->create) \
|
||||
_deque_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = (V){ 0 }; \
|
||||
\
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) \
|
||||
? 0 \
|
||||
: _deque_->front + 1; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->delete) \
|
||||
_deque_->callbacks->delete (); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->back = \
|
||||
(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = (V){ 0 }; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->delete) \
|
||||
_deque_->callbacks->delete (); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _front)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->read) \
|
||||
_deque_->callbacks->read(); \
|
||||
\
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _back)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->read) \
|
||||
_deque_->callbacks->read(); \
|
||||
\
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 \
|
||||
: _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
bool result = false; \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \
|
||||
{ \
|
||||
result = true; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->read) \
|
||||
_deque_->callbacks->read(); \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _full)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
int CMC_(PFX, _flag)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->flag; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->capacity == capacity) \
|
||||
goto success; \
|
||||
\
|
||||
if (capacity < _deque_->count) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_ALLOC; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
new_buffer[j] = _deque_->buffer[i]; \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
_deque_->alloc->free(_deque_->buffer); \
|
||||
\
|
||||
_deque_->buffer = new_buffer; \
|
||||
_deque_->capacity = capacity; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = _deque_->count; \
|
||||
\
|
||||
success: \
|
||||
\
|
||||
if (_deque_->callbacks && _deque_->callbacks->resize) \
|
||||
_deque_->callbacks->resize(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
struct SNAME *result = \
|
||||
CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, \
|
||||
_deque_->alloc, _deque_->callbacks); \
|
||||
\
|
||||
if (!result) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_ERROR; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
if (_deque_->f_val->cpy) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
result->buffer[j] = _deque_->buffer[i]; \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
result->count = _deque_->count; \
|
||||
result->front = 0; \
|
||||
result->back = _deque_->count; \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
/* None */ \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_deque_) \
|
||||
return NULL; \
|
||||
\
|
||||
_deque_->buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_deque_->buffer) \
|
||||
{ \
|
||||
alloc->free(_deque_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
_deque_->capacity = capacity; \
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
_deque_->f_val = f_val; \
|
||||
_deque_->alloc = alloc; \
|
||||
CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _clear)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (_deque_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
_deque_->f_val->free(_deque_->buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
|
||||
\
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _free)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (_deque_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
_deque_->f_val->free(_deque_->buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_deque_->alloc->free(_deque_->buffer); \
|
||||
_deque_->alloc->free(_deque_); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \
|
||||
struct CMC_CALLBACKS_NAME * callbacks) \
|
||||
{ \
|
||||
if (!alloc) \
|
||||
_deque_->alloc = &cmc_alloc_node_default; \
|
||||
else \
|
||||
_deque_->alloc = alloc; \
|
||||
\
|
||||
CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \
|
||||
{ \
|
||||
if (CMC_(PFX, _full)(_deque_)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = value; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, create); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \
|
||||
{ \
|
||||
if (CMC_(PFX, _full)(_deque_)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = value; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, create); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = (V){ 0 }; \
|
||||
\
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, delete); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = (V){ 0 }; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, delete); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _front)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, read); \
|
||||
\
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _back)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_deque_)) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_EMPTY; \
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, read); \
|
||||
\
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
bool result = false; \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \
|
||||
{ \
|
||||
result = true; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, read); \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _full)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
int CMC_(PFX, _flag)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
return _deque_->flag; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque_->capacity == capacity) \
|
||||
goto success; \
|
||||
\
|
||||
if (capacity < _deque_->count) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_ALLOC; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
new_buffer[j] = _deque_->buffer[i]; \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
_deque_->alloc->free(_deque_->buffer); \
|
||||
\
|
||||
_deque_->buffer = new_buffer; \
|
||||
_deque_->capacity = capacity; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = _deque_->count; \
|
||||
\
|
||||
success: \
|
||||
\
|
||||
CMC_CALLBACKS_CALL(_deque_, resize); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \
|
||||
{ \
|
||||
struct SNAME *result = CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, _deque_->alloc, NULL); \
|
||||
\
|
||||
if (!result) \
|
||||
{ \
|
||||
_deque_->flag = CMC_FLAG_ERROR; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
CMC_CALLBACKS_ASSIGN(result, _deque_->callbacks); \
|
||||
\
|
||||
if (_deque_->f_val->cpy) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
result->buffer[j] = _deque_->buffer[i]; \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
result->count = _deque_->count; \
|
||||
result->front = 0; \
|
||||
result->back = _deque_->count; \
|
||||
\
|
||||
_deque_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \
|
||||
{ \
|
||||
_deque1_->flag = CMC_FLAG_OK; \
|
||||
_deque2_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque1_->count != _deque2_->count) \
|
||||
return false; \
|
||||
\
|
||||
size_t i, j, k; \
|
||||
for (i = _deque1_->front, j = _deque2_->front, k = 0; \
|
||||
k < _deque1_->count; k++) \
|
||||
{ \
|
||||
if (_deque1_->f_val->cmp(_deque1_->buffer[i], \
|
||||
_deque2_->buffer[j]) != 0) \
|
||||
return false; \
|
||||
\
|
||||
i = (i + 1) % _deque1_->capacity; \
|
||||
j = (j + 1) % _deque2_->capacity; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
{ \
|
||||
_deque1_->flag = CMC_FLAG_OK; \
|
||||
_deque2_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_deque1_->count != _deque2_->count) \
|
||||
return false; \
|
||||
\
|
||||
size_t i, j, k; \
|
||||
for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++) \
|
||||
{ \
|
||||
if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) \
|
||||
return false; \
|
||||
\
|
||||
i = (i + 1) % _deque1_->capacity; \
|
||||
j = (j + 1) % _deque2_->capacity; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_CMC_DEQUE_H */
|
||||
+1338
-1397
File diff suppressed because it is too large.
Load diff
+755
-781
File diff suppressed because it is too large.
Load diff
+963
-1039
File diff suppressed because it is too large.
Load diff
+793
-867
File diff suppressed because it is too large.
Load diff
+581
-638
File diff suppressed because it is too large.
Load diff
+420
-472
@@ -43,494 +43,442 @@
|
||||
/**
|
||||
* Core Heap implementation
|
||||
*/
|
||||
#define CMC_CMC_HEAP_CORE(PARAMS) \
|
||||
#define CMC_CMC_HEAP_CORE(PARAMS) \
|
||||
CMC_CMC_HEAP_CORE_HEADER(PARAMS) \
|
||||
CMC_CMC_HEAP_CORE_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \
|
||||
CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \
|
||||
CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_CMC_HEAP_CORE_SOURCE(PARAMS) \
|
||||
CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_CMC_HEAP_CORE_SOURCE(PARAMS) \
|
||||
CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Header
|
||||
* ------------------------------------------------------------------------- */
|
||||
#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements in the heap */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Heap order (MaxHeap or MinHeap) */ \
|
||||
enum cmc_heap_order HO; \
|
||||
\
|
||||
/* 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, enum cmc_heap_order HO, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME *CMC_(PFX, _new_custom)( \
|
||||
size_t capacity, enum cmc_heap_order HO, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks); \
|
||||
void CMC_(PFX, _clear)(struct SNAME * _heap_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _heap_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _heap_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks); \
|
||||
/* Collection Input and Output */ \
|
||||
bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \
|
||||
bool CMC_(PFX, _remove)(struct SNAME * _heap_); \
|
||||
/* Element Access */ \
|
||||
V CMC_(PFX, _peek)(struct SNAME * _heap_); \
|
||||
/* Collection State */ \
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _heap_); \
|
||||
bool CMC_(PFX, _full)(struct SNAME * _heap_); \
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _heap_); \
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \
|
||||
int CMC_(PFX, _flag)(struct SNAME * _heap_); \
|
||||
/* Collection Utility */ \
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \
|
||||
#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements in the heap */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Heap order (MaxHeap or MinHeap) */ \
|
||||
enum cmc_heap_order HO; \
|
||||
\
|
||||
/* Flags indicating errors or success */ \
|
||||
int flag; \
|
||||
\
|
||||
/* Value function table */ \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val; \
|
||||
\
|
||||
/* Custom allocation functions */ \
|
||||
struct CMC_ALLOC_NODE_NAME *alloc; \
|
||||
\
|
||||
/* Custom callback functions */ \
|
||||
CMC_CALLBACKS_DECL; \
|
||||
}; \
|
||||
\
|
||||
/* 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, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \
|
||||
void CMC_(PFX, _clear)(struct SNAME * _heap_); \
|
||||
void CMC_(PFX, _free)(struct SNAME * _heap_); \
|
||||
/* Customization of Allocation and Callbacks */ \
|
||||
void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \
|
||||
struct CMC_CALLBACKS_NAME * callbacks); \
|
||||
/* Collection Input and Output */ \
|
||||
bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \
|
||||
bool CMC_(PFX, _remove)(struct SNAME * _heap_); \
|
||||
/* Element Access */ \
|
||||
V CMC_(PFX, _peek)(struct SNAME * _heap_); \
|
||||
/* Collection State */ \
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _heap_); \
|
||||
bool CMC_(PFX, _full)(struct SNAME * _heap_); \
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _heap_); \
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \
|
||||
int CMC_(PFX, _flag)(struct SNAME * _heap_); \
|
||||
/* Collection Utility */ \
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Source
|
||||
* ------------------------------------------------------------------------- */
|
||||
#define CMC_CMC_HEAP_CORE_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, \
|
||||
size_t index); \
|
||||
static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, \
|
||||
size_t index); \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_heap_) \
|
||||
return NULL; \
|
||||
\
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_heap_->buffer) \
|
||||
{ \
|
||||
alloc->free(_heap_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
_heap_->capacity = capacity; \
|
||||
_heap_->count = 0; \
|
||||
_heap_->HO = HO; \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
_heap_->f_val = f_val; \
|
||||
_heap_->alloc = alloc; \
|
||||
_heap_->callbacks = NULL; \
|
||||
\
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _new_custom)( \
|
||||
size_t capacity, enum cmc_heap_order HO, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_heap_) \
|
||||
return NULL; \
|
||||
\
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_heap_->buffer) \
|
||||
{ \
|
||||
alloc->free(_heap_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
_heap_->capacity = capacity; \
|
||||
_heap_->count = 0; \
|
||||
_heap_->HO = HO; \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
_heap_->f_val = f_val; \
|
||||
_heap_->alloc = alloc; \
|
||||
_heap_->callbacks = callbacks; \
|
||||
\
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _clear)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (_heap_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
_heap_->f_val->free(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \
|
||||
\
|
||||
_heap_->count = 0; \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _free)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (_heap_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
_heap_->f_val->free(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_heap_->alloc->free(_heap_->buffer); \
|
||||
_heap_->alloc->free(_heap_); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _customize)(struct SNAME * _heap_, \
|
||||
struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks) \
|
||||
{ \
|
||||
if (!alloc) \
|
||||
_heap_->alloc = &cmc_alloc_node_default; \
|
||||
else \
|
||||
_heap_->alloc = alloc; \
|
||||
\
|
||||
_heap_->callbacks = callbacks; \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \
|
||||
{ \
|
||||
if (CMC_(PFX, _full)(_heap_)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_heap_, _heap_->count * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_heap_->buffer[_heap_->count++] = value; \
|
||||
\
|
||||
if (_heap_->count > 1) \
|
||||
{ \
|
||||
CMC_(PFX, _impl_float_up)(_heap_, _heap_->count - 1); \
|
||||
} \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->create) \
|
||||
_heap_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _remove)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_heap_)) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_EMPTY; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \
|
||||
_heap_->buffer[_heap_->count - 1] = (V){ 0 }; \
|
||||
\
|
||||
_heap_->count--; \
|
||||
\
|
||||
CMC_(PFX, _impl_float_down)(_heap_, 0); \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->delete) \
|
||||
_heap_->callbacks->delete (); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _peek)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_heap_)) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_EMPTY; \
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||
_heap_->callbacks->read(); \
|
||||
\
|
||||
return _heap_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
bool result = false; \
|
||||
\
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) \
|
||||
{ \
|
||||
result = true; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||
_heap_->callbacks->read(); \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _full)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->count >= _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->count; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
int CMC_(PFX, _flag)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->flag; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->capacity == capacity) \
|
||||
goto success; \
|
||||
\
|
||||
if (capacity < _heap_->count) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V *new_buffer = \
|
||||
_heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_ALLOC; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
/* TODO zero out new slots */ \
|
||||
\
|
||||
_heap_->buffer = new_buffer; \
|
||||
_heap_->capacity = capacity; \
|
||||
\
|
||||
success: \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->resize) \
|
||||
_heap_->callbacks->resize(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
struct SNAME *result = CMC_(PFX, _new_custom)( \
|
||||
_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, \
|
||||
_heap_->callbacks); \
|
||||
\
|
||||
if (!result) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_ERROR; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
if (_heap_->f_val->cpy) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
#define CMC_CMC_HEAP_CORE_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index); \
|
||||
static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, size_t index); \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _new_custom)(capacity, HO, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return NULL; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_heap_) \
|
||||
return NULL; \
|
||||
\
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_heap_->buffer) \
|
||||
{ \
|
||||
alloc->free(_heap_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
_heap_->capacity = capacity; \
|
||||
_heap_->count = 0; \
|
||||
_heap_->HO = HO; \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
_heap_->f_val = f_val; \
|
||||
_heap_->alloc = alloc; \
|
||||
CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \
|
||||
\
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _clear)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (_heap_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
_heap_->f_val->free(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \
|
||||
\
|
||||
_heap_->count = 0; \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _free)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (_heap_->f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
_heap_->f_val->free(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_heap_->alloc->free(_heap_->buffer); \
|
||||
_heap_->alloc->free(_heap_); \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \
|
||||
struct CMC_CALLBACKS_NAME * callbacks) \
|
||||
{ \
|
||||
if (!alloc) \
|
||||
_heap_->alloc = &cmc_alloc_node_default; \
|
||||
else \
|
||||
_heap_->alloc = alloc; \
|
||||
\
|
||||
CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \
|
||||
{ \
|
||||
if (CMC_(PFX, _full)(_heap_)) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _resize)(_heap_, _heap_->count * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_heap_->buffer[_heap_->count++] = value; \
|
||||
\
|
||||
if (_heap_->count > 1) \
|
||||
{ \
|
||||
CMC_(PFX, _impl_float_up)(_heap_, _heap_->count - 1); \
|
||||
} \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->create) \
|
||||
_heap_->callbacks->create(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _remove)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_heap_)) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_EMPTY; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \
|
||||
_heap_->buffer[_heap_->count - 1] = (V){ 0 }; \
|
||||
\
|
||||
_heap_->count--; \
|
||||
\
|
||||
CMC_(PFX, _impl_float_down)(_heap_, 0); \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->delete) \
|
||||
_heap_->callbacks->delete (); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _peek)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(_heap_)) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_EMPTY; \
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||
_heap_->callbacks->read(); \
|
||||
\
|
||||
return _heap_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
bool result = false; \
|
||||
\
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) \
|
||||
{ \
|
||||
result = true; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||
_heap_->callbacks->read(); \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _empty)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _full)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->count >= _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _count)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->count; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
int CMC_(PFX, _flag)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
return _heap_->flag; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap_->capacity == capacity) \
|
||||
goto success; \
|
||||
\
|
||||
if (capacity < _heap_->count) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_ALLOC; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
/* TODO zero out new slots */ \
|
||||
\
|
||||
_heap_->buffer = new_buffer; \
|
||||
_heap_->capacity = capacity; \
|
||||
\
|
||||
success: \
|
||||
\
|
||||
if (_heap_->callbacks && _heap_->callbacks->resize) \
|
||||
_heap_->callbacks->resize(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \
|
||||
{ \
|
||||
struct SNAME *result = \
|
||||
CMC_(PFX, _new_custom)(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, NULL); \
|
||||
\
|
||||
if (!result) \
|
||||
{ \
|
||||
_heap_->flag = CMC_FLAG_ERROR; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
CMC_CALLBACKS_ASSIGN(result, _heap_->callbacks); \
|
||||
\
|
||||
if (_heap_->f_val->cpy) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _heap_->buffer, sizeof(V) * _heap_->count); \
|
||||
\
|
||||
result->count = _heap_->count; \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \
|
||||
{ \
|
||||
_heap1_->flag = CMC_FLAG_OK; \
|
||||
_heap2_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap1_->count != _heap2_->count) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < _heap1_->count; i++) \
|
||||
{ \
|
||||
if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != \
|
||||
0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
result->count = _heap_->count; \
|
||||
\
|
||||
_heap_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \
|
||||
{ \
|
||||
_heap1_->flag = CMC_FLAG_OK; \
|
||||
_heap2_->flag = CMC_FLAG_OK; \
|
||||
\
|
||||
if (_heap1_->count != _heap2_->count) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < _heap1_->count; i++) \
|
||||
{ \
|
||||
if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index) \
|
||||
{ \
|
||||
/* Current index */ \
|
||||
size_t C = index; \
|
||||
V child = _heap_->buffer[C]; \
|
||||
V parent = _heap_->buffer[(index - 1) / 2]; \
|
||||
\
|
||||
int mod = _heap_->HO; \
|
||||
\
|
||||
while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) \
|
||||
{ \
|
||||
/* Swap between C (current element) and its parent */ \
|
||||
V tmp = _heap_->buffer[C]; \
|
||||
_heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; \
|
||||
_heap_->buffer[(C - 1) / 2] = tmp; \
|
||||
\
|
||||
/* Go to parent */ \
|
||||
C = (C - 1) / 2; \
|
||||
\
|
||||
/* Prevent the two lines below from accessing a negative index */ \
|
||||
if (C == 0) \
|
||||
break; \
|
||||
\
|
||||
child = _heap_->buffer[C]; \
|
||||
parent = _heap_->buffer[(C - 1) / 2]; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, \
|
||||
size_t index) \
|
||||
{ \
|
||||
int mod = _heap_->HO; \
|
||||
\
|
||||
while (index < _heap_->count) \
|
||||
{ \
|
||||
size_t L = 2 * index + 1; \
|
||||
size_t R = 2 * index + 2; \
|
||||
size_t C = index; \
|
||||
\
|
||||
/* Determine if we swap with the left or right element */ \
|
||||
if (L < _heap_->count && \
|
||||
_heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * \
|
||||
mod > \
|
||||
0) \
|
||||
{ \
|
||||
C = L; \
|
||||
} \
|
||||
\
|
||||
if (R < _heap_->count && \
|
||||
_heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * \
|
||||
mod > \
|
||||
0) \
|
||||
{ \
|
||||
C = R; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
/* Current index */ \
|
||||
size_t C = index; \
|
||||
V child = _heap_->buffer[C]; \
|
||||
V parent = _heap_->buffer[(index - 1) / 2]; \
|
||||
\
|
||||
int mod = _heap_->HO; \
|
||||
\
|
||||
while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) \
|
||||
{ \
|
||||
/* Swap between C (current element) and its parent */ \
|
||||
V tmp = _heap_->buffer[C]; \
|
||||
_heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; \
|
||||
_heap_->buffer[(C - 1) / 2] = tmp; \
|
||||
\
|
||||
/* Go to parent */ \
|
||||
C = (C - 1) / 2; \
|
||||
\
|
||||
/* Prevent the two lines below from accessing a negative index */ \
|
||||
if (C == 0) \
|
||||
break; \
|
||||
\
|
||||
child = _heap_->buffer[C]; \
|
||||
parent = _heap_->buffer[(C - 1) / 2]; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, size_t index) \
|
||||
{ \
|
||||
int mod = _heap_->HO; \
|
||||
\
|
||||
while (index < _heap_->count) \
|
||||
{ \
|
||||
size_t L = 2 * index + 1; \
|
||||
size_t R = 2 * index + 2; \
|
||||
size_t C = index; \
|
||||
\
|
||||
/* Determine if we swap with the left or right element */ \
|
||||
if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) \
|
||||
{ \
|
||||
C = L; \
|
||||
} \
|
||||
\
|
||||
if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) \
|
||||
{ \
|
||||
C = R; \
|
||||
} \
|
||||
\
|
||||
/* Swap only if either left or right was picked, otherwise done */ \
|
||||
if (C != index) \
|
||||
{ \
|
||||
V tmp = _heap_->buffer[index]; \
|
||||
_heap_->buffer[index] = _heap_->buffer[C]; \
|
||||
_heap_->buffer[C] = tmp; \
|
||||
\
|
||||
index = C; \
|
||||
} \
|
||||
else \
|
||||
break; \
|
||||
} \
|
||||
if (C != index) \
|
||||
{ \
|
||||
V tmp = _heap_->buffer[index]; \
|
||||
_heap_->buffer[index] = _heap_->buffer[C]; \
|
||||
_heap_->buffer[C] = tmp; \
|
||||
\
|
||||
index = C; \
|
||||
} \
|
||||
else \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* CMC_CMC_HEAP_H */
|
||||
+828
-881
File diff suppressed because it is too large.
Load diff
+550
-581
File diff suppressed because it is too large.
Load diff
+531
-572
File diff suppressed because it is too large.
Load diff
+661
-713
File diff suppressed because it is too large.
Load diff
+781
-839
File diff suppressed because it is too large.
Load diff
+578
-624
File diff suppressed because it is too large.
Load diff
+1181
-1240
File diff suppressed because it is too large.
Load diff
+1259
-1322
File diff suppressed because it is too large.
Load diff
+7
-1
@@ -11,6 +11,12 @@
|
||||
#ifndef CMC_COR_ALLOC_H
|
||||
#define CMC_COR_ALLOC_H
|
||||
|
||||
#ifdef CMC_CAMEL_CASE
|
||||
#define CMC_ALLOC_NODE_NAME CMCAllocNode
|
||||
#else
|
||||
#define CMC_ALLOC_NODE_NAME cmc_alloc_node
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
@@ -20,7 +26,7 @@
|
||||
* functions. The cmc_alloc_node_default is the default heap allocator provided
|
||||
* by the standard library.
|
||||
*/
|
||||
static struct cmc_alloc_node
|
||||
static struct CMC_ALLOC_NODE_NAME
|
||||
{
|
||||
void *(*malloc)(size_t);
|
||||
void *(*calloc)(size_t, size_t);
|
||||
|
||||
+28
-4
@@ -8,8 +8,32 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CMC_COR_CALLBACK_H
|
||||
#define CMC_COR_CALLBACK_H
|
||||
#ifndef CMC_COR_CALLBACKS_H
|
||||
#define CMC_COR_CALLBACKS_H
|
||||
|
||||
#ifdef CMC_CAMEL_CASE
|
||||
#define CMC_CALLBACKS_NAME CMCCallbacks
|
||||
#else
|
||||
#define CMC_CALLBACKS_NAME cmc_callbacks
|
||||
#endif
|
||||
|
||||
#ifdef CMC_NO_CALLBACKS
|
||||
|
||||
#define CMC_CALLBACKS_DECL
|
||||
#define CMC_CALLBACKS_GET(ds) NULL /* Placeholder for STR */
|
||||
#define CMC_CALLBACKS_ASSIGN(ds, cb)
|
||||
#define CMC_CALLBACKS_CALL(ds, cb)
|
||||
|
||||
#else
|
||||
|
||||
#define CMC_CALLBACKS_DECL struct CMC_CALLBACKS_NAME *callbacks
|
||||
#define CMC_CALLBACKS_GET(ds) (ds)->callbacks
|
||||
#define CMC_CALLBACKS_ASSIGN(ds, cb) CMC_CALLBACKS_GET(ds) = cb
|
||||
#define CMC_CALLBACKS_CALL(ds, cb) \
|
||||
if (CMC_CALLBACKS_GET(ds) && CMC_CALLBACKS_GET(ds)->cb) \
|
||||
CMC_CALLBACKS_GET(ds)->cb();
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct cmc_callbacks
|
||||
@@ -21,7 +45,7 @@
|
||||
* - delete : an element was successfully removed from the collection
|
||||
* - resize : the collection was full and successfully resized
|
||||
*/
|
||||
struct cmc_callbacks
|
||||
struct CMC_CALLBACKS_NAME
|
||||
{
|
||||
void (*create)(void);
|
||||
void (*read)(void);
|
||||
@@ -30,4 +54,4 @@ struct cmc_callbacks
|
||||
void (*resize)(void);
|
||||
};
|
||||
|
||||
#endif /* CMC_COR_CALLBACK_H */
|
||||
#endif /* CMC_COR_CALLBACKS_H */
|
||||
+2
-4
@@ -37,9 +37,7 @@ enum cmc_flags
|
||||
*
|
||||
* Maps the error codes to their character representation.
|
||||
*/
|
||||
const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY",
|
||||
"NOT_FOUND", "INVALID", "RANGE",
|
||||
"DUPLICATE", "ERROR", "THREAD",
|
||||
"MUTEX" };
|
||||
const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID",
|
||||
"RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX" };
|
||||
|
||||
#endif /* CMC_COR_FLAGS_H */
|
||||
+353
-374
@@ -24,422 +24,401 @@
|
||||
* The part 'INIT' gives a new way of initializing a collection. The collection
|
||||
* struct is not heap allocated, only its internal structure (nodes, buffers).
|
||||
*/
|
||||
#define CMC_EXT_CMC_DEQUE_INIT(PARAMS) \
|
||||
#define CMC_EXT_CMC_DEQUE_INIT(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_INIT_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_INIT_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \
|
||||
void CMC_(PFX, _release)(struct SNAME _deque_);
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \
|
||||
{ \
|
||||
struct SNAME _deque_ = { 0 }; \
|
||||
\
|
||||
if (capacity < 1) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
_deque_.buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_deque_.buffer) \
|
||||
return _deque_; \
|
||||
\
|
||||
_deque_.capacity = capacity; \
|
||||
_deque_.count = 0; \
|
||||
_deque_.front = 0; \
|
||||
_deque_.back = 0; \
|
||||
_deque_.flag = CMC_FLAG_OK; \
|
||||
_deque_.f_val = f_val; \
|
||||
_deque_.alloc = alloc; \
|
||||
_deque_.callbacks = callbacks; \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _deque_) \
|
||||
{ \
|
||||
if (_deque_.f_val->free) \
|
||||
{ \
|
||||
#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \
|
||||
struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \
|
||||
{ \
|
||||
struct SNAME _deque_ = { 0 }; \
|
||||
\
|
||||
if (capacity < 1) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!f_val) \
|
||||
return _deque_; \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
_deque_.buffer = alloc->calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_deque_.buffer) \
|
||||
return _deque_; \
|
||||
\
|
||||
_deque_.capacity = capacity; \
|
||||
_deque_.count = 0; \
|
||||
_deque_.front = 0; \
|
||||
_deque_.back = 0; \
|
||||
_deque_.flag = CMC_FLAG_OK; \
|
||||
_deque_.f_val = f_val; \
|
||||
_deque_.alloc = alloc; \
|
||||
CMC_CALLBACKS_ASSIGN(&_deque_, callbacks); \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _deque_) \
|
||||
{ \
|
||||
if (_deque_.f_val->free) \
|
||||
{ \
|
||||
for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \
|
||||
{ \
|
||||
_deque_.f_val->free(_deque_.buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_.capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_deque_.alloc->free(_deque_.buffer); \
|
||||
{ \
|
||||
_deque_.f_val->free(_deque_.buffer[i]); \
|
||||
\
|
||||
i = (i + 1) % _deque_.capacity; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_deque_.alloc->free(_deque_.buffer); \
|
||||
}
|
||||
|
||||
/**
|
||||
* ITER
|
||||
*/
|
||||
#define CMC_EXT_CMC_DEQUE_ITER(PARAMS) \
|
||||
#define CMC_EXT_CMC_DEQUE_ITER(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_ITER_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Deque Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target deque */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* 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 */ \
|
||||
#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Deque Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target deque */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* 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); \
|
||||
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_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
#define CMC_EXT_CMC_DEQUE_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 = target->front; \
|
||||
iter.index = 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; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
if (iter.target->back == 0) \
|
||||
iter.cursor = iter.target->capacity - 1; \
|
||||
else \
|
||||
iter.cursor = iter.target->back - 1; \
|
||||
\
|
||||
iter.index = iter.target->count - 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
} \
|
||||
\
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
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 = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = false; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
if (iter->target->back == 0) \
|
||||
iter->cursor = iter->target->capacity - 1; \
|
||||
else \
|
||||
iter->cursor = iter->target->back - 1; \
|
||||
\
|
||||
iter->index = iter->target->count - 1; \
|
||||
\
|
||||
iter->start = false; \
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
|
||||
iter->index++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \
|
||||
: iter->cursor - 1; \
|
||||
iter->index--; \
|
||||
\
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->index += steps; \
|
||||
iter->cursor = (iter->cursor + steps) % iter->target->capacity; \
|
||||
\
|
||||
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->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index < steps) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->index -= steps; \
|
||||
\
|
||||
/* Prevent underflow */ \
|
||||
if (iter->cursor < steps) \
|
||||
iter->cursor += iter->target->capacity; \
|
||||
\
|
||||
iter->cursor -= steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.cursor = target->front; \
|
||||
iter.index = 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; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
if (iter.target->back == 0) \
|
||||
iter.cursor = iter.target->capacity - 1; \
|
||||
else \
|
||||
iter.cursor = iter.target->back - 1; \
|
||||
\
|
||||
iter.index = iter.target->count - 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
} \
|
||||
\
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
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 = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = false; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
if (iter->target->back == 0) \
|
||||
iter->cursor = iter->target->capacity - 1; \
|
||||
else \
|
||||
iter->cursor = iter->target->back - 1; \
|
||||
\
|
||||
iter->index = iter->target->count - 1; \
|
||||
\
|
||||
iter->start = false; \
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
|
||||
iter->index++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
|
||||
iter->index--; \
|
||||
\
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->index += steps; \
|
||||
iter->cursor = (iter->cursor + steps) % iter->target->capacity; \
|
||||
\
|
||||
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->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index < steps) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
iter->index -= steps; \
|
||||
\
|
||||
/* Prevent underflow */ \
|
||||
if (iter->cursor < steps) \
|
||||
iter->cursor += iter->target->capacity; \
|
||||
\
|
||||
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->index > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
|
||||
else if (iter->index < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
|
||||
\
|
||||
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->index; \
|
||||
/* 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->index > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
|
||||
else if (iter->index < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
|
||||
\
|
||||
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->index; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*/
|
||||
#define CMC_EXT_CMC_DEQUE_STR(PARAMS) \
|
||||
#define CMC_EXT_CMC_DEQUE_STR(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_STR_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_DEQUE_STR_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end);
|
||||
|
||||
#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *d_ = _deque_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"front:%" PRIuMAX ", " \
|
||||
"back:%" PRIuMAX ", " \
|
||||
"flag:%d, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, \
|
||||
d_->buffer, d_->capacity, d_->count, d_->front, \
|
||||
d_->back, d_->flag, d_->f_val, d_->alloc, \
|
||||
d_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \
|
||||
return false; \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
\
|
||||
if (j + 1 < _deque_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *d_ = _deque_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"front:%" PRIuMAX ", " \
|
||||
"back:%" PRIuMAX ", " \
|
||||
"flag:%d, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, d_->buffer, d_->capacity, d_->count, \
|
||||
d_->front, d_->back, d_->flag, d_->f_val, d_->alloc, CMC_CALLBACKS_GET(d_)); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \
|
||||
return false; \
|
||||
\
|
||||
i = (i + 1) % _deque_->capacity; \
|
||||
\
|
||||
if (j + 1 < _deque_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_DEQUE_H */
|
||||
+459
-484
@@ -24,524 +24,499 @@
|
||||
* The part 'INIT' gives a new way of initializing a collection. The collection
|
||||
* struct is not heap allocated, only its internal structure (nodes, buffers).
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT(PARAMS) \
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, double load, \
|
||||
struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks); \
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val); \
|
||||
struct SNAME CMC_(PFX, _init_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
|
||||
struct CMC_CALLBACKS_NAME * callbacks); \
|
||||
void CMC_(PFX, _release)(struct SNAME _map_);
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, double load, \
|
||||
struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _init_custom)(capacity, load, f_key, f_val, NULL, \
|
||||
NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init_custom)( \
|
||||
size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \
|
||||
struct cmc_callbacks * callbacks) \
|
||||
{ \
|
||||
struct SNAME _map_ = { 0 }; \
|
||||
\
|
||||
if (capacity == 0 || load <= 0 || load >= 1) \
|
||||
return _map_; \
|
||||
\
|
||||
/* Prevent integer overflow */ \
|
||||
if (capacity >= UINTMAX_MAX * load) \
|
||||
return _map_; \
|
||||
\
|
||||
if (!f_key || !f_val) \
|
||||
return _map_; \
|
||||
\
|
||||
size_t real_capacity = \
|
||||
CMC_(PFX, _impl_calculate_size)(capacity / load); \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
_map_.buffer = \
|
||||
alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \
|
||||
\
|
||||
if (!_map_.buffer) \
|
||||
return _map_; \
|
||||
\
|
||||
_map_.count = 0; \
|
||||
_map_.capacity = real_capacity; \
|
||||
_map_.load = load; \
|
||||
_map_.flag = CMC_FLAG_OK; \
|
||||
_map_.f_key = f_key; \
|
||||
_map_.f_val = f_val; \
|
||||
_map_.alloc = alloc; \
|
||||
_map_.callbacks = callbacks; \
|
||||
\
|
||||
return _map_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _map_) \
|
||||
{ \
|
||||
if (_map_.f_key->free || _map_.f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _map_.capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (_map_.f_key->free) \
|
||||
_map_.f_key->free(entry->key); \
|
||||
if (_map_.f_val->free) \
|
||||
_map_.f_val->free(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_map_.alloc->free(_map_.buffer); \
|
||||
#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val) \
|
||||
{ \
|
||||
return CMC_(PFX, _init_custom)(capacity, load, f_key, f_val, NULL, NULL); \
|
||||
} \
|
||||
\
|
||||
struct SNAME CMC_(PFX, _init_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
|
||||
struct CMC_CALLBACKS_NAME * callbacks) \
|
||||
{ \
|
||||
struct SNAME _map_ = { 0 }; \
|
||||
\
|
||||
if (capacity == 0 || load <= 0 || load >= 1) \
|
||||
return _map_; \
|
||||
\
|
||||
/* Prevent integer overflow */ \
|
||||
if (capacity >= UINTMAX_MAX * load) \
|
||||
return _map_; \
|
||||
\
|
||||
if (!f_key || !f_val) \
|
||||
return _map_; \
|
||||
\
|
||||
size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \
|
||||
\
|
||||
if (!alloc) \
|
||||
alloc = &cmc_alloc_node_default; \
|
||||
\
|
||||
_map_.buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \
|
||||
\
|
||||
if (!_map_.buffer) \
|
||||
return _map_; \
|
||||
\
|
||||
_map_.count = 0; \
|
||||
_map_.capacity = real_capacity; \
|
||||
_map_.load = load; \
|
||||
_map_.flag = CMC_FLAG_OK; \
|
||||
_map_.f_key = f_key; \
|
||||
_map_.f_val = f_val; \
|
||||
_map_.alloc = alloc; \
|
||||
CMC_CALLBACKS_ASSIGN(&_map_, callbacks); \
|
||||
\
|
||||
return _map_; \
|
||||
} \
|
||||
\
|
||||
void CMC_(PFX, _release)(struct SNAME _map_) \
|
||||
{ \
|
||||
if (_map_.f_key->free || _map_.f_val->free) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _map_.capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (_map_.f_key->free) \
|
||||
_map_.f_key->free(entry->key); \
|
||||
if (_map_.f_val->free) \
|
||||
_map_.f_val->free(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_map_.alloc->free(_map_.buffer); \
|
||||
}
|
||||
|
||||
/**
|
||||
* ITER
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER(PARAMS) \
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
/* HashMap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target hashmap */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* The index of the first element */ \
|
||||
size_t first; \
|
||||
\
|
||||
/* The index of the last element */ \
|
||||
size_t last; \
|
||||
\
|
||||
/* 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 */ \
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
/* HashMap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target hashmap */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* The index of the first element */ \
|
||||
size_t first; \
|
||||
\
|
||||
/* The index of the last element */ \
|
||||
size_t last; \
|
||||
\
|
||||
/* 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 */ \
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
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 */ \
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
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_HASHMAP_ITER_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(PFX, SNAME, K, 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.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = true; \
|
||||
iter.end = CMC_(PFX, _empty)(target); \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
if (target->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.first; \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
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.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
if (target->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.last; \
|
||||
iter.index = 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 = iter->first; \
|
||||
iter->index = 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->cursor = iter->last; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
struct CMC_DEF_ENTRY(SNAME) *scan = \
|
||||
&(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
iter->index++; \
|
||||
\
|
||||
while (1) \
|
||||
{ \
|
||||
iter->cursor++; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
struct CMC_DEF_ENTRY(SNAME) *scan = \
|
||||
&(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
iter->index--; \
|
||||
\
|
||||
while (1) \
|
||||
{ \
|
||||
iter->cursor--; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_next)(iter); \
|
||||
\
|
||||
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->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index < steps) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_prev)(iter); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = true; \
|
||||
iter.end = CMC_(PFX, _empty)(target); \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
if (target->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.first; \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
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.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
if (target->buffer[i].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if (target->buffer[i - 1].state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.last; \
|
||||
iter.index = 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 = iter->first; \
|
||||
iter->index = 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->cursor = iter->last; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
iter->index++; \
|
||||
\
|
||||
while (1) \
|
||||
{ \
|
||||
iter->cursor++; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
iter->index--; \
|
||||
\
|
||||
while (1) \
|
||||
{ \
|
||||
iter->cursor--; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_next)(iter); \
|
||||
\
|
||||
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->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index < steps) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_prev)(iter); \
|
||||
\
|
||||
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->index > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
|
||||
else if (iter->index < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (K){ 0 }; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor].key; \
|
||||
} \
|
||||
\
|
||||
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].value; \
|
||||
} \
|
||||
\
|
||||
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].value); \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
/* 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->index > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
|
||||
else if (iter->index < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (K){ 0 }; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor].key; \
|
||||
} \
|
||||
\
|
||||
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].value; \
|
||||
} \
|
||||
\
|
||||
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].value); \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHMAP_STR(PARAMS) \
|
||||
#define CMC_EXT_CMC_HASHMAP_STR(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), \
|
||||
CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end, const char *key_val_sep);
|
||||
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *m_ = _map_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s, %s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"load:%lf, " \
|
||||
"flag:%d, " \
|
||||
"f_key:%p, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(K), \
|
||||
CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
|
||||
m_->count, m_->load, m_->flag, m_->f_key, \
|
||||
m_->f_val, m_->alloc, m_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end, const char *key_val_sep) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
size_t last = 0; \
|
||||
for (size_t i = _map_->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (!_map_->f_key->str(fptr, entry->key)) \
|
||||
return false; \
|
||||
\
|
||||
fprintf(fptr, "%s", key_val_sep); \
|
||||
\
|
||||
if (!_map_->f_val->str(fptr, entry->value)) \
|
||||
return false; \
|
||||
\
|
||||
if (i + 1 < last) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *m_ = _map_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s, %s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"load:%lf, " \
|
||||
"flag:%d, " \
|
||||
"f_key:%p, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
|
||||
m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end, const char *key_val_sep) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
size_t last = 0; \
|
||||
for (size_t i = _map_->capacity; i > 0; i--) \
|
||||
{ \
|
||||
if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
if (!_map_->f_key->str(fptr, entry->key)) \
|
||||
return false; \
|
||||
\
|
||||
fprintf(fptr, "%s", key_val_sep); \
|
||||
\
|
||||
if (!_map_->f_val->str(fptr, entry->value)) \
|
||||
return false; \
|
||||
\
|
||||
if (i + 1 < last) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_HASHMAP_H */
|
||||
+409
-423
@@ -21,451 +21,437 @@
|
||||
/**
|
||||
* ITER
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER(PARAMS) \
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
/* HashMultiMap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target hashmultimap */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Current entry */ \
|
||||
struct CMC_DEF_ENTRY(SNAME) * curr_entry; \
|
||||
\
|
||||
/* Cursor`s position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* The index of the first element */ \
|
||||
size_t first; \
|
||||
\
|
||||
/* The index of the last element */ \
|
||||
size_t last; \
|
||||
\
|
||||
/* 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 */ \
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
/* HashMultiMap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target hashmultimap */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Current entry */ \
|
||||
struct CMC_DEF_ENTRY(SNAME) * curr_entry; \
|
||||
\
|
||||
/* Cursor`s position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* The index of the first element */ \
|
||||
size_t first; \
|
||||
\
|
||||
/* The index of the last element */ \
|
||||
size_t last; \
|
||||
\
|
||||
/* 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 */ \
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
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 */ \
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
|
||||
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_HASHMULTIMAP_ITER_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.curr_entry = NULL; \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = true; \
|
||||
iter.end = CMC_(PFX, _empty)(target); \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.curr_entry = target->buffer[i][0]; \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.first; \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.curr_entry = NULL; \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = true; \
|
||||
iter.end = CMC_(PFX, _empty)(target); \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.curr_entry = target->buffer[i][0]; \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.first; \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.curr_entry = NULL; \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \
|
||||
{ \
|
||||
struct CMC_DEF_ITER(SNAME) iter; \
|
||||
\
|
||||
iter.target = target; \
|
||||
iter.curr_entry = NULL; \
|
||||
iter.cursor = 0; \
|
||||
iter.index = 0; \
|
||||
iter.first = 0; \
|
||||
iter.last = 0; \
|
||||
iter.start = CMC_(PFX, _empty)(target); \
|
||||
iter.end = true; \
|
||||
\
|
||||
if (!CMC_(PFX, _empty)(target)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < target->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.first = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = target->capacity; i > 0; i--) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.curr_entry = target->buffer[i - 1][1]; \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.last; \
|
||||
iter.index = 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 = iter->first; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
iter->curr_entry = iter->target->buffer[iter->first][0]; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->last; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
iter->end = true; \
|
||||
iter->curr_entry = iter->target->buffer[iter->last][1]; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->curr_entry->next != NULL) \
|
||||
{ \
|
||||
iter->curr_entry = iter->curr_entry->next; \
|
||||
iter->index++; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (iter->cursor == iter->last) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->cursor++; \
|
||||
\
|
||||
while (iter->target->buffer[iter->cursor][0] == NULL) \
|
||||
iter->cursor++; \
|
||||
\
|
||||
iter->curr_entry = iter->target->buffer[iter->cursor][0]; \
|
||||
\
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->curr_entry->prev != NULL) \
|
||||
{ \
|
||||
iter->curr_entry = iter->curr_entry->prev; \
|
||||
iter->index--; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (iter->cursor == iter->first) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->cursor--; \
|
||||
\
|
||||
while (iter->target->buffer[iter->cursor][1] == NULL) \
|
||||
iter->cursor--; \
|
||||
\
|
||||
iter->curr_entry = iter->target->buffer[iter->cursor][1]; \
|
||||
\
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_next)(iter); \
|
||||
\
|
||||
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->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index < steps) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_prev)(iter); \
|
||||
\
|
||||
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->index > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
|
||||
else if (iter->index < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (K){ 0 }; \
|
||||
\
|
||||
return iter->curr_entry->key; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (V){ 0 }; \
|
||||
\
|
||||
return iter->curr_entry->value; \
|
||||
} \
|
||||
\
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->curr_entry->value); \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
iter.curr_entry = target->buffer[i - 1][1]; \
|
||||
iter.last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
iter.cursor = iter.last; \
|
||||
iter.index = 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 = iter->first; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
iter->curr_entry = iter->target->buffer[iter->first][0]; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (!CMC_(PFX, _empty)(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->last; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
iter->end = true; \
|
||||
iter->curr_entry = iter->target->buffer[iter->last][1]; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->curr_entry->next != NULL) \
|
||||
{ \
|
||||
iter->curr_entry = iter->curr_entry->next; \
|
||||
iter->index++; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (iter->cursor == iter->last) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->cursor++; \
|
||||
\
|
||||
while (iter->target->buffer[iter->cursor][0] == NULL) \
|
||||
iter->cursor++; \
|
||||
\
|
||||
iter->curr_entry = iter->target->buffer[iter->cursor][0]; \
|
||||
\
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->curr_entry->prev != NULL) \
|
||||
{ \
|
||||
iter->curr_entry = iter->curr_entry->prev; \
|
||||
iter->index--; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (iter->cursor == iter->first) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->cursor--; \
|
||||
\
|
||||
while (iter->target->buffer[iter->cursor][1] == NULL) \
|
||||
iter->cursor--; \
|
||||
\
|
||||
iter->curr_entry = iter->target->buffer[iter->cursor][1]; \
|
||||
\
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
iter->end = CMC_(PFX, _empty)(iter->target); \
|
||||
\
|
||||
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->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_next)(iter); \
|
||||
\
|
||||
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->index == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index < steps) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
CMC_(PFX, _iter_prev)(iter); \
|
||||
\
|
||||
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->index > index) \
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
|
||||
else if (iter->index < index) \
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (K){ 0 }; \
|
||||
\
|
||||
return iter->curr_entry->key; \
|
||||
} \
|
||||
\
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return (V){ 0 }; \
|
||||
\
|
||||
return iter->curr_entry->value; \
|
||||
} \
|
||||
\
|
||||
V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
if (CMC_(PFX, _empty)(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->curr_entry->value); \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*/
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR(PARAMS) \
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
|
||||
CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end, const char *key_val_sep);
|
||||
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *m_ = _map_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s, %s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"load:%lf, " \
|
||||
"flag:%d, " \
|
||||
"f_key:%p, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(K), \
|
||||
CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
|
||||
m_->count, m_->load, m_->flag, m_->f_key, \
|
||||
m_->f_val, m_->alloc, m_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end, const char *key_val_sep) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
size_t last = 0; \
|
||||
for (size_t i = _map_->capacity; i > 0; i--) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][1]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (!_map_->f_key->str(fptr, scan->key)) \
|
||||
return false; \
|
||||
\
|
||||
fprintf(fptr, "%s", key_val_sep); \
|
||||
\
|
||||
if (!_map_->f_val->str(fptr, scan->value)) \
|
||||
return false; \
|
||||
\
|
||||
scan = scan->next; \
|
||||
\
|
||||
if (i + 1 < last) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(PFX, SNAME, K, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *m_ = _map_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s, %s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"load:%lf, " \
|
||||
"flag:%d, " \
|
||||
"f_key:%p, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
|
||||
m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end, const char *key_val_sep) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
size_t last = 0; \
|
||||
for (size_t i = _map_->capacity; i > 0; i--) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][1]; \
|
||||
\
|
||||
if (entry && entry != CMC_ENTRY_DELETED) \
|
||||
{ \
|
||||
last = i - 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (!_map_->f_key->str(fptr, scan->key)) \
|
||||
return false; \
|
||||
\
|
||||
fprintf(fptr, "%s", key_val_sep); \
|
||||
\
|
||||
if (!_map_->f_val->str(fptr, scan->value)) \
|
||||
return false; \
|
||||
\
|
||||
scan = scan->next; \
|
||||
\
|
||||
if (i + 1 < last) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_HASHMULTIMAP_H */
|
||||
+630
-679
File diff suppressed because it is too large.
Load diff
+597
-638
File diff suppressed because it is too large.
Load diff
+258
-271
@@ -18,301 +18,288 @@
|
||||
*/
|
||||
#define CMC_EXT_CMC_HEAP_PARTS ITER, STR
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_ITER(PARAMS) \
|
||||
#define CMC_EXT_CMC_HEAP_ITER(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_ITER_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_ITER_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target heap */ \
|
||||
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 */ \
|
||||
#define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target heap */ \
|
||||
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); \
|
||||
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); \
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_ITER_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
#define CMC_EXT_CMC_HEAP_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->cursor = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
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; \
|
||||
\
|
||||
if (iter->end) \
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
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->cursor = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
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; \
|
||||
\
|
||||
if (iter->end) \
|
||||
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]; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
/* 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]; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*/
|
||||
#define CMC_EXT_CMC_HEAP_STR(PARAMS) \
|
||||
#define CMC_EXT_CMC_HEAP_STR(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \
|
||||
CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
#define CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
#define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end);
|
||||
|
||||
#define CMC_EXT_CMC_HEAP_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *h_ = _heap_; \
|
||||
const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"type:%s, " \
|
||||
"flag:%d, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks: %p}", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \
|
||||
h_->buffer, h_->capacity, h_->count, t, h_->flag, \
|
||||
h_->f_val, h_->alloc, h_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \
|
||||
return false; \
|
||||
\
|
||||
if (i + 1 < _heap_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
#define CMC_EXT_CMC_HEAP_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *h_ = _heap_; \
|
||||
const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"type:%s, " \
|
||||
"flag:%d, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks: %p}", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->count, t, \
|
||||
h_->flag, h_->f_val, h_->alloc, CMC_CALLBACKS_GET(h_)); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \
|
||||
return false; \
|
||||
\
|
||||
if (i + 1 < _heap_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_HEAP_H */
|
||||
+255
-268
@@ -21,300 +21,287 @@
|
||||
/**
|
||||
* ITER
|
||||
*/
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_ITER(PARAMS) \
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_ITER(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* IntervalHeap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target IntervalHeap */ \
|
||||
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 */ \
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
/* IntervalHeap Iterator */ \
|
||||
struct CMC_DEF_ITER(SNAME) \
|
||||
{ \
|
||||
/* Target IntervalHeap */ \
|
||||
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); \
|
||||
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); \
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_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->cursor = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
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; \
|
||||
\
|
||||
if (iter->end) \
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
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->cursor = iter->target->count - 1; \
|
||||
iter->start = CMC_(PFX, _empty)(iter->target); \
|
||||
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; \
|
||||
\
|
||||
if (iter->end) \
|
||||
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 / 2][iter->cursor % 2]; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
/* 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 / 2][iter->cursor % 2]; \
|
||||
} \
|
||||
\
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
}
|
||||
|
||||
/**
|
||||
* STR
|
||||
*/
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR(PARAMS) \
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS)
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) \
|
||||
CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_( \
|
||||
CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end);
|
||||
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *h_ = _heap_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"size:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"flag:%d, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \
|
||||
h_->buffer, h_->capacity, h_->size, h_->count, \
|
||||
h_->flag, h_->f_val, h_->alloc, h_->callbacks); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \
|
||||
const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \
|
||||
return false; \
|
||||
\
|
||||
if (i + 1 < _heap_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \
|
||||
\
|
||||
bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \
|
||||
{ \
|
||||
struct SNAME *h_ = _heap_; \
|
||||
\
|
||||
return 0 <= fprintf(fptr, \
|
||||
"struct %s<%s> " \
|
||||
"at %p { " \
|
||||
"buffer:%p, " \
|
||||
"capacity:%" PRIuMAX ", " \
|
||||
"size:%" PRIuMAX ", " \
|
||||
"count:%" PRIuMAX ", " \
|
||||
"flag:%d, " \
|
||||
"f_val:%p, " \
|
||||
"alloc:%p, " \
|
||||
"callbacks:%p }", \
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->size, h_->count, \
|
||||
h_->flag, h_->f_val, h_->alloc, CMC_CALLBACKS_GET(h_)); \
|
||||
} \
|
||||
\
|
||||
bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \
|
||||
const char *end) \
|
||||
{ \
|
||||
fprintf(fptr, "%s", start); \
|
||||
\
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \
|
||||
return false; \
|
||||
\
|
||||
if (i + 1 < _heap_->count) \
|
||||
fprintf(fptr, "%s", separator); \
|
||||
} \
|
||||
\
|
||||
fprintf(fptr, "%s", end); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_CMC_INTERVALHEAP_H */
|
||||
+503
-543
File diff suppressed because it is too large.
Load diff
+434
-465
@@ -21,507 +21,476 @@
|
||||
/**
|
||||
* ITER
|
||||
*/
|
||||
#define CMC_EXT_CMC_LIST_ITER(PARAMS) \
|
||||
#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))
|
||||
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))
|
||||
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 */ \
|
||||
#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); \
|
||||
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) \
|
||||
\
|
||||
#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; \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
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; \
|
||||
/* 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) \
|
||||
#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_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_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_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; \
|
||||
} \
|
||||
\
|
||||
#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; \
|
||||
{ \
|
||||
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) \
|
||||
#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_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_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, \
|
||||
#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; \
|
||||
#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, CMC_CALLBACKS_GET(l_)); \
|
||||
} \
|
||||
\
|
||||
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 */
|
||||
+28
-35
@@ -86,8 +86,7 @@
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE)(PARAMS)
|
||||
#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE) \
|
||||
CMC_##LIB##_##COLLECTION##_##PART##_##FILE
|
||||
#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE) CMC_##LIB##_##COLLECTION##_##PART##_##FILE
|
||||
|
||||
/**
|
||||
* C_MACRO_COLLECTIONS_GEN
|
||||
@@ -100,7 +99,7 @@
|
||||
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
|
||||
* \param PARTS A non-empty tuple of all desired EXT parts
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \
|
||||
#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \
|
||||
C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \
|
||||
C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS)
|
||||
|
||||
@@ -115,7 +114,7 @@
|
||||
* \param PARTS A non-empty tuple of all desired EXT parts
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \
|
||||
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, CMC_EVAL PARTS)
|
||||
|
||||
/**
|
||||
@@ -129,7 +128,7 @@
|
||||
* \param PARTS A non-empty tuple of all desired EXT parts
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \
|
||||
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, CMC_EVAL PARTS)
|
||||
|
||||
/**
|
||||
@@ -142,7 +141,7 @@
|
||||
* \param COLLECTION The name of the collection in all uppercase
|
||||
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \
|
||||
#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \
|
||||
C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \
|
||||
C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS)
|
||||
|
||||
@@ -156,9 +155,8 @@
|
||||
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \
|
||||
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, \
|
||||
C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \
|
||||
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
|
||||
|
||||
/**
|
||||
* C_MACRO_COLLECTIONS_ALL_SOURCE
|
||||
@@ -170,9 +168,8 @@
|
||||
* \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \
|
||||
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, \
|
||||
C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \
|
||||
CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
|
||||
|
||||
/**
|
||||
* C_MACRO_COLLECTIONS_PARTS
|
||||
@@ -180,8 +177,7 @@
|
||||
* Gets the macro with all EXT parts of a collection. Every collection has this
|
||||
* macro defined in the EXT libraries.
|
||||
*/
|
||||
#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \
|
||||
CMC_EXT_##LIB##_##COLLECTION##_PARTS,
|
||||
#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) CMC_EXT_##LIB##_##COLLECTION##_PARTS,
|
||||
|
||||
/* Evaluates a tuple so that (A, B) -> A, B, */
|
||||
#define CMC_EVAL(...) __VA_ARGS__,
|
||||
@@ -195,50 +191,47 @@
|
||||
*/
|
||||
#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N())
|
||||
#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__)
|
||||
#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
|
||||
_14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \
|
||||
_26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \
|
||||
_38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
|
||||
_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \
|
||||
_62, _63, N, ...) \
|
||||
#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, \
|
||||
_22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, \
|
||||
_42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \
|
||||
_62, _63, N, ...) \
|
||||
N
|
||||
#define CMC_SEQ_N() \
|
||||
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \
|
||||
45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \
|
||||
28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
|
||||
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
#define CMC_SEQ_N() \
|
||||
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, \
|
||||
35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, \
|
||||
7, 6, 5, 4, 3, 2, 1, 0
|
||||
|
||||
/* Generates the FILE for each part (__VA_ARGS__) of a collection */
|
||||
#define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \
|
||||
CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \
|
||||
CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \
|
||||
(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
|
||||
#define CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, PART, ...)
|
||||
#define CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
#define CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
|
||||
CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
|
||||
#define CMC_MAP_10(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
|
||||
|
||||
+2114
-2335
File diff suppressed because it is too large.
Load diff
+4
-6
@@ -22,14 +22,12 @@
|
||||
|
||||
#include "../cor/core.h"
|
||||
|
||||
#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \
|
||||
for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_start)(TARGET); \
|
||||
!CMC_(PFX, _iter_at_end)(&ITERNAME); \
|
||||
#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \
|
||||
for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_start)(TARGET); !CMC_(PFX, _iter_at_end)(&ITERNAME); \
|
||||
CMC_(PFX, _iter_next)(&ITERNAME))
|
||||
|
||||
#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \
|
||||
for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_end)(TARGET); \
|
||||
!CMC_(PFX, _iter_at_start)(&ITERNAME); \
|
||||
#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \
|
||||
for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_end)(TARGET); !CMC_(PFX, _iter_at_start)(&ITERNAME); \
|
||||
CMC_(PFX, _iter_prev)(&ITERNAME))
|
||||
|
||||
#endif /* CMC_UTL_FOREACH_H */
|
||||
+13
-24
@@ -66,12 +66,10 @@
|
||||
|
||||
#include "../cor/core.h"
|
||||
|
||||
static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO",
|
||||
"WARN", "ERROR", "FATAL" };
|
||||
static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" };
|
||||
|
||||
#ifdef CMC_LOG_COLOR
|
||||
static const char *cmc_log_color[] = { "\x1b[94m", "\x1b[36m", "\x1b[32m",
|
||||
"\x1b[33m", "\x1b[31m", "\x1b[35m" };
|
||||
static const char *cmc_log_color[] = { "\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m" };
|
||||
#endif
|
||||
|
||||
enum cmc_log_type
|
||||
@@ -95,21 +93,14 @@ static struct
|
||||
|
||||
} cmc_log_config = { 0, 0, true, true, true, NULL };
|
||||
|
||||
#define cmc_log_trace(fmt, ...) \
|
||||
cmc_log(CMC_LOG_TRACE, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_debug(fmt, ...) \
|
||||
cmc_log(CMC_LOG_DEBUG, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_info(fmt, ...) \
|
||||
cmc_log(CMC_LOG_INFO, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_warn(fmt, ...) \
|
||||
cmc_log(CMC_LOG_WARN, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_error(fmt, ...) \
|
||||
cmc_log(CMC_LOG_ERROR, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_fatal(fmt, ...) \
|
||||
cmc_log(CMC_LOG_FATAL, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_trace(fmt, ...) cmc_log(CMC_LOG_TRACE, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_debug(fmt, ...) cmc_log(CMC_LOG_DEBUG, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_info(fmt, ...) cmc_log(CMC_LOG_INFO, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_warn(fmt, ...) cmc_log(CMC_LOG_WARN, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_error(fmt, ...) cmc_log(CMC_LOG_ERROR, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define cmc_log_fatal(fmt, ...) cmc_log(CMC_LOG_FATAL, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
|
||||
CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename,
|
||||
const char *funcname, unsigned line,
|
||||
CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename, const char *funcname, unsigned line,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
if (!cmc_log_config.enabled)
|
||||
@@ -133,11 +124,10 @@ CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename,
|
||||
time[strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", lt)] = '\0';
|
||||
|
||||
#ifdef CMC_LOG_COLOR
|
||||
fprintf(stderr, "%s %s%5s\x1b[0m at\x1b[90m %s:%s:%u\x1b[0m | ", time,
|
||||
cmc_log_color[i], cmc_log_names[i], filename, funcname, line);
|
||||
#else
|
||||
fprintf(stderr, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i],
|
||||
fprintf(stderr, "%s %s%5s\x1b[0m at\x1b[90m %s:%s:%u\x1b[0m | ", time, cmc_log_color[i], cmc_log_names[i],
|
||||
filename, funcname, line);
|
||||
#else
|
||||
fprintf(stderr, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i], filename, funcname, line);
|
||||
#endif
|
||||
|
||||
va_list args;
|
||||
@@ -168,8 +158,7 @@ skip:
|
||||
char time[32];
|
||||
time[strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", lt)] = '\0';
|
||||
|
||||
fprintf(cmc_log_config.file, "%s %5s at %s:%s:%u | ", time,
|
||||
cmc_log_names[i], filename, funcname, line);
|
||||
fprintf(cmc_log_config.file, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i], filename, funcname, line);
|
||||
|
||||
va_list file_args;
|
||||
va_start(file_args, fmt);
|
||||
|
||||
+122
-133
@@ -66,9 +66,7 @@ static inline const char *cmc_test_color(int i)
|
||||
// 3 - Box (gray)
|
||||
// 4 - Name (cyan)
|
||||
// 5 - Total (yellow)
|
||||
static const char *cmc_test_colors[] = {
|
||||
"\x1b[0m", "\x1b[31m", "\x1b[32m", "\x1b[90m", "\x1b[36m", "\x1b[33m"
|
||||
};
|
||||
static const char *cmc_test_colors[] = { "\x1b[0m", "\x1b[31m", "\x1b[32m", "\x1b[90m", "\x1b[36m", "\x1b[33m" };
|
||||
return cmc_test_colors[i];
|
||||
#else
|
||||
static inline const char *cmc_test_color(int i)
|
||||
@@ -79,9 +77,7 @@ static inline const char *cmc_test_color(int i)
|
||||
}
|
||||
|
||||
/* Logging function */
|
||||
CMC_UNUSED static void cmc_test_log(const char *unit_name,
|
||||
const char *current_test, bool aborted,
|
||||
bool passed)
|
||||
CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_test, bool aborted, bool passed)
|
||||
{
|
||||
if (aborted)
|
||||
{
|
||||
@@ -110,139 +106,132 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name,
|
||||
}
|
||||
}
|
||||
|
||||
#define CMC_CREATE_UNIT(UNAME, VERBOSE, BODY) \
|
||||
uintmax_t UNAME(void) \
|
||||
{ \
|
||||
const char *unit_name = #UNAME; \
|
||||
const char *current_test = NULL; \
|
||||
\
|
||||
struct cmc_test_info tinfo = { 0 }; \
|
||||
struct cmc_timer timer = { 0 }; \
|
||||
\
|
||||
tinfo.verbose = VERBOSE; \
|
||||
tinfo.assert_total = cmc_assert_total; \
|
||||
tinfo.assert_failed = cmc_assert_failed; \
|
||||
\
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf( \
|
||||
" +---------------------------------------------------------------+\n"); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Unit "); \
|
||||
printf("%s", cmc_test_color(4)); \
|
||||
printf("%-56s", unit_name); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf( \
|
||||
" |\n +---------------------------------------------------------------+"); \
|
||||
printf("%s\n", cmc_test_color(0)); \
|
||||
\
|
||||
/* Tests */ \
|
||||
cmc_timer_start(timer); \
|
||||
\
|
||||
BODY; \
|
||||
\
|
||||
cmc_timer_stop(timer); \
|
||||
\
|
||||
unittest_abort: \
|
||||
if (tinfo.aborted) \
|
||||
{ \
|
||||
cmc_test_log(unit_name, current_test, true, false); \
|
||||
} \
|
||||
\
|
||||
tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \
|
||||
tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \
|
||||
\
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf( \
|
||||
" +---------------------------------------------------------------+\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Summary : "); \
|
||||
printf("%s", cmc_test_color(4)); \
|
||||
printf("%-52s", unit_name); \
|
||||
printf("%s|\n", cmc_test_color(3)); \
|
||||
printf( \
|
||||
" +---------++----------------+-----------------+-----------------+\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Tests "); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf("||"); \
|
||||
printf("%s", cmc_test_color(5)); \
|
||||
printf(" Total %8" PRIuMAX "", tinfo.total); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(2)); \
|
||||
printf("Passed %8" PRIuMAX "", tinfo.passed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(1)); \
|
||||
printf("Failed %8" PRIuMAX "", tinfo.failed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" |\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Asserts "); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf("||"); \
|
||||
printf("%s", cmc_test_color(5)); \
|
||||
printf(" Total %8" PRIuMAX "", tinfo.assert_total); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(2)); \
|
||||
printf("Passed %8" PRIuMAX "", \
|
||||
tinfo.assert_total - tinfo.assert_failed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(1)); \
|
||||
printf("Failed %8" PRIuMAX "", tinfo.assert_failed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" |\n"); \
|
||||
printf( \
|
||||
" +---------++----------------+-----------------+-----------------+\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Total Runtime : %32.0f milliseconds", timer.result); \
|
||||
printf(" %s|\n", cmc_test_color(3)); \
|
||||
printf( \
|
||||
" +---------------------------------------------------------------+\n"); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("\n"); \
|
||||
\
|
||||
return tinfo.failed; \
|
||||
#define CMC_CREATE_UNIT(UNAME, VERBOSE, BODY) \
|
||||
uintmax_t UNAME(void) \
|
||||
{ \
|
||||
const char *unit_name = #UNAME; \
|
||||
const char *current_test = NULL; \
|
||||
\
|
||||
struct cmc_test_info tinfo = { 0 }; \
|
||||
struct cmc_timer timer = { 0 }; \
|
||||
\
|
||||
tinfo.verbose = VERBOSE; \
|
||||
tinfo.assert_total = cmc_assert_total; \
|
||||
tinfo.assert_failed = cmc_assert_failed; \
|
||||
\
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" +---------------------------------------------------------------+\n"); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Unit "); \
|
||||
printf("%s", cmc_test_color(4)); \
|
||||
printf("%-56s", unit_name); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" |\n +---------------------------------------------------------------+"); \
|
||||
printf("%s\n", cmc_test_color(0)); \
|
||||
\
|
||||
/* Tests */ \
|
||||
cmc_timer_start(timer); \
|
||||
\
|
||||
BODY; \
|
||||
\
|
||||
cmc_timer_stop(timer); \
|
||||
\
|
||||
unittest_abort: \
|
||||
if (tinfo.aborted) \
|
||||
{ \
|
||||
cmc_test_log(unit_name, current_test, true, false); \
|
||||
} \
|
||||
\
|
||||
tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \
|
||||
tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \
|
||||
\
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" +---------------------------------------------------------------+\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Summary : "); \
|
||||
printf("%s", cmc_test_color(4)); \
|
||||
printf("%-52s", unit_name); \
|
||||
printf("%s|\n", cmc_test_color(3)); \
|
||||
printf(" +---------++----------------+-----------------+-----------------+\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Tests "); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf("||"); \
|
||||
printf("%s", cmc_test_color(5)); \
|
||||
printf(" Total %8" PRIuMAX "", tinfo.total); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(2)); \
|
||||
printf("Passed %8" PRIuMAX "", tinfo.passed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(1)); \
|
||||
printf("Failed %8" PRIuMAX "", tinfo.failed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" |\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Asserts "); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf("||"); \
|
||||
printf("%s", cmc_test_color(5)); \
|
||||
printf(" Total %8" PRIuMAX "", tinfo.assert_total); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(2)); \
|
||||
printf("Passed %8" PRIuMAX "", tinfo.assert_total - tinfo.assert_failed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" | "); \
|
||||
printf("%s", cmc_test_color(1)); \
|
||||
printf("Failed %8" PRIuMAX "", tinfo.assert_failed); \
|
||||
printf("%s", cmc_test_color(3)); \
|
||||
printf(" |\n"); \
|
||||
printf(" +---------++----------------+-----------------+-----------------+\n | "); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("Total Runtime : %32.0f milliseconds", timer.result); \
|
||||
printf(" %s|\n", cmc_test_color(3)); \
|
||||
printf(" +---------------------------------------------------------------+\n"); \
|
||||
printf("%s", cmc_test_color(0)); \
|
||||
printf("\n"); \
|
||||
\
|
||||
return tinfo.failed; \
|
||||
}
|
||||
|
||||
#define CMC_CREATE_TEST(TNAME, BODY) \
|
||||
do \
|
||||
{ \
|
||||
current_test = #TNAME; \
|
||||
\
|
||||
tinfo.total += 1; \
|
||||
\
|
||||
/* Provided by assert.h */ \
|
||||
cmc_assert_state = true; \
|
||||
\
|
||||
BODY; \
|
||||
\
|
||||
if (tinfo.verbose) \
|
||||
{ \
|
||||
if (!cmc_assert_state) \
|
||||
{ \
|
||||
tinfo.failed += 1; \
|
||||
#define CMC_CREATE_TEST(TNAME, BODY) \
|
||||
do \
|
||||
{ \
|
||||
current_test = #TNAME; \
|
||||
\
|
||||
tinfo.total += 1; \
|
||||
\
|
||||
/* Provided by assert.h */ \
|
||||
cmc_assert_state = true; \
|
||||
\
|
||||
BODY; \
|
||||
\
|
||||
if (tinfo.verbose) \
|
||||
{ \
|
||||
if (!cmc_assert_state) \
|
||||
{ \
|
||||
tinfo.failed += 1; \
|
||||
cmc_test_log(unit_name, current_test, false, false); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
tinfo.passed += 1; \
|
||||
cmc_test_log(unit_name, current_test, false, true); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
tinfo.passed += 1; \
|
||||
cmc_test_log(unit_name, current_test, false, true); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define CMC_TEST_ABORT() \
|
||||
do \
|
||||
{ \
|
||||
#define CMC_TEST_ABORT() \
|
||||
do \
|
||||
{ \
|
||||
tinfo.aborted = true; \
|
||||
tinfo.total -= 1; \
|
||||
goto unittest_abort; \
|
||||
\
|
||||
tinfo.total -= 1; \
|
||||
goto unittest_abort; \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#endif /* CMC_UTL_TEST_H */
|
||||
+1
-2
@@ -88,8 +88,7 @@ static void *cmc_thread_wrapper(void *arg)
|
||||
* \param args The arguments passed to the proc function.
|
||||
* \return True or false if the thread creation was successfull.
|
||||
*/
|
||||
static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc,
|
||||
void *args)
|
||||
static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc, void *args)
|
||||
{
|
||||
#if defined(CMC_THREAD_WINDOWS)
|
||||
thr->args = args;
|
||||
|
||||
+10
-11
@@ -24,20 +24,19 @@ struct cmc_timer
|
||||
double result; /* The result is given in milliseconds */
|
||||
};
|
||||
|
||||
#define cmc_timer_start(timer) \
|
||||
do \
|
||||
{ \
|
||||
#define cmc_timer_start(timer) \
|
||||
do \
|
||||
{ \
|
||||
struct cmc_timer *t__ = &(timer); \
|
||||
t__->start = clock(); \
|
||||
t__->start = clock(); \
|
||||
} while (0)
|
||||
|
||||
#define cmc_timer_stop(timer) \
|
||||
do \
|
||||
{ \
|
||||
struct cmc_timer *t__ = &(timer); \
|
||||
t__->stop = clock(); \
|
||||
t__->result = \
|
||||
(double)(t__->stop - t__->start) * 1000.0 / CLOCKS_PER_SEC; \
|
||||
#define cmc_timer_stop(timer) \
|
||||
do \
|
||||
{ \
|
||||
struct cmc_timer *t__ = &(timer); \
|
||||
t__->stop = clock(); \
|
||||
t__->result = (double)(t__->stop - t__->start) * 1000.0 / CLOCKS_PER_SEC; \
|
||||
} while (0)
|
||||
|
||||
#endif /* CMC_UTL_TIMER_H */
|
||||
Reference in new issue
Block a user