Added CMC prefix to all macros and removed FMOD
This commit is contained in:
1 parent
4fe4e96811
commit
2ca2210a77
21 files changed
+5691
-5699
No files matched your search
+153
-153
@@ -37,135 +37,135 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define DEQUE_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_DEQUE(PFX, SNAME, V) \
|
||||
CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define DEQUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_DEQUE_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define DEQUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_DEQUE_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, 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 */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push_front(SNAME *_deque_, V element); \
|
||||
FMOD bool PFX##_push_back(SNAME *_deque_, V element); \
|
||||
FMOD bool PFX##_pop_front(SNAME *_deque_); \
|
||||
FMOD bool PFX##_pop_back(SNAME *_deque_); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition); \
|
||||
FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition); \
|
||||
FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition); \
|
||||
FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_front(SNAME *_deque_); \
|
||||
FMOD V PFX##_back(SNAME *_deque_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_deque_); \
|
||||
FMOD bool PFX##_full(SNAME *_deque_); \
|
||||
FMOD size_t PFX##_count(SNAME *_deque_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_deque_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_deque_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_deque1_, SNAME *_deque2_, int (*comparator)(V, V)); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_deque_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#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_); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition); \
|
||||
bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition); \
|
||||
bool PFX##_pop_front_if(SNAME *_deque_, bool condition); \
|
||||
bool PFX##_pop_back_if(SNAME *_deque_, bool condition); \
|
||||
/* 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 */ \
|
||||
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); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_deque_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
@@ -196,7 +196,7 @@
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -213,7 +213,7 @@
|
||||
_deque_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
void PFX##_free(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -227,7 +227,7 @@
|
||||
free(_deque_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_deque_, V element) \
|
||||
bool PFX##_push_front(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
@@ -244,7 +244,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_deque_, V element) \
|
||||
bool PFX##_push_back(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
@@ -261,7 +261,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_deque_) \
|
||||
bool PFX##_pop_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
@@ -275,7 +275,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_deque_) \
|
||||
bool PFX##_pop_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
@@ -289,7 +289,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
|
||||
bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_front(_deque_, element); \
|
||||
@@ -297,7 +297,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
|
||||
bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_back(_deque_, element); \
|
||||
@@ -305,7 +305,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
|
||||
bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_front(_deque_); \
|
||||
@@ -313,7 +313,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
|
||||
bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_back(_deque_); \
|
||||
@@ -321,7 +321,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_front(SNAME *_deque_) \
|
||||
V PFX##_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -329,7 +329,7 @@
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_back(SNAME *_deque_) \
|
||||
V PFX##_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -337,7 +337,7 @@
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \
|
||||
{ \
|
||||
@@ -348,27 +348,27 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_deque_) \
|
||||
bool PFX##_empty(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_deque_) \
|
||||
bool PFX##_full(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_deque_) \
|
||||
size_t PFX##_count(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_deque_) \
|
||||
size_t PFX##_capacity(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_deque_, V (*copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_deque_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_deque_->capacity); \
|
||||
\
|
||||
@@ -395,7 +395,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_deque1_, SNAME *_deque2_, int (*comparator)(V, V)) \
|
||||
bool PFX##_equals(SNAME *_deque1_, SNAME *_deque2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_deque1_) != PFX##_count(_deque2_)) \
|
||||
return false; \
|
||||
@@ -413,7 +413,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_deque_) \
|
||||
cmc_string PFX##_to_string(SNAME *_deque_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *d_ = _deque_; \
|
||||
@@ -425,7 +425,7 @@
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -437,12 +437,12 @@
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->front; \
|
||||
@@ -451,17 +451,17 @@
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
@@ -469,7 +469,7 @@
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -486,7 +486,7 @@
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -505,7 +505,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -525,7 +525,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -548,7 +548,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -576,7 +576,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -589,7 +589,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -597,7 +597,7 @@
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
@@ -605,7 +605,7 @@
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
|
||||
+842
-841
File diff suppressed because it is too large.
Load diff
+947
-947
File diff suppressed because it is too large.
Load diff
+140
-140
@@ -42,120 +42,120 @@ typedef enum cmc_heap_order_e
|
||||
cmc_min_heap = -1
|
||||
} cmc_heap_order;
|
||||
|
||||
#define HEAP_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_HEAP(PFX, SNAME, V) \
|
||||
CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define HEAP_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_HEAP_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define HEAP_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_HEAP_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, 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 */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_heap_, V *result); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_heap_); \
|
||||
FMOD V *PFX##_peek_ref(SNAME *_heap_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_heap_); \
|
||||
FMOD bool PFX##_full(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_count(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_heap_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#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); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Element Access */ \
|
||||
V PFX##_peek(SNAME *_heap_); \
|
||||
V *PFX##_peek_ref(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 */ \
|
||||
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); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_heap_); \
|
||||
@@ -164,7 +164,7 @@ typedef enum cmc_heap_order_e
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)) \
|
||||
SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
@@ -198,7 +198,7 @@ typedef enum cmc_heap_order_e
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -213,7 +213,7 @@ typedef enum cmc_heap_order_e
|
||||
_heap_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -227,7 +227,7 @@ typedef enum cmc_heap_order_e
|
||||
free(_heap_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element) \
|
||||
bool PFX##_insert(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_heap_)) \
|
||||
{ \
|
||||
@@ -249,7 +249,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_heap_, V *result) \
|
||||
bool PFX##_remove(SNAME *_heap_, V *result) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -266,7 +266,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition) \
|
||||
bool PFX##_insert_if(SNAME *_heap_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_insert(_heap_, element); \
|
||||
@@ -274,7 +274,7 @@ typedef enum cmc_heap_order_e
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition) \
|
||||
bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove(_heap_, result); \
|
||||
@@ -282,7 +282,7 @@ typedef enum cmc_heap_order_e
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_peek(SNAME *_heap_) \
|
||||
V PFX##_peek(SNAME *_heap_) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -290,7 +290,7 @@ typedef enum cmc_heap_order_e
|
||||
return _heap_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_peek_ref(SNAME *_heap_) \
|
||||
V *PFX##_peek_ref(SNAME *_heap_) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return NULL; \
|
||||
@@ -298,7 +298,7 @@ typedef enum cmc_heap_order_e
|
||||
return &(_heap_->buffer[0]); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
@@ -309,27 +309,27 @@ typedef enum cmc_heap_order_e
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_heap_) \
|
||||
bool PFX##_empty(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_heap_) \
|
||||
bool PFX##_full(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count >= _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_heap_) \
|
||||
size_t PFX##_count(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_) \
|
||||
size_t PFX##_capacity(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_heap_->capacity, _heap_->HO, _heap_->cmp); \
|
||||
\
|
||||
@@ -349,7 +349,7 @@ typedef enum cmc_heap_order_e
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_) \
|
||||
bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_) \
|
||||
{ \
|
||||
if (PFX##_count(_heap1_) != PFX##_count(_heap2_)) \
|
||||
return false; \
|
||||
@@ -363,7 +363,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_heap_) \
|
||||
cmc_string PFX##_to_string(SNAME *_heap_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *h_ = _heap_; \
|
||||
@@ -376,7 +376,7 @@ typedef enum cmc_heap_order_e
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -388,12 +388,12 @@ typedef enum cmc_heap_order_e
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
@@ -401,17 +401,17 @@ typedef enum cmc_heap_order_e
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -421,7 +421,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -431,7 +431,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -449,7 +449,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -468,7 +468,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -493,7 +493,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -515,7 +515,7 @@ typedef enum cmc_heap_order_e
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -528,7 +528,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -536,7 +536,7 @@ typedef enum cmc_heap_order_e
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
|
||||
+886
-886
File diff suppressed because it is too large.
Load diff
+165
-165
@@ -49,137 +49,137 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define LIST_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
LIST_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_LIST(PFX, SNAME, V) \
|
||||
CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define LIST_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
LIST_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_LIST_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_LIST_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define LIST_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_LIST_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define LIST_GENERATE_HEADER(PFX, SNAME, FMOD, 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; \
|
||||
\
|
||||
/* 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 */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD SNAME *PFX##_new_from(V *elements, size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_list_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_list_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, V element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, V element, size_t index); \
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, V element); \
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition); \
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition); \
|
||||
/* Collection Range Input and Output */ \
|
||||
FMOD bool PFX##_prepend(SNAME *_list_, V *elements, size_t size); \
|
||||
FMOD bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index); \
|
||||
FMOD bool PFX##_append(SNAME *_list_, V *elements, size_t size); \
|
||||
FMOD bool PFX##_remove(SNAME *_list_, size_t from, size_t to); \
|
||||
FMOD SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_front(SNAME *_list_); \
|
||||
FMOD V PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD V *PFX##_get_ref(SNAME *_list_, size_t index); \
|
||||
FMOD V PFX##_back(SNAME *_list_); \
|
||||
FMOD size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_list_); \
|
||||
FMOD bool PFX##_full(SNAME *_list_); \
|
||||
FMOD size_t PFX##_count(SNAME *_list_); \
|
||||
FMOD bool PFX##_fits(SNAME *_list_, size_t size); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_list_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_LIST_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; \
|
||||
\
|
||||
/* 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); \
|
||||
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)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_push_front(SNAME *_list_, V element); \
|
||||
bool PFX##_push(SNAME *_list_, V element, size_t index); \
|
||||
bool PFX##_push_back(SNAME *_list_, V element); \
|
||||
bool PFX##_pop_front(SNAME *_list_); \
|
||||
bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
bool PFX##_pop_back(SNAME *_list_); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition); \
|
||||
bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition); \
|
||||
/* Collection Range Input and Output */ \
|
||||
bool PFX##_prepend(SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index); \
|
||||
bool PFX##_append(SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_remove(SNAME *_list_, size_t from, size_t to); \
|
||||
SNAME *PFX##_extract(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); \
|
||||
/* 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_); \
|
||||
/* Collection Utility */ \
|
||||
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_); \
|
||||
\
|
||||
/* 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); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_list_, size_t required); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
@@ -208,7 +208,7 @@
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_new_from(V *elements, size_t size) \
|
||||
SNAME *PFX##_new_from(V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return NULL; \
|
||||
@@ -225,7 +225,7 @@
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -238,7 +238,7 @@
|
||||
_list_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \
|
||||
void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -250,7 +250,7 @@
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, V element) \
|
||||
bool PFX##_push_front(SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
@@ -270,7 +270,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_list_, V element, size_t index) \
|
||||
bool PFX##_push(SNAME *_list_, V element, size_t index) \
|
||||
{ \
|
||||
if (index > _list_->count) \
|
||||
return false; \
|
||||
@@ -299,7 +299,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, V element) \
|
||||
bool PFX##_push_back(SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
@@ -312,7 +312,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_) \
|
||||
bool PFX##_pop_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -324,7 +324,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -348,7 +348,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_) \
|
||||
bool PFX##_pop_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -358,7 +358,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition) \
|
||||
bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_list_, element, index); \
|
||||
@@ -366,7 +366,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition) \
|
||||
bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_list_, index); \
|
||||
@@ -374,7 +374,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_prepend(SNAME *_list_, V *elements, size_t size) \
|
||||
bool PFX##_prepend(SNAME *_list_, V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return false; \
|
||||
@@ -394,7 +394,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index) \
|
||||
bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index) \
|
||||
{ \
|
||||
if (size == 0 || index > _list_->count) \
|
||||
return false; \
|
||||
@@ -421,7 +421,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_append(SNAME *_list_, V *elements, size_t size) \
|
||||
bool PFX##_append(SNAME *_list_, V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return false; \
|
||||
@@ -439,7 +439,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_list_, size_t from, size_t to) \
|
||||
bool PFX##_remove(SNAME *_list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to || to >= _list_->count) \
|
||||
return false; \
|
||||
@@ -455,7 +455,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to) \
|
||||
SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to || to >= _list_->count) \
|
||||
return false; \
|
||||
@@ -476,7 +476,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_front(SNAME *_list_) \
|
||||
V PFX##_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -484,7 +484,7 @@
|
||||
return _list_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_get(SNAME *_list_, size_t index) \
|
||||
V PFX##_get(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count || PFX##_empty(_list_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -492,7 +492,7 @@
|
||||
return _list_->buffer[index]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_get_ref(SNAME *_list_, size_t index) \
|
||||
V *PFX##_get_ref(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return NULL; \
|
||||
@@ -503,7 +503,7 @@
|
||||
return &(_list_->buffer[index]); \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_back(SNAME *_list_) \
|
||||
V PFX##_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -511,7 +511,7 @@
|
||||
return _list_->buffer[_list_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start) \
|
||||
size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start) \
|
||||
{ \
|
||||
if (from_start) \
|
||||
{ \
|
||||
@@ -533,7 +533,7 @@
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
@@ -544,32 +544,32 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_list_) \
|
||||
bool PFX##_full(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count >= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_list_) \
|
||||
size_t PFX##_count(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_fits(SNAME *_list_, size_t size) \
|
||||
bool PFX##_fits(SNAME *_list_, size_t size) \
|
||||
{ \
|
||||
return _list_->count + size <= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_) \
|
||||
size_t PFX##_capacity(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_list_->capacity); \
|
||||
\
|
||||
@@ -589,7 +589,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)) \
|
||||
bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_list1_) != PFX##_count(_list2_)) \
|
||||
return false; \
|
||||
@@ -603,7 +603,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_list_) \
|
||||
cmc_string PFX##_to_string(SNAME *_list_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *l_ = _list_; \
|
||||
@@ -615,7 +615,7 @@
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -627,12 +627,12 @@
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
@@ -640,17 +640,17 @@
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -660,7 +660,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -670,7 +670,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -688,7 +688,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -707,7 +707,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -729,7 +729,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -751,7 +751,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -764,7 +764,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -772,7 +772,7 @@
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
@@ -780,7 +780,7 @@
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
|
||||
+143
-143
@@ -49,130 +49,130 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define QUEUE_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_QUEUE(PFX, SNAME, V) \
|
||||
CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define QUEUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_QUEUE_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define QUEUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_QUEUE_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Queue 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 queue */ \
|
||||
size_t front; \
|
||||
\
|
||||
/* Index representing the back of the queue */ \
|
||||
size_t back; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the queue */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the queue */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Queue Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target queue */ \
|
||||
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 */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_queue_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_queue_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element); \
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition); \
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_queue_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_queue_); \
|
||||
FMOD bool PFX##_full(SNAME *_queue_); \
|
||||
FMOD size_t PFX##_count(SNAME *_queue_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_queue_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_queue_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_queue1_, SNAME *_queue2_, int (*comparator)(V, V)); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_queue_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Queue 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 queue */ \
|
||||
size_t front; \
|
||||
\
|
||||
/* Index representing the back of the queue */ \
|
||||
size_t back; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the queue */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the queue */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Queue Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target queue */ \
|
||||
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 *_queue_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_queue_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_enqueue(SNAME *_queue_, V element); \
|
||||
bool PFX##_dequeue(SNAME *_queue_); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition); \
|
||||
bool PFX##_dequeue_if(SNAME *_queue_, bool condition); \
|
||||
/* Element Access */ \
|
||||
V PFX##_peek(SNAME *_queue_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_queue_); \
|
||||
bool PFX##_full(SNAME *_queue_); \
|
||||
size_t PFX##_count(SNAME *_queue_); \
|
||||
size_t PFX##_capacity(SNAME *_queue_); \
|
||||
/* Collection Utility */ \
|
||||
SNAME *PFX##_copy_of(SNAME *_queue_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_queue1_, SNAME *_queue2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_queue_); \
|
||||
\
|
||||
/* 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); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
@@ -203,7 +203,7 @@
|
||||
return _queue_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -220,7 +220,7 @@
|
||||
_queue_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
void PFX##_free(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -234,7 +234,7 @@
|
||||
free(_queue_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \
|
||||
bool PFX##_enqueue(SNAME *_queue_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_queue_)) \
|
||||
{ \
|
||||
@@ -250,7 +250,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_) \
|
||||
bool PFX##_dequeue(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return false; \
|
||||
@@ -263,7 +263,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
|
||||
bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_enqueue(_queue_, element); \
|
||||
@@ -271,7 +271,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
|
||||
bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_dequeue(_queue_); \
|
||||
@@ -279,7 +279,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_peek(SNAME *_queue_) \
|
||||
V PFX##_peek(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -287,7 +287,7 @@
|
||||
return _queue_->buffer[_queue_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \
|
||||
{ \
|
||||
@@ -298,27 +298,27 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_queue_) \
|
||||
bool PFX##_empty(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_queue_) \
|
||||
bool PFX##_full(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count >= _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_queue_) \
|
||||
size_t PFX##_count(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_queue_) \
|
||||
size_t PFX##_capacity(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_queue_, V (*copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_queue_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_queue_->capacity); \
|
||||
\
|
||||
@@ -345,7 +345,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_queue1_, SNAME *_queue2_, int (*comparator)(V, V)) \
|
||||
bool PFX##_equals(SNAME *_queue1_, SNAME *_queue2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_queue1_) != PFX##_count(_queue2_)) \
|
||||
return false; \
|
||||
@@ -363,7 +363,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_queue_) \
|
||||
cmc_string PFX##_to_string(SNAME *_queue_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *q_ = _queue_; \
|
||||
@@ -375,7 +375,7 @@
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -387,12 +387,12 @@
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->front; \
|
||||
@@ -401,17 +401,17 @@
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->front; \
|
||||
iter->index = 0; \
|
||||
@@ -419,7 +419,7 @@
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
iter->cursor = 0; \
|
||||
@@ -431,7 +431,7 @@
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -450,7 +450,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -470,7 +470,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -493,7 +493,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -521,7 +521,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -534,7 +534,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -542,7 +542,7 @@
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
@@ -550,7 +550,7 @@
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
|
||||
+494
-494
@@ -34,505 +34,505 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define STACK_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_STACK(PFX, SNAME, V) \
|
||||
CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define STACK_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_STACK_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_STACK_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define STACK_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_STACK_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define STACK_GENERATE_HEADER(PFX, SNAME, FMOD, 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 */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element); \
|
||||
FMOD bool PFX##_pop(SNAME *_stack_); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition); \
|
||||
FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_top(SNAME *_stack_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_stack_); \
|
||||
FMOD bool PFX##_full(SNAME *_stack_); \
|
||||
FMOD size_t PFX##_count(SNAME *_stack_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_stack_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_stack_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_stack1_, SNAME *_stack2_, int (*comparator)(V, V)); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_stack_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#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_); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_push_if(SNAME *_stack_, V element, bool condition); \
|
||||
bool PFX##_pop_if(SNAME *_stack_, bool condition); \
|
||||
/* 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 */ \
|
||||
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); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_stack_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_stack_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_stack_) \
|
||||
return NULL; \
|
||||
\
|
||||
_stack_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_stack_->capacity = capacity; \
|
||||
_stack_->count = 0; \
|
||||
\
|
||||
_stack_->it_start = PFX##_impl_it_start; \
|
||||
_stack_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_stack_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
deallocator(_stack_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
|
||||
\
|
||||
_stack_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_stack_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
free(_stack_->buffer); \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
deallocator(_stack_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
free(_stack_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_stack_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_stack_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_stack_->buffer[_stack_->count++] = element; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer[--_stack_->count] = PFX##_impl_default_value(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_stack_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_stack_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_top(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _stack_->buffer[_stack_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD 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; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count >= _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD 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; \
|
||||
} \
|
||||
\
|
||||
FMOD 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; \
|
||||
} \
|
||||
\
|
||||
FMOD 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; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = PFX##_empty(target) ? 0 : iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD 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; \
|
||||
} \
|
||||
\
|
||||
FMOD 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 */ \
|
||||
FMOD 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 */ \
|
||||
FMOD 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 */ \
|
||||
FMOD 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; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
\
|
||||
return iter->target->count - 1 - iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_stack_) \
|
||||
{ \
|
||||
size_t new_capacity = _stack_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = realloc(_stack_->buffer, sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer = new_buffer; \
|
||||
_stack_->capacity = new_capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
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 bool PFX##_impl_grow(SNAME *_stack_); \
|
||||
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 = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_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##_impl_grow(_stack_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_stack_->buffer[_stack_->count++] = element; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer[--_stack_->count] = PFX##_impl_default_value(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_if(SNAME *_stack_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_stack_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_if(SNAME *_stack_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_stack_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V PFX##_top(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
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 PFX##_impl_default_value(); \
|
||||
\
|
||||
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 bool PFX##_impl_grow(SNAME *_stack_) \
|
||||
{ \
|
||||
size_t new_capacity = _stack_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = realloc(_stack_->buffer, sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer = new_buffer; \
|
||||
_stack_->capacity = new_capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
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; \
|
||||
}
|
||||
|
||||
#endif /* CMC_STACK_H */
|
||||
+182
-182
@@ -25,159 +25,159 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define TREEMAP_GENERATE(PFX, SNAME, FMOD, K, V) \
|
||||
TREEMAP_GENERATE_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
TREEMAP_GENERATE_SOURCE(PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_GENERATE_TREEMAP(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V)
|
||||
|
||||
#define TREEMAP_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
TREEMAP_GENERATE_HEADER(PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_WRAPGEN_TREEMAP_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V)
|
||||
|
||||
#define TREEMAP_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
TREEMAP_GENERATE_SOURCE(PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_WRAPGEN_TREEMAP_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define TREEMAP_GENERATE_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
\
|
||||
/* Treemap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Root node */ \
|
||||
struct SNAME##_node_s *root; \
|
||||
\
|
||||
/* Current amount of keys */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Key comparison function */ \
|
||||
int (*cmp)(K, K); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the treemap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the treemap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Treemap Node */ \
|
||||
typedef struct SNAME##_node_s \
|
||||
{ \
|
||||
/* Node Key */ \
|
||||
K key; \
|
||||
\
|
||||
/* Node Value */ \
|
||||
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; \
|
||||
\
|
||||
/* Treemap Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target treemap */ \
|
||||
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 */ \
|
||||
FMOD SNAME *PFX##_new(int (*compare)(K, K)); \
|
||||
FMOD void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
FMOD void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_map_, K key, V value); \
|
||||
FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \
|
||||
FMOD bool PFX##_remove(SNAME *_map_, K key, V *out_value); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_map_, K key, V *out_value, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD bool PFX##_max(SNAME *_map_, K *key, V *value); \
|
||||
FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \
|
||||
FMOD V PFX##_get(SNAME *_map_, K key); \
|
||||
FMOD V *PFX##_get_ref(SNAME *_map_, K key); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_map_, K key); \
|
||||
FMOD bool PFX##_empty(SNAME *_map_); \
|
||||
FMOD size_t PFX##_count(SNAME *_map_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_map_, K (*key_copy_func)(K), V (*value_copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_map1_, SNAME *_map2_, int (*value_comparator)(V, V)); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_map_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD K PFX##_iter_key(SNAME##_iter *iter); \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Key */ \
|
||||
static inline K PFX##_impl_default_key(void) \
|
||||
{ \
|
||||
K _empty_key_; \
|
||||
\
|
||||
memset(&_empty_key_, 0, sizeof(K)); \
|
||||
\
|
||||
return _empty_key_; \
|
||||
} \
|
||||
\
|
||||
/* 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_TREEMAP_HEADER(PFX, SNAME, K, V) \
|
||||
\
|
||||
/* Treemap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Root node */ \
|
||||
struct SNAME##_node_s *root; \
|
||||
\
|
||||
/* Current amount of keys */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Key comparison function */ \
|
||||
int (*cmp)(K, K); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the treemap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the treemap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Treemap Node */ \
|
||||
typedef struct SNAME##_node_s \
|
||||
{ \
|
||||
/* Node Key */ \
|
||||
K key; \
|
||||
\
|
||||
/* Node Value */ \
|
||||
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; \
|
||||
\
|
||||
/* Treemap Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target treemap */ \
|
||||
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)(K, K)); \
|
||||
void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(SNAME *_map_, K key, V value); \
|
||||
bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \
|
||||
bool PFX##_remove(SNAME *_map_, K key, V *out_value); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition); \
|
||||
bool PFX##_remove_if(SNAME *_map_, K key, V *out_value, bool condition); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(SNAME *_map_, K *key, V *value); \
|
||||
bool PFX##_min(SNAME *_map_, K *key, V *value); \
|
||||
V PFX##_get(SNAME *_map_, K key); \
|
||||
V *PFX##_get_ref(SNAME *_map_, K key); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_map_, K key); \
|
||||
bool PFX##_empty(SNAME *_map_); \
|
||||
size_t PFX##_count(SNAME *_map_); \
|
||||
/* Collection Utility */ \
|
||||
SNAME *PFX##_copy_of(SNAME *_map_, K (*key_copy_func)(K), V (*value_copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_map1_, SNAME *_map2_, int (*value_comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_map_); \
|
||||
\
|
||||
/* 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 */ \
|
||||
K PFX##_iter_key(SNAME##_iter *iter); \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Key */ \
|
||||
static inline K PFX##_impl_default_key(void) \
|
||||
{ \
|
||||
K _empty_key_; \
|
||||
\
|
||||
memset(&_empty_key_, 0, sizeof(K)); \
|
||||
\
|
||||
return _empty_key_; \
|
||||
} \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define TREEMAP_GENERATE_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
#define CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_node *PFX##_impl_new_node(K key, V value); \
|
||||
@@ -190,7 +190,7 @@
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_map_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_map_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(int (*compare)(K, K)) \
|
||||
SNAME *PFX##_new(int (*compare)(K, K)) \
|
||||
{ \
|
||||
SNAME *_map_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
@@ -207,7 +207,7 @@
|
||||
return _map_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
void PFX##_clear(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _map_->root; \
|
||||
SNAME##_node *up = NULL; \
|
||||
@@ -268,14 +268,14 @@
|
||||
_map_->root = NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
void PFX##_free(SNAME *_map_, void (*deallocator)(K, V)) \
|
||||
{ \
|
||||
PFX##_clear(_map_, deallocator); \
|
||||
\
|
||||
free(_map_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_map_, K key, V value) \
|
||||
bool PFX##_insert(SNAME *_map_, K key, V value) \
|
||||
{ \
|
||||
if (PFX##_empty(_map_)) \
|
||||
{ \
|
||||
@@ -332,7 +332,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value) \
|
||||
bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
|
||||
\
|
||||
@@ -347,7 +347,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_map_, K key, V *out_value) \
|
||||
bool PFX##_remove(SNAME *_map_, K key, V *out_value) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
|
||||
\
|
||||
@@ -473,7 +473,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition) \
|
||||
bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_insert(_map_, key, value); \
|
||||
@@ -481,7 +481,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_map_, K key, V *out_value, bool condition) \
|
||||
bool PFX##_remove_if(SNAME *_map_, K key, V *out_value, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove(_map_, key, out_value); \
|
||||
@@ -489,7 +489,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_max(SNAME *_map_, K *key, V *value) \
|
||||
bool PFX##_max(SNAME *_map_, K *key, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_map_)) \
|
||||
return false; \
|
||||
@@ -505,7 +505,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_min(SNAME *_map_, K *key, V *value) \
|
||||
bool PFX##_min(SNAME *_map_, K *key, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_map_)) \
|
||||
return false; \
|
||||
@@ -521,7 +521,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_get(SNAME *_map_, K key) \
|
||||
V PFX##_get(SNAME *_map_, K key) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
|
||||
\
|
||||
@@ -531,7 +531,7 @@
|
||||
return node->value; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_get_ref(SNAME *_map_, K key) \
|
||||
V *PFX##_get_ref(SNAME *_map_, K key) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
|
||||
\
|
||||
@@ -541,7 +541,7 @@
|
||||
return &(node->value); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_map_, K key) \
|
||||
bool PFX##_contains(SNAME *_map_, K key) \
|
||||
{ \
|
||||
SNAME##_node *scan = _map_->root; \
|
||||
\
|
||||
@@ -558,17 +558,17 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_map_) \
|
||||
bool PFX##_empty(SNAME *_map_) \
|
||||
{ \
|
||||
return _map_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_map_) \
|
||||
size_t PFX##_count(SNAME *_map_) \
|
||||
{ \
|
||||
return _map_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_map_, K (*key_copy_func)(K), V (*value_copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_map_, K (*key_copy_func)(K), V (*value_copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_map_->cmp); \
|
||||
\
|
||||
@@ -597,7 +597,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_map1_, SNAME *_map2_, int (*value_comparator)(V, V)) \
|
||||
bool PFX##_equals(SNAME *_map1_, SNAME *_map2_, int (*value_comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_map1_) != PFX##_count(_map2_)) \
|
||||
return false; \
|
||||
@@ -622,7 +622,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_map_) \
|
||||
cmc_string PFX##_to_string(SNAME *_map_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *m_ = _map_; \
|
||||
@@ -634,7 +634,7 @@
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -646,12 +646,12 @@
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
memset(iter, 0, sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -674,17 +674,17 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -695,7 +695,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -706,7 +706,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -746,7 +746,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -787,7 +787,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -810,7 +810,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -833,7 +833,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -846,7 +846,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD K PFX##_iter_key(SNAME##_iter *iter) \
|
||||
K PFX##_iter_key(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_key(); \
|
||||
@@ -854,7 +854,7 @@
|
||||
return iter->cursor->key; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -862,7 +862,7 @@
|
||||
return iter->cursor->value; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
@@ -870,7 +870,7 @@
|
||||
return &(iter->cursor->value); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
|
||||
+85
-85
@@ -25,18 +25,18 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define TREESET_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
TREESET_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
TREESET_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_TREESET(PFX, SNAME, V) \
|
||||
CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define TREESET_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
TREESET_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_TREESET_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define TREESET_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
TREESET_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_TREESET_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define TREESET_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Treeset Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
@@ -106,58 +106,58 @@
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
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 */ \
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element); \
|
||||
bool PFX##_insert(SNAME *_set_, V element); \
|
||||
bool PFX##_remove(SNAME *_set_, V element); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_set_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
bool PFX##_insert_if(SNAME *_set_, V element, bool condition); \
|
||||
bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD bool PFX##_max(SNAME *_set_, V *value); \
|
||||
FMOD bool PFX##_min(SNAME *_set_, V *value); \
|
||||
bool PFX##_max(SNAME *_set_, V *value); \
|
||||
bool PFX##_min(SNAME *_set_, V *value); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_set_); \
|
||||
FMOD size_t PFX##_count(SNAME *_set_); \
|
||||
bool PFX##_contains(SNAME *_set_, V element); \
|
||||
bool PFX##_empty(SNAME *_set_); \
|
||||
size_t PFX##_count(SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_set_); \
|
||||
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 */ \
|
||||
FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_); \
|
||||
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 */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
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 */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
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) \
|
||||
@@ -170,7 +170,7 @@
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define TREESET_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_node *PFX##_impl_new_node(V element); \
|
||||
@@ -183,7 +183,7 @@
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(int (*compare)(V, V)) \
|
||||
SNAME *PFX##_new(int (*compare)(V, V)) \
|
||||
{ \
|
||||
SNAME *_set_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
@@ -200,7 +200,7 @@
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
SNAME##_node *up = NULL; \
|
||||
@@ -261,14 +261,14 @@
|
||||
_set_->root = NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
PFX##_clear(_set_, deallocator); \
|
||||
\
|
||||
free(_set_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element) \
|
||||
bool PFX##_insert(SNAME *_set_, V element) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
{ \
|
||||
@@ -325,7 +325,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element) \
|
||||
bool PFX##_remove(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_impl_get_node(_set_, element); \
|
||||
\
|
||||
@@ -446,7 +446,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_set_, V element, bool condition) \
|
||||
bool PFX##_insert_if(SNAME *_set_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_insert(_set_, element); \
|
||||
@@ -454,7 +454,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition) \
|
||||
bool PFX##_remove_if(SNAME *_set_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove(_set_, element); \
|
||||
@@ -462,7 +462,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_max(SNAME *_set_, V *value) \
|
||||
bool PFX##_max(SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
@@ -477,7 +477,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_min(SNAME *_set_, V *value) \
|
||||
bool PFX##_min(SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
@@ -492,7 +492,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element) \
|
||||
bool PFX##_contains(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
\
|
||||
@@ -509,17 +509,17 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_set_) \
|
||||
bool PFX##_empty(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_set_) \
|
||||
size_t PFX##_count(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_set_->cmp); \
|
||||
\
|
||||
@@ -543,7 +543,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) != PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -560,7 +560,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _set_; \
|
||||
@@ -572,7 +572,7 @@
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
@@ -596,7 +596,7 @@
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
@@ -620,7 +620,7 @@
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
@@ -641,7 +641,7 @@
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->cmp); \
|
||||
\
|
||||
@@ -674,7 +674,7 @@
|
||||
/* 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 */ \
|
||||
FMOD bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_subset(SNAME *_set1_, 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_ */ \
|
||||
@@ -703,7 +703,7 @@
|
||||
/* 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 */ \
|
||||
FMOD bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_subset(_set2_, _set1_); \
|
||||
} \
|
||||
@@ -711,7 +711,7 @@
|
||||
/* 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 */ \
|
||||
FMOD bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, 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_ */ \
|
||||
@@ -746,7 +746,7 @@
|
||||
/* 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 */ \
|
||||
FMOD bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_proper_subset(_set2_, _set1_); \
|
||||
} \
|
||||
@@ -754,7 +754,7 @@
|
||||
/* 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 */ \
|
||||
FMOD bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
/* The intersection of an empty set with any other set will result in an empty */ \
|
||||
/* set */ \
|
||||
@@ -776,7 +776,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -788,12 +788,12 @@
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
memset(iter, 0, sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -816,17 +816,17 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -837,7 +837,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -848,7 +848,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -888,7 +888,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -930,7 +930,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -953,7 +953,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -976,7 +976,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -989,7 +989,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -997,7 +997,7 @@
|
||||
return iter->cursor->value; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
|
||||
+158
-158
@@ -27,134 +27,134 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define INTERVALHEAP_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
INTERVALHEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
INTERVALHEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_INTERVALHEAP(PFX, SNAME, V) \
|
||||
CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define INTERVALHEAP_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
INTERVALHEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_INTERVALHEAP_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define INTERVALHEAP_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
INTERVALHEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_INTERVALHEAP_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define INTERVALHEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of nodes */ \
|
||||
struct SNAME##_node_s *buffer; \
|
||||
\
|
||||
/* Current array capacity (how many nodes can be stored) */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of nodes in the dynamic array */ \
|
||||
size_t size; \
|
||||
\
|
||||
/* Current amount of elements in the heap */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* 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 Node */ \
|
||||
typedef struct SNAME##_node_s \
|
||||
{ \
|
||||
/* 0 - Value belonging to the MinHeap */ \
|
||||
/* 1 - Value belonging to the MaxHeap */ \
|
||||
V data[2]; \
|
||||
\
|
||||
} SNAME##_node, *SNAME##_node_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 */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_remove_max(SNAME *_heap_, V *result); \
|
||||
FMOD bool PFX##_remove_min(SNAME *_heap_, V *result); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_max_if(SNAME *_heap_, V *result, bool condition); \
|
||||
FMOD bool PFX##_remove_min_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Collection Update */ \
|
||||
FMOD bool PFX##_update_max(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_update_min(SNAME *_heap_, V element); \
|
||||
/* Element Access */ \
|
||||
FMOD bool PFX##_max(SNAME *_heap_, V *value); \
|
||||
FMOD bool PFX##_min(SNAME *_heap_, V *value); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_heap_); \
|
||||
FMOD bool PFX##_full(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_count(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_heap_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of nodes */ \
|
||||
struct SNAME##_node_s *buffer; \
|
||||
\
|
||||
/* Current array capacity (how many nodes can be stored) */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of nodes in the dynamic array */ \
|
||||
size_t size; \
|
||||
\
|
||||
/* Current amount of elements in the heap */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* 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 Node */ \
|
||||
typedef struct SNAME##_node_s \
|
||||
{ \
|
||||
/* 0 - Value belonging to the MinHeap */ \
|
||||
/* 1 - Value belonging to the MaxHeap */ \
|
||||
V data[2]; \
|
||||
\
|
||||
} SNAME##_node, *SNAME##_node_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, 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_max(SNAME *_heap_, V *result); \
|
||||
bool PFX##_remove_min(SNAME *_heap_, V *result); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
bool PFX##_remove_max_if(SNAME *_heap_, V *result, bool condition); \
|
||||
bool PFX##_remove_min_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Collection Update */ \
|
||||
bool PFX##_update_max(SNAME *_heap_, V element); \
|
||||
bool PFX##_update_min(SNAME *_heap_, V element); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(SNAME *_heap_, V *value); \
|
||||
bool PFX##_min(SNAME *_heap_, V *value); \
|
||||
/* 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 */ \
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, 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); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define INTERVALHEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_heap_); \
|
||||
@@ -165,7 +165,7 @@
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)) \
|
||||
SNAME *PFX##_new(size_t capacity, int (*compare)(V, V)) \
|
||||
{ \
|
||||
SNAME *_heap_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
@@ -197,7 +197,7 @@
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -213,7 +213,7 @@
|
||||
_heap_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -228,7 +228,7 @@
|
||||
free(_heap_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element) \
|
||||
bool PFX##_insert(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_heap_)) \
|
||||
{ \
|
||||
@@ -279,7 +279,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_max(SNAME *_heap_, V *result) \
|
||||
bool PFX##_remove_max(SNAME *_heap_, V *result) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -324,7 +324,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_min(SNAME *_heap_, V *result) \
|
||||
bool PFX##_remove_min(SNAME *_heap_, V *result) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -367,7 +367,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition) \
|
||||
bool PFX##_insert_if(SNAME *_heap_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_insert(_heap_, element); \
|
||||
@@ -375,7 +375,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_max_if(SNAME *_heap_, V *result, bool condition) \
|
||||
bool PFX##_remove_max_if(SNAME *_heap_, V *result, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove_max(_heap_, result); \
|
||||
@@ -383,7 +383,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_min_if(SNAME *_heap_, V *result, bool condition) \
|
||||
bool PFX##_remove_min_if(SNAME *_heap_, V *result, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove_min(_heap_, result); \
|
||||
@@ -391,7 +391,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_update_max(SNAME *_heap_, V element) \
|
||||
bool PFX##_update_max(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -420,7 +420,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_update_min(SNAME *_heap_, V element) \
|
||||
bool PFX##_update_min(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -449,7 +449,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_max(SNAME *_heap_, V *value) \
|
||||
bool PFX##_max(SNAME *_heap_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -464,7 +464,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_min(SNAME *_heap_, V *value) \
|
||||
bool PFX##_min(SNAME *_heap_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -474,7 +474,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
@@ -485,28 +485,28 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_heap_) \
|
||||
bool PFX##_empty(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_heap_) \
|
||||
bool PFX##_full(SNAME *_heap_) \
|
||||
{ \
|
||||
/* The heap is full if all nodes are completely filled */ \
|
||||
return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_heap_) \
|
||||
size_t PFX##_count(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_) \
|
||||
size_t PFX##_capacity(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
@@ -534,7 +534,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_) \
|
||||
bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_) \
|
||||
{ \
|
||||
if (PFX##_count(_heap1_) != PFX##_count(_heap2_)) \
|
||||
return false; \
|
||||
@@ -551,7 +551,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_heap_) \
|
||||
cmc_string PFX##_to_string(SNAME *_heap_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *h_ = _heap_; \
|
||||
@@ -563,7 +563,7 @@
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -575,12 +575,12 @@
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
@@ -588,17 +588,17 @@
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -608,7 +608,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -618,7 +618,7 @@
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -636,7 +636,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -655,7 +655,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -677,7 +677,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -699,7 +699,7 @@
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator was able to be positioned at the given index */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -712,7 +712,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -720,7 +720,7 @@
|
||||
return iter->target->buffer[iter->cursor / 2].data[iter->cursor % 2]; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
|
||||
+1044
-1044
File diff suppressed because it is too large.
Load diff
+203
-203
@@ -71,168 +71,168 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
|
||||
#endif /* CMC_HASH_TABLE_SETUP */
|
||||
|
||||
#define MULTISET_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
MULTISET_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
MULTISET_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_MULTISET(PFX, SNAME, V) \
|
||||
CMC_GENERATE_MULTISET_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_MULTISET_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define MULTISET_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
MULTISET_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_MULTISET_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_MULTISET_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define MULTISET_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
MULTISET_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_MULTISET_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_MULTISET_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define MULTISET_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Hashset Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Array of Entries */ \
|
||||
struct SNAME##_entry_s *buffer; \
|
||||
\
|
||||
/* Current Array Capcity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of unique elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Total amount of elements taking into account their multiplicity */ \
|
||||
size_t cardinality; \
|
||||
\
|
||||
/* Load factor in range (0.0, 1.0) */ \
|
||||
double load; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Element hash function */ \
|
||||
size_t (*hash)(V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
typedef struct SNAME##_entry_s \
|
||||
{ \
|
||||
/* Entry element */ \
|
||||
V value; \
|
||||
\
|
||||
/* The element's multiplicity */ \
|
||||
size_t multiplicity; \
|
||||
\
|
||||
/* The distance of this node to its original position, used by robin-hood hashing */ \
|
||||
size_t dist; \
|
||||
\
|
||||
/* The sate of this node (DELETED, EMPTY, FILLED) */ \
|
||||
enum cmc_entry_state_e state; \
|
||||
\
|
||||
} SNAME##_entry, *SNAME##_entry_ptr; \
|
||||
\
|
||||
/* Hashset Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target Hashset */ \
|
||||
struct SNAME##_s *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* The index of the first element */ \
|
||||
size_t first; \
|
||||
\
|
||||
/* The index of the last element */ \
|
||||
size_t last; \
|
||||
\
|
||||
/* If the iterator has reached the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)); \
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_insert_many(SNAME *_set_, V element, size_t count); \
|
||||
FMOD bool PFX##_update(SNAME *_set_, V element, size_t multiplicity); \
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element); \
|
||||
FMOD size_t PFX##_remove_all(SNAME *_set_, V element); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_set_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD bool PFX##_max(SNAME *_set_, V *value); \
|
||||
FMOD bool PFX##_min(SNAME *_set_, V *value); \
|
||||
FMOD size_t PFX##_multiplicity_of(SNAME *_set_, V element); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_set_); \
|
||||
FMOD size_t PFX##_count(SNAME *_set_); \
|
||||
FMOD size_t PFX##_cardinality(SNAME *_set_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)); \
|
||||
FMOD bool PFX##_equals(SNAME *_set1_, SNAME *_set2_, bool ignore_multiplicity); \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_set_); \
|
||||
\
|
||||
/* Set Operations */ \
|
||||
FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_multiplicity(SNAME##_iter *iter); \
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
{ \
|
||||
V _empty_value_; \
|
||||
\
|
||||
memset(&_empty_value_, 0, sizeof(V)); \
|
||||
\
|
||||
return _empty_value_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_MULTISET_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Hashset Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Array of Entries */ \
|
||||
struct SNAME##_entry_s *buffer; \
|
||||
\
|
||||
/* Current Array Capcity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of unique elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Total amount of elements taking into account their multiplicity */ \
|
||||
size_t cardinality; \
|
||||
\
|
||||
/* Load factor in range (0.0, 1.0) */ \
|
||||
double load; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Element hash function */ \
|
||||
size_t (*hash)(V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
typedef struct SNAME##_entry_s \
|
||||
{ \
|
||||
/* Entry element */ \
|
||||
V value; \
|
||||
\
|
||||
/* The element's multiplicity */ \
|
||||
size_t multiplicity; \
|
||||
\
|
||||
/* The distance of this node to its original position, used by robin-hood hashing */ \
|
||||
size_t dist; \
|
||||
\
|
||||
/* The sate of this node (DELETED, EMPTY, FILLED) */ \
|
||||
enum cmc_entry_state_e state; \
|
||||
\
|
||||
} SNAME##_entry, *SNAME##_entry_ptr; \
|
||||
\
|
||||
/* Hashset Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target Hashset */ \
|
||||
struct SNAME##_s *target; \
|
||||
\
|
||||
/* Cursor's position (index) */ \
|
||||
size_t cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* The index of the first element */ \
|
||||
size_t first; \
|
||||
\
|
||||
/* The index of the last element */ \
|
||||
size_t last; \
|
||||
\
|
||||
/* If the iterator has reached the start of the iteration */ \
|
||||
bool start; \
|
||||
\
|
||||
/* If the iterator has reached the end of the iteration */ \
|
||||
bool end; \
|
||||
\
|
||||
} 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)); \
|
||||
/* 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); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_insert_if(SNAME *_set_, V element, bool condition); \
|
||||
bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
/* 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); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_set_, V element); \
|
||||
bool PFX##_empty(SNAME *_set_); \
|
||||
size_t PFX##_count(SNAME *_set_); \
|
||||
size_t PFX##_cardinality(SNAME *_set_); \
|
||||
size_t PFX##_capacity(SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
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_); \
|
||||
\
|
||||
/* 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_); \
|
||||
\
|
||||
/* 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_multiplicity(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_; \
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define MULTISET_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#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); \
|
||||
@@ -242,7 +242,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)) \
|
||||
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; \
|
||||
@@ -281,7 +281,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -301,7 +301,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
_set_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
@@ -320,7 +320,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
free(_set_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element) \
|
||||
bool PFX##_insert(SNAME *_set_, V element) \
|
||||
{ \
|
||||
bool new_node; \
|
||||
\
|
||||
@@ -337,7 +337,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_many(SNAME *_set_, V element, size_t count) \
|
||||
bool PFX##_insert_many(SNAME *_set_, V element, size_t count) \
|
||||
{ \
|
||||
if (count == 0) \
|
||||
return true; \
|
||||
@@ -359,7 +359,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_update(SNAME *_set_, V element, size_t multiplicity) \
|
||||
bool PFX##_update(SNAME *_set_, V element, size_t multiplicity) \
|
||||
{ \
|
||||
if (multiplicity == 0) \
|
||||
return PFX##_remove_all(_set_, element); \
|
||||
@@ -381,7 +381,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element) \
|
||||
bool PFX##_remove(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
@@ -405,7 +405,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_remove_all(SNAME *_set_, V element) \
|
||||
size_t PFX##_remove_all(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
@@ -425,7 +425,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return removed; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_set_, V element, bool condition) \
|
||||
bool PFX##_insert_if(SNAME *_set_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_insert(_set_, element); \
|
||||
@@ -433,7 +433,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition) \
|
||||
bool PFX##_remove_if(SNAME *_set_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove(_set_, element); \
|
||||
@@ -441,7 +441,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_max(SNAME *_set_, V *value) \
|
||||
bool PFX##_max(SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
@@ -462,7 +462,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_min(SNAME *_set_, V *value) \
|
||||
bool PFX##_min(SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
@@ -483,7 +483,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_multiplicity_of(SNAME *_set_, V element) \
|
||||
size_t PFX##_multiplicity_of(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *entry = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
@@ -493,32 +493,32 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return entry->multiplicity; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element) \
|
||||
bool PFX##_contains(SNAME *_set_, V element) \
|
||||
{ \
|
||||
return PFX##_impl_get_entry(_set_, element) != NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_set_) \
|
||||
bool PFX##_empty(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_set_) \
|
||||
size_t PFX##_count(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_cardinality(SNAME *_set_) \
|
||||
size_t PFX##_cardinality(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->cardinality; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_set_) \
|
||||
size_t PFX##_capacity(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)) \
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_set_->capacity, _set_->load, _set_->cmp, _set_->hash); \
|
||||
\
|
||||
@@ -557,7 +557,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_equals(SNAME *_set1_, SNAME *_set2_, bool ignore_multiplicity) \
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_, bool ignore_multiplicity) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) != PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -585,7 +585,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _set_; \
|
||||
@@ -597,7 +597,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -633,7 +633,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -660,7 +660,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -684,7 +684,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -708,7 +708,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME##_iter iter1, iter2; \
|
||||
\
|
||||
@@ -755,7 +755,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) > PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -781,12 +781,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_subset(_set2_, _set1_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) >= PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -817,12 +817,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_proper_subset(_set2_, _set1_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_empty(_set1_)) \
|
||||
return true; \
|
||||
@@ -842,7 +842,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -854,12 +854,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
memset(iter, 0, sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -891,17 +891,17 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -912,7 +912,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
@@ -923,7 +923,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -952,7 +952,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -982,7 +982,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
@@ -1003,7 +1003,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
FMOD bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
@@ -1024,7 +1024,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 */ \
|
||||
FMOD bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
@@ -1037,7 +1037,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -1045,7 +1045,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter->target->buffer[iter->cursor].value; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_multiplicity(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_multiplicity(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
@@ -1053,7 +1053,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter->target->buffer[iter->cursor].multiplicity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
|
||||
+12
-14
@@ -8,26 +8,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CMC_MACRO_COLLECTIONS
|
||||
#define CMC_MACRO_COLLECTIONS
|
||||
#ifndef CMC_MACRO_COLLECTIONS_H
|
||||
#define CMC_MACRO_COLLECTIONS_H
|
||||
|
||||
#define CMC_CONCATH_(C) C##_WRAPGEN_HEADER
|
||||
#define CMC_CONCATC_(C) C##_WRAPGEN_SOURCE
|
||||
#define CMC_CONCATH_(C) CMC_WRAPGEN_##C##_HEADER
|
||||
#define CMC_CONCATC_(C) CMC_WRAPGEN_##C##_SOURCE
|
||||
|
||||
#define CMC_CONCATH(C) CMC_CONCATH_(C)
|
||||
#define CMC_CONCATC(C) CMC_CONCATC_(C)
|
||||
|
||||
#define COLLECTION_GENERATE(C, PFX, SNAME, FMOD, K, V) \
|
||||
COLLECTION_GENERATE_HEADER(C, PFX, SNAME, FMOD, K, V) \
|
||||
COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_COLLECTION_GENERATE(C, PFX, SNAME, K, V) \
|
||||
CMC_COLLECTION_GENERATE_HEADER(C, PFX, SNAME, K, V) \
|
||||
CMC_COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, K, V)
|
||||
|
||||
#define COLLECTION_GENERATE_HEADER(C, PFX, SNAME, FMOD, K, V) \
|
||||
CMC_CONCATH(C) \
|
||||
(PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_COLLECTION_GENERATE_HEADER(C, PFX, SNAME, K, V) \
|
||||
CMC_CONCATH(C)(PFX, SNAME, K, V)
|
||||
|
||||
#define COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, FMOD, K, V) \
|
||||
CMC_CONCATC(C) \
|
||||
(PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, K, V) \
|
||||
CMC_CONCATC(C)(PFX, SNAME, K, V)
|
||||
|
||||
#include "cmc/deque.h"
|
||||
#include "cmc/hashmap.h"
|
||||
@@ -53,4 +51,4 @@
|
||||
#include "utl/test.h"
|
||||
#include "utl/timer.h"
|
||||
|
||||
#endif /* CMC_MACRO_COLLECTIONS */
|
||||
#endif /* CMC_MACRO_COLLECTIONS_H */
|
||||
+17
-23
@@ -8,31 +8,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* ForEach utility
|
||||
*
|
||||
* Read Documentation.md for more information
|
||||
*/
|
||||
#ifndef CMC_FOR_EACH_H
|
||||
#define CMC_FOR_EACH_H
|
||||
|
||||
#ifndef CMC_FOR_EACH
|
||||
#define CMC_FOR_EACH
|
||||
|
||||
#define 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 (SNAME##_iter iter = (TARGET)->it_start(TARGET); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define 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 (SNAME##_iter iter = (TARGET)->it_end(TARGET); !PFX##_iter_start(&iter); PFX##_iter_prev(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* CMC_FOR_EACH */
|
||||
#endif /* CMC_FOR_EACH_H */
|
||||
+13
-13
@@ -20,20 +20,20 @@ size_t inthash(int t)
|
||||
return a;
|
||||
}
|
||||
|
||||
COLLECTION_GENERATE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int)
|
||||
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* FMOD */, , int)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm, mmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE(MULTISET, ms, mset, , , int)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, , int)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms, mset, , int)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
+41
-41
@@ -20,20 +20,20 @@ size_t inthash(int t)
|
||||
return a;
|
||||
}
|
||||
|
||||
COLLECTION_GENERATE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int)
|
||||
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* FMOD */, , int)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm, mmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE(MULTISET, ms, mset, , , int)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, , int)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms, mset, , int)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@@ -84,62 +84,62 @@ int main(void)
|
||||
|
||||
int sums[16] = {0};
|
||||
|
||||
FOR_EACH(d, deque, d, {
|
||||
CMC_FOR_EACH(d, deque, d, {
|
||||
sums[0] += d_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(hm, hmap, hm, {
|
||||
CMC_FOR_EACH(hm, hmap, hm, {
|
||||
sums[1] += hm_iter_key(&iter);
|
||||
sums[2] += hm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(hs, hset, hs, {
|
||||
CMC_FOR_EACH(hs, hset, hs, {
|
||||
sums[3] += hs_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(h, heap, h, {
|
||||
CMC_FOR_EACH(h, heap, h, {
|
||||
sums[4] += h_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(ll, linked, ll, {
|
||||
CMC_FOR_EACH(ll, linked, ll, {
|
||||
sums[5] += ll_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(l, list, l, {
|
||||
CMC_FOR_EACH(l, list, l, {
|
||||
sums[6] += l_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(q, queue, q, {
|
||||
CMC_FOR_EACH(q, queue, q, {
|
||||
sums[7] += q_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(s, stack, s, {
|
||||
CMC_FOR_EACH(s, stack, s, {
|
||||
sums[8] += s_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(tm, tmap, tm, {
|
||||
CMC_FOR_EACH(tm, tmap, tm, {
|
||||
sums[9] += tm_iter_key(&iter);
|
||||
sums[10] += tm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(ts, tset, ts, {
|
||||
CMC_FOR_EACH(ts, tset, ts, {
|
||||
sums[11] += ts_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(ih, iheap, ih, {
|
||||
CMC_FOR_EACH(ih, iheap, ih, {
|
||||
sums[12] += ih_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(mm, mmap, mm, {
|
||||
CMC_FOR_EACH(mm, mmap, mm, {
|
||||
sums[13] += mm_iter_key(&iter);
|
||||
sums[14] += mm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(ms, mset, ms, {
|
||||
CMC_FOR_EACH(ms, mset, ms, {
|
||||
sums[15] += ms_iter_value(&iter);
|
||||
});
|
||||
|
||||
printf("\n-------------------- FOR_EACH --------------------\n");
|
||||
printf("\n-------------------- CMC_FOR_EACH --------------------\n");
|
||||
if (sums[0] == 50005000)
|
||||
printf("%12s PASSED\n", "DEQUE");
|
||||
else
|
||||
@@ -197,62 +197,62 @@ int main(void)
|
||||
|
||||
memset(sums, 0, sizeof sums);
|
||||
|
||||
FOR_EACH_REV(d, deque, d, {
|
||||
CMC_FOR_EACH_REV(d, deque, d, {
|
||||
sums[0] += d_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(hm, hmap, hm, {
|
||||
CMC_FOR_EACH_REV(hm, hmap, hm, {
|
||||
sums[1] += hm_iter_key(&iter);
|
||||
sums[2] += hm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(hs, hset, hs, {
|
||||
CMC_FOR_EACH_REV(hs, hset, hs, {
|
||||
sums[3] += hs_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(h, heap, h, {
|
||||
CMC_FOR_EACH_REV(h, heap, h, {
|
||||
sums[4] += h_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(ll, linked, ll, {
|
||||
CMC_FOR_EACH_REV(ll, linked, ll, {
|
||||
sums[5] += ll_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(l, list, l, {
|
||||
CMC_FOR_EACH_REV(l, list, l, {
|
||||
sums[6] += l_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(q, queue, q, {
|
||||
CMC_FOR_EACH_REV(q, queue, q, {
|
||||
sums[7] += q_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(s, stack, s, {
|
||||
CMC_FOR_EACH_REV(s, stack, s, {
|
||||
sums[8] += s_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(tm, tmap, tm, {
|
||||
CMC_FOR_EACH_REV(tm, tmap, tm, {
|
||||
sums[9] += tm_iter_key(&iter);
|
||||
sums[10] += tm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(ts, tset, ts, {
|
||||
CMC_FOR_EACH_REV(ts, tset, ts, {
|
||||
sums[11] += ts_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(ih, iheap, ih, {
|
||||
CMC_FOR_EACH_REV(ih, iheap, ih, {
|
||||
sums[12] += ih_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(mm, mmap, mm, {
|
||||
CMC_FOR_EACH_REV(mm, mmap, mm, {
|
||||
sums[13] += mm_iter_key(&iter);
|
||||
sums[14] += mm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(ms, mset, ms, {
|
||||
CMC_FOR_EACH_REV(ms, mset, ms, {
|
||||
sums[15] += ms_iter_value(&iter);
|
||||
});
|
||||
|
||||
printf("-------------------- FOR_EACH_REV --------------------\n");
|
||||
printf("-------------------- CMC_FOR_EACH_REV --------------------\n");
|
||||
if (sums[0] == 50005000)
|
||||
printf("%12s PASSED\n", "DEQUE");
|
||||
else
|
||||
|
||||
+13
-13
@@ -18,20 +18,20 @@ size_t inthash(int t)
|
||||
return a;
|
||||
}
|
||||
|
||||
COLLECTION_GENERATE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm, tmap, /* FMOD */, int, double)
|
||||
COLLECTION_GENERATE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, double)
|
||||
CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, double)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, double)
|
||||
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* FMOD */, , int)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm, mmap, /* FMOD */, int, double)
|
||||
COLLECTION_GENERATE(MULTISET, ms, mset, , , int)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, double)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms, mset, /* K */, int)
|
||||
|
||||
#define ITERATOR_TEST(NAME, PFX, sname, initfunc, insertbody, sumbody, validation1, validation2) \
|
||||
void NAME##_iterator_test(void) \
|
||||
|
||||
+13
-13
@@ -1,16 +1,16 @@
|
||||
#include "sep.h"
|
||||
|
||||
COLLECTION_GENERATE_SOURCE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE_SOURCE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(LIST, l, list, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(STACK, s, stack, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(QUEUE, q, queue, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(DEQUE, d, deque, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(LINKEDLIST, ll, linked, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(HEAP, h, heap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(TREESET, ts, tset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(TREEMAP, tm, tmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(HASHSET, hs, hset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(HASHMAP, hm, hmap, int, int)
|
||||
|
||||
COLLECTION_GENERATE_SOURCE(INTERVALHEAP, ih, iheap, /* FMOD */, , int)
|
||||
COLLECTION_GENERATE_SOURCE(MULTIMAP, mm, mmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE_SOURCE(MULTISET, ms, mset, , , int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(INTERVALHEAP, ih, iheap, , int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(MULTIMAP, mm, mmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(MULTISET, ms, mset, , int)
|
||||
+13
-13
@@ -1,16 +1,16 @@
|
||||
#include "../../src/macro_collections.h"
|
||||
|
||||
COLLECTION_GENERATE_HEADER(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE_HEADER(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(LIST, l, list, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(STACK, s, stack, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(QUEUE, q, queue, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(DEQUE, d, deque, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(LINKEDLIST, ll, linked, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(HEAP, h, heap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(TREESET, ts, tset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(TREEMAP, tm, tmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(HASHSET, hs, hset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(HASHMAP, hm, hmap, int, int)
|
||||
|
||||
COLLECTION_GENERATE_HEADER(INTERVALHEAP, ih, iheap, /* FMOD */, , int)
|
||||
COLLECTION_GENERATE_HEADER(MULTIMAP, mm, mmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE_HEADER(MULTISET, ms, mset, , , int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(INTERVALHEAP, ih, iheap, , int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(MULTIMAP, mm, mmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(MULTISET, ms, mset, , int)
|
||||
+127
-128
@@ -26,143 +26,142 @@ typedef union union_u {
|
||||
|
||||
typedef int (*func_t)(int, double, char *);
|
||||
|
||||
COLLECTION_GENERATE(LIST, l0, list0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(STACK, s0, stack0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(QUEUE, q0, queue0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(DEQUE, d0, deque0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll0, linked0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(HEAP, h0, heap0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(TREESET, ts0, tset0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm0, tmap0, static, struct_t *, struct_t *)
|
||||
COLLECTION_GENERATE(HASHSET, hs0, hset0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm0, hmap0, static, struct_t *, struct_t *)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih0, iheap0, static, struct_t *, struct_t *)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm0, mmap0, static, struct_t *, struct_t *)
|
||||
COLLECTION_GENERATE(MULTISET, ms0, mset0, static, struct_t *, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(LIST, l0, list0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(STACK, s0, stack0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q0, queue0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d0, deque0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll0, linked0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h0, heap0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts0, tset0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm0, tmap0, struct_t *, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs0, hset0, /* K */, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm0, hmap0, struct_t *, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih0, iheap0, struct_t *, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm0, mmap0, struct_t *, struct_t *)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms0, mset0, struct_t *, struct_t *)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l1, list1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(STACK, s1, stack1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(QUEUE, q1, queue1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(DEQUE, d1, deque1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll1, linked1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(HEAP, h1, heap1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(TREESET, ts1, tset1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm1, tmap1, static, struct_t, struct_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs1, hset1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm1, hmap1, static, struct_t, struct_t)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih1, iheap1, static, struct_t, struct_t)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm1, mmap1, static, struct_t, struct_t)
|
||||
COLLECTION_GENERATE(MULTISET, ms1, mset1, static, struct_t, struct_t)
|
||||
CMC_COLLECTION_GENERATE(LIST, l1, list1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(STACK, s1, stack1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q1, queue1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d1, deque1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll1, linked1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h1, heap1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts1, tset1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm1, tmap1, struct_t, struct_t)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs1, hset1, /* K */, struct_t)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm1, hmap1, struct_t, struct_t)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih1, iheap1, struct_t, struct_t)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm1, mmap1, struct_t, struct_t)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms1, mset1, struct_t, struct_t)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l2, list2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s2, stack2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q2, queue2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d2, deque2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll2, linked2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h2, heap2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts2, tset2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm2, tmap2, static, int, int)
|
||||
COLLECTION_GENERATE(HASHSET, hs2, hset2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm2, hmap2, static, int, int)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih2, iheap2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm2, mmap2, static, int, int)
|
||||
COLLECTION_GENERATE(MULTISET, ms2, mset2, static, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(LIST, l2, list2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(STACK, s2, stack2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q2, queue2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d2, deque2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll2, linked2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h2, heap2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts2, tset2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm2, tmap2, int, int)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs2, hset2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm2, hmap2, int, int)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih2, iheap2, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm2, mmap2, int, int)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms2, mset2, /* K */, int)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l3, list3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(STACK, s3, stack3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(QUEUE, q3, queue3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(DEQUE, d3, deque3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll3, linked3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(HEAP, h3, heap3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(TREESET, ts3, tset3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm3, tmap3, static, int *, int *)
|
||||
COLLECTION_GENERATE(HASHSET, hs3, hset3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm3, hmap3, static, int *, int *)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih3, iheap3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm3, mmap3, static, int *, int *)
|
||||
COLLECTION_GENERATE(MULTISET, ms3, mset3, static, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(LIST, l3, list3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(STACK, s3, stack3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q3, queue3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d3, deque3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll3, linked3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h3, heap3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts3, tset3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm3, tmap3, int *, int *)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs3, hset3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm3, hmap3, int *, int *)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih3, iheap3, /* K */, int *)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm3, mmap3, int *, int *)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms3, mset3, /* K */, int *)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l4, list4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(STACK, s4, stack4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(QUEUE, q4, queue4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(DEQUE, d4, deque4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll4, linked4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(HEAP, h4, heap4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(TREESET, ts4, tset4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm4, tmap4, static, enum_t *, enum_t *)
|
||||
COLLECTION_GENERATE(HASHSET, hs4, hset4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm4, hmap4, static, enum_t *, enum_t *)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih4, iheap4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm4, mmap4, static, enum_t *, enum_t *)
|
||||
COLLECTION_GENERATE(MULTISET, ms4, mset4, static, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(LIST, l4, list4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(STACK, s4, stack4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q4, queue4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d4, deque4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll4, linked4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h4, heap4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts4, tset4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm4, tmap4, enum_t *, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs4, hset4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm4, hmap4, enum_t *, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih4, iheap4, /* K */, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm4, mmap4, enum_t *, enum_t *)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms4, mset4, /* K */, enum_t *)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l5, list5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(STACK, s5, stack5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(QUEUE, q5, queue5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(DEQUE, d5, deque5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll5, linked5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(HEAP, h5, heap5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(TREESET, ts5, tset5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm5, tmap5, static, enum_t, enum_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs5, hset5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm5, hmap5, static, enum_t, enum_t)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih5, iheap5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm5, mmap5, static, enum_t, enum_t)
|
||||
COLLECTION_GENERATE(MULTISET, ms5, mset5, static, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(LIST, l5, list5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(STACK, s5, stack5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q5, queue5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d5, deque5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll5, linked5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h5, heap5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts5, tset5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm5, tmap5, enum_t, enum_t)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs5, hset5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm5, hmap5, enum_t, enum_t)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih5, iheap5, /* K */, enum_t)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm5, mmap5, enum_t, enum_t)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms5, mset5, /* K */, enum_t)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l6, list6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(STACK, s6, stack6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(QUEUE, q6, queue6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(DEQUE, d6, deque6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll6, linked6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(HEAP, h6, heap6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(TREESET, ts6, tset6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm6, tmap6, static, union_t *, union_t *)
|
||||
COLLECTION_GENERATE(HASHSET, hs6, hset6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm6, hmap6, static, union_t *, union_t *)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih6, iheap6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm6, mmap6, static, union_t *, union_t *)
|
||||
COLLECTION_GENERATE(MULTISET, ms6, mset6, static, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(LIST, l6, list6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(STACK, s6, stack6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q6, queue6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d6, deque6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll6, linked6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h6, heap6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts6, tset6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm6, tmap6, union_t *, union_t *)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs6, hset6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm6, hmap6, union_t *, union_t *)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih6, iheap6, /* K */, union_t *)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm6, mmap6, union_t *, union_t *)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms6, mset6, /* K */, union_t *)
|
||||
|
||||
CMC_COLLECTION_GENERATE(LIST, l7, list7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(STACK, s7, stack7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q7, queue7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d7, deque7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll7, linked7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h7, heap7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts7, tset7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm7, tmap7, union_t, union_t)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs7, hset7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm7, hmap7, union_t, union_t)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih7, iheap7, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm7, mmap7, union_t, union_t)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms7, mset7, /* K */, union_t)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l7, list7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(STACK, s7, stack7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(QUEUE, q7, queue7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(DEQUE, d7, deque7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll7, linked7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(HEAP, h7, heap7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(TREESET, ts7, tset7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm7, tmap7, static, union_t, union_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs7, hset7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm7, hmap7, static, union_t, union_t)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih7, iheap7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm7, mmap7, static, union_t, union_t)
|
||||
COLLECTION_GENERATE(MULTISET, ms7, mset7, static, /* K */, union_t)
|
||||
CMC_COLLECTION_GENERATE(LIST, l8, list8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(STACK, s8, stack8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q8, queue8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d8, deque8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll8, linked8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h8, heap8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts8, tset8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm8, tmap8, func_t, func_t)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs8, hset8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm8, hmap8, func_t, func_t)
|
||||
CMC_COLLECTION_GENERATE(INTERVALHEAP, ih8, iheap8, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(MULTIMAP, mm8, mmap8, func_t, func_t)
|
||||
CMC_COLLECTION_GENERATE(MULTISET, ms8, mset8, /* K */, func_t)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l8, list8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(STACK, s8, stack8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(QUEUE, q8, queue8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(DEQUE, d8, deque8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll8, linked8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HEAP, h8, heap8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREESET, ts8, tset8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm8, tmap8, static, func_t, func_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs8, hset8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm8, hmap8, static, func_t, func_t)
|
||||
COLLECTION_GENERATE(INTERVALHEAP, ih8, iheap8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(MULTIMAP, mm8, mmap8, static, func_t, func_t)
|
||||
COLLECTION_GENERATE(MULTISET, ms8, mset8, static, /* K */, func_t)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l9, list9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(STACK, s9, stack9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(QUEUE, q9, queue9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(DEQUE, d9, deque9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll9, linked9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HEAP, h9, heap9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREESET, ts9, tset9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm9, tmap9, static, func_t, func_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs9, hset9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm9, hmap9, static, func_t, func_t)
|
||||
CMC_COLLECTION_GENERATE(LIST, l9, list9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(STACK, s9, stack9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(QUEUE, q9, queue9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(DEQUE, d9, deque9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(LINKEDLIST, ll9, linked9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(HEAP, h9, heap9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(TREESET, ts9, tset9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(TREEMAP, tm9, tmap9, func_t, func_t)
|
||||
CMC_COLLECTION_GENERATE(HASHSET, hs9, hset9, /* K */, func_t)
|
||||
CMC_COLLECTION_GENERATE(HASHMAP, hm9, hmap9, func_t, func_t)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user