Completely removed typedefs
This commit is contained in:
1 parent
db61269d42
commit
33c33e8947
55 files changed
+8637
-8651
No files matched your search
+908
-905
File diff suppressed because it is too large.
Load diff
+137
-139
@@ -52,114 +52,112 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Deque Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* 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; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the deque */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the deque */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Deque Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target deque */ \
|
||||
struct SNAME##_s *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; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(size_t capacity); \
|
||||
void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_push_front(SNAME *_deque_, V element); \
|
||||
bool PFX##_push_back(SNAME *_deque_, V element); \
|
||||
bool PFX##_pop_front(SNAME *_deque_); \
|
||||
bool PFX##_pop_back(SNAME *_deque_); \
|
||||
/* Element Access */ \
|
||||
V PFX##_front(SNAME *_deque_); \
|
||||
V PFX##_back(SNAME *_deque_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_deque_); \
|
||||
bool PFX##_full(SNAME *_deque_); \
|
||||
size_t PFX##_count(SNAME *_deque_); \
|
||||
size_t PFX##_capacity(SNAME *_deque_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(SNAME *_deque_, size_t capacity); \
|
||||
SNAME *PFX##_copy_of(SNAME *_deque_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_deque1_, SNAME *_deque2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_deque_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
#define CMC_GENERATE_DEQUE_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; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the deque */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the deque */ \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
/* Deque Iterator */ \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
/* 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; \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *PFX##_new(size_t capacity); \
|
||||
void PFX##_clear(struct SNAME *_deque_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_deque_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_push_front(struct SNAME *_deque_, V element); \
|
||||
bool PFX##_push_back(struct SNAME *_deque_, V element); \
|
||||
bool PFX##_pop_front(struct SNAME *_deque_); \
|
||||
bool PFX##_pop_back(struct SNAME *_deque_); \
|
||||
/* Element Access */ \
|
||||
V PFX##_front(struct SNAME *_deque_); \
|
||||
V PFX##_back(struct SNAME *_deque_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(struct SNAME *_deque_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(struct SNAME *_deque_); \
|
||||
bool PFX##_full(struct SNAME *_deque_); \
|
||||
size_t PFX##_count(struct SNAME *_deque_); \
|
||||
size_t PFX##_capacity(struct SNAME *_deque_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(struct SNAME *_deque_, size_t capacity); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_deque_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_deque1_, struct SNAME *_deque2_, int (*comparator)(V, V)); \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_deque_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_deque_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_deque_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
struct SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_deque_ = malloc(sizeof(SNAME)); \
|
||||
struct SNAME *_deque_ = malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_deque_) \
|
||||
return NULL; \
|
||||
@@ -183,7 +181,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -202,7 +200,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
_deque_->back = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -218,7 +216,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
free(_deque_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_front(SNAME *_deque_, V element) \
|
||||
bool PFX##_push_front(struct SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
@@ -235,7 +233,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_back(SNAME *_deque_, V element) \
|
||||
bool PFX##_push_back(struct SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
@@ -252,7 +250,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_front(SNAME *_deque_) \
|
||||
bool PFX##_pop_front(struct SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
@@ -266,7 +264,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_back(SNAME *_deque_) \
|
||||
bool PFX##_pop_back(struct SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
@@ -280,7 +278,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_front(SNAME *_deque_) \
|
||||
V PFX##_front(struct SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return (V){0}; \
|
||||
@@ -288,7 +286,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
V PFX##_back(SNAME *_deque_) \
|
||||
V PFX##_back(struct SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return (V){0}; \
|
||||
@@ -296,7 +294,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(struct SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
|
||||
{ \
|
||||
@@ -309,27 +307,27 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_deque_) \
|
||||
bool PFX##_empty(struct SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_deque_) \
|
||||
bool PFX##_full(struct SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_deque_) \
|
||||
size_t PFX##_count(struct SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_deque_) \
|
||||
size_t PFX##_capacity(struct SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(SNAME *_deque_, size_t capacity) \
|
||||
bool PFX##_resize(struct SNAME *_deque_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_deque_) == capacity) \
|
||||
return true; \
|
||||
@@ -359,9 +357,9 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_deque_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_deque_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_deque_->capacity); \
|
||||
struct SNAME *result = PFX##_new(_deque_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -390,7 +388,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_deque1_, SNAME *_deque2_, int (*comparator)(V, V)) \
|
||||
bool PFX##_equals(struct SNAME *_deque1_, struct SNAME *_deque2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_deque1_) != PFX##_count(_deque2_)) \
|
||||
return false; \
|
||||
@@ -408,10 +406,10 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_deque_) \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_deque_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *d_ = _deque_; \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *d_ = _deque_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, \
|
||||
@@ -420,9 +418,9 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
struct SNAME##_iter *iter = malloc(sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
@@ -432,12 +430,12 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->front; \
|
||||
@@ -446,17 +444,17 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
@@ -464,7 +462,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -485,7 +483,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -504,7 +502,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -524,7 +522,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -547,7 +545,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -575,7 +573,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -588,7 +586,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
@@ -596,7 +594,7 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
@@ -604,23 +602,23 @@ static const char *cmc_string_fmt_deque = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_deque_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _deque_); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_deque_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _deque_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
|
||||
+833
-831
File diff suppressed because it is too large.
Load diff
+868
-866
File diff suppressed because it is too large.
Load diff
+132
-134
@@ -40,11 +40,11 @@
|
||||
/* to_string format */
|
||||
static const char *cmc_string_fmt_heap = "%s at %p { buffer:%p, capacity:%" PRIuMAX ", count:%" PRIuMAX ", type:%s, cmp:%p }";
|
||||
|
||||
typedef enum cmc_heap_order_e
|
||||
enum cmc_heap_order
|
||||
{
|
||||
cmc_max_heap = 1,
|
||||
cmc_min_heap = -1
|
||||
} cmc_heap_order;
|
||||
};
|
||||
|
||||
#define CMC_GENERATE_HEAP(PFX, SNAME, V) \
|
||||
CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \
|
||||
@@ -57,104 +57,102 @@ typedef enum cmc_heap_order_e
|
||||
CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* 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_e HO; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the heap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the heap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target heap */ \
|
||||
struct SNAME##_s *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; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)); \
|
||||
void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
bool PFX##_remove(SNAME *_heap_, V *result); \
|
||||
/* Element Access */ \
|
||||
V PFX##_peek(SNAME *_heap_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_heap_, V element); \
|
||||
bool PFX##_empty(SNAME *_heap_); \
|
||||
bool PFX##_full(SNAME *_heap_); \
|
||||
size_t PFX##_count(SNAME *_heap_); \
|
||||
size_t PFX##_capacity(SNAME *_heap_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(SNAME *_heap_, size_t capacity); \
|
||||
SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_); \
|
||||
cmc_string PFX##_to_string(SNAME *_heap_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
#define CMC_GENERATE_HEAP_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; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the heap */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the heap */ \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
/* 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; \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *PFX##_new(size_t capacity, enum cmc_heap_order HO, int (*compare)(V, V)); \
|
||||
void PFX##_clear(struct SNAME *_heap_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_heap_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(struct SNAME *_heap_, V element); \
|
||||
bool PFX##_remove(struct SNAME *_heap_, V *result); \
|
||||
/* Element Access */ \
|
||||
V PFX##_peek(struct SNAME *_heap_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(struct SNAME *_heap_, V element); \
|
||||
bool PFX##_empty(struct SNAME *_heap_); \
|
||||
bool PFX##_full(struct SNAME *_heap_); \
|
||||
size_t PFX##_count(struct SNAME *_heap_); \
|
||||
size_t PFX##_capacity(struct SNAME *_heap_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(struct SNAME *_heap_, size_t capacity); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_heap_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_); \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_heap_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_float_up(SNAME *_heap_, size_t index); \
|
||||
static bool PFX##_impl_float_down(SNAME *_heap_, size_t index); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_); \
|
||||
static bool PFX##_impl_float_up(struct SNAME *_heap_, size_t index); \
|
||||
static bool PFX##_impl_float_down(struct SNAME *_heap_, size_t index); \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_heap_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)) \
|
||||
struct SNAME *PFX##_new(size_t capacity, enum cmc_heap_order HO, int (*compare)(V, V)) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
@@ -162,7 +160,7 @@ typedef enum cmc_heap_order_e
|
||||
if (HO != cmc_min_heap && HO != cmc_max_heap) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_heap_ = malloc(sizeof(SNAME)); \
|
||||
struct SNAME *_heap_ = malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_heap_) \
|
||||
return NULL; \
|
||||
@@ -186,7 +184,7 @@ typedef enum cmc_heap_order_e
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -201,7 +199,7 @@ typedef enum cmc_heap_order_e
|
||||
_heap_->count = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -215,7 +213,7 @@ typedef enum cmc_heap_order_e
|
||||
free(_heap_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_insert(SNAME *_heap_, V element) \
|
||||
bool PFX##_insert(struct SNAME *_heap_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_heap_)) \
|
||||
{ \
|
||||
@@ -237,7 +235,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_remove(SNAME *_heap_, V *result) \
|
||||
bool PFX##_remove(struct SNAME *_heap_, V *result) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -254,7 +252,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_peek(SNAME *_heap_) \
|
||||
V PFX##_peek(struct SNAME *_heap_) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return (V){0}; \
|
||||
@@ -262,7 +260,7 @@ typedef enum cmc_heap_order_e
|
||||
return _heap_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
bool PFX##_contains(struct SNAME *_heap_, V element) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
@@ -273,27 +271,27 @@ typedef enum cmc_heap_order_e
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_heap_) \
|
||||
bool PFX##_empty(struct SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_heap_) \
|
||||
bool PFX##_full(struct SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count >= _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_heap_) \
|
||||
size_t PFX##_count(struct SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_heap_) \
|
||||
size_t PFX##_capacity(struct SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(SNAME *_heap_, size_t capacity) \
|
||||
bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_heap_) == capacity) \
|
||||
return true; \
|
||||
@@ -312,9 +310,9 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_heap_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_heap_->capacity, _heap_->HO, _heap_->cmp); \
|
||||
struct SNAME *result = PFX##_new(_heap_->capacity, _heap_->HO, _heap_->cmp); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -332,7 +330,7 @@ typedef enum cmc_heap_order_e
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_) \
|
||||
bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_) \
|
||||
{ \
|
||||
if (PFX##_count(_heap1_) != PFX##_count(_heap2_)) \
|
||||
return false; \
|
||||
@@ -346,10 +344,10 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_heap_) \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_heap_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *h_ = _heap_; \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *h_ = _heap_; \
|
||||
const char *name = #SNAME; \
|
||||
const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \
|
||||
\
|
||||
@@ -359,9 +357,9 @@ typedef enum cmc_heap_order_e
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
struct SNAME##_iter *iter = malloc(sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
@@ -371,12 +369,12 @@ typedef enum cmc_heap_order_e
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
@@ -384,17 +382,17 @@ typedef enum cmc_heap_order_e
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -404,7 +402,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -414,7 +412,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -432,7 +430,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -451,7 +449,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -476,7 +474,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -498,7 +496,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -511,7 +509,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
@@ -519,12 +517,12 @@ typedef enum cmc_heap_order_e
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_float_up(SNAME *_heap_, size_t index) \
|
||||
static bool PFX##_impl_float_up(struct SNAME *_heap_, size_t index) \
|
||||
{ \
|
||||
/* Current index */ \
|
||||
size_t C = index; \
|
||||
@@ -550,7 +548,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_float_down(SNAME *_heap_, size_t index) \
|
||||
static bool PFX##_impl_float_down(struct SNAME *_heap_, size_t index) \
|
||||
{ \
|
||||
int mod = _heap_->HO; \
|
||||
\
|
||||
@@ -587,9 +585,9 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _heap_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
@@ -597,9 +595,9 @@ typedef enum cmc_heap_order_e
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_heap_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _heap_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
|
||||
+899
-902
File diff suppressed because it is too large.
Load diff
+847
-850
File diff suppressed because it is too large.
Load diff
+112
-112
@@ -67,7 +67,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
#define CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* List Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
@@ -79,18 +79,17 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the list */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
/* Target list */ \
|
||||
struct SNAME##_s *target; \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
@@ -100,82 +99,82 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(size_t capacity); \
|
||||
SNAME *PFX##_new_from(V *elements, size_t size); \
|
||||
void PFX##_clear(SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_list_, void (*deallocator)(V)); \
|
||||
struct SNAME *PFX##_new(size_t capacity); \
|
||||
struct SNAME *PFX##_new_from(V *elements, size_t size); \
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_push_front(SNAME *_list_, V element); \
|
||||
bool PFX##_push_at(SNAME *_list_, V element, size_t index); \
|
||||
bool PFX##_push_back(SNAME *_list_, V element); \
|
||||
bool PFX##_pop_front(SNAME *_list_); \
|
||||
bool PFX##_pop_at(SNAME *_list_, size_t index); \
|
||||
bool PFX##_pop_back(SNAME *_list_); \
|
||||
bool PFX##_push_front(struct SNAME *_list_, V element); \
|
||||
bool PFX##_push_at(struct SNAME *_list_, V element, size_t index); \
|
||||
bool PFX##_push_back(struct SNAME *_list_, V element); \
|
||||
bool PFX##_pop_front(struct SNAME *_list_); \
|
||||
bool PFX##_pop_at(struct SNAME *_list_, size_t index); \
|
||||
bool PFX##_pop_back(struct SNAME *_list_); \
|
||||
/* Collection Sequence Input and Output */ \
|
||||
bool PFX##_seq_push_front(SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_seq_push_at(SNAME *_list_, V *elements, size_t size, size_t index); \
|
||||
bool PFX##_seq_push_back(SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_seq_pop_at(SNAME *_list_, size_t from, size_t to); \
|
||||
SNAME *PFX##_seq_sublist(SNAME *_list_, size_t from, size_t to); \
|
||||
bool PFX##_seq_push_front(struct SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_seq_push_at(struct SNAME *_list_, V *elements, size_t size, size_t index); \
|
||||
bool PFX##_seq_push_back(struct SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_seq_pop_at(struct SNAME *_list_, size_t from, size_t to); \
|
||||
struct SNAME *PFX##_seq_sublist(struct SNAME *_list_, size_t from, size_t to); \
|
||||
/* Element Access */ \
|
||||
V PFX##_front(SNAME *_list_); \
|
||||
V PFX##_get(SNAME *_list_, size_t index); \
|
||||
V *PFX##_get_ref(SNAME *_list_, size_t index); \
|
||||
V PFX##_back(SNAME *_list_); \
|
||||
size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start); \
|
||||
V PFX##_front(struct SNAME *_list_); \
|
||||
V PFX##_get(struct SNAME *_list_, size_t index); \
|
||||
V *PFX##_get_ref(struct SNAME *_list_, size_t index); \
|
||||
V PFX##_back(struct SNAME *_list_); \
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, int (*comparator)(V, V), \
|
||||
bool from_start); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_list_); \
|
||||
bool PFX##_full(SNAME *_list_); \
|
||||
size_t PFX##_count(SNAME *_list_); \
|
||||
bool PFX##_fits(SNAME *_list_, size_t size); \
|
||||
size_t PFX##_capacity(SNAME *_list_); \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(struct SNAME *_list_); \
|
||||
bool PFX##_full(struct SNAME *_list_); \
|
||||
size_t PFX##_count(struct SNAME *_list_); \
|
||||
bool PFX##_fits(struct SNAME *_list_, size_t size); \
|
||||
size_t PFX##_capacity(struct SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(SNAME *_list_, size_t capacity); \
|
||||
SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_list_); \
|
||||
bool PFX##_resize(struct SNAME *_list_, size_t capacity); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_, int (*comparator)(V, V)); \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_list_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_list_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_list_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
struct SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_list_ = malloc(sizeof(SNAME)); \
|
||||
struct SNAME *_list_ = malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_list_) \
|
||||
return NULL; \
|
||||
@@ -197,12 +196,12 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_new_from(V *elements, size_t size) \
|
||||
struct SNAME *PFX##_new_from(V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_list_ = PFX##_new(size + size / 2); \
|
||||
struct SNAME *_list_ = PFX##_new(size + size / 2); \
|
||||
\
|
||||
if (!_list_) \
|
||||
return NULL; \
|
||||
@@ -214,7 +213,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -227,7 +226,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
_list_->count = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -239,7 +238,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_front(SNAME *_list_, V element) \
|
||||
bool PFX##_push_front(struct SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
@@ -259,7 +258,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_at(SNAME *_list_, V element, size_t index) \
|
||||
bool PFX##_push_at(struct SNAME *_list_, V element, size_t index) \
|
||||
{ \
|
||||
if (index > _list_->count) \
|
||||
return false; \
|
||||
@@ -279,7 +278,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_back(SNAME *_list_, V element) \
|
||||
bool PFX##_push_back(struct SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
@@ -292,7 +291,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_front(SNAME *_list_) \
|
||||
bool PFX##_pop_front(struct SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -304,7 +303,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_at(SNAME *_list_, size_t index) \
|
||||
bool PFX##_pop_at(struct SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return false; \
|
||||
@@ -317,7 +316,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_back(SNAME *_list_) \
|
||||
bool PFX##_pop_back(struct SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -327,7 +326,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_seq_push_front(SNAME *_list_, V *elements, size_t size) \
|
||||
bool PFX##_seq_push_front(struct SNAME *_list_, V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return false; \
|
||||
@@ -347,7 +346,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_seq_push_at(SNAME *_list_, V *elements, size_t size, size_t index) \
|
||||
bool PFX##_seq_push_at(struct SNAME *_list_, V *elements, size_t size, size_t index) \
|
||||
{ \
|
||||
if (size == 0 || index > _list_->count) \
|
||||
return false; \
|
||||
@@ -375,7 +374,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_seq_push_back(SNAME *_list_, V *elements, size_t size) \
|
||||
bool PFX##_seq_push_back(struct SNAME *_list_, V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return false; \
|
||||
@@ -393,7 +392,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_seq_pop_at(SNAME *_list_, size_t from, size_t to) \
|
||||
bool PFX##_seq_pop_at(struct SNAME *_list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to || to >= _list_->count) \
|
||||
return false; \
|
||||
@@ -410,14 +409,14 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_seq_sublist(SNAME *_list_, size_t from, size_t to) \
|
||||
struct SNAME *PFX##_seq_sublist(struct SNAME *_list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to || to >= _list_->count) \
|
||||
return false; \
|
||||
\
|
||||
size_t length = to - from + 1; \
|
||||
\
|
||||
SNAME *result = PFX##_new(length); \
|
||||
struct SNAME *result = PFX##_new(length); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -435,7 +434,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
V PFX##_front(SNAME *_list_) \
|
||||
V PFX##_front(struct SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return (V){0}; \
|
||||
@@ -443,7 +442,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return _list_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
V PFX##_get(SNAME *_list_, size_t index) \
|
||||
V PFX##_get(struct SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count || PFX##_empty(_list_)) \
|
||||
return (V){0}; \
|
||||
@@ -451,7 +450,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return _list_->buffer[index]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_get_ref(SNAME *_list_, size_t index) \
|
||||
V *PFX##_get_ref(struct SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return NULL; \
|
||||
@@ -462,7 +461,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return &(_list_->buffer[index]); \
|
||||
} \
|
||||
\
|
||||
V PFX##_back(SNAME *_list_) \
|
||||
V PFX##_back(struct SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return (V){0}; \
|
||||
@@ -470,7 +469,8 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return _list_->buffer[_list_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start) \
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, int (*comparator)(V, V), \
|
||||
bool from_start) \
|
||||
{ \
|
||||
if (from_start) \
|
||||
{ \
|
||||
@@ -492,7 +492,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
@@ -503,32 +503,32 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_list_) \
|
||||
bool PFX##_empty(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_list_) \
|
||||
bool PFX##_full(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count >= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_list_) \
|
||||
size_t PFX##_count(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_fits(SNAME *_list_, size_t size) \
|
||||
bool PFX##_fits(struct SNAME *_list_, size_t size) \
|
||||
{ \
|
||||
return _list_->count + size <= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_list_) \
|
||||
size_t PFX##_capacity(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(SNAME *_list_, size_t capacity) \
|
||||
bool PFX##_resize(struct SNAME *_list_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_list_) == capacity) \
|
||||
return true; \
|
||||
@@ -547,9 +547,9 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_list_->capacity); \
|
||||
struct SNAME *result = PFX##_new(_list_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -567,7 +567,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)) \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_list1_) != PFX##_count(_list2_)) \
|
||||
return false; \
|
||||
@@ -581,10 +581,10 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_list_) \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_list_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *l_ = _list_; \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *l_ = _list_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_list, \
|
||||
@@ -593,9 +593,9 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
struct SNAME##_iter *iter = malloc(sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
@@ -605,12 +605,12 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
@@ -618,17 +618,17 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -638,7 +638,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -648,7 +648,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -666,7 +666,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -685,7 +685,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -707,7 +707,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -729,7 +729,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -742,7 +742,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
@@ -750,7 +750,7 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
@@ -758,14 +758,14 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_list_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _list_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
@@ -773,9 +773,9 @@ static const char *cmc_string_fmt_list = "%s at %p { buffer:%p, capacity:%" PRIu
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_list_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _list_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
|
||||
+1013
-1016
File diff suppressed because it is too large.
Load diff
+170
-165
@@ -34,7 +34,7 @@ static const char *cmc_string_fmt_multiset = "%s at %p { buffer:%p, capacity:%"
|
||||
#ifndef CMC_IMPL_HASHTABLE_STATE
|
||||
#define CMC_IMPL_HASHTABLE_STATE
|
||||
|
||||
enum cmc_entry_state_e
|
||||
enum cmc_entry_state
|
||||
{
|
||||
CMC_ES_DELETED = -1,
|
||||
CMC_ES_EMPTY = 0,
|
||||
@@ -94,10 +94,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
#define CMC_GENERATE_MULTISET_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Hashset Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Array of Entries */ \
|
||||
struct SNAME##_entry_s *buffer; \
|
||||
struct SNAME##_entry *buffer; \
|
||||
\
|
||||
/* Current Array Capcity */ \
|
||||
size_t capacity; \
|
||||
@@ -118,14 +118,13 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
size_t (*hash)(V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
typedef struct SNAME##_entry_s \
|
||||
struct SNAME##_entry \
|
||||
{ \
|
||||
/* Entry element */ \
|
||||
V value; \
|
||||
@@ -137,15 +136,14 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
size_t dist; \
|
||||
\
|
||||
/* The sate of this node (DELETED, EMPTY, FILLED) */ \
|
||||
enum cmc_entry_state_e state; \
|
||||
\
|
||||
} SNAME##_entry, *SNAME##_entry_ptr; \
|
||||
enum cmc_entry_state state; \
|
||||
}; \
|
||||
\
|
||||
/* Hashset Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
/* Target Hashset */ \
|
||||
struct SNAME##_s *target; \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
@@ -164,83 +162,84 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)); \
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
struct SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), \
|
||||
size_t (*hash)(V)); \
|
||||
void PFX##_clear(struct SNAME *_set_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(SNAME *_set_, V element); \
|
||||
bool PFX##_insert_many(SNAME *_set_, V element, size_t count); \
|
||||
bool PFX##_update(SNAME *_set_, V element, size_t multiplicity); \
|
||||
bool PFX##_remove(SNAME *_set_, V element); \
|
||||
size_t PFX##_remove_all(SNAME *_set_, V element); \
|
||||
bool PFX##_insert(struct SNAME *_set_, V element); \
|
||||
bool PFX##_insert_many(struct SNAME *_set_, V element, size_t count); \
|
||||
bool PFX##_update(struct SNAME *_set_, V element, size_t multiplicity); \
|
||||
bool PFX##_remove(struct SNAME *_set_, V element); \
|
||||
size_t PFX##_remove_all(struct SNAME *_set_, V element); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(SNAME *_set_, V *value); \
|
||||
bool PFX##_min(SNAME *_set_, V *value); \
|
||||
size_t PFX##_multiplicity_of(SNAME *_set_, V element); \
|
||||
bool PFX##_max(struct SNAME *_set_, V *value); \
|
||||
bool PFX##_min(struct SNAME *_set_, V *value); \
|
||||
size_t PFX##_multiplicity_of(struct SNAME *_set_, V element); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_set_, V element); \
|
||||
bool PFX##_empty(SNAME *_set_); \
|
||||
bool PFX##_full(SNAME *_set_); \
|
||||
size_t PFX##_count(SNAME *_set_); \
|
||||
size_t PFX##_cardinality(SNAME *_set_); \
|
||||
size_t PFX##_capacity(SNAME *_set_); \
|
||||
double PFX##_load(SNAME *_set_); \
|
||||
bool PFX##_contains(struct SNAME *_set_, V element); \
|
||||
bool PFX##_empty(struct SNAME *_set_); \
|
||||
bool PFX##_full(struct SNAME *_set_); \
|
||||
size_t PFX##_count(struct SNAME *_set_); \
|
||||
size_t PFX##_cardinality(struct SNAME *_set_); \
|
||||
size_t PFX##_capacity(struct SNAME *_set_); \
|
||||
double PFX##_load(struct SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(SNAME *_set_, size_t capacity); \
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_, bool ignore_multiplicity); \
|
||||
cmc_string PFX##_to_string(SNAME *_set_); \
|
||||
bool PFX##_resize(struct SNAME *_set_, size_t capacity); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_set_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_, bool ignore_multiplicity); \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_set_); \
|
||||
\
|
||||
/* Set Operations */ \
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_); \
|
||||
struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct SNAME *PFX##_intersection(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct SNAME *PFX##_summation(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_multiplicity(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_multiplicity(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define CMC_GENERATE_MULTISET_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_entry *PFX##_impl_insert_and_return(SNAME *_set_, V element, bool *new_node); \
|
||||
static SNAME##_entry *PFX##_impl_get_entry(SNAME *_set_, V element); \
|
||||
static struct SNAME##_entry *PFX##_impl_insert_and_return(struct SNAME *_set_, V element, \
|
||||
bool *new_node); \
|
||||
static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, V element); \
|
||||
static size_t PFX##_impl_calculate_size(size_t required); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_set_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_set_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)) \
|
||||
struct SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)) \
|
||||
{ \
|
||||
if (capacity == 0 || load <= 0 || load >= 1) \
|
||||
return NULL; \
|
||||
@@ -251,12 +250,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
|
||||
\
|
||||
SNAME *_set_ = malloc(sizeof(SNAME)); \
|
||||
struct SNAME *_set_ = malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_set_) \
|
||||
return NULL; \
|
||||
\
|
||||
_set_->buffer = calloc(real_capacity, sizeof(SNAME##_entry)); \
|
||||
_set_->buffer = calloc(real_capacity, sizeof(struct SNAME##_entry)); \
|
||||
\
|
||||
if (!_set_->buffer) \
|
||||
{ \
|
||||
@@ -277,13 +276,13 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
struct SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
@@ -292,18 +291,18 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_set_->buffer, 0, sizeof(SNAME##_entry) * _set_->capacity); \
|
||||
memset(_set_->buffer, 0, sizeof(struct SNAME##_entry) * _set_->capacity); \
|
||||
\
|
||||
_set_->count = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
struct SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
@@ -316,11 +315,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
free(_set_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_insert(SNAME *_set_, V element) \
|
||||
bool PFX##_insert(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
bool new_node; \
|
||||
\
|
||||
SNAME##_entry *entry = PFX##_impl_insert_and_return(_set_, element, &new_node); \
|
||||
struct SNAME##_entry *entry = PFX##_impl_insert_and_return(_set_, element, &new_node); \
|
||||
\
|
||||
if (!entry) \
|
||||
return false; \
|
||||
@@ -333,14 +332,14 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_insert_many(SNAME *_set_, V element, size_t count) \
|
||||
bool PFX##_insert_many(struct SNAME *_set_, V element, size_t count) \
|
||||
{ \
|
||||
if (count == 0) \
|
||||
return true; \
|
||||
\
|
||||
bool new_node; \
|
||||
\
|
||||
SNAME##_entry *entry = PFX##_impl_insert_and_return(_set_, element, &new_node); \
|
||||
struct SNAME##_entry *entry = PFX##_impl_insert_and_return(_set_, element, &new_node); \
|
||||
\
|
||||
if (!entry) \
|
||||
return false; \
|
||||
@@ -355,14 +354,14 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_update(SNAME *_set_, V element, size_t multiplicity) \
|
||||
bool PFX##_update(struct SNAME *_set_, V element, size_t multiplicity) \
|
||||
{ \
|
||||
if (multiplicity == 0) \
|
||||
return PFX##_remove_all(_set_, element); \
|
||||
\
|
||||
bool new_node; \
|
||||
\
|
||||
SNAME##_entry *entry = PFX##_impl_insert_and_return(_set_, element, &new_node); \
|
||||
struct SNAME##_entry *entry = PFX##_impl_insert_and_return(_set_, element, &new_node); \
|
||||
\
|
||||
if (!entry) \
|
||||
return false; \
|
||||
@@ -377,9 +376,9 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_remove(SNAME *_set_, V element) \
|
||||
bool PFX##_remove(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
if (result == NULL) \
|
||||
return false; \
|
||||
@@ -401,9 +400,9 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_remove_all(SNAME *_set_, V element) \
|
||||
size_t PFX##_remove_all(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
if (result == NULL) \
|
||||
return 0; \
|
||||
@@ -421,12 +420,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return removed; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_max(SNAME *_set_, V *value) \
|
||||
bool PFX##_max(struct SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
for (PFX##_iter_init(&iter, _set_); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
@@ -442,12 +441,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_min(SNAME *_set_, V *value) \
|
||||
bool PFX##_min(struct SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
for (PFX##_iter_init(&iter, _set_); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
@@ -463,9 +462,9 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_multiplicity_of(SNAME *_set_, V element) \
|
||||
size_t PFX##_multiplicity_of(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *entry = PFX##_impl_get_entry(_set_, element); \
|
||||
struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
if (!entry) \
|
||||
return 0; \
|
||||
@@ -473,42 +472,42 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return entry->multiplicity; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_set_, V element) \
|
||||
bool PFX##_contains(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
return PFX##_impl_get_entry(_set_, element) != NULL; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_set_) \
|
||||
bool PFX##_empty(struct SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_set_) \
|
||||
bool PFX##_full(struct SNAME *_set_) \
|
||||
{ \
|
||||
return (double)PFX##_capacity(_set_) * PFX##_load(_set_) <= (double)PFX##_count(_set_); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_set_) \
|
||||
size_t PFX##_count(struct SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_cardinality(SNAME *_set_) \
|
||||
size_t PFX##_cardinality(struct SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->cardinality; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_set_) \
|
||||
size_t PFX##_capacity(struct SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->capacity; \
|
||||
} \
|
||||
\
|
||||
double PFX##_load(SNAME *_set_) \
|
||||
double PFX##_load(struct SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->load; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(SNAME *_set_, size_t capacity) \
|
||||
bool PFX##_resize(struct SNAME *_set_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_set_) == capacity) \
|
||||
return true; \
|
||||
@@ -527,12 +526,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
if (theoretical_size < PFX##_count(_set_) / PFX##_load(_set_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME *_new_set_ = PFX##_new(capacity, PFX##_load(_set_), _set_->cmp, _set_->hash); \
|
||||
struct SNAME *_new_set_ = PFX##_new(capacity, PFX##_load(_set_), _set_->cmp, _set_->hash); \
|
||||
\
|
||||
if (!_new_set_) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
for (PFX##_iter_init(&iter, _set_); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
@@ -545,7 +544,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
SNAME##_entry *tmp_b = _set_->buffer; \
|
||||
struct SNAME##_entry *tmp_b = _set_->buffer; \
|
||||
_set_->buffer = _new_set_->buffer; \
|
||||
_new_set_->buffer = tmp_b; \
|
||||
\
|
||||
@@ -558,9 +557,9 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_set_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_set_->capacity, _set_->load, _set_->cmp, _set_->hash); \
|
||||
struct SNAME *result = PFX##_new(_set_->capacity, _set_->load, _set_->cmp, _set_->hash); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -569,11 +568,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *scan = &(_set_->buffer[i]); \
|
||||
struct SNAME##_entry *scan = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (scan->state != CMC_ES_EMPTY) \
|
||||
{ \
|
||||
SNAME##_entry *target = &(result->buffer[i]); \
|
||||
struct SNAME##_entry *target = &(result->buffer[i]); \
|
||||
\
|
||||
if (scan->state == CMC_ES_DELETED) \
|
||||
target->state = CMC_ES_DELETED; \
|
||||
@@ -589,7 +588,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _set_->buffer, sizeof(SNAME##_entry) * _set_->capacity); \
|
||||
memcpy(result->buffer, _set_->buffer, sizeof(struct SNAME##_entry) * _set_->capacity); \
|
||||
\
|
||||
result->count = _set_->count; \
|
||||
result->cardinality = _set_->cardinality; \
|
||||
@@ -597,7 +596,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_, bool ignore_multiplicity) \
|
||||
bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_, bool ignore_multiplicity) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) != PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -608,12 +607,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
if (PFX##_count(_set1_) == 0) \
|
||||
return true; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
SNAME##_entry *entry = PFX##_impl_get_entry(_set2_, PFX##_iter_value(&iter)); \
|
||||
struct SNAME##_entry *entry = PFX##_impl_get_entry(_set2_, PFX##_iter_value(&iter)); \
|
||||
\
|
||||
if (entry == NULL) \
|
||||
return false; \
|
||||
@@ -625,10 +624,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_set_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _set_; \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *s_ = _set_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_multiset, \
|
||||
@@ -638,14 +637,15 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, \
|
||||
_set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter1, iter2; \
|
||||
struct SNAME##_iter iter1, iter2; \
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
PFX##_iter_init(&iter2, _set2_); \
|
||||
\
|
||||
@@ -674,17 +674,18 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_intersection(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, \
|
||||
_set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
|
||||
SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
|
||||
struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
|
||||
struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set_A_); \
|
||||
\
|
||||
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
@@ -701,14 +702,15 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, \
|
||||
_set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
@@ -725,14 +727,15 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_summation(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, \
|
||||
_set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter1, iter2; \
|
||||
struct SNAME##_iter iter1, iter2; \
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
PFX##_iter_init(&iter2, _set2_); \
|
||||
\
|
||||
@@ -749,11 +752,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME##_iter iter1, iter2; \
|
||||
struct SNAME##_iter iter1, iter2; \
|
||||
\
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, \
|
||||
_set1_->hash); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
@@ -796,7 +800,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) > PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -804,7 +808,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
if (PFX##_empty(_set1_)) \
|
||||
return true; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
@@ -822,12 +826,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_subset(_set2_, _set1_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) >= PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -840,7 +844,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
@@ -858,17 +862,17 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_proper_subset(_set2_, _set1_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_empty(_set1_)) \
|
||||
return true; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
@@ -883,9 +887,9 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
struct SNAME##_iter *iter = malloc(sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
@@ -895,14 +899,14 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
|
||||
{ \
|
||||
memset(iter, 0, sizeof(SNAME##_iter)); \
|
||||
memset(iter, 0, sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
iter->target = target; \
|
||||
iter->start = true; \
|
||||
@@ -932,17 +936,17 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -953,7 +957,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -964,7 +968,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -977,7 +981,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
iter->index++; \
|
||||
\
|
||||
@@ -993,7 +997,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -1006,7 +1010,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
iter->index--; \
|
||||
\
|
||||
@@ -1023,7 +1027,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -1044,7 +1048,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -1065,7 +1069,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -1078,7 +1082,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
@@ -1086,7 +1090,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter->target->buffer[iter->cursor].value; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_multiplicity(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_multiplicity(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
@@ -1094,19 +1098,20 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter->target->buffer[iter->cursor].multiplicity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_entry *PFX##_impl_insert_and_return(SNAME *_set_, V element, bool *new_node) \
|
||||
static struct SNAME##_entry *PFX##_impl_insert_and_return(struct SNAME *_set_, V element, \
|
||||
bool *new_node) \
|
||||
{ \
|
||||
/* If the entry already exists simply return it as we might do something with it */ \
|
||||
/* This function only guarantees that there is a valid entry for a given element */ \
|
||||
\
|
||||
*new_node = false; \
|
||||
\
|
||||
SNAME##_entry *entry = PFX##_impl_get_entry(_set_, element); \
|
||||
struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
if (entry != NULL) \
|
||||
return entry; \
|
||||
@@ -1125,7 +1130,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
/* Current multiplicity. Might change due to robin hood hashing */ \
|
||||
size_t curr_mul = 1; \
|
||||
\
|
||||
SNAME##_entry *target = &(_set_->buffer[pos]); \
|
||||
struct SNAME##_entry *target = &(_set_->buffer[pos]); \
|
||||
\
|
||||
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
@@ -1173,12 +1178,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return target; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_entry *PFX##_impl_get_entry(SNAME *_set_, V element) \
|
||||
static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
size_t hash = _set_->hash(element); \
|
||||
size_t pos = hash % _set_->capacity; \
|
||||
\
|
||||
SNAME##_entry *target = &(_set_->buffer[pos]); \
|
||||
struct SNAME##_entry *target = &(_set_->buffer[pos]); \
|
||||
\
|
||||
while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \
|
||||
{ \
|
||||
@@ -1206,18 +1211,18 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return cmc_hashtable_primes[i]; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_set_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_set_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set_); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_set_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_set_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
|
||||
+524
-526
File diff suppressed because it is too large.
Load diff
+138
-140
@@ -43,115 +43,113 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* List Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Flag if the list is sorted or not, used by lazy evaluation */ \
|
||||
bool is_sorted; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the list */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target list */ \
|
||||
struct SNAME##_s *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; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)); \
|
||||
void PFX##_clear(SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_list_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(SNAME *_list_, V element); \
|
||||
bool PFX##_remove(SNAME *_list_, size_t index); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(SNAME *_list_, V *result); \
|
||||
bool PFX##_min(SNAME *_list_, V *result); \
|
||||
V PFX##_get(SNAME *_list_, size_t index); \
|
||||
size_t PFX##_indexof(SNAME *_list_, V element, bool from_start); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_list_, V element); \
|
||||
bool PFX##_empty(SNAME *_list_); \
|
||||
bool PFX##_full(SNAME *_list_); \
|
||||
size_t PFX##_count(SNAME *_list_); \
|
||||
size_t PFX##_capacity(SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(SNAME *_list_, size_t capacity); \
|
||||
void PFX##_sort(SNAME *_list_); \
|
||||
SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_list1_, SNAME *_list2_); \
|
||||
cmc_string PFX##_to_string(SNAME *_list_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* List Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Flag if the list is sorted or not, used by lazy evaluation */ \
|
||||
bool is_sorted; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the list */ \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
/* Target list */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* If the iterator has reached the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)); \
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(struct SNAME *_list_, V element); \
|
||||
bool PFX##_remove(struct SNAME *_list_, size_t index); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(struct SNAME *_list_, V *result); \
|
||||
bool PFX##_min(struct SNAME *_list_, V *result); \
|
||||
V PFX##_get(struct SNAME *_list_, size_t index); \
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element); \
|
||||
bool PFX##_empty(struct SNAME *_list_); \
|
||||
bool PFX##_full(struct SNAME *_list_); \
|
||||
size_t PFX##_count(struct SNAME *_list_); \
|
||||
size_t PFX##_capacity(struct SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(struct SNAME *_list_, size_t capacity); \
|
||||
void PFX##_sort(struct SNAME *_list_); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_list_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static size_t PFX##_impl_binary_search_first(SNAME *_list_, V value); \
|
||||
static size_t PFX##_impl_binary_search_last(SNAME *_list_, V value); \
|
||||
static size_t PFX##_impl_binary_search_first(struct SNAME *_list_, V value); \
|
||||
static size_t PFX##_impl_binary_search_last(struct SNAME *_list_, V value); \
|
||||
void PFX##_impl_sort_quicksort(V *array, int (*cmp)(V, V), size_t low, size_t high); \
|
||||
void PFX##_impl_sort_insertion(V *array, int (*cmp)(V, V), size_t low, size_t high); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_list_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_list_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)) \
|
||||
struct SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_list_ = malloc(sizeof(SNAME)); \
|
||||
struct SNAME *_list_ = malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_list_) \
|
||||
return NULL; \
|
||||
@@ -175,7 +173,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -188,7 +186,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
_list_->count = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -200,7 +198,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_insert(SNAME *_list_, V element) \
|
||||
bool PFX##_insert(struct SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
@@ -215,7 +213,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_remove(SNAME *_list_, size_t index) \
|
||||
bool PFX##_remove(struct SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return false; \
|
||||
@@ -228,7 +226,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_min(SNAME *_list_, V *result) \
|
||||
bool PFX##_min(struct SNAME *_list_, V *result) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -240,7 +238,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_max(SNAME *_list_, V *result) \
|
||||
bool PFX##_max(struct SNAME *_list_, V *result) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -252,7 +250,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_get(SNAME *_list_, size_t index) \
|
||||
V PFX##_get(struct SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return (V){0}; \
|
||||
@@ -262,7 +260,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return _list_->buffer[index]; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_indexof(SNAME *_list_, V element, bool from_start) \
|
||||
size_t PFX##_indexof(struct SNAME *_list_, V element, bool from_start) \
|
||||
{ \
|
||||
PFX##_sort(_list_); \
|
||||
\
|
||||
@@ -274,7 +272,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return PFX##_impl_binary_search_last(_list_, element); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_list_, V element) \
|
||||
bool PFX##_contains(struct SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -284,27 +282,27 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return PFX##_impl_binary_search_first(_list_, element) < PFX##_count(_list_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_list_) \
|
||||
bool PFX##_empty(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_list_) \
|
||||
bool PFX##_full(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count >= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_list_) \
|
||||
size_t PFX##_count(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_list_) \
|
||||
size_t PFX##_capacity(struct SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(SNAME *_list_, size_t capacity) \
|
||||
bool PFX##_resize(struct SNAME *_list_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_list_) == capacity) \
|
||||
return true; \
|
||||
@@ -323,7 +321,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
void PFX##_sort(SNAME *_list_) \
|
||||
void PFX##_sort(struct SNAME *_list_) \
|
||||
{ \
|
||||
if (!_list_->is_sorted && _list_->count > 1) \
|
||||
{ \
|
||||
@@ -333,9 +331,9 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
} \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_list_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_list_->capacity, _list_->cmp); \
|
||||
struct SNAME *result = PFX##_new(_list_->capacity, _list_->cmp); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
@@ -353,7 +351,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_list1_, SNAME *_list2_) \
|
||||
bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \
|
||||
{ \
|
||||
if (PFX##_count(_list1_) != PFX##_count(_list2_)) \
|
||||
return false; \
|
||||
@@ -370,10 +368,10 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_list_) \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_list_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *l_ = _list_; \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *l_ = _list_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_sortedlist, \
|
||||
@@ -383,9 +381,9 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
struct SNAME##_iter *iter = malloc(sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
@@ -395,12 +393,12 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
|
||||
{ \
|
||||
PFX##_sort(target); \
|
||||
\
|
||||
@@ -410,17 +408,17 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -430,7 +428,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -440,7 +438,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -458,7 +456,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -477,7 +475,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -499,7 +497,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -521,7 +519,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -534,7 +532,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
@@ -542,12 +540,12 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static size_t PFX##_impl_binary_search_first(SNAME *_list_, V value) \
|
||||
static size_t PFX##_impl_binary_search_first(struct SNAME *_list_, V value) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 1; \
|
||||
@@ -572,7 +570,7 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return PFX##_count(_list_); \
|
||||
} \
|
||||
\
|
||||
static size_t PFX##_impl_binary_search_last(SNAME *_list_, V value) \
|
||||
static size_t PFX##_impl_binary_search_last(struct SNAME *_list_, V value) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 1; \
|
||||
@@ -669,9 +667,9 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_list_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _list_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
@@ -679,9 +677,9 @@ static const char *cmc_string_fmt_sortedlist = "%s at %p { buffer:%p, capacity:%
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_list_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _list_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
|
||||
+458
-460
@@ -49,467 +49,465 @@ static const char *cmc_string_fmt_stack = "%s at %p { buffer:%p, capacity:%" PRI
|
||||
CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Stack Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the stack */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the stack */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Stack Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target stack */ \
|
||||
struct SNAME##_s *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; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(size_t capacity); \
|
||||
void PFX##_clear(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_push(SNAME *_stack_, V element); \
|
||||
bool PFX##_pop(SNAME *_stack_); \
|
||||
/* Element Access */ \
|
||||
V PFX##_top(SNAME *_stack_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_stack_); \
|
||||
bool PFX##_full(SNAME *_stack_); \
|
||||
size_t PFX##_count(SNAME *_stack_); \
|
||||
size_t PFX##_capacity(SNAME *_stack_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(SNAME *_stack_, size_t capacity); \
|
||||
SNAME *PFX##_copy_of(SNAME *_stack_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_stack1_, SNAME *_stack2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_stack_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
#define CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Stack Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the stack */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the stack */ \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
/* Stack Iterator */ \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
/* Target stack */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* If the iterator has reached the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *PFX##_new(size_t capacity); \
|
||||
void PFX##_clear(struct SNAME *_stack_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_stack_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_push(struct SNAME *_stack_, V element); \
|
||||
bool PFX##_pop(struct SNAME *_stack_); \
|
||||
/* Element Access */ \
|
||||
V PFX##_top(struct SNAME *_stack_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(struct SNAME *_stack_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(struct SNAME *_stack_); \
|
||||
bool PFX##_full(struct SNAME *_stack_); \
|
||||
size_t PFX##_count(struct SNAME *_stack_); \
|
||||
size_t PFX##_capacity(struct SNAME *_stack_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(struct SNAME *_stack_, size_t capacity); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_stack_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_, int (*comparator)(V, V)); \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_stack_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_stack_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_stack_) \
|
||||
return NULL; \
|
||||
\
|
||||
_stack_->buffer = calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
_stack_->capacity = capacity; \
|
||||
_stack_->count = 0; \
|
||||
\
|
||||
_stack_->it_start = PFX##_impl_it_start; \
|
||||
_stack_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
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_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push(SNAME *_stack_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_stack_)) \
|
||||
{ \
|
||||
if (!PFX##_resize(_stack_, PFX##_capacity(_stack_) * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_stack_->buffer[_stack_->count++] = element; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer[--_stack_->count] = (V){0}; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_top(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return (V){0}; \
|
||||
\
|
||||
return _stack_->buffer[_stack_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
{ \
|
||||
if (comparator(_stack_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count >= _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(SNAME *_stack_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_stack_) == capacity) \
|
||||
return true; \
|
||||
\
|
||||
if (capacity < PFX##_count(_stack_)) \
|
||||
return false; \
|
||||
\
|
||||
V *new_buffer = realloc(_stack_->buffer, sizeof(V) * capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer = new_buffer; \
|
||||
_stack_->capacity = capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_stack_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_stack_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
result->buffer[i] = copy_func(_stack_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _stack_->buffer, sizeof(V) * _stack_->count); \
|
||||
\
|
||||
result->count = _stack_->count; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_stack1_, SNAME *_stack2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_stack1_) != PFX##_count(_stack2_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < PFX##_count(_stack1_); i++) \
|
||||
{ \
|
||||
if (comparator(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_stack_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _stack_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, \
|
||||
name, s_, s_->buffer, s_->capacity, s_->count); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = PFX##_empty(target) ? 0 : iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor < steps) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor -= steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = 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 PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor > index) \
|
||||
return PFX##_iter_rewind(iter, iter->cursor - index); \
|
||||
else if (iter->cursor < index) \
|
||||
return PFX##_iter_advance(iter, index - iter->cursor); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
\
|
||||
return iter->target->count - 1 - iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _stack_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _stack_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
#define CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_stack_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_stack_); \
|
||||
\
|
||||
struct SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
struct SNAME *_stack_ = malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_stack_) \
|
||||
return NULL; \
|
||||
\
|
||||
_stack_->buffer = calloc(capacity, sizeof(V)); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
_stack_->capacity = capacity; \
|
||||
_stack_->count = 0; \
|
||||
\
|
||||
_stack_->it_start = PFX##_impl_it_start; \
|
||||
_stack_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(struct SNAME *_stack_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(struct 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_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push(struct SNAME *_stack_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_stack_)) \
|
||||
{ \
|
||||
if (!PFX##_resize(_stack_, PFX##_capacity(_stack_) * 2)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_stack_->buffer[_stack_->count++] = element; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop(struct SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer[--_stack_->count] = (V){0}; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_top(struct SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return (V){0}; \
|
||||
\
|
||||
return _stack_->buffer[_stack_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(struct SNAME *_stack_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
{ \
|
||||
if (comparator(_stack_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(struct SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(struct SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count >= _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(struct SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(struct SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(struct SNAME *_stack_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_stack_) == capacity) \
|
||||
return true; \
|
||||
\
|
||||
if (capacity < PFX##_count(_stack_)) \
|
||||
return false; \
|
||||
\
|
||||
V *new_buffer = realloc(_stack_->buffer, sizeof(V) * capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer = new_buffer; \
|
||||
_stack_->capacity = capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_stack_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
struct SNAME *result = PFX##_new(_stack_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
result->buffer[i] = copy_func(_stack_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _stack_->buffer, sizeof(V) * _stack_->count); \
|
||||
\
|
||||
result->count = _stack_->count; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_stack1_) != PFX##_count(_stack2_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < PFX##_count(_stack1_); i++) \
|
||||
{ \
|
||||
if (comparator(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_stack_) \
|
||||
{ \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *s_ = _stack_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, \
|
||||
name, s_, s_->buffer, s_->capacity, s_->count); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
{ \
|
||||
struct SNAME##_iter *iter = malloc(sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = PFX##_empty(target) ? 0 : iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor < steps) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor -= steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = 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 PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor > index) \
|
||||
return PFX##_iter_rewind(iter, iter->cursor - index); \
|
||||
else if (iter->cursor < index) \
|
||||
return PFX##_iter_advance(iter, index - iter->cursor); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
\
|
||||
return iter->target->count - 1 - iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_stack_) \
|
||||
{ \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _stack_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_stack_) \
|
||||
{ \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _stack_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
}
|
||||
|
||||
#endif /* CMC_STACK_H */
|
||||
+973
-974
File diff suppressed because it is too large.
Load diff
+223
-226
@@ -40,153 +40,150 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Treeset Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Root node */ \
|
||||
struct SNAME##_node_s *root; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the treeset */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the treeset */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Treeset Node */ \
|
||||
typedef struct SNAME##_node_s \
|
||||
{ \
|
||||
/* Node element */ \
|
||||
V value; \
|
||||
\
|
||||
/* Node height used by the AVL tree to keep it strictly balanced */ \
|
||||
unsigned char height; \
|
||||
\
|
||||
/* Right child node or subtree */ \
|
||||
struct SNAME##_node_s *right; \
|
||||
\
|
||||
/* Left child node or subtree */ \
|
||||
struct SNAME##_node_s *left; \
|
||||
\
|
||||
/* Parent node */ \
|
||||
struct SNAME##_node_s *parent; \
|
||||
\
|
||||
} SNAME##_node, *SNAME##_node_ptr; \
|
||||
\
|
||||
/* Treeset Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target treeset */ \
|
||||
struct SNAME##_s *target; \
|
||||
\
|
||||
/* Cursor's current node */ \
|
||||
struct SNAME##_node_s *cursor; \
|
||||
\
|
||||
/* The first node in the iteration */ \
|
||||
struct SNAME##_node_s *first; \
|
||||
\
|
||||
/* The last node in the iteration */ \
|
||||
struct SNAME##_node_s *last; \
|
||||
\
|
||||
/* 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; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(int (*compare)(V, V)); \
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(SNAME *_set_, V element); \
|
||||
bool PFX##_remove(SNAME *_set_, V element); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(SNAME *_set_, V *value); \
|
||||
bool PFX##_min(SNAME *_set_, V *value); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_set_, V element); \
|
||||
bool PFX##_empty(SNAME *_set_); \
|
||||
size_t PFX##_count(SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_); \
|
||||
cmc_string PFX##_to_string(SNAME *_set_); \
|
||||
\
|
||||
/* Set Operations */ \
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
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_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Treeset Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Root node */ \
|
||||
struct SNAME##_node *root; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the treeset */ \
|
||||
struct SNAME##_iter (*it_start)(struct SNAME *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the treeset */ \
|
||||
struct SNAME##_iter (*it_end)(struct SNAME *); \
|
||||
}; \
|
||||
\
|
||||
/* Treeset Node */ \
|
||||
struct SNAME##_node \
|
||||
{ \
|
||||
/* Node element */ \
|
||||
V value; \
|
||||
\
|
||||
/* Node height used by the AVL tree to keep it strictly balanced */ \
|
||||
unsigned char height; \
|
||||
\
|
||||
/* Right child node or subtree */ \
|
||||
struct SNAME##_node *right; \
|
||||
\
|
||||
/* Left child node or subtree */ \
|
||||
struct SNAME##_node *left; \
|
||||
\
|
||||
/* Parent node */ \
|
||||
struct SNAME##_node *parent; \
|
||||
}; \
|
||||
\
|
||||
/* Treeset Iterator */ \
|
||||
struct SNAME##_iter \
|
||||
{ \
|
||||
/* Target treeset */ \
|
||||
struct SNAME *target; \
|
||||
\
|
||||
/* Cursor's current node */ \
|
||||
struct SNAME##_node *cursor; \
|
||||
\
|
||||
/* The first node in the iteration */ \
|
||||
struct SNAME##_node *first; \
|
||||
\
|
||||
/* The last node in the iteration */ \
|
||||
struct SNAME##_node *last; \
|
||||
\
|
||||
/* 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; \
|
||||
}; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
struct SNAME *PFX##_new(int (*compare)(V, V)); \
|
||||
void PFX##_clear(struct SNAME *_set_, void (*deallocator)(V)); \
|
||||
void PFX##_free(struct SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(struct SNAME *_set_, V element); \
|
||||
bool PFX##_remove(struct SNAME *_set_, V element); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(struct SNAME *_set_, V *value); \
|
||||
bool PFX##_min(struct SNAME *_set_, V *value); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(struct SNAME *_set_, V element); \
|
||||
bool PFX##_empty(struct SNAME *_set_); \
|
||||
size_t PFX##_count(struct SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_set_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_set_); \
|
||||
\
|
||||
/* Set Operations */ \
|
||||
struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct SNAME *PFX##_intersection(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_node *PFX##_impl_new_node(V element); \
|
||||
static SNAME##_node *PFX##_impl_get_node(SNAME *_set_, V element); \
|
||||
static unsigned char PFX##_impl_h(SNAME##_node *node); \
|
||||
static unsigned char PFX##_impl_hupdate(SNAME##_node *node); \
|
||||
static void PFX##_impl_rotate_right(SNAME##_node **Z); \
|
||||
static void PFX##_impl_rotate_left(SNAME##_node **Z); \
|
||||
static void PFX##_impl_rebalance(SNAME *_set_, SNAME##_node *node); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \
|
||||
static struct SNAME##_node *PFX##_impl_new_node(V element); \
|
||||
static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_set_, V element); \
|
||||
static unsigned char PFX##_impl_h(struct SNAME##_node *node); \
|
||||
static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node); \
|
||||
static void PFX##_impl_rotate_right(struct SNAME##_node **Z); \
|
||||
static void PFX##_impl_rotate_left(struct SNAME##_node **Z); \
|
||||
static void PFX##_impl_rebalance(struct SNAME *_set_, struct SNAME##_node *node); \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_set_); \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_set_); \
|
||||
\
|
||||
SNAME *PFX##_new(int (*compare)(V, V)) \
|
||||
struct SNAME *PFX##_new(int (*compare)(V, V)) \
|
||||
{ \
|
||||
SNAME *_set_ = malloc(sizeof(SNAME)); \
|
||||
struct SNAME *_set_ = malloc(sizeof(struct SNAME)); \
|
||||
\
|
||||
if (!_set_) \
|
||||
return NULL; \
|
||||
@@ -201,16 +198,16 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(struct SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
SNAME##_node *up = NULL; \
|
||||
struct SNAME##_node *scan = _set_->root; \
|
||||
struct SNAME##_node *up = NULL; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (scan->left != NULL) \
|
||||
{ \
|
||||
SNAME##_node *left = scan->left; \
|
||||
struct SNAME##_node *left = scan->left; \
|
||||
\
|
||||
scan->left = up; \
|
||||
up = scan; \
|
||||
@@ -218,7 +215,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
else if (scan->right != NULL) \
|
||||
{ \
|
||||
SNAME##_node *right = scan->right; \
|
||||
struct SNAME##_node *right = scan->right; \
|
||||
\
|
||||
scan->left = up; \
|
||||
scan->right = NULL; \
|
||||
@@ -262,14 +259,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
_set_->root = NULL; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_free(struct SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
PFX##_clear(_set_, deallocator); \
|
||||
\
|
||||
free(_set_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_insert(SNAME *_set_, V element) \
|
||||
bool PFX##_insert(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
{ \
|
||||
@@ -280,8 +277,8 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
SNAME##_node *parent = scan; \
|
||||
struct SNAME##_node *scan = _set_->root; \
|
||||
struct SNAME##_node *parent = scan; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
@@ -295,7 +292,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
SNAME##_node *node; \
|
||||
struct SNAME##_node *node; \
|
||||
\
|
||||
if (_set_->cmp(parent->value, element) > 0) \
|
||||
{ \
|
||||
@@ -326,14 +323,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_remove(SNAME *_set_, V element) \
|
||||
bool PFX##_remove(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_impl_get_node(_set_, element); \
|
||||
struct SNAME##_node *node = PFX##_impl_get_node(_set_, element); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *temp = NULL, *unbalanced = NULL; \
|
||||
struct SNAME##_node *temp = NULL, *unbalanced = NULL; \
|
||||
\
|
||||
bool is_root = node->parent == NULL; \
|
||||
\
|
||||
@@ -447,12 +444,12 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_max(SNAME *_set_, V *value) \
|
||||
bool PFX##_max(struct SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
struct SNAME##_node *scan = _set_->root; \
|
||||
\
|
||||
while (scan->right != NULL) \
|
||||
scan = scan->right; \
|
||||
@@ -462,12 +459,12 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_min(SNAME *_set_, V *value) \
|
||||
bool PFX##_min(struct SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
struct SNAME##_node *scan = _set_->root; \
|
||||
\
|
||||
while (scan->left != NULL) \
|
||||
scan = scan->left; \
|
||||
@@ -477,9 +474,9 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_set_, V element) \
|
||||
bool PFX##_contains(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
struct SNAME##_node *scan = _set_->root; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
@@ -494,24 +491,24 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_set_) \
|
||||
bool PFX##_empty(struct SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count == 0; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_set_) \
|
||||
size_t PFX##_count(struct SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)) \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_set_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_set_->cmp); \
|
||||
struct SNAME *result = PFX##_new(_set_->cmp); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set_); \
|
||||
\
|
||||
if (!PFX##_empty(_set_)) \
|
||||
@@ -528,12 +525,12 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) != PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
@@ -545,10 +542,10 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
struct cmc_string PFX##_to_string(struct SNAME *_set_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _set_; \
|
||||
struct cmc_string str; \
|
||||
struct SNAME *s_ = _set_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_treeset, \
|
||||
@@ -557,14 +554,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter1, iter2; \
|
||||
struct SNAME##_iter iter1, iter2; \
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
PFX##_iter_init(&iter2, _set2_); \
|
||||
\
|
||||
@@ -581,17 +578,17 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_intersection(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
|
||||
SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
|
||||
struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
|
||||
struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set_A_); \
|
||||
\
|
||||
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
@@ -605,14 +602,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
@@ -626,14 +623,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
struct SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
if (!_set_r_) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_iter iter1, iter2; \
|
||||
struct SNAME##_iter iter1, iter2; \
|
||||
PFX##_iter_init(&iter1, _set1_); \
|
||||
PFX##_iter_init(&iter2, _set2_); \
|
||||
\
|
||||
@@ -659,7 +656,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
/* Is _set1_ a subset of _set2_ ? */ \
|
||||
/* A set X is a subset of a set Y when: X <= Y */ \
|
||||
/* If X is a subset of Y, then Y is a superset of X */ \
|
||||
bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
/* If the cardinality of _set1_ is greater than that of _set2_, then it is safe */ \
|
||||
/* to say that _set1_ can't be a subset of _set2_ */ \
|
||||
@@ -670,7 +667,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
if (PFX##_empty(_set1_)) \
|
||||
return true; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
@@ -688,7 +685,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
/* Is _set1_ a superset of _set2_ ? */ \
|
||||
/* A set X is a superset of a set Y when: X >= Y */ \
|
||||
/* If X is a superset of Y, then Y is a subset of X */ \
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_subset(_set2_, _set1_); \
|
||||
} \
|
||||
@@ -696,7 +693,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
/* Is _set1_ a proper subset of _set2_ ? */ \
|
||||
/* A set X is a proper subset of a set Y when: X < Y */ \
|
||||
/* If X is a proper subset of Y, then Y is a proper superset of X */ \
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
/* If the cardinality of _set1_ is greater than or equal to that of _set2_, then */ \
|
||||
/* it is safe to say that _set1_ can't be a proper subset of _set2_ */ \
|
||||
@@ -713,7 +710,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
@@ -731,7 +728,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
/* Is _set1_ a proper superset of _set2_ ? */ \
|
||||
/* A set X is a proper superset of a set Y when: X > Y */ \
|
||||
/* If X is a proper superset of Y, then Y is a proper subset of X */ \
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_proper_subset(_set2_, _set1_); \
|
||||
} \
|
||||
@@ -739,14 +736,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
/* Is _set1_ a disjointset of _set2_ ? */ \
|
||||
/* A set X is a disjointset of a set Y if their intersection is empty, that is, if */ \
|
||||
/* there are no elements in common between the two */ \
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \
|
||||
{ \
|
||||
/* The intersection of an empty set with any other set will result in an empty */ \
|
||||
/* set */ \
|
||||
if (PFX##_empty(_set1_)) \
|
||||
return true; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
@@ -761,9 +758,9 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
struct SNAME##_iter *iter = malloc(sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
@@ -773,14 +770,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
|
||||
{ \
|
||||
memset(iter, 0, sizeof(SNAME##_iter)); \
|
||||
memset(iter, 0, sizeof(struct SNAME##_iter)); \
|
||||
\
|
||||
iter->target = target; \
|
||||
iter->start = true; \
|
||||
@@ -801,17 +798,17 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -822,7 +819,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -833,7 +830,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -873,7 +870,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -915,7 +912,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -938,7 +935,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -961,7 +958,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -974,7 +971,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){0}; \
|
||||
@@ -982,14 +979,14 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return iter->cursor->value; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_node *PFX##_impl_new_node(V element) \
|
||||
static struct SNAME##_node *PFX##_impl_new_node(V element) \
|
||||
{ \
|
||||
SNAME##_node *node = malloc(sizeof(SNAME##_node)); \
|
||||
struct SNAME##_node *node = malloc(sizeof(struct SNAME##_node)); \
|
||||
\
|
||||
if (!node) \
|
||||
return NULL; \
|
||||
@@ -1003,12 +1000,12 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_node *PFX##_impl_get_node(SNAME *_set_, V element) \
|
||||
static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_set_, V element) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
struct SNAME##_node *scan = _set_->root; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
@@ -1023,7 +1020,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
static unsigned char PFX##_impl_h(SNAME##_node *node) \
|
||||
static unsigned char PFX##_impl_h(struct SNAME##_node *node) \
|
||||
{ \
|
||||
if (node == NULL) \
|
||||
return 0; \
|
||||
@@ -1031,7 +1028,7 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return node->height; \
|
||||
} \
|
||||
\
|
||||
static unsigned char PFX##_impl_hupdate(SNAME##_node *node) \
|
||||
static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node) \
|
||||
{ \
|
||||
if (node == NULL) \
|
||||
return 0; \
|
||||
@@ -1042,10 +1039,10 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
return 1 + (h_l > h_r ? h_l : h_r); \
|
||||
} \
|
||||
\
|
||||
static void PFX##_impl_rotate_right(SNAME##_node **Z) \
|
||||
static void PFX##_impl_rotate_right(struct SNAME##_node **Z) \
|
||||
{ \
|
||||
SNAME##_node *root = *Z; \
|
||||
SNAME##_node *new_root = root->left; \
|
||||
struct SNAME##_node *root = *Z; \
|
||||
struct SNAME##_node *new_root = root->left; \
|
||||
\
|
||||
if (root->parent != NULL) \
|
||||
{ \
|
||||
@@ -1071,10 +1068,10 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
*Z = new_root; \
|
||||
} \
|
||||
\
|
||||
static void PFX##_impl_rotate_left(SNAME##_node **Z) \
|
||||
static void PFX##_impl_rotate_left(struct SNAME##_node **Z) \
|
||||
{ \
|
||||
SNAME##_node *root = *Z; \
|
||||
SNAME##_node *new_root = root->right; \
|
||||
struct SNAME##_node *root = *Z; \
|
||||
struct SNAME##_node *new_root = root->right; \
|
||||
\
|
||||
if (root->parent != NULL) \
|
||||
{ \
|
||||
@@ -1100,9 +1097,9 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
*Z = new_root; \
|
||||
} \
|
||||
\
|
||||
static void PFX##_impl_rebalance(SNAME *_set_, SNAME##_node *node) \
|
||||
static void PFX##_impl_rebalance(struct SNAME *_set_, struct SNAME##_node *node) \
|
||||
{ \
|
||||
SNAME##_node *scan = node, *child = NULL; \
|
||||
struct SNAME##_node *scan = node, *child = NULL; \
|
||||
\
|
||||
int balance; \
|
||||
bool is_root = false; \
|
||||
@@ -1144,18 +1141,18 @@ static const char *cmc_string_fmt_treeset = "%s at %p { root:%p, count:%" PRIuMA
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_set_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_set_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set_); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_set_) \
|
||||
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_set_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
struct SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _set_); \
|
||||
PFX##_iter_to_end(&iter); \
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
static const size_t cmc_string_len = 200;
|
||||
|
||||
typedef struct cmc_string_s
|
||||
struct cmc_string
|
||||
{
|
||||
char s[200];
|
||||
} cmc_string;
|
||||
};
|
||||
|
||||
#endif /* CMC_STRING_H */
|
||||
+14
-14
@@ -11,22 +11,22 @@
|
||||
#ifndef CMC_FOR_EACH_H
|
||||
#define CMC_FOR_EACH_H
|
||||
|
||||
#define CMC_FOR_EACH(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (SNAME##_iter iter = (TARGET)->it_start(TARGET); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
#define CMC_FOR_EACH(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (struct SNAME##_iter iter = (TARGET)->it_start(TARGET); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CMC_FOR_EACH_REV(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (SNAME##_iter iter = (TARGET)->it_end(TARGET); !PFX##_iter_start(&iter); PFX##_iter_prev(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
#define CMC_FOR_EACH_REV(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (struct SNAME##_iter iter = (TARGET)->it_end(TARGET); !PFX##_iter_start(&iter); PFX##_iter_prev(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* CMC_FOR_EACH_H */
|
||||
+1
-1
@@ -103,7 +103,7 @@ static void cmc_test_log(const char *unit_name, const char *current_test, bool a
|
||||
const char *current_test = NULL; \
|
||||
\
|
||||
struct cmc_test_info tinfo = {0}; \
|
||||
cmc_timer timer = {0}; \
|
||||
struct cmc_timer timer = {0}; \
|
||||
\
|
||||
tinfo.verbose = VERBOSE; \
|
||||
\
|
||||
|
||||
+15
-15
@@ -15,33 +15,33 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef struct cmc_timer_s
|
||||
struct cmc_timer
|
||||
{
|
||||
clock_t start;
|
||||
clock_t stop;
|
||||
double result;
|
||||
} cmc_timer;
|
||||
};
|
||||
|
||||
#define cmc_timer_start(timer) \
|
||||
do \
|
||||
{ \
|
||||
cmc_timer *t = &(timer); \
|
||||
t->start = clock(); \
|
||||
\
|
||||
#define cmc_timer_start(timer) \
|
||||
do \
|
||||
{ \
|
||||
struct cmc_timer *t = &(timer); \
|
||||
t->start = clock(); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define cmc_timer_stop(timer) \
|
||||
do \
|
||||
{ \
|
||||
cmc_timer *t = &(timer); \
|
||||
t->stop = clock(); \
|
||||
\
|
||||
#define cmc_timer_stop(timer) \
|
||||
do \
|
||||
{ \
|
||||
struct cmc_timer *t = &(timer); \
|
||||
t->stop = clock(); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define cmc_timer_calc(timer) \
|
||||
do \
|
||||
{ \
|
||||
cmc_timer *t = &(timer); \
|
||||
struct cmc_timer *t = &(timer); \
|
||||
t->result = (double)(t->stop - t->start) * 1000.0 / CLOCKS_PER_SEC; \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
Reference in new issue
Block a user