From aac07a645cf263160efa9d404492fdec8525ddd0 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 7 Jun 2019 01:44:15 -0300 Subject: [PATCH] Now collections accept plain struct Also fixed impl prefixes and function modifiers Added new test for all possible data types Fixed some READMEs --- .travis.yml | 4 +- CHANGELOG | 8 ++ TODO | 6 +- examples/hashmap/README.md | 1 + src/deque.h | 32 +++++--- src/hashmap.h | 49 +++++++++---- src/hashset.h | 54 ++++++++------ src/heap.h | 48 +++++++----- src/linkedlist.h | 35 +++++---- src/list.h | 41 ++++++----- src/queue.h | 30 +++++--- src/stack.h | 28 ++++--- src/treemap.h | 67 ++++++++++++----- src/treeset.h | 98 ++++++++++++++----------- tests/README.md | 2 +- tests/pointertype.c | 29 -------- tests/types.c | 146 +++++++++++++++++++++++++++++++++++++ 17 files changed, 467 insertions(+), 211 deletions(-) delete mode 100644 tests/pointertype.c create mode 100644 tests/types.c diff --git a/.travis.yml b/.travis.yml index 0ae2fdb..950854d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ script: - ./iterators - gcc contains.c -Wall -Wextra -o contains -std=c11 - ./contains - - gcc pointertype.c -Wall -Wextra -o pointertype -std=c11 - - ./pointertype + - gcc types.c.c -Wall -Wextra -o types.c -std=c11 + - ./types.c - gcc -c ./sep/sep.c -Wall -Wextra -o ./sep/sep.o -std=c11 - gcc -c ./sep/main.c -Wall -Wextra -o ./sep/main.o -std=c11 - gcc ./sep/sep.o ./sep/main.o -o ./sep/sep diff --git a/CHANGELOG b/CHANGELOG index 3541cfe..6d1e6db 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,13 @@ # MAJOR.MINOR.ADJUSTMENTS +1.4.2 + Adapted code so that plain struct type is accepted + Changed TreeSet max and min to be compatible with the TreeMap and the hash collections + Changed function modifier of all implementation detail to static + Fixed some implementation detail functions that were not prefixed with impl + Added types.c to test if it is possible to compile all the collections' generated code accepting all C data types + Removed pointertype.c (replaced by types.c) + 1.4.1 Removed PUBLIC and PRIVATE from the main macro Corrected examples and benchmark diff --git a/TODO b/TODO index 0b6d49b..2018593 100644 --- a/TODO +++ b/TODO @@ -22,13 +22,15 @@ Before 2.0 1.5 OK - Remove PUBLIC and PRIVATE + OK - Allow for struct to be a possible data type (instead of just pointer to struct) Iterator move and move_to - LinkedList - Insert/Remove/Append/Prepend/Extract + Set functions: is_subset, is_superset, is_disjointset from_array - Creates a collection with all the elements in a specified array to_array - Creates an array with all the elements inside the collection 1.6 - Add shrink function that shrinks the internal buffer to current count of elements + LinkedList - Insert/Remove/Append/Prepend/Extract + Resize buffer function Add dispose method to each collection in order to automatically free its data 2.0 diff --git a/examples/hashmap/README.md b/examples/hashmap/README.md index 835454d..19acaf6 100644 --- a/examples/hashmap/README.md +++ b/examples/hashmap/README.md @@ -1,4 +1,5 @@ # Hashmap examples * countries - Uses a hashmap to map the country name to its population +* foreach.c - ForEach macro example * iterator.c - A complete example of the hashmap iterator diff --git a/src/deque.h b/src/deque.h index 5260ef4..8bbc193 100644 --- a/src/deque.h +++ b/src/deque.h @@ -122,13 +122,23 @@ 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ /* Implementation Detail Functions */ \ - FMOD bool PFX##_impl_grow(SNAME *_deque_); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \ + 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 size) \ { \ @@ -215,7 +225,7 @@ if (PFX##_empty(_deque_)) \ return false; \ \ - _deque_->buffer[_deque_->front] = 0; \ + _deque_->buffer[_deque_->front] = PFX##_impl_default_value(); \ \ _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \ \ @@ -231,7 +241,7 @@ \ _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ \ - _deque_->buffer[_deque_->back] = 0; \ + _deque_->buffer[_deque_->back] = PFX##_impl_default_value(); \ \ _deque_->count--; \ \ @@ -273,7 +283,7 @@ FMOD V PFX##_front(SNAME *_deque_) \ { \ if (PFX##_empty(_deque_)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return _deque_->buffer[_deque_->front]; \ } \ @@ -281,7 +291,7 @@ FMOD V PFX##_back(SNAME *_deque_) \ { \ if (PFX##_empty(_deque_)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \ } \ @@ -412,7 +422,7 @@ FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return iter->target->buffer[iter->cursor]; \ } \ @@ -430,7 +440,7 @@ return iter->index; \ } \ \ - FMOD bool PFX##_impl_grow(SNAME *_deque_) \ + static bool PFX##_impl_grow(SNAME *_deque_) \ { \ \ size_t new_capacity = _deque_->capacity * 2; \ @@ -455,7 +465,7 @@ return true; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \ { \ SNAME##_iter iter; \ \ @@ -464,7 +474,7 @@ return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/hashmap.h b/src/hashmap.h index 43ffc00..05e56e5 100644 --- a/src/hashmap.h +++ b/src/hashmap.h @@ -190,15 +190,35 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define HASHMAP_GENERATE_SOURCE(PFX, SNAME, FMOD, K, V) \ \ /* Implementation Detail Functions */ \ - FMOD bool PFX##_impl_grow(SNAME *_map_); \ - FMOD SNAME##_entry *PFX##_impl_get_entry(SNAME *_map_, K key); \ - FMOD size_t PFX##_impl_calculate_size(size_t required); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_map_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_map_); \ + static bool PFX##_impl_grow(SNAME *_map_); \ + static SNAME##_entry *PFX##_impl_get_entry(SNAME *_map_, K key); \ + static size_t PFX##_impl_calculate_size(size_t required); \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_map_); \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_map_); \ \ FMOD SNAME *PFX##_new(size_t size, double load, int (*compare)(K, K), size_t (*hash)(K)) \ { \ @@ -318,7 +338,8 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, \ *value = result->value; \ \ - result->value = 0; \ + result->key = PFX##_impl_default_key(); \ + result->value = PFX##_impl_default_value(); \ result->dist = 0; \ result->state = ES_DELETED; \ \ @@ -404,7 +425,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ \ if (!entry) \ - return 0; \ + PFX##_impl_default_value(); \ \ return entry->value; \ } \ @@ -577,7 +598,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD K PFX##_iter_key(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + PFX##_impl_default_key(); \ \ return iter->target->buffer[iter->cursor].key; \ } \ @@ -585,7 +606,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return iter->target->buffer[iter->cursor].value; \ } \ @@ -603,7 +624,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return iter->index; \ } \ \ - FMOD bool PFX##_impl_grow(SNAME *_map_) \ + static bool PFX##_impl_grow(SNAME *_map_) \ { \ size_t new_size = PFX##_impl_calculate_size(_map_->capacity + _map_->capacity / 2); \ \ @@ -639,7 +660,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return true; \ } \ \ - FMOD SNAME##_entry *PFX##_impl_get_entry(SNAME *_map_, K key) \ + static SNAME##_entry *PFX##_impl_get_entry(SNAME *_map_, K key) \ { \ size_t hash = _map_->hash(key); \ size_t pos = hash % _map_->capacity; \ @@ -658,7 +679,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return NULL; \ } \ \ - FMOD size_t PFX##_impl_calculate_size(size_t required) \ + static size_t PFX##_impl_calculate_size(size_t required) \ { \ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ \ @@ -672,7 +693,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return cmc_hashtable_primes[i]; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_map_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_map_) \ { \ SNAME##_iter iter; \ \ @@ -681,7 +702,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_map_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_map_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/hashset.h b/src/hashset.h index b4fdebc..2b214b3 100644 --- a/src/hashset.h +++ b/src/hashset.h @@ -188,22 +188,32 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define HASHSET_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ /* Implementation Detail Functions */ \ - FMOD bool PFX##_grow(SNAME *_set_); \ - FMOD SNAME##_entry *PFX##_get_entry(SNAME *_set_, V element); \ - FMOD size_t PFX##_calculate_size(size_t required); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \ + static bool PFX##_impl_grow(SNAME *_set_); \ + static SNAME##_entry *PFX##_impl_get_entry(SNAME *_set_, V element); \ + static size_t PFX##_impl_calculate_size(size_t required); \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \ \ FMOD SNAME *PFX##_new(size_t size, double load, int (*compare)(V, V), size_t (*hash)(V)) \ { \ if (size == 0 || load <= 0 || load >= 1) \ return NULL; \ \ - size_t real_size = PFX##_calculate_size(size); \ + size_t real_size = PFX##_impl_calculate_size(size); \ \ SNAME *_set_ = malloc(sizeof(SNAME)); \ \ @@ -249,7 +259,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, { \ if ((double)_set_->capacity * _set_->load <= (double)_set_->count) \ { \ - if (!PFX##_grow(_set_)) \ + if (!PFX##_impl_grow(_set_)) \ return false; \ } \ \ @@ -259,7 +269,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, \ SNAME##_entry *target = &(_set_->buffer[pos]); \ \ - if (PFX##_get_entry(_set_, element) != NULL) \ + if (PFX##_impl_get_entry(_set_, element) != NULL) \ return false; \ \ if (target->state == ES_EMPTY || target->state == ES_DELETED) \ @@ -304,12 +314,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, \ FMOD bool PFX##_remove(SNAME *_set_, V element) \ { \ - SNAME##_entry *result = PFX##_get_entry(_set_, element); \ + SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \ \ if (result == NULL) \ return false; \ \ - result->value = 0; \ + result->value = PFX##_impl_default_value(); \ result->dist = 0; \ result->state = ES_DELETED; \ \ @@ -378,7 +388,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, \ FMOD bool PFX##_contains(SNAME *_set_, V element) \ { \ - return PFX##_get_entry(_set_, element) != NULL; \ + return PFX##_impl_get_entry(_set_, element) != NULL; \ } \ \ FMOD bool PFX##_empty(SNAME *_set_) \ @@ -437,7 +447,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, { \ V value = PFX##_iter_value(&iter); \ \ - if (PFX##_get_entry(_set_B_, value) != NULL) \ + if (PFX##_impl_get_entry(_set_B_, value) != NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -458,7 +468,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, { \ V value = PFX##_iter_value(&iter); \ \ - if (PFX##_get_entry(_set2_, value) == NULL) \ + if (PFX##_impl_get_entry(_set2_, value) == NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -481,7 +491,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, { \ V value = PFX##_iter_value(&iter1); \ \ - if (PFX##_get_entry(_set2_, value) == NULL) \ + if (PFX##_impl_get_entry(_set2_, value) == NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -489,7 +499,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, { \ V value = PFX##_iter_value(&iter2); \ \ - if (PFX##_get_entry(_set1_, value) == NULL) \ + if (PFX##_impl_get_entry(_set1_, value) == NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -630,7 +640,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return iter->target->buffer[iter->cursor].value; \ } \ @@ -640,9 +650,9 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return iter->index; \ } \ \ - FMOD bool PFX##_grow(SNAME *_set_) \ + static bool PFX##_impl_grow(SNAME *_set_) \ { \ - size_t new_size = PFX##_calculate_size(_set_->capacity + _set_->capacity / 2); \ + size_t new_size = PFX##_impl_calculate_size(_set_->capacity + _set_->capacity / 2); \ \ SNAME *_new_set_ = PFX##_new(new_size, _set_->load, _set_->cmp, _set_->hash); \ \ @@ -674,7 +684,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return true; \ } \ \ - FMOD SNAME##_entry *PFX##_get_entry(SNAME *_set_, V element) \ + static SNAME##_entry *PFX##_impl_get_entry(SNAME *_set_, V element) \ { \ size_t hash = _set_->hash(element); \ size_t pos = hash % _set_->capacity; \ @@ -693,7 +703,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return NULL; \ } \ \ - FMOD size_t PFX##_calculate_size(size_t required) \ + static size_t PFX##_impl_calculate_size(size_t required) \ { \ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ \ @@ -707,7 +717,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return cmc_hashtable_primes[i]; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_set_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_set_) \ { \ SNAME##_iter iter; \ \ @@ -716,7 +726,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_set_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_set_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/heap.h b/src/heap.h index 5e03c8c..16c7bbf 100644 --- a/src/heap.h +++ b/src/heap.h @@ -120,18 +120,28 @@ typedef enum HeapOrder 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ /* Implementation Detail Functions */ \ - FMOD bool PFX##_impl_grow(SNAME *_heap_); \ - FMOD size_t PFX##_impl_p(size_t index); \ - FMOD size_t PFX##_impl_l(size_t index); \ - FMOD size_t PFX##_impl_r(size_t index); \ - FMOD bool PFX##_impl_float_up(SNAME *_heap_, size_t index); \ - FMOD bool PFX##_impl_float_down(SNAME *_heap_, size_t index); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_heap_); \ + static bool PFX##_impl_grow(SNAME *_heap_); \ + static size_t PFX##_impl_p(size_t index); \ + static size_t PFX##_impl_l(size_t index); \ + static size_t PFX##_impl_r(size_t index); \ + static bool PFX##_impl_float_up(SNAME *_heap_, size_t index); \ + static bool PFX##_impl_float_down(SNAME *_heap_, size_t index); \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_); \ \ FMOD SNAME *PFX##_new(size_t size, HeapOrder HO, int (*compare)(V, V)) \ { \ @@ -209,7 +219,7 @@ typedef enum HeapOrder \ *result = _heap_->buffer[0]; \ _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \ - _heap_->buffer[_heap_->count - 1] = 0; \ + _heap_->buffer[_heap_->count - 1] = PFX##_impl_default_value(); \ \ _heap_->count--; \ \ @@ -238,7 +248,7 @@ typedef enum HeapOrder FMOD V PFX##_peek(SNAME *_heap_) \ { \ if (PFX##_empty(_heap_)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return _heap_->buffer[0]; \ } \ @@ -364,7 +374,7 @@ typedef enum HeapOrder FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return iter->target->buffer[iter->cursor]; \ } \ @@ -374,7 +384,7 @@ typedef enum HeapOrder return iter->cursor; \ } \ \ - FMOD bool PFX##_impl_grow(SNAME *_heap_) \ + static bool PFX##_impl_grow(SNAME *_heap_) \ { \ size_t new_capacity = _heap_->capacity * 2; \ \ @@ -389,7 +399,7 @@ typedef enum HeapOrder return true; \ } \ \ - FMOD size_t PFX##_impl_p(size_t index) \ + static size_t PFX##_impl_p(size_t index) \ { \ if (index == 0) \ return 0; \ @@ -397,17 +407,17 @@ typedef enum HeapOrder return (index - 1) / 2; \ } \ \ - FMOD size_t PFX##_impl_l(size_t index) \ + static size_t PFX##_impl_l(size_t index) \ { \ return 2 * index + 1; \ } \ \ - FMOD size_t PFX##_impl_r(size_t index) \ + static size_t PFX##_impl_r(size_t index) \ { \ return 2 * index + 2; \ } \ \ - FMOD bool PFX##_impl_float_up(SNAME *_heap_, size_t index) \ + static bool PFX##_impl_float_up(SNAME *_heap_, size_t index) \ { \ size_t C = index; \ V child = _heap_->buffer[C]; \ @@ -430,7 +440,7 @@ typedef enum HeapOrder return true; \ } \ \ - FMOD bool PFX##_impl_float_down(SNAME *_heap_, size_t index) \ + static bool PFX##_impl_float_down(SNAME *_heap_, size_t index) \ { \ int mod = _heap_->HO; \ \ @@ -465,7 +475,7 @@ typedef enum HeapOrder return true; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_heap_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_) \ { \ SNAME##_iter iter; \ \ @@ -475,7 +485,7 @@ typedef enum HeapOrder return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_heap_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/linkedlist.h b/src/linkedlist.h index df310c3..4816da9 100644 --- a/src/linkedlist.h +++ b/src/linkedlist.h @@ -49,7 +49,7 @@ /* Function that returns an iterator to the end of the list */ \ struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \ \ - } SNAME, *SNAME_ptr; \ + } SNAME, *SNAME##_ptr; \ \ /* Doubly-linked list node */ \ typedef struct SNAME##_node_s \ @@ -148,12 +148,22 @@ FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \ FMOD SNAME##_node *PFX##_iter_node(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 LINKEDLIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ /* Implementation Detail Functions */ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \ \ FMOD SNAME *PFX##_new(void) \ { \ @@ -365,23 +375,20 @@ FMOD V PFX##_front(SNAME *_list_) \ { \ if (PFX##_empty(_list_)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return _list_->head->data; \ } \ \ FMOD V PFX##_get(SNAME *_list_, size_t index) \ { \ - if (index >= _list_->count) \ - return 0; \ - \ - if (PFX##_empty(_list_)) \ - return 0; \ + if (index >= _list_->count || PFX##_empty(_list_)) \ + PFX##_impl_default_value(); \ \ SNAME##_node *scan = PFX##_get_node(_list_, index); \ \ if (scan == NULL) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return scan->data; \ } \ @@ -405,7 +412,7 @@ FMOD V PFX##_back(SNAME *_list_) \ { \ if (PFX##_empty(_list_)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return _list_->tail->data; \ } \ @@ -702,7 +709,7 @@ FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return iter->cursor->data; \ } \ @@ -725,7 +732,7 @@ return iter->cursor; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \ { \ SNAME##_iter iter; \ \ @@ -735,7 +742,7 @@ return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/list.h b/src/list.h index ae21178..e20a278 100644 --- a/src/list.h +++ b/src/list.h @@ -124,13 +124,23 @@ 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ /* Implementation Detail Functions */ \ - FMOD bool PFX##_impl_grow(SNAME *_list_, size_t required); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \ + 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) \ { \ @@ -260,7 +270,7 @@ \ memmove(_list_->buffer, _list_->buffer + 1, _list_->count * sizeof(V)); \ \ - _list_->buffer[--_list_->count] = 0; \ + _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ \ return true; \ } \ @@ -284,7 +294,7 @@ \ memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(V)); \ \ - _list_->buffer[--_list_->count] = 0; \ + _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ \ return true; \ } \ @@ -294,7 +304,7 @@ if (PFX##_empty(_list_)) \ return false; \ \ - _list_->buffer[--_list_->count] = 0; \ + _list_->buffer[--_list_->count] = PFX##_impl_default_value(); \ \ return true; \ } \ @@ -420,18 +430,15 @@ FMOD V PFX##_front(SNAME *_list_) \ { \ if (PFX##_empty(_list_)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return _list_->buffer[0]; \ } \ \ FMOD V PFX##_get(SNAME *_list_, size_t index) \ { \ - if (index >= _list_->count) \ - return 0; \ - \ - if (PFX##_empty(_list_)) \ - return 0; \ + if (index >= _list_->count || PFX##_empty(_list_)) \ + return PFX##_impl_default_value(); \ \ return _list_->buffer[index]; \ } \ @@ -450,7 +457,7 @@ FMOD V PFX##_back(SNAME *_list_) \ { \ if (PFX##_empty(_list_)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return _list_->buffer[_list_->count - 1]; \ } \ @@ -595,7 +602,7 @@ FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return iter->target->buffer[iter->cursor]; \ } \ @@ -613,7 +620,7 @@ return iter->cursor; \ } \ \ - FMOD bool PFX##_impl_grow(SNAME *_list_, size_t required) \ + static bool PFX##_impl_grow(SNAME *_list_, size_t required) \ { \ size_t new_capacity = _list_->capacity * 2; \ \ @@ -631,7 +638,7 @@ return true; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_list_) \ { \ SNAME##_iter iter; \ \ @@ -641,7 +648,7 @@ return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_list_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/queue.h b/src/queue.h index 8efa41f..0dc1dfb 100644 --- a/src/queue.h +++ b/src/queue.h @@ -117,13 +117,23 @@ 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ /* Implementation Detail Functions */ \ - FMOD bool PFX##_grow(SNAME *_queue_); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \ + static FMOD 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 size) \ { \ @@ -175,7 +185,7 @@ { \ if (PFX##_full(_queue_)) \ { \ - if (!PFX##_grow(_queue_)) \ + if (!PFX##_impl_grow(_queue_)) \ return false; \ } \ \ @@ -192,7 +202,7 @@ if (PFX##_empty(_queue_)) \ return false; \ \ - _queue_->buffer[_queue_->front] = 0; \ + _queue_->buffer[_queue_->front] = PFX##_impl_default_value(); \ \ _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \ _queue_->count--; \ @@ -219,7 +229,7 @@ FMOD V PFX##_peek(SNAME *_queue_) \ { \ if (PFX##_empty(_queue_)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return _queue_->buffer[_queue_->front]; \ } \ @@ -350,7 +360,7 @@ FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return iter->target->buffer[iter->cursor]; \ } \ @@ -368,7 +378,7 @@ return iter->index; \ } \ \ - FMOD bool PFX##_grow(SNAME *_queue_) \ + static bool PFX##_impl_grow(SNAME *_queue_) \ { \ \ size_t new_capacity = _queue_->capacity * 2; \ @@ -393,7 +403,7 @@ return true; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \ { \ SNAME##_iter iter; \ \ @@ -403,7 +413,7 @@ return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/stack.h b/src/stack.h index 9e134b9..f59933b 100644 --- a/src/stack.h +++ b/src/stack.h @@ -108,13 +108,23 @@ 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ /* Implementation Detail Functions */ \ - FMOD bool PFX##_impl_grow(SNAME *_stack_); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_stack_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_stack_); \ + 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 size) \ { \ @@ -176,7 +186,7 @@ if (PFX##_empty(_stack_)) \ return false; \ \ - _stack_->buffer[--_stack_->count] = 0; \ + _stack_->buffer[--_stack_->count] = PFX##_impl_default_value(); \ \ return true; \ } \ @@ -200,7 +210,7 @@ FMOD V PFX##_top(SNAME *_stack_) \ { \ if (PFX##_empty(_stack_)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return _stack_->buffer[_stack_->count - 1]; \ } \ @@ -318,7 +328,7 @@ FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ if (PFX##_empty(iter->target)) \ - return 0; \ + PFX##_impl_default_value(); \ \ return iter->target->buffer[iter->cursor]; \ } \ @@ -336,7 +346,7 @@ return iter->target->count - 1 - iter->cursor; \ } \ \ - FMOD bool PFX##_impl_grow(SNAME *_stack_) \ + static bool PFX##_impl_grow(SNAME *_stack_) \ { \ size_t new_capacity = _stack_->capacity * 2; \ \ @@ -351,7 +361,7 @@ return true; \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_stack_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_) \ { \ SNAME##_iter iter; \ \ @@ -361,7 +371,7 @@ return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_stack_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/treemap.h b/src/treemap.h index 190b74f..9063e44 100644 --- a/src/treemap.h +++ b/src/treemap.h @@ -141,19 +141,39 @@ 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define TREEMAP_GENERATE_SOURCE(PFX, SNAME, FMOD, K, V) \ \ /* Implementation Detail Functions */ \ - FMOD SNAME##_node *PFX##_impl_new_node(K key, V value); \ - FMOD SNAME##_node *PFX##_impl_get_node(SNAME *_map_, K key); \ - FMOD unsigned char PFX##_impl_h(SNAME##_node *node); \ - FMOD unsigned char PFX##_impl_hupdate(SNAME##_node *node); \ - FMOD void PFX##_impl_rotate_right(SNAME##_node **Z); \ - FMOD void PFX##_impl_rotate_left(SNAME##_node **Z); \ - FMOD void PFX##_impl_rebalance(SNAME *_map_, SNAME##_node *node); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_map_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_map_); \ + static SNAME##_node *PFX##_impl_new_node(K key, V value); \ + static SNAME##_node *PFX##_impl_get_node(SNAME *_map_, K key); \ + static unsigned char PFX##_impl_h(SNAME##_node *node); \ + static unsigned char PFX##_impl_hupdate(SNAME##_node *node); \ + static void PFX##_impl_rotate_right(SNAME##_node **Z); \ + static void PFX##_impl_rotate_left(SNAME##_node **Z); \ + static void PFX##_impl_rebalance(SNAME *_map_, SNAME##_node *node); \ + 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)) \ { \ @@ -469,7 +489,7 @@ SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ \ if (!node) \ - return 0; \ + return PFX##_impl_default_value(); \ \ return node->value; \ } \ @@ -655,16 +675,25 @@ \ FMOD K PFX##_iter_key(SNAME##_iter *iter) \ { \ + if (PFX##_empty(iter->target)) \ + PFX##_impl_default_key(); \ + \ return iter->cursor->key; \ } \ \ FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ + if (PFX##_empty(iter->target)) \ + PFX##_impl_default_value(); \ + \ return iter->cursor->value; \ } \ \ FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \ { \ + if (PFX##_empty(iter->target)) \ + return NULL; \ + \ return &(iter->cursor->value); \ } \ \ @@ -673,7 +702,7 @@ return iter->index; \ } \ \ - FMOD SNAME##_node *PFX##_impl_new_node(K key, V value) \ + static SNAME##_node *PFX##_impl_new_node(K key, V value) \ { \ SNAME##_node *node = malloc(sizeof(SNAME##_node)); \ \ @@ -690,7 +719,7 @@ return node; \ } \ \ - FMOD SNAME##_node *PFX##_impl_get_node(SNAME *_map_, K key) \ + static SNAME##_node *PFX##_impl_get_node(SNAME *_map_, K key) \ { \ if (PFX##_empty(_map_)) \ return NULL; \ @@ -710,7 +739,7 @@ return NULL; \ } \ \ - FMOD unsigned char PFX##_impl_h(SNAME##_node *node) \ + static unsigned char PFX##_impl_h(SNAME##_node *node) \ { \ if (node == NULL) \ return 0; \ @@ -718,7 +747,7 @@ return node->height; \ } \ \ - FMOD unsigned char PFX##_impl_hupdate(SNAME##_node *node) \ + static unsigned char PFX##_impl_hupdate(SNAME##_node *node) \ { \ if (node == NULL) \ return 0; \ @@ -729,7 +758,7 @@ return 1 + (h_l > h_r ? h_l : h_r); \ } \ \ - FMOD void PFX##_impl_rotate_right(SNAME##_node **Z) \ + static void PFX##_impl_rotate_right(SNAME##_node **Z) \ { \ SNAME##_node *root = *Z; \ SNAME##_node *new_root = root->left; \ @@ -758,7 +787,7 @@ *Z = new_root; \ } \ \ - FMOD void PFX##_impl_rotate_left(SNAME##_node **Z) \ + static void PFX##_impl_rotate_left(SNAME##_node **Z) \ { \ SNAME##_node *root = *Z; \ SNAME##_node *new_root = root->right; \ @@ -787,7 +816,7 @@ *Z = new_root; \ } \ \ - FMOD void PFX##_impl_rebalance(SNAME *_map_, SNAME##_node *node) \ + static void PFX##_impl_rebalance(SNAME *_map_, SNAME##_node *node) \ { \ SNAME##_node *scan = node, *child = NULL; \ \ @@ -831,7 +860,7 @@ } \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_map_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_map_) \ { \ SNAME##_iter iter; \ \ @@ -840,7 +869,7 @@ return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_map_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_map_) \ { \ SNAME##_iter iter; \ \ diff --git a/src/treeset.h b/src/treeset.h index a08cef3..b09c879 100644 --- a/src/treeset.h +++ b/src/treeset.h @@ -139,18 +139,29 @@ 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_; \ + } \ + \ /* SOURCE ********************************************************************/ #define TREESET_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ \ - FMOD SNAME##_node *PFX##_new_node(V element); \ - FMOD SNAME##_node *PFX##_get_node(SNAME *_set_, V element); \ - FMOD unsigned char PFX##_h(SNAME##_node *node); \ - FMOD unsigned char PFX##_hupdate(SNAME##_node *node); \ - FMOD void PFX##_rotate_right(SNAME##_node **Z); \ - FMOD void PFX##_rotate_left(SNAME##_node **Z); \ - FMOD void PFX##_rebalance(SNAME *_set_, SNAME##_node *node); \ - SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \ - SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \ + /* Implementation Detail Functions */ \ + static SNAME##_node *PFX##_impl_new_node(V element); \ + static SNAME##_node *PFX##_impl_get_node(SNAME *_set_, V element); \ + static unsigned char PFX##_impl_h(SNAME##_node *node); \ + static unsigned char PFX##_impl_hupdate(SNAME##_node *node); \ + static void PFX##_impl_rotate_right(SNAME##_node **Z); \ + static void PFX##_impl_rotate_left(SNAME##_node **Z); \ + static void PFX##_impl_rebalance(SNAME *_set_, SNAME##_node *node); \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \ \ FMOD SNAME *PFX##_new(int (*compare)(V, V)) \ { \ @@ -235,7 +246,7 @@ { \ if (PFX##_empty(_set_)) \ { \ - _set_->root = PFX##_new_node(element); \ + _set_->root = PFX##_impl_new_node(element); \ \ if (!_set_->root) \ return false; \ @@ -261,7 +272,7 @@ \ if (_set_->cmp(parent->value, element) > 0) \ { \ - parent->left = PFX##_new_node(element); \ + parent->left = PFX##_impl_new_node(element); \ \ if (!parent->left) \ return false; \ @@ -271,7 +282,7 @@ } \ else \ { \ - parent->right = PFX##_new_node(element); \ + parent->right = PFX##_impl_new_node(element); \ \ if (!parent->right) \ return false; \ @@ -280,7 +291,7 @@ node = parent->right; \ } \ \ - PFX##_rebalance(_set_, node); \ + PFX##_impl_rebalance(_set_, node); \ } \ \ _set_->count++; \ @@ -290,7 +301,7 @@ \ FMOD bool PFX##_remove(SNAME *_set_, V element) \ { \ - SNAME##_node *node = PFX##_get_node(_set_, element); \ + SNAME##_node *node = PFX##_impl_get_node(_set_, element); \ \ if (!node) \ return false; \ @@ -399,7 +410,7 @@ } \ \ if (unbalanced != NULL) \ - PFX##_rebalance(_set_, unbalanced); \ + PFX##_impl_rebalance(_set_, unbalanced); \ \ _set_->count--; \ \ @@ -523,7 +534,7 @@ { \ V value = PFX##_iter_value(&iter); \ \ - if (PFX##_get_node(_set_B_, value) != NULL) \ + if (PFX##_impl_get_node(_set_B_, value) != NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -544,7 +555,7 @@ { \ V value = PFX##_iter_value(&iter); \ \ - if (PFX##_get_node(_set2_, value) == NULL) \ + if (PFX##_impl_get_node(_set2_, value) == NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -566,7 +577,7 @@ { \ V value = PFX##_iter_value(&iter1); \ \ - if (PFX##_get_node(_set2_, value) == NULL) \ + if (PFX##_impl_get_node(_set2_, value) == NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -574,7 +585,7 @@ { \ V value = PFX##_iter_value(&iter2); \ \ - if (PFX##_get_node(_set1_, value) == NULL) \ + if (PFX##_impl_get_node(_set1_, value) == NULL) \ PFX##_insert(_set_r_, value); \ } \ \ @@ -724,6 +735,9 @@ \ FMOD V PFX##_iter_value(SNAME##_iter *iter) \ { \ + if (PFX##_empty(iter->target)) \ + PFX##_impl_default_value(); \ + \ return iter->cursor->value; \ } \ \ @@ -732,7 +746,7 @@ return iter->index; \ } \ \ - FMOD SNAME##_node *PFX##_new_node(V element) \ + static SNAME##_node *PFX##_impl_new_node(V element) \ { \ SNAME##_node *node = malloc(sizeof(SNAME##_node)); \ \ @@ -748,7 +762,7 @@ return node; \ } \ \ - FMOD SNAME##_node *PFX##_get_node(SNAME *_set_, V element) \ + static SNAME##_node *PFX##_impl_get_node(SNAME *_set_, V element) \ { \ if (PFX##_empty(_set_)) \ return NULL; \ @@ -768,7 +782,7 @@ return NULL; \ } \ \ - FMOD unsigned char PFX##_h(SNAME##_node *node) \ + static unsigned char PFX##_impl_h(SNAME##_node *node) \ { \ if (node == NULL) \ return 0; \ @@ -776,18 +790,18 @@ return node->height; \ } \ \ - FMOD unsigned char PFX##_hupdate(SNAME##_node *node) \ + static unsigned char PFX##_impl_hupdate(SNAME##_node *node) \ { \ if (node == NULL) \ return 0; \ \ - unsigned char h_l = PFX##_h(node->left); \ - unsigned char h_r = PFX##_h(node->right); \ + unsigned char h_l = PFX##_impl_h(node->left); \ + unsigned char h_r = PFX##_impl_h(node->right); \ \ return 1 + (h_l > h_r ? h_l : h_r); \ } \ \ - FMOD void PFX##_rotate_right(SNAME##_node **Z) \ + static void PFX##_impl_rotate_right(SNAME##_node **Z) \ { \ SNAME##_node *root = *Z; \ SNAME##_node *new_root = root->left; \ @@ -810,13 +824,13 @@ \ new_root->right = root; \ \ - root->height = PFX##_hupdate(root); \ - new_root->height = PFX##_hupdate(new_root); \ + root->height = PFX##_impl_hupdate(root); \ + new_root->height = PFX##_impl_hupdate(new_root); \ \ *Z = new_root; \ } \ \ - FMOD void PFX##_rotate_left(SNAME##_node **Z) \ + static void PFX##_impl_rotate_left(SNAME##_node **Z) \ { \ SNAME##_node *root = *Z; \ SNAME##_node *new_root = root->right; \ @@ -839,13 +853,13 @@ \ new_root->left = root; \ \ - root->height = PFX##_hupdate(root); \ - new_root->height = PFX##_hupdate(new_root); \ + root->height = PFX##_impl_hupdate(root); \ + new_root->height = PFX##_impl_hupdate(new_root); \ \ *Z = new_root; \ } \ \ - FMOD void PFX##_rebalance(SNAME *_set_, SNAME##_node *node) \ + static void PFX##_impl_rebalance(SNAME *_set_, SNAME##_node *node) \ { \ SNAME##_node *scan = node, *child = NULL; \ \ @@ -857,26 +871,26 @@ if (scan->parent == NULL) \ is_root = true; \ \ - scan->height = PFX##_hupdate(scan); \ - balance = PFX##_h(scan->right) - PFX##_h(scan->left); \ + scan->height = PFX##_impl_hupdate(scan); \ + balance = PFX##_impl_h(scan->right) - PFX##_impl_h(scan->left); \ \ if (balance >= 2) \ { \ child = scan->right; \ \ - if (PFX##_h(child->right) < PFX##_h(child->left)) \ - PFX##_rotate_right(&(scan->right)); \ + if (PFX##_impl_h(child->right) < PFX##_impl_h(child->left)) \ + PFX##_impl_rotate_right(&(scan->right)); \ \ - PFX##_rotate_left(&scan); \ + PFX##_impl_rotate_left(&scan); \ } \ else if (balance <= -2) \ { \ child = scan->left; \ \ - if (PFX##_h(child->left) < PFX##_h(child->right)) \ - PFX##_rotate_left(&(scan->left)); \ + if (PFX##_impl_h(child->left) < PFX##_impl_h(child->right)) \ + PFX##_impl_rotate_left(&(scan->left)); \ \ - PFX##_rotate_right(&scan); \ + PFX##_impl_rotate_right(&scan); \ } \ \ if (is_root) \ @@ -889,7 +903,7 @@ } \ } \ \ - SNAME##_iter PFX##_impl_it_start(SNAME *_set_) \ + static SNAME##_iter PFX##_impl_it_start(SNAME *_set_) \ { \ SNAME##_iter iter; \ \ @@ -898,7 +912,7 @@ return iter; \ } \ \ - SNAME##_iter PFX##_impl_it_end(SNAME *_set_) \ + static SNAME##_iter PFX##_impl_it_end(SNAME *_set_) \ { \ SNAME##_iter iter; \ \ diff --git a/tests/README.md b/tests/README.md index 9f7a84d..4547ec1 100644 --- a/tests/README.md +++ b/tests/README.md @@ -4,4 +4,4 @@ * `contains.c` - Tests the `contains` function for all collections; * `foreach.c` - Tests the ForEach macros for all collections; * `iterators.c` - Tests all collection's iterators; -* `pointertype.c` - Tests if the source code is compatible with pointer types. +* `types.c` - Tests if all containers accept all possible C data types (struct, union, enum, pointers, function pointers) diff --git a/tests/pointertype.c b/tests/pointertype.c deleted file mode 100644 index 19f16cf..0000000 --- a/tests/pointertype.c +++ /dev/null @@ -1,29 +0,0 @@ -// Tests all containers if they accept a pinter type -// Compile with -Wall -Wextra -#include "../src/macro_collections.h" -#include - -typedef struct my_struct_s -{ - int a, b; -} my_struct; - -COLLECTION_GENERATE(LIST, l, list, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(STACK, s, stack, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(QUEUE, q, queue, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(DEQUE, d, deque, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(HEAP, h, heap, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(TREESET, ts, tset, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(TREEMAP, tm, tmap, /* FMOD */, my_struct *, my_struct *) -COLLECTION_GENERATE(HASHSET, hs, hset, /* FMOD */, /* K */, my_struct *) -COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, my_struct *, my_struct *) - -int main(void) -{ - printf("+--------------------------------------------------+\n"); - printf("| Pointer Data Type is Working |\n"); - printf("+--------------------------------------------------+\n"); - - return 0; -} diff --git a/tests/types.c b/tests/types.c new file mode 100644 index 0000000..bfbd3c3 --- /dev/null +++ b/tests/types.c @@ -0,0 +1,146 @@ +// Tests all containers if they accept all C data types +// Compile with -Wall -Wextra +#include "../src/macro_collections.h" +#include + +typedef struct struct_s +{ + int a, b; + char *c, *d; + double e[10]; +} struct_t; + +typedef enum enum_e +{ + HELLO, + WORLD, + NONE = 0 +} enum_t; + +typedef union union_u { + enum enum_e a; + struct struct_s b; + double c; + char *d; +} union_t; + +typedef int (*func_t)(int, double, char *); + +COLLECTION_GENERATE(LIST, l0, list0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(STACK, s0, stack0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(QUEUE, q0, queue0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(DEQUE, d0, deque0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(LINKEDLIST, ll0, linked0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(HEAP, h0, heap0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(TREESET, ts0, tset0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(TREEMAP, tm0, tmap0, /* FMOD */, struct_t *, struct_t *) +COLLECTION_GENERATE(HASHSET, hs0, hset0, /* FMOD */, /* K */, struct_t *) +COLLECTION_GENERATE(HASHMAP, hm0, hmap0, /* FMOD */, struct_t *, struct_t *) + +COLLECTION_GENERATE(LIST, l1, list1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(STACK, s1, stack1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(QUEUE, q1, queue1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(DEQUE, d1, deque1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(LINKEDLIST, ll1, linked1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(HEAP, h1, heap1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(TREESET, ts1, tset1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(TREEMAP, tm1, tmap1, /* FMOD */, struct_t, struct_t) +COLLECTION_GENERATE(HASHSET, hs1, hset1, /* FMOD */, /* K */, struct_t) +COLLECTION_GENERATE(HASHMAP, hm1, hmap1, /* FMOD */, struct_t, struct_t) + +COLLECTION_GENERATE(LIST, l2, list2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(STACK, s2, stack2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(QUEUE, q2, queue2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(DEQUE, d2, deque2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(LINKEDLIST, ll2, linked2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(HEAP, h2, heap2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(TREESET, ts2, tset2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(TREEMAP, tm2, tmap2, /* FMOD */, int, int) +COLLECTION_GENERATE(HASHSET, hs2, hset2, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(HASHMAP, hm2, hmap2, /* FMOD */, int, int) + +COLLECTION_GENERATE(LIST, l3, list3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(STACK, s3, stack3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(QUEUE, q3, queue3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(DEQUE, d3, deque3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(LINKEDLIST, ll3, linked3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(HEAP, h3, heap3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(TREESET, ts3, tset3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(TREEMAP, tm3, tmap3, /* FMOD */, int *, int *) +COLLECTION_GENERATE(HASHSET, hs3, hset3, /* FMOD */, /* K */, int *) +COLLECTION_GENERATE(HASHMAP, hm3, hmap3, /* FMOD */, int *, int *) + +COLLECTION_GENERATE(LIST, l4, list4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(STACK, s4, stack4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(QUEUE, q4, queue4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(DEQUE, d4, deque4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(LINKEDLIST, ll4, linked4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(HEAP, h4, heap4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(TREESET, ts4, tset4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(TREEMAP, tm4, tmap4, /* FMOD */, enum_t *, enum_t *) +COLLECTION_GENERATE(HASHSET, hs4, hset4, /* FMOD */, /* K */, enum_t *) +COLLECTION_GENERATE(HASHMAP, hm4, hmap4, /* FMOD */, enum_t *, enum_t *) + +COLLECTION_GENERATE(LIST, l5, list5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(STACK, s5, stack5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(QUEUE, q5, queue5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(DEQUE, d5, deque5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(LINKEDLIST, ll5, linked5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(HEAP, h5, heap5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(TREESET, ts5, tset5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(TREEMAP, tm5, tmap5, /* FMOD */, enum_t, enum_t) +COLLECTION_GENERATE(HASHSET, hs5, hset5, /* FMOD */, /* K */, enum_t) +COLLECTION_GENERATE(HASHMAP, hm5, hmap5, /* FMOD */, enum_t, enum_t) + +COLLECTION_GENERATE(LIST, l6, list6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(STACK, s6, stack6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(QUEUE, q6, queue6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(DEQUE, d6, deque6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(LINKEDLIST, ll6, linked6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(HEAP, h6, heap6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(TREESET, ts6, tset6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(TREEMAP, tm6, tmap6, /* FMOD */, union_t *, union_t *) +COLLECTION_GENERATE(HASHSET, hs6, hset6, /* FMOD */, /* K */, union_t *) +COLLECTION_GENERATE(HASHMAP, hm6, hmap6, /* FMOD */, union_t *, union_t *) + +COLLECTION_GENERATE(LIST, l7, list7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(STACK, s7, stack7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(QUEUE, q7, queue7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(DEQUE, d7, deque7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(LINKEDLIST, ll7, linked7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(HEAP, h7, heap7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(TREESET, ts7, tset7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(TREEMAP, tm7, tmap7, /* FMOD */, union_t, union_t) +COLLECTION_GENERATE(HASHSET, hs7, hset7, /* FMOD */, /* K */, union_t) +COLLECTION_GENERATE(HASHMAP, hm7, hmap7, /* FMOD */, union_t, union_t) + +COLLECTION_GENERATE(LIST, l8, list8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(STACK, s8, stack8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(QUEUE, q8, queue8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(DEQUE, d8, deque8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(LINKEDLIST, ll8, linked8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(HEAP, h8, heap8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(TREESET, ts8, tset8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(TREEMAP, tm8, tmap8, /* FMOD */, func_t, func_t) +COLLECTION_GENERATE(HASHSET, hs8, hset8, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(HASHMAP, hm8, hmap8, /* FMOD */, func_t, func_t) + +COLLECTION_GENERATE(LIST, l9, list9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(STACK, s9, stack9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(QUEUE, q9, queue9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(DEQUE, d9, deque9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(LINKEDLIST, ll9, linked9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(HEAP, h9, heap9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(TREESET, ts9, tset9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(TREEMAP, tm9, tmap9, /* FMOD */, func_t, func_t) +COLLECTION_GENERATE(HASHSET, hs9, hset9, /* FMOD */, /* K */, func_t) +COLLECTION_GENERATE(HASHMAP, hm9, hmap9, /* FMOD */, func_t, func_t) + +int main(void) +{ + printf("+--------------------------------------------------+\n"); + printf("| All Data Types Are Working |\n"); + printf("+--------------------------------------------------+\n"); + + return 0; +}