removed linkedqueue and now _free and _clear have a deallocator parameter
This commit is contained in:
1 parent
613392ae76
commit
8ec768d30e
20 files changed
+1891
-2054
No files matched your search
+378
-362
@@ -99,8 +99,8 @@
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_deque_); \
|
||||
FMOD void PFX##_free(SNAME *_deque_); \
|
||||
FMOD void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push_front(SNAME *_deque_, V element); \
|
||||
FMOD bool PFX##_push_back(SNAME *_deque_, V element); \
|
||||
@@ -153,366 +153,382 @@
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_deque_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_deque_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_deque_) \
|
||||
return NULL; \
|
||||
\
|
||||
_deque_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_deque_->buffer) \
|
||||
{ \
|
||||
free(_deque_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_deque_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_deque_->capacity = capacity; \
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
\
|
||||
_deque_->it_start = PFX##_impl_it_start; \
|
||||
_deque_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_deque_) \
|
||||
{ \
|
||||
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
|
||||
\
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_deque_) \
|
||||
{ \
|
||||
free(_deque_->buffer); \
|
||||
free(_deque_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = element; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = element; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_deque_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_front(_deque_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_back(_deque_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_front(_deque_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_back(_deque_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \
|
||||
{ \
|
||||
if (comparator(_deque_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_deque_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *d_ = _deque_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, \
|
||||
name, d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
iter->cursor = 0; \
|
||||
else \
|
||||
iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \
|
||||
\
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == iter->target->count - 1) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_deque_) \
|
||||
{ \
|
||||
size_t new_capacity = _deque_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = malloc(sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
new_buffer[j] = _deque_->buffer[i]; \
|
||||
} \
|
||||
\
|
||||
free(_deque_->buffer); \
|
||||
\
|
||||
_deque_->buffer = new_buffer; \
|
||||
_deque_->capacity = new_capacity; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = _deque_->count; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _deque_); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _deque_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_deque_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_deque_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_deque_) \
|
||||
return NULL; \
|
||||
\
|
||||
_deque_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_deque_->buffer) \
|
||||
{ \
|
||||
free(_deque_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_deque_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_deque_->capacity = capacity; \
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
\
|
||||
_deque_->it_start = PFX##_impl_it_start; \
|
||||
_deque_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_deque_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
|
||||
\
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_deque_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_deque_->buffer); \
|
||||
free(_deque_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = element; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = element; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_deque_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_front(_deque_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_back(_deque_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_front(_deque_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_back(_deque_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \
|
||||
{ \
|
||||
if (comparator(_deque_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_deque_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *d_ = _deque_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, \
|
||||
name, d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
iter->cursor = 0; \
|
||||
else \
|
||||
iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \
|
||||
\
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == iter->target->count - 1) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_deque_) \
|
||||
{ \
|
||||
size_t new_capacity = _deque_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = malloc(sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
new_buffer[j] = _deque_->buffer[i]; \
|
||||
} \
|
||||
\
|
||||
free(_deque_->buffer); \
|
||||
\
|
||||
_deque_->buffer = new_buffer; \
|
||||
_deque_->capacity = new_capacity; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = _deque_->count; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _deque_); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _deque_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
}
|
||||
|
||||
#endif /* CMC_DEQUE_H */
|
||||
+32
-6
@@ -157,8 +157,8 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(K, K), size_t (*hash)(K)); \
|
||||
FMOD void PFX##_clear(SNAME *_map_); \
|
||||
FMOD void PFX##_free(SNAME *_map_); \
|
||||
FMOD void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
FMOD void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_map_, K key, V value); \
|
||||
FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \
|
||||
@@ -268,15 +268,41 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _map_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_map_) \
|
||||
FMOD void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_map_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->key, entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_map_->buffer, 0, sizeof(SNAME##_entry) * _map_->capacity); \
|
||||
\
|
||||
_map_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_map_) \
|
||||
FMOD void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_map_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->key, entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_map_->buffer); \
|
||||
free(_map_); \
|
||||
} \
|
||||
@@ -696,7 +722,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
if (_map_->count != _new_map_->count) \
|
||||
{ \
|
||||
PFX##_free(_new_map_); \
|
||||
PFX##_free(_new_map_, NULL); \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
@@ -706,7 +732,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
_map_->capacity = _new_map_->capacity; \
|
||||
\
|
||||
PFX##_free(_new_map_); \
|
||||
PFX##_free(_new_map_, NULL); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
|
||||
+32
-6
@@ -152,8 +152,8 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)); \
|
||||
FMOD void PFX##_clear(SNAME *_set_); \
|
||||
FMOD void PFX##_free(SNAME *_set_); \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element); \
|
||||
@@ -258,15 +258,41 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_set_) \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_set_->buffer, 0, sizeof(SNAME##_entry) * _set_->capacity); \
|
||||
\
|
||||
_set_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_set_) \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_set_->buffer); \
|
||||
free(_set_); \
|
||||
} \
|
||||
@@ -800,7 +826,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
if (_set_->count != _new_set_->count) \
|
||||
{ \
|
||||
PFX##_free(_new_set_); \
|
||||
PFX##_free(_new_set_, NULL); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
@@ -811,7 +837,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
_set_->capacity = _new_set_->capacity; \
|
||||
\
|
||||
PFX##_free(_new_set_); \
|
||||
PFX##_free(_new_set_, NULL); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
|
||||
+20
-4
@@ -101,8 +101,8 @@ typedef enum cmc_heap_order_e
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_); \
|
||||
FMOD void PFX##_free(SNAME *_heap_); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_heap_, V *result); \
|
||||
@@ -193,15 +193,31 @@ typedef enum cmc_heap_order_e
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_heap_) \
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
deallocator(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \
|
||||
\
|
||||
_heap_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_heap_) \
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
deallocator(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_heap_->buffer); \
|
||||
free(_heap_); \
|
||||
} \
|
||||
|
||||
+12
-5
@@ -104,8 +104,8 @@
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(void); \
|
||||
FMOD void PFX##_clear(SNAME *_list_); \
|
||||
FMOD void PFX##_free(SNAME *_list_); \
|
||||
FMOD void PFX##_clear(SNAME *_list_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_list_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, V element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, V element, size_t index); \
|
||||
@@ -200,14 +200,21 @@
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_list_) \
|
||||
FMOD void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _list_->head; \
|
||||
\
|
||||
while (_list_->head != NULL) \
|
||||
{ \
|
||||
_list_->head = _list_->head->next; \
|
||||
\
|
||||
if (deallocator) \
|
||||
{ \
|
||||
deallocator(scan->data); \
|
||||
} \
|
||||
\
|
||||
free(scan); \
|
||||
\
|
||||
scan = _list_->head; \
|
||||
} \
|
||||
\
|
||||
@@ -216,9 +223,9 @@
|
||||
_list_->tail = NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_) \
|
||||
FMOD void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
PFX##_clear(_list_); \
|
||||
PFX##_clear(_list_, deallocator); \
|
||||
\
|
||||
free(_list_); \
|
||||
} \
|
||||
|
||||
+16
-4
@@ -103,8 +103,8 @@
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD SNAME *PFX##_new_from(V *elements, size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_list_); \
|
||||
FMOD void PFX##_free(SNAME *_list_); \
|
||||
FMOD void PFX##_clear(SNAME *_list_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_list_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, V element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, V element, size_t index); \
|
||||
@@ -220,15 +220,27 @@
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_list_) \
|
||||
FMOD void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
deallocator(_list_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
|
||||
\
|
||||
_list_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_) \
|
||||
FMOD void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
deallocator(_list_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
free(_list_->buffer); \
|
||||
free(_list_); \
|
||||
} \
|
||||
|
||||
+323
-307
@@ -111,8 +111,8 @@
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_queue_); \
|
||||
FMOD void PFX##_free(SNAME *_queue_); \
|
||||
FMOD void PFX##_clear(SNAME *_queue_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_queue_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element); \
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_); \
|
||||
@@ -160,311 +160,327 @@
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_queue_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_queue_) \
|
||||
return NULL; \
|
||||
\
|
||||
_queue_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_queue_->buffer) \
|
||||
{ \
|
||||
free(_queue_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_queue_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_queue_->capacity = capacity; \
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
\
|
||||
_queue_->it_start = PFX##_impl_it_start; \
|
||||
_queue_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _queue_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_queue_) \
|
||||
{ \
|
||||
memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
|
||||
\
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_queue_) \
|
||||
{ \
|
||||
free(_queue_->buffer); \
|
||||
free(_queue_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_queue_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_queue_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_queue_->buffer[_queue_->back] = element; \
|
||||
\
|
||||
_queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \
|
||||
_queue_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return false; \
|
||||
\
|
||||
_queue_->buffer[_queue_->front] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \
|
||||
_queue_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_enqueue(_queue_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_dequeue(_queue_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_peek(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _queue_->buffer[_queue_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \
|
||||
{ \
|
||||
if (comparator(_queue_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count >= _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_queue_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *q_ = _queue_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, \
|
||||
name, q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
iter->cursor = 0; \
|
||||
else \
|
||||
iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \
|
||||
\
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == iter->target->count - 1) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_queue_) \
|
||||
{ \
|
||||
\
|
||||
size_t new_capacity = _queue_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = malloc(sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
new_buffer[j] = _queue_->buffer[i]; \
|
||||
} \
|
||||
\
|
||||
free(_queue_->buffer); \
|
||||
\
|
||||
_queue_->buffer = new_buffer; \
|
||||
_queue_->capacity = new_capacity; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = _queue_->count; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _queue_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _queue_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
#define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_queue_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_queue_) \
|
||||
return NULL; \
|
||||
\
|
||||
_queue_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_queue_->buffer) \
|
||||
{ \
|
||||
free(_queue_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_queue_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_queue_->capacity = capacity; \
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
\
|
||||
_queue_->it_start = PFX##_impl_it_start; \
|
||||
_queue_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _queue_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_queue_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
|
||||
\
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_queue_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_queue_->buffer); \
|
||||
free(_queue_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_queue_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_queue_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_queue_->buffer[_queue_->back] = element; \
|
||||
\
|
||||
_queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \
|
||||
_queue_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return false; \
|
||||
\
|
||||
_queue_->buffer[_queue_->front] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \
|
||||
_queue_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_enqueue(_queue_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_dequeue(_queue_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_peek(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _queue_->buffer[_queue_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \
|
||||
{ \
|
||||
if (comparator(_queue_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count >= _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_queue_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *q_ = _queue_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, \
|
||||
name, q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
iter->cursor = 0; \
|
||||
else \
|
||||
iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \
|
||||
\
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == iter->target->count - 1) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->index == 0) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_queue_) \
|
||||
{ \
|
||||
\
|
||||
size_t new_capacity = _queue_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = malloc(sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
new_buffer[j] = _queue_->buffer[i]; \
|
||||
} \
|
||||
\
|
||||
free(_queue_->buffer); \
|
||||
\
|
||||
_queue_->buffer = new_buffer; \
|
||||
_queue_->capacity = new_capacity; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = _queue_->count; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _queue_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _queue_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
}
|
||||
|
||||
#endif /* CMC_QUEUE_H */
|
||||
+16
-4
@@ -87,8 +87,8 @@
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_stack_); \
|
||||
FMOD void PFX##_free(SNAME *_stack_); \
|
||||
FMOD void PFX##_clear(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element); \
|
||||
FMOD bool PFX##_pop(SNAME *_stack_); \
|
||||
@@ -172,16 +172,28 @@
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_stack_) \
|
||||
FMOD void PFX##_clear(SNAME *_stack_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
deallocator(_stack_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
|
||||
\
|
||||
_stack_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_stack_) \
|
||||
FMOD void PFX##_free(SNAME *_stack_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
free(_stack_->buffer); \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
deallocator(_stack_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
free(_stack_); \
|
||||
} \
|
||||
\
|
||||
|
||||
+894
-888
File diff suppressed because it is too large.
Load diff
+12
-6
@@ -107,8 +107,8 @@
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_set_); \
|
||||
FMOD void PFX##_free(SNAME *_set_); \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element); \
|
||||
@@ -123,7 +123,7 @@
|
||||
FMOD bool PFX##_empty(SNAME *_set_); \
|
||||
FMOD size_t PFX##_count(SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_map_); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_set_); \
|
||||
\
|
||||
/* Set Operations */ \
|
||||
FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \
|
||||
@@ -195,7 +195,7 @@
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_set_) \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
SNAME##_node *up = NULL; \
|
||||
@@ -223,12 +223,18 @@
|
||||
{ \
|
||||
if (up == NULL) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
deallocator(scan->value); \
|
||||
\
|
||||
free(scan); \
|
||||
scan = NULL; \
|
||||
} \
|
||||
\
|
||||
while (up != NULL) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
deallocator(scan->value); \
|
||||
\
|
||||
free(scan); \
|
||||
\
|
||||
if (up->right != NULL) \
|
||||
@@ -250,9 +256,9 @@
|
||||
_set_->root = NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_set_) \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
PFX##_clear(_set_); \
|
||||
PFX##_clear(_set_, deallocator); \
|
||||
\
|
||||
free(_set_); \
|
||||
} \
|
||||
|
||||
+20
-4
@@ -95,8 +95,8 @@
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_); \
|
||||
FMOD void PFX##_free(SNAME *_heap_); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_remove_max(SNAME *_heap_, V *result); \
|
||||
@@ -192,16 +192,32 @@
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_heap_) \
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
deallocator(_heap_->buffer[i / 2].data[i % 2]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \
|
||||
\
|
||||
_heap_->size = 0; \
|
||||
_heap_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_heap_) \
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
deallocator(_heap_->buffer[i / 2].data[i % 2]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_heap_->buffer); \
|
||||
\
|
||||
free(_heap_); \
|
||||
|
||||
@@ -1,384 +0,0 @@
|
||||
/**
|
||||
* linkedqueue.h
|
||||
*
|
||||
* Creation Date: 21/06/2019
|
||||
*
|
||||
* Authors:
|
||||
* Leonardo Vencovsky (https://github.com/LeoVen)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A node-based Queue using a Singly Linked List
|
||||
*
|
||||
* enqueue : is equivalent to a push_back from a LinkedList
|
||||
* dequeue : is equivalent to a pop_front from a LinkedList
|
||||
*
|
||||
* This Queue has a one-way iterator
|
||||
*/
|
||||
|
||||
#ifndef CMC_LINKEDQUEUE_H
|
||||
#define CMC_LINKEDQUEUE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LINKEDQUEUE_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
LINKEDQUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
LINKEDQUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
|
||||
#define LINKEDQUEUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
LINKEDQUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
|
||||
#define LINKEDQUEUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
LINKEDQUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define LINKEDQUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Linked Queue Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* First node in the list */ \
|
||||
struct SNAME##_node_s *head; \
|
||||
\
|
||||
/* Last node in the list */ \
|
||||
struct SNAME##_node_s *tail; \
|
||||
\
|
||||
/* Current amount of elements in the list */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Singly-linked list node */ \
|
||||
typedef struct SNAME##_node_s \
|
||||
{ \
|
||||
/* Node's data */ \
|
||||
V data; \
|
||||
\
|
||||
/* Pointer to the next node on the linked list */ \
|
||||
struct SNAME##_node_s *next; \
|
||||
\
|
||||
} SNAME##_node, *SNAME##_node_ptr; \
|
||||
\
|
||||
/* Linked Queue Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target Linked Queue */ \
|
||||
struct SNAME##_s *target; \
|
||||
\
|
||||
/* Cursor's current node */ \
|
||||
struct SNAME##_node_s *cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* If the iterator is at the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(void); \
|
||||
FMOD void PFX##_clear(SNAME *_lqueue_); \
|
||||
FMOD void PFX##_free(SNAME *_lqueue_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_enqueue(SNAME *_lqueue_, V element); \
|
||||
FMOD bool PFX##_dequeue(SNAME *_lqueue_); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_lqueue_, V element, bool condition); \
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_lqueue_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_lqueue_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_lqueue_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_lqueue_); \
|
||||
FMOD size_t PFX##_count(SNAME *_lqueue_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define LINKEDQUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
FMOD SNAME##_node *PFX##_impl_new_node(V element); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_lqueue_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(void) \
|
||||
{ \
|
||||
SNAME *_lqueue_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_lqueue_) \
|
||||
return NULL; \
|
||||
\
|
||||
_lqueue_->count = 0; \
|
||||
_lqueue_->head = NULL; \
|
||||
_lqueue_->tail = NULL; \
|
||||
\
|
||||
_lqueue_->it_start = PFX##_impl_it_start; \
|
||||
\
|
||||
return _lqueue_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_lqueue_) \
|
||||
{ \
|
||||
SNAME##_node *scan = _lqueue_->head; \
|
||||
\
|
||||
while (_lqueue_->head != NULL) \
|
||||
{ \
|
||||
_lqueue_->head = _lqueue_->head->next; \
|
||||
free(scan); \
|
||||
scan = _lqueue_->head; \
|
||||
} \
|
||||
\
|
||||
_lqueue_->count = 0; \
|
||||
_lqueue_->head = NULL; \
|
||||
_lqueue_->tail = NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_lqueue_) \
|
||||
{ \
|
||||
PFX##_clear(_lqueue_); \
|
||||
\
|
||||
free(_lqueue_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue(SNAME *_lqueue_, V element) \
|
||||
{ \
|
||||
SNAME##_node *_node_ = PFX##_impl_new_node(element); \
|
||||
\
|
||||
if (!_node_) \
|
||||
return false; \
|
||||
\
|
||||
if (PFX##_empty(_lqueue_)) \
|
||||
{ \
|
||||
_lqueue_->head = _node_; \
|
||||
_lqueue_->tail = _node_; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_lqueue_->tail->next = _node_; \
|
||||
_lqueue_->tail = _node_; \
|
||||
} \
|
||||
\
|
||||
_lqueue_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue(SNAME *_lqueue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_lqueue_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *_node_ = _lqueue_->head; \
|
||||
_lqueue_->head = _lqueue_->head->next; \
|
||||
\
|
||||
free(_node_); \
|
||||
\
|
||||
if (_lqueue_->head == NULL) \
|
||||
_lqueue_->tail = NULL; \
|
||||
\
|
||||
_lqueue_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_lqueue_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_enqueue(_lqueue_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_lqueue_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_dequeue(_lqueue_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_peek(SNAME *_lqueue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_lqueue_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _lqueue_->head->data; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_lqueue_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _lqueue_->head; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (comparator(scan->data, element) == 0) \
|
||||
return true; \
|
||||
\
|
||||
scan = scan->next; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_lqueue_) \
|
||||
{ \
|
||||
return _lqueue_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_lqueue_) \
|
||||
{ \
|
||||
return _lqueue_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->head; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->head; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->tail; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->cursor->next == NULL) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = iter->cursor->next; \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->cursor->data; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->cursor->data); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_impl_new_node(V element) \
|
||||
{ \
|
||||
SNAME##_node *_node_ = malloc(sizeof(SNAME##_node)); \
|
||||
\
|
||||
if (!_node_) \
|
||||
return NULL; \
|
||||
\
|
||||
_node_->data = element; \
|
||||
_node_->next = NULL; \
|
||||
\
|
||||
return _node_; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_lqueue_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _lqueue_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
}
|
||||
|
||||
#endif /* CMC_LINKEDQUEUE_H */
|
||||
+46
-15
@@ -175,24 +175,25 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(K, K), size_t (*hash)(K)); \
|
||||
FMOD void PFX##_clear(SNAME *_map_); \
|
||||
FMOD void PFX##_free(SNAME *_map_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
FMOD void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
/* Create */ \
|
||||
FMOD bool PFX##_insert(SNAME *_map_, K key, V value); \
|
||||
FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \
|
||||
FMOD size_t PFX##_update_all(SNAME *_map_, K key, V new_value, V **old_values); \
|
||||
FMOD bool PFX##_remove(SNAME *_map_, K key, V *value); \
|
||||
FMOD size_t PFX##_remove_all(SNAME *_map_, K key); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_map_, K key, V *value, bool condition); \
|
||||
/* Element Access */ \
|
||||
/* Read */ \
|
||||
FMOD bool PFX##_max(SNAME *_map_, K *key, V *value); \
|
||||
FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \
|
||||
FMOD V PFX##_get(SNAME *_map_, K key); \
|
||||
FMOD V *PFX##_get_ref(SNAME *_map_, K key); \
|
||||
/* Update */ \
|
||||
FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \
|
||||
FMOD size_t PFX##_update_all(SNAME *_map_, K key, V new_value, V **old_values); \
|
||||
FMOD bool PFX##_set(SNAME *_map_, K key, V new_value); \
|
||||
FMOD size_t PFX##_set_all(SNAME *_map_, K key, V new_value); \
|
||||
/* Delete */ \
|
||||
FMOD bool PFX##_remove(SNAME *_map_, K key, V *value); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_map_, K key, V *value, bool condition); \
|
||||
FMOD size_t PFX##_remove_all(SNAME *_map_, K key); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_map_, K key); \
|
||||
FMOD bool PFX##_empty(SNAME *_map_); \
|
||||
@@ -286,7 +287,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _map_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_map_) \
|
||||
FMOD void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
{ \
|
||||
size_t index = 0; \
|
||||
SNAME##_entry *scan; \
|
||||
@@ -307,6 +308,8 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
scan = scan->next; \
|
||||
\
|
||||
deallocator(tmp->key, tmp->scan); \
|
||||
\
|
||||
free(tmp); \
|
||||
} \
|
||||
} \
|
||||
@@ -320,9 +323,37 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
_map_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_map_) \
|
||||
FMOD void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
{ \
|
||||
PFX##_clear(_map_); \
|
||||
size_t index = 0; \
|
||||
SNAME##_entry *scan; \
|
||||
\
|
||||
while (index < _map_->capacity) \
|
||||
{ \
|
||||
scan = _map_->buffer[index][0]; \
|
||||
\
|
||||
if (scan != NULL) \
|
||||
{ \
|
||||
if (scan->next == NULL && scan->prev == NULL) \
|
||||
free(scan); \
|
||||
else \
|
||||
{ \
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
SNAME##_entry *tmp = scan; \
|
||||
\
|
||||
scan = scan->next; \
|
||||
\
|
||||
deallocator(tmp->key, tmp->scan); \
|
||||
\
|
||||
free(tmp); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
index++; \
|
||||
} \
|
||||
\
|
||||
free(_map_->buffer); \
|
||||
free(_map_); \
|
||||
} \
|
||||
@@ -888,7 +919,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
if (_map_->count != _new_map_->count) \
|
||||
{ \
|
||||
PFX##_free(_new_map_); \
|
||||
PFX##_free(_new_map_, NULL); \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
@@ -900,7 +931,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
_map_->capacity = _new_map_->capacity; \
|
||||
_new_map_->capacity = tmp_c; \
|
||||
\
|
||||
PFX##_free(_new_map_); \
|
||||
PFX##_free(_new_map_, NULL); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
|
||||
+32
-6
@@ -161,8 +161,8 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)); \
|
||||
FMOD void PFX##_clear(SNAME *_set_); \
|
||||
FMOD void PFX##_free(SNAME *_set_); \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_insert_many(SNAME *_set_, V element, size_t count); \
|
||||
@@ -276,15 +276,41 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_set_) \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_set_->buffer, 0, sizeof(SNAME##_entry) * _set_->capacity); \
|
||||
\
|
||||
_set_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_set_) \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_set_->buffer); \
|
||||
free(_set_); \
|
||||
} \
|
||||
@@ -988,7 +1014,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
if (_set_->count != _new_set_->count) \
|
||||
{ \
|
||||
PFX##_free(_new_set_); \
|
||||
PFX##_free(_new_set_, NULL); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
@@ -999,7 +1025,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
_set_->capacity = _new_set_->capacity; \
|
||||
\
|
||||
PFX##_free(_new_set_); \
|
||||
PFX##_free(_new_set_, NULL); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "cmc/treeset.h"
|
||||
|
||||
#include "ext/intervalheap.h"
|
||||
#include "ext/linkedqueue.h"
|
||||
#include "ext/multimap.h"
|
||||
#include "ext/multiset.h"
|
||||
|
||||
|
||||
+16
-10
@@ -3,15 +3,21 @@ CFLAGS = -std=c11 -Wall -Wextra
|
||||
CFLAGS += -Wno-unused-function -Wno-unused-paramter -Wno-unused-variable -Wno-unused-label
|
||||
|
||||
main:
|
||||
$(CC) foreach.c -o foreach $(CFLAGS)
|
||||
./foreach
|
||||
$(CC) iterators.c -o iterators $(CFLAGS)
|
||||
./iterators
|
||||
$(CC) contains.c -o contains $(CFLAGS)
|
||||
./contains
|
||||
$(CC) types.c -o types $(CFLAGS)
|
||||
./types
|
||||
$(CC) foreach.c -o foreach.exe $(CFLAGS)
|
||||
./foreach.exe
|
||||
$(CC) iterators.c -o iterators.exe $(CFLAGS)
|
||||
./iterators.exe
|
||||
$(CC) contains.c -o contains.exe $(CFLAGS)
|
||||
./contains.exe
|
||||
$(CC) types.c -o types.exe $(CFLAGS)
|
||||
./types.exe
|
||||
$(CC) -c ./sep/sep.c -o ./sep/sep.o $(CFLAGS)
|
||||
$(CC) -c ./sep/main.c -o ./sep/main.o $(CFLAGS)
|
||||
$(CC) ./sep/sep.o ./sep/main.o -o ./sep/sep
|
||||
./sep/sep
|
||||
$(CC) ./sep/sep.o ./sep/main.o -o ./sep/sep.exe
|
||||
./sep/sep.exe
|
||||
|
||||
dev: main
|
||||
rm *.exe ./sep/*.o ./sep/*.exe
|
||||
|
||||
windev: main
|
||||
del *.exe .\\sep\\*.o .\\sep\\*.exe
|
||||
+20
-20
@@ -125,16 +125,16 @@ int main(void)
|
||||
a[9] = a[9] || ts_contains(ts, i);
|
||||
}
|
||||
|
||||
d_clear(d);
|
||||
hm_clear(hm);
|
||||
hs_clear(hs);
|
||||
h_clear(h);
|
||||
ll_clear(ll);
|
||||
l_clear(l);
|
||||
q_clear(q);
|
||||
s_clear(s);
|
||||
tm_clear(tm);
|
||||
ts_clear(ts);
|
||||
d_clear(d, NULL);
|
||||
hm_clear(hm, NULL);
|
||||
hs_clear(hs, NULL);
|
||||
h_clear(h, NULL);
|
||||
ll_clear(ll, NULL);
|
||||
l_clear(l, NULL);
|
||||
q_clear(q, NULL);
|
||||
s_clear(s, NULL);
|
||||
tm_clear(tm, NULL);
|
||||
ts_clear(ts, NULL);
|
||||
|
||||
b[0] = b[0] || d_contains(d, 1, intcmp);
|
||||
b[1] = b[1] || hm_contains(hm, 1);
|
||||
@@ -189,16 +189,16 @@ int main(void)
|
||||
else
|
||||
printf("%10s FAILED\n", "TREESET");
|
||||
|
||||
l_free(l);
|
||||
ll_free(ll);
|
||||
s_free(s);
|
||||
q_free(q);
|
||||
d_free(d);
|
||||
h_free(h);
|
||||
ts_free(ts);
|
||||
tm_free(tm);
|
||||
hs_free(hs);
|
||||
hm_free(hm);
|
||||
l_free(l, NULL);
|
||||
ll_free(ll, NULL);
|
||||
s_free(s, NULL);
|
||||
q_free(q, NULL);
|
||||
d_free(d, NULL);
|
||||
h_free(h, NULL);
|
||||
ts_free(ts, NULL);
|
||||
tm_free(tm, NULL);
|
||||
hs_free(hs, NULL);
|
||||
hm_free(hm, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+10
-10
@@ -243,16 +243,16 @@ int main(void)
|
||||
else
|
||||
printf("%10s FAILED\n", "TREESET");
|
||||
|
||||
l_free(l);
|
||||
ll_free(ll);
|
||||
s_free(s);
|
||||
q_free(q);
|
||||
d_free(d);
|
||||
h_free(h);
|
||||
ts_free(ts);
|
||||
tm_free(tm);
|
||||
hs_free(hs);
|
||||
hm_free(hm);
|
||||
l_free(l, NULL);
|
||||
ll_free(ll, NULL);
|
||||
s_free(s, NULL);
|
||||
q_free(q, NULL);
|
||||
d_free(d, NULL);
|
||||
h_free(h, NULL);
|
||||
ts_free(ts, NULL);
|
||||
tm_free(tm, NULL);
|
||||
hs_free(hs, NULL);
|
||||
hm_free(hm, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+1
-1
@@ -69,7 +69,7 @@ COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, double)
|
||||
sumbody; \
|
||||
} \
|
||||
\
|
||||
PFX##_free(coll); \
|
||||
PFX##_free(coll, NULL); \
|
||||
\
|
||||
if (validation1 && validation2) \
|
||||
printf("%10s PASSED\n", #NAME); \
|
||||
|
||||
+11
-11
@@ -35,16 +35,16 @@ int main(void)
|
||||
printf("| Separate Header and Source is Working |\n");
|
||||
printf("+--------------------------------------------------+\n");
|
||||
|
||||
l_free(l);
|
||||
ll_free(ll);
|
||||
s_free(s);
|
||||
q_free(q);
|
||||
d_free(d);
|
||||
h_free(h);
|
||||
ts_free(ts);
|
||||
tm_free(tm);
|
||||
hs_free(hs);
|
||||
hm_free(hm);
|
||||
l_free(l, NULL);
|
||||
ll_free(ll, NULL);
|
||||
s_free(s, NULL);
|
||||
q_free(q, NULL);
|
||||
d_free(d, NULL);
|
||||
h_free(h, NULL);
|
||||
ts_free(ts, NULL);
|
||||
tm_free(tm, NULL);
|
||||
hs_free(hs, NULL);
|
||||
hm_free(hm, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user