Completely removed typedefs

This commit is contained in:
Leonardo committed 2019-10-29 02:19:34 -03:00
1 parent db61269d42
commit 33c33e8947
55 files changed
+8637 -8651

No files matched your search

+908 -905
View File
File diff suppressed because it is too large. Load diff
+137 -139
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+868 -866
View File
File diff suppressed because it is too large. Load diff
+132 -134
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+847 -850
View File
File diff suppressed because it is too large. Load diff
+112 -112
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+170 -165
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+138 -140
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+223 -226
View File
@@ -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); \
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)