Added contains functions to all collections
This commit is contained in:
1 parent
ae5c745ef8
commit
e4d5687907
10 files changed
+495
-288
No files matched your search
+43
-31
@@ -58,37 +58,38 @@
|
||||
}; \
|
||||
\
|
||||
/* HEADER ********************************************************************/
|
||||
#define DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_deque_); \
|
||||
FMOD void PFX##_free(SNAME *_deque_); \
|
||||
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_); \
|
||||
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); \
|
||||
FMOD V PFX##_front(SNAME *_deque_); \
|
||||
FMOD V PFX##_back(SNAME *_deque_); \
|
||||
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_); \
|
||||
\
|
||||
FMOD void PFX##_iter_new(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
\
|
||||
#define DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_deque_); \
|
||||
FMOD void PFX##_free(SNAME *_deque_); \
|
||||
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_); \
|
||||
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); \
|
||||
FMOD V PFX##_front(SNAME *_deque_); \
|
||||
FMOD V PFX##_back(SNAME *_deque_); \
|
||||
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_); \
|
||||
\
|
||||
FMOD void PFX##_iter_new(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
@@ -247,6 +248,17 @@
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \
|
||||
{ \
|
||||
if (comparator(_deque_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
|
||||
+38
-8
@@ -29,13 +29,37 @@ typedef enum EntryState_e
|
||||
ES_FILLED = 1
|
||||
} EntryState;
|
||||
|
||||
static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
6151, 12289, 24593, 49157, 98317,
|
||||
196613, 393241, 786433, 1572869,
|
||||
3145739, 6291469, 12582917,
|
||||
25165843, 50331653, 100663319,
|
||||
201326611, 402653189, 805306457,
|
||||
1610612741};
|
||||
static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
3067, 6143, 12289, 24571, 49157,
|
||||
98299, 196613, 393209, 786431,
|
||||
1572869, 3145721, 6291449,
|
||||
12582917, 25165813, 50331653,
|
||||
100663291, 201326611, 402653189,
|
||||
805306357, 1610612741,
|
||||
3221225473, 6442450939,
|
||||
12884901893, 25769803799,
|
||||
51539607551, 103079215111,
|
||||
206158430209, 412316860441,
|
||||
824633720831, 1649267441651,
|
||||
3298534883309, 6597069766657,
|
||||
13194139533299, 26388279066623,
|
||||
52776558133303, 105553116266489,
|
||||
211106232532969, 422212465066001,
|
||||
844424930131963,
|
||||
1688849860263953,
|
||||
3377699720527861,
|
||||
6755399441055731,
|
||||
13510798882111483,
|
||||
27021597764222939,
|
||||
54043195528445957,
|
||||
108086391056891903,
|
||||
216172782113783773,
|
||||
432345564227567621,
|
||||
864691128455135207,
|
||||
1729382256910270481,
|
||||
3458764513820540933,
|
||||
6917529027641081903,
|
||||
13835058055282163729llu};
|
||||
|
||||
#endif /* CMC_HASH_TABLE_SETUP */
|
||||
|
||||
@@ -104,6 +128,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
FMOD bool PFX##_remove_if(SNAME *_map_, K key, V *value, bool condition); \
|
||||
FMOD bool PFX##_max(SNAME *_map_, K *key, V *value); \
|
||||
FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \
|
||||
FMOD bool PFX##_contains(SNAME *_map_, K key); \
|
||||
FMOD V PFX##_get(SNAME *_map_, K key); \
|
||||
FMOD bool PFX##_empty(SNAME *_map_); \
|
||||
FMOD size_t PFX##_count(SNAME *_map_); \
|
||||
@@ -325,6 +350,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_map_, K key) \
|
||||
{ \
|
||||
return PFX##_get_entry(_map_, key) != NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_get(SNAME *_map_, K key) \
|
||||
{ \
|
||||
SNAME##_entry *entry = PFX##_get_entry(_map_, key); \
|
||||
@@ -469,7 +499,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_map_) \
|
||||
{ \
|
||||
size_t new_size = PFX##_calculate_size((size_t)((double)_map_->capacity * 1.5)); \
|
||||
size_t new_size = PFX##_calculate_size(_map_->capacity + _map_->capacity / 2); \
|
||||
\
|
||||
SNAME *_new_map_ = PFX##_new(new_size, _map_->load, _map_->cmp, _map_->hash); \
|
||||
\
|
||||
|
||||
+38
-8
@@ -29,13 +29,37 @@ typedef enum EntryState_e
|
||||
ES_FILLED = 1
|
||||
} EntryState;
|
||||
|
||||
static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
6151, 12289, 24593, 49157, 98317,
|
||||
196613, 393241, 786433, 1572869,
|
||||
3145739, 6291469, 12582917,
|
||||
25165843, 50331653, 100663319,
|
||||
201326611, 402653189, 805306457,
|
||||
1610612741};
|
||||
static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
3067, 6143, 12289, 24571, 49157,
|
||||
98299, 196613, 393209, 786431,
|
||||
1572869, 3145721, 6291449,
|
||||
12582917, 25165813, 50331653,
|
||||
100663291, 201326611, 402653189,
|
||||
805306357, 1610612741,
|
||||
3221225473, 6442450939,
|
||||
12884901893, 25769803799,
|
||||
51539607551, 103079215111,
|
||||
206158430209, 412316860441,
|
||||
824633720831, 1649267441651,
|
||||
3298534883309, 6597069766657,
|
||||
13194139533299, 26388279066623,
|
||||
52776558133303, 105553116266489,
|
||||
211106232532969, 422212465066001,
|
||||
844424930131963,
|
||||
1688849860263953,
|
||||
3377699720527861,
|
||||
6755399441055731,
|
||||
13510798882111483,
|
||||
27021597764222939,
|
||||
54043195528445957,
|
||||
108086391056891903,
|
||||
216172782113783773,
|
||||
432345564227567621,
|
||||
864691128455135207,
|
||||
1729382256910270481,
|
||||
3458764513820540933,
|
||||
6917529027641081903,
|
||||
13835058055282163729llu};
|
||||
|
||||
#endif /* CMC_HASH_TABLE_SETUP */
|
||||
|
||||
@@ -103,6 +127,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
FMOD V PFX##_max(SNAME *_set_); \
|
||||
FMOD V PFX##_min(SNAME *_set_); \
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_set_); \
|
||||
FMOD size_t PFX##_count(SNAME *_set_); \
|
||||
\
|
||||
@@ -303,6 +328,11 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
return min; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element) \
|
||||
{ \
|
||||
return PFX##_get_entry(_set_, element) != NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count == 0; \
|
||||
@@ -548,7 +578,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 193, 389, 769, 1543, 3079,
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_set_) \
|
||||
{ \
|
||||
size_t new_size = PFX##_calculate_size((size_t)((double)_set_->capacity * 1.5)); \
|
||||
size_t new_size = PFX##_calculate_size(_set_->capacity + _set_->capacity / 2); \
|
||||
\
|
||||
SNAME *_new_set_ = PFX##_new(new_size, _set_->load, _set_->cmp, _set_->hash); \
|
||||
\
|
||||
|
||||
+12
@@ -76,6 +76,7 @@ typedef enum HeapOrder
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \
|
||||
FMOD V PFX##_peek(SNAME *_heap_); \
|
||||
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_); \
|
||||
@@ -206,6 +207,17 @@ typedef enum HeapOrder
|
||||
return _heap_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
if (_heap_->cmp(_heap_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count == 0; \
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
FMOD V PFX##_front(SNAME *_list_); \
|
||||
FMOD V PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD V PFX##_back(SNAME *_list_); \
|
||||
FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_list_); \
|
||||
FMOD size_t PFX##_count(SNAME *_list_); \
|
||||
\
|
||||
@@ -345,6 +346,21 @@
|
||||
return _list_->tail->data; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _list_->head; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (comparator(scan->data, element) == 0) \
|
||||
return true; \
|
||||
\
|
||||
scan = scan->next; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
|
||||
+41
@@ -76,9 +76,11 @@
|
||||
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); \
|
||||
FMOD V PFX##_front(SNAME *_list_); \
|
||||
FMOD V PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD V PFX##_back(SNAME *_list_); \
|
||||
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_); \
|
||||
@@ -395,6 +397,34 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to || to >= _list_->count) \
|
||||
return false; \
|
||||
\
|
||||
size_t length = to - from + 1; \
|
||||
\
|
||||
SNAME *result = PFX##_new(length); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
for (size_t i = from; i <= to; i++) \
|
||||
{ \
|
||||
result->buffer[i - from] = _list_->buffer[i]; \
|
||||
} \
|
||||
\
|
||||
for (size_t i = from, j = to + 1; i < _list_->count; i++, j++) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[j]; \
|
||||
} \
|
||||
\
|
||||
result->count = length; \
|
||||
_list_->count -= length; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
@@ -422,6 +452,17 @@
|
||||
return _list_->buffer[_list_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
if (comparator(_list_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
|
||||
+38
-26
@@ -58,32 +58,33 @@
|
||||
}; \
|
||||
\
|
||||
/* HEADER ********************************************************************/
|
||||
#define QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_queue_); \
|
||||
FMOD void PFX##_free(SNAME *_queue_); \
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element); \
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_); \
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition); \
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition); \
|
||||
FMOD V PFX##_peek(SNAME *_queue_); \
|
||||
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_); \
|
||||
\
|
||||
FMOD void PFX##_iter_new(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
\
|
||||
#define QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_queue_); \
|
||||
FMOD void PFX##_free(SNAME *_queue_); \
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element); \
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_); \
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition); \
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition); \
|
||||
FMOD V PFX##_peek(SNAME *_queue_); \
|
||||
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_); \
|
||||
\
|
||||
FMOD void PFX##_iter_new(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
@@ -185,6 +186,17 @@
|
||||
return _queue_->buffer[_queue_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \
|
||||
{ \
|
||||
if (comparator(_queue_->buffer[i], element) == 0) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count == 0; \
|
||||
|
||||
+227
-215
@@ -55,222 +55,234 @@
|
||||
}; \
|
||||
\
|
||||
/* HEADER ********************************************************************/
|
||||
#define STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_stack_); \
|
||||
FMOD void PFX##_free(SNAME *_stack_); \
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element); \
|
||||
FMOD bool PFX##_pop(SNAME *_stack_); \
|
||||
FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition); \
|
||||
FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition); \
|
||||
FMOD V PFX##_top(SNAME *_stack_); \
|
||||
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_); \
|
||||
\
|
||||
FMOD void PFX##_iter_new(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
\
|
||||
#define STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_stack_); \
|
||||
FMOD void PFX##_free(SNAME *_stack_); \
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element); \
|
||||
FMOD bool PFX##_pop(SNAME *_stack_); \
|
||||
FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition); \
|
||||
FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition); \
|
||||
FMOD V PFX##_top(SNAME *_stack_); \
|
||||
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_); \
|
||||
\
|
||||
FMOD void PFX##_iter_new(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_stack_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size) \
|
||||
{ \
|
||||
if (size < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_stack_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_stack_) \
|
||||
return NULL; \
|
||||
\
|
||||
_stack_->buffer = malloc(sizeof(V) * size); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * size); \
|
||||
\
|
||||
_stack_->capacity = size; \
|
||||
_stack_->count = 0; \
|
||||
\
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_stack_) \
|
||||
{ \
|
||||
memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
|
||||
\
|
||||
_stack_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_stack_) \
|
||||
{ \
|
||||
free(_stack_->buffer); \
|
||||
free(_stack_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_stack_)) \
|
||||
{ \
|
||||
if (!PFX##_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] = 0; \
|
||||
\
|
||||
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 0; \
|
||||
\
|
||||
return _stack_->buffer[_stack_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
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 void PFX##_iter_new(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 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_tostart(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->target->count - iter->cursor - 1; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->start = false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->target->count - iter->cursor - 1; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->end = false; \
|
||||
\
|
||||
if (iter->cursor == iter->target->count - 1) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_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; \
|
||||
#define STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_stack_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size) \
|
||||
{ \
|
||||
if (size < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_stack_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_stack_) \
|
||||
return NULL; \
|
||||
\
|
||||
_stack_->buffer = malloc(sizeof(V) * size); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * size); \
|
||||
\
|
||||
_stack_->capacity = size; \
|
||||
_stack_->count = 0; \
|
||||
\
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_stack_) \
|
||||
{ \
|
||||
memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
|
||||
\
|
||||
_stack_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_stack_) \
|
||||
{ \
|
||||
free(_stack_->buffer); \
|
||||
free(_stack_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_stack_)) \
|
||||
{ \
|
||||
if (!PFX##_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] = 0; \
|
||||
\
|
||||
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 0; \
|
||||
\
|
||||
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 void PFX##_iter_new(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 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_tostart(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, V *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->target->count - iter->cursor - 1; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->start = false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, V *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->target->count - iter->cursor - 1; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->end = false; \
|
||||
\
|
||||
if (iter->cursor == iter->target->count - 1) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_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; \
|
||||
}
|
||||
|
||||
#endif /* CMC_STACK_H */
|
||||
@@ -83,6 +83,7 @@
|
||||
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 bool PFX##_contains(SNAME *_map_, K key); \
|
||||
FMOD bool PFX##_empty(SNAME *_map_); \
|
||||
FMOD size_t PFX##_count(SNAME *_map_); \
|
||||
\
|
||||
@@ -357,6 +358,9 @@
|
||||
\
|
||||
_map_->count--; \
|
||||
\
|
||||
if (_map_->count == 0) \
|
||||
_map_->root = NULL; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
@@ -418,6 +422,23 @@
|
||||
return node->value; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_map_, K key) \
|
||||
{ \
|
||||
SNAME##_node *scan = _map_->root; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (_map_->cmp(scan->key, key) > 0) \
|
||||
scan = scan->left; \
|
||||
else if (_map_->cmp(scan->key, key) < 0) \
|
||||
scan = scan->right; \
|
||||
else \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_map_) \
|
||||
{ \
|
||||
return _map_->count == 0; \
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
FMOD V PFX##_max(SNAME *_set_); \
|
||||
FMOD V PFX##_min(SNAME *_set_); \
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_set_); \
|
||||
FMOD size_t PFX##_count(SNAME *_set_); \
|
||||
\
|
||||
@@ -356,6 +357,9 @@
|
||||
\
|
||||
_set_->count--; \
|
||||
\
|
||||
if (_set_->count == 0) \
|
||||
_set_->root = NULL; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
@@ -401,6 +405,23 @@
|
||||
return scan->key; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_node *scan = _set_->root; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (_set_->cmp(scan->key, element) > 0) \
|
||||
scan = scan->left; \
|
||||
else if (_set_->cmp(scan->key, element) < 0) \
|
||||
scan = scan->right; \
|
||||
else \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count == 0; \
|
||||
|
||||
Reference in new issue
Block a user