From e4d5687907d78297d57af1868ad38080c1db5d0a Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sun, 14 Apr 2019 18:12:58 -0300 Subject: [PATCH] Added contains functions to all collections --- src/deque.h | 74 ++++---- src/hashmap.h | 46 ++++- src/hashset.h | 46 ++++- src/heap.h | 12 ++ src/linkedlist.h | 16 ++ src/list.h | 41 +++++ src/queue.h | 64 ++++--- src/stack.h | 442 ++++++++++++++++++++++++----------------------- src/treemap.h | 21 +++ src/treeset.h | 21 +++ 10 files changed, 495 insertions(+), 288 deletions(-) diff --git a/src/deque.h b/src/deque.h index 93ea3c2..46d7d0d 100644 --- a/src/deque.h +++ b/src/deque.h @@ -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; \ diff --git a/src/hashmap.h b/src/hashmap.h index 6634538..a1af6cb 100644 --- a/src/hashmap.h +++ b/src/hashmap.h @@ -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); \ \ diff --git a/src/hashset.h b/src/hashset.h index 2a5a8f3..c817834 100644 --- a/src/hashset.h +++ b/src/hashset.h @@ -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); \ \ diff --git a/src/heap.h b/src/heap.h index 513e136..068aafa 100644 --- a/src/heap.h +++ b/src/heap.h @@ -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; \ diff --git a/src/linkedlist.h b/src/linkedlist.h index 4f4c48c..bbf61b6 100644 --- a/src/linkedlist.h +++ b/src/linkedlist.h @@ -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; \ diff --git a/src/list.h b/src/list.h index bbbe684..39ec234 100644 --- a/src/list.h +++ b/src/list.h @@ -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; \ diff --git a/src/queue.h b/src/queue.h index 1d76bd7..25df579 100644 --- a/src/queue.h +++ b/src/queue.h @@ -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; \ diff --git a/src/stack.h b/src/stack.h index 2634a3c..177757c 100644 --- a/src/stack.h +++ b/src/stack.h @@ -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 */ diff --git a/src/treemap.h b/src/treemap.h index ced66ab..a6d3bc5 100644 --- a/src/treemap.h +++ b/src/treemap.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; \ diff --git a/src/treeset.h b/src/treeset.h index a875f89..d531c8e 100644 --- a/src/treeset.h +++ b/src/treeset.h @@ -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; \