From 147e622580c04ba9869cfe9a3679021c5e3ebc8b Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 8 Feb 2020 00:01:46 -0300 Subject: [PATCH] Adding functions table to multimap and multiset --- src/cmc/multimap.h | 257 +++++++++++++++++++++++--------------- src/cmc/multiset.h | 204 ++++++++++++++++-------------- tests/main/unt/multimap.c | 58 +++++---- tests/main/unt/multiset.c | 38 +++--- 4 files changed, 326 insertions(+), 231 deletions(-) diff --git a/src/cmc/multimap.h b/src/cmc/multimap.h index 9ff2ed3..eedecdd 100644 --- a/src/cmc/multimap.h +++ b/src/cmc/multimap.h @@ -160,8 +160,9 @@ static const char *cmc_string_fmt_multimap = "struct %s<%s, %s> " "capacity:%" PRIuMAX ", " "count:%" PRIuMAX ", " "load:%lf, " - "cmp:%p, " - "hash:%p, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " "alloc:%p, " "callbacks:%p }"; @@ -210,23 +211,26 @@ struct cmc_callbacks_multimap /* Load factor in range (0.0, infinity) */ \ double load; \ \ - /* Key comparison functions */ \ - int (*cmp)(K, K); \ + /* Flags indicating errors or success */ \ + int flag; \ \ - /* Key hash function */ \ - size_t (*hash)(K); \ + /* Key function table */ \ + struct SNAME##_ftab_key *f_key; \ \ - /* Function that returns an iterator to the start of the multimap */ \ - struct SNAME##_iter (*it_start)(struct SNAME *); \ - \ - /* Function that returns an iterator to the end of the multimap */ \ - struct SNAME##_iter (*it_end)(struct SNAME *); \ + /* Value function table */ \ + struct SNAME##_ftab_val *f_val; \ \ /* Custom allocation functions */ \ struct cmc_alloc_node *alloc; \ \ /* Custom callback functions */ \ struct cmc_callbacks_multimap *callbacks; \ + \ + /* Function that returns an iterator to the start of the multimap */ \ + struct SNAME##_iter (*it_start)(struct SNAME *); \ + \ + /* Function that returns an iterator to the end of the multimap */ \ + struct SNAME##_iter (*it_end)(struct SNAME *); \ }; \ \ /* Multimap Entry */ \ @@ -245,6 +249,50 @@ struct cmc_callbacks_multimap struct SNAME##_entry *prev; \ }; \ \ + /* Key struct function table */ \ + struct SNAME##_ftab_key \ + { \ + /* Comparator function */ \ + int (*cmp)(K, K); \ + \ + /* Copy function */ \ + K (*cpy)(K); \ + \ + /* To string function */ \ + bool (*str)(FILE *, K); \ + \ + /* Free from memory function */ \ + void (*free)(K); \ + \ + /* Hash function */ \ + size_t (*hash)(K); \ + \ + /* Priority function */ \ + int (*pri)(K, K); \ + }; \ + \ + /* Value struct function table */ \ + struct SNAME##_ftab_val \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ struct SNAME##_iter \ { \ /* Target multimap */ \ @@ -275,13 +323,14 @@ struct cmc_callbacks_multimap /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ struct SNAME *PFX##_new(size_t capacity, double load, \ - int (*compare)(K, K), size_t (*hash)(K)); \ - struct SNAME *PFX##_new_custom(size_t capacity, double load, \ - int (*compare)(K, K), size_t (*hash)(K), \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks_multimap *callbacks); \ - void PFX##_clear(struct SNAME *_map_, void (*deallocator)(K, V)); \ - void PFX##_free(struct SNAME *_map_, void (*deallocator)(K, V)); \ + struct SNAME##_ftab_key *f_key, \ + struct SNAME##_ftab_val *f_val); \ + struct SNAME *PFX##_new_custom( \ + size_t capacity, double load, struct SNAME##_ftab_key *f_key, \ + struct SNAME##_ftab_val *f_val, struct cmc_alloc_node *alloc, \ + struct cmc_callbacks_multimap *callbacks); \ + void PFX##_clear(struct SNAME *_map_); \ + void PFX##_free(struct SNAME *_map_); \ /* Customization of Allocation and Callbacks */ \ void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ struct cmc_callbacks_multimap *callbacks); \ @@ -307,8 +356,7 @@ struct cmc_callbacks_multimap double PFX##_load(struct SNAME *_map_); \ /* Collection Utility */ \ bool PFX##_resize(struct SNAME *_map_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_, K (*key_copy_func)(K), \ - V (*value_copy_func)(V)); \ + struct SNAME *PFX##_copy_of(struct SNAME *_map_); \ bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_, \ bool ignore_key_count); \ struct cmc_string PFX##_to_string(struct SNAME *_map_); \ @@ -350,7 +398,8 @@ struct cmc_callbacks_multimap static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_); \ \ struct SNAME *PFX##_new(size_t capacity, double load, \ - int (*compare)(K, K), size_t (*hash)(K)) \ + struct SNAME##_ftab_key *f_key, \ + struct SNAME##_ftab_val *f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -361,6 +410,9 @@ struct cmc_callbacks_multimap if (capacity >= UINTMAX_MAX * load) \ return NULL; \ \ + if (!f_key || !f_val) \ + return NULL; \ + \ size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ \ struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ @@ -380,22 +432,21 @@ struct cmc_callbacks_multimap _map_->count = 0; \ _map_->capacity = real_capacity; \ _map_->load = load; \ - _map_->cmp = compare; \ - _map_->hash = hash; \ - \ - _map_->it_start = PFX##_impl_it_start; \ - _map_->it_end = PFX##_impl_it_end; \ - \ + _map_->flag = cmc_flags.OK; \ + _map_->f_key = f_key; \ + _map_->f_val = f_val; \ _map_->alloc = alloc; \ _map_->callbacks = NULL; \ + _map_->it_end = PFX##_impl_it_end; \ + _map_->it_start = PFX##_impl_it_start; \ \ return _map_; \ } \ \ - struct SNAME *PFX##_new_custom(size_t capacity, double load, \ - int (*compare)(K, K), size_t (*hash)(K), \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks_multimap *callbacks) \ + struct SNAME *PFX##_new_custom( \ + size_t capacity, double load, struct SNAME##_ftab_key *f_key, \ + struct SNAME##_ftab_val *f_val, struct cmc_alloc_node *alloc, \ + struct cmc_callbacks_multimap *callbacks) \ { \ if (capacity == 0 || load <= 0) \ return NULL; \ @@ -404,6 +455,9 @@ struct cmc_callbacks_multimap if (capacity >= UINTMAX_MAX * load) \ return NULL; \ \ + if (!f_key || !f_val) \ + return NULL; \ + \ if (!alloc) \ alloc = &cmc_alloc_node_default; \ \ @@ -426,35 +480,35 @@ struct cmc_callbacks_multimap _map_->count = 0; \ _map_->capacity = real_capacity; \ _map_->load = load; \ - _map_->cmp = compare; \ - _map_->hash = hash; \ - \ - _map_->it_start = PFX##_impl_it_start; \ - _map_->it_end = PFX##_impl_it_end; \ - \ + _map_->flag = cmc_flags.OK; \ + _map_->f_key = f_key; \ + _map_->f_val = f_val; \ _map_->alloc = alloc; \ _map_->callbacks = callbacks; \ + _map_->it_start = PFX##_impl_it_start; \ + _map_->it_end = PFX##_impl_it_end; \ \ return _map_; \ } \ \ - void PFX##_clear(struct SNAME *_map_, void (*deallocator)(K, V)) \ + void PFX##_clear(struct SNAME *_map_) \ { \ size_t index = 0; \ - struct SNAME##_entry *scan; \ \ while (index < _map_->capacity) \ { \ - scan = _map_->buffer[index][0]; \ + struct SNAME##_entry *scan = _map_->buffer[index][0]; \ \ if (scan != NULL) \ { \ if (scan->next == NULL && scan->prev == NULL) \ { \ - if (deallocator) \ - deallocator(scan->key, scan->value); \ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ \ - free(scan); \ + _map_->alloc->free(scan); \ } \ else \ { \ @@ -464,10 +518,12 @@ struct cmc_callbacks_multimap \ scan = scan->next; \ \ - if (deallocator) \ - deallocator(tmp->key, tmp->value); \ + if (_map_->f_key->free) \ + _map_->f_key->free(tmp->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(tmp->value); \ \ - free(tmp); \ + _map_->alloc->free(tmp); \ } \ } \ } \ @@ -481,19 +537,25 @@ struct cmc_callbacks_multimap _map_->count = 0; \ } \ \ - void PFX##_free(struct SNAME *_map_, void (*deallocator)(K, V)) \ + void PFX##_free(struct SNAME *_map_) \ { \ size_t index = 0; \ - struct SNAME##_entry *scan; \ \ while (index < _map_->capacity) \ { \ - scan = _map_->buffer[index][0]; \ + struct SNAME##_entry *scan = _map_->buffer[index][0]; \ \ if (scan != NULL) \ { \ if (scan->next == NULL && scan->prev == NULL) \ - free(scan); \ + { \ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ + \ + _map_->alloc->free(scan); \ + } \ else \ { \ while (scan != NULL) \ @@ -502,10 +564,12 @@ struct cmc_callbacks_multimap \ scan = scan->next; \ \ - if (deallocator) \ - deallocator(tmp->key, tmp->value); \ + if (_map_->f_key->free) \ + _map_->f_key->free(tmp->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(tmp->value); \ \ - free(tmp); \ + _map_->alloc->free(tmp); \ } \ } \ } \ @@ -513,8 +577,8 @@ struct cmc_callbacks_multimap index++; \ } \ \ - free(_map_->buffer); \ - free(_map_); \ + _map_->alloc->free(_map_->buffer); \ + _map_->alloc->free(_map_); \ } \ \ void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ @@ -535,7 +599,7 @@ struct cmc_callbacks_multimap return false; \ } \ \ - size_t hash = _map_->hash(key); \ + size_t hash = _map_->f_key->hash(key); \ size_t pos = hash % _map_->capacity; \ \ struct SNAME##_entry *entry = PFX##_impl_new_entry(_map_, key, value); \ @@ -590,14 +654,14 @@ struct cmc_callbacks_multimap return false; \ } \ \ - size_t hash = _map_->hash(key); \ + size_t hash = _map_->f_key->hash(key); \ \ struct SNAME##_entry *entry = \ _map_->buffer[hash % _map_->capacity][0]; \ \ while (entry != NULL) \ { \ - if (_map_->cmp(entry->key, key) == 0) \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ { \ if (old_values) \ (*old_values)[index++] = entry->value; \ @@ -613,7 +677,7 @@ struct cmc_callbacks_multimap \ bool PFX##_remove(struct SNAME *_map_, K key, V *out_value) \ { \ - size_t hash = _map_->hash(key); \ + size_t hash = _map_->f_key->hash(key); \ \ struct SNAME##_entry **head = \ &(_map_->buffer[hash % _map_->capacity][0]); \ @@ -627,7 +691,7 @@ struct cmc_callbacks_multimap \ if (entry->next == NULL && entry->prev == NULL) \ { \ - if (_map_->cmp(entry->key, key) == 0) \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ { \ *head = NULL; \ *tail = NULL; \ @@ -644,7 +708,7 @@ struct cmc_callbacks_multimap \ while (entry != NULL) \ { \ - if (_map_->cmp(entry->key, key) == 0) \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ { \ if (*head == entry) \ *head = entry->next; \ @@ -671,7 +735,7 @@ struct cmc_callbacks_multimap return false; \ } \ \ - free(entry); \ + _map_->alloc->free(entry); \ \ _map_->count--; \ \ @@ -680,7 +744,7 @@ struct cmc_callbacks_multimap \ size_t PFX##_remove_all(struct SNAME *_map_, K key, V **out_values) \ { \ - size_t hash = _map_->hash(key); \ + size_t hash = _map_->f_key->hash(key); \ \ struct SNAME##_entry **head = \ &(_map_->buffer[hash % _map_->capacity][0]); \ @@ -707,13 +771,13 @@ struct cmc_callbacks_multimap if (out_values) \ (*out_values)[index++] = entry->value; \ \ - free(entry); \ + _map_->alloc->free(entry); \ } \ else \ { \ while (entry != NULL) \ { \ - if (_map_->cmp(entry->key, key) == 0) \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ { \ if (*head == entry) \ *head = entry->next; \ @@ -730,7 +794,7 @@ struct cmc_callbacks_multimap if (out_values) \ (*out_values)[index++] = entry->value; \ \ - free(entry); \ + _map_->alloc->free(entry); \ \ entry = temp; \ } \ @@ -763,7 +827,7 @@ struct cmc_callbacks_multimap *key = result_key; \ *value = result_value; \ } \ - else if (_map_->cmp(result_key, *key) > 0) \ + else if (_map_->f_key->cmp(result_key, *key) > 0) \ { \ *key = result_key; \ *value = result_value; \ @@ -792,7 +856,7 @@ struct cmc_callbacks_multimap *key = result_key; \ *value = result_value; \ } \ - else if (_map_->cmp(result_key, *key) < 0) \ + else if (_map_->f_key->cmp(result_key, *key) < 0) \ { \ *key = result_key; \ *value = result_value; \ @@ -834,8 +898,7 @@ struct cmc_callbacks_multimap \ bool PFX##_full(struct SNAME *_map_) \ { \ - return (double)PFX##_capacity(_map_) * PFX##_load(_map_) <= \ - (double)PFX##_count(_map_); \ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ } \ \ size_t PFX##_count(struct SNAME *_map_) \ @@ -845,7 +908,7 @@ struct cmc_callbacks_multimap \ size_t PFX##_key_count(struct SNAME *_map_, K key) \ { \ - size_t hash = _map_->hash(key); \ + size_t hash = _map_->f_key->hash(key); \ \ struct SNAME##_entry *entry = \ _map_->buffer[hash % _map_->capacity][0]; \ @@ -857,7 +920,7 @@ struct cmc_callbacks_multimap \ while (entry != NULL) \ { \ - if (_map_->cmp(entry->key, key) == 0) \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ total_count++; \ \ entry = entry->next; \ @@ -881,23 +944,23 @@ struct cmc_callbacks_multimap if (PFX##_capacity(_map_) == capacity) \ return true; \ \ - if (PFX##_capacity(_map_) > capacity / PFX##_load(_map_)) \ + if (PFX##_capacity(_map_) > capacity / _map_->load) \ return true; \ \ /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * PFX##_load(_map_)) \ + if (capacity >= UINTMAX_MAX * _map_->load) \ return false; \ \ /* Calculate required capacity based on the prime numbers */ \ size_t theoretical_size = PFX##_impl_calculate_size(capacity); \ \ /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < PFX##_count(_map_) / PFX##_load(_map_)) \ + if (theoretical_size < PFX##_count(_map_) / _map_->load) \ return false; \ \ struct SNAME *_new_map_ = \ - PFX##_new_custom(capacity, PFX##_load(_map_), _map_->cmp, \ - _map_->hash, _map_->alloc, _map_->callbacks); \ + PFX##_new_custom(capacity, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, _map_->callbacks); \ \ if (!_new_map_) \ return false; \ @@ -915,7 +978,7 @@ struct cmc_callbacks_multimap \ if (PFX##_count(_map_) != PFX##_count(_new_map_)) \ { \ - PFX##_free(_new_map_, NULL); \ + PFX##_free(_new_map_); \ return false; \ } \ \ @@ -927,17 +990,16 @@ struct cmc_callbacks_multimap _map_->capacity = _new_map_->capacity; \ _new_map_->capacity = tmp_c; \ \ - PFX##_free(_new_map_, NULL); \ + PFX##_free(_new_map_); \ \ return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_, K (*key_copy_func)(K), \ - V (*value_copy_func)(V)) \ + struct SNAME *PFX##_copy_of(struct SNAME *_map_) \ { \ struct SNAME *result = \ - PFX##_new_custom(_map_->capacity, _map_->load, _map_->cmp, \ - _map_->hash, _map_->alloc, _map_->callbacks); \ + PFX##_new_custom(_map_->capacity, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, _map_->callbacks); \ \ if (!result) \ return NULL; \ @@ -953,10 +1015,10 @@ struct cmc_callbacks_multimap K key = PFX##_iter_key(&iter); \ V value = PFX##_iter_value(&iter); \ \ - if (key_copy_func) \ - key = key_copy_func(key); \ - if (value_copy_func) \ - value = value_copy_func(value); \ + if (_map_->f_key->cpy) \ + key = _map_->f_key->cpy(key); \ + if (_map_->f_val->cpy) \ + value = _map_->f_val->cpy(value); \ \ PFX##_insert(result, key, value); \ } \ @@ -1010,17 +1072,12 @@ struct cmc_callbacks_multimap struct cmc_string str; \ struct SNAME *m_ = _map_; \ \ - int n = \ - snprintf(str.s, cmc_string_len, cmc_string_fmt_multimap, #SNAME, \ - #K, #V, m_, m_->buffer, m_->capacity, m_->count, \ - m_->load, m_->cmp, m_->hash, m_->alloc, m_->callbacks); \ + int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_multimap, \ + #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ + m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ + m_->alloc, m_->callbacks); \ \ - if (n < 0 || n == (int)cmc_string_len) \ - return (struct cmc_string){ 0 }; \ - \ - str.s[n] = '\0'; \ - \ - return str; \ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ @@ -1038,7 +1095,7 @@ struct cmc_callbacks_multimap \ void PFX##_iter_free(struct SNAME##_iter *iter) \ { \ - free(iter); \ + iter->target->alloc->free(iter); \ } \ \ void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \ @@ -1279,14 +1336,14 @@ struct cmc_callbacks_multimap \ struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, K key) \ { \ - size_t hash = _map_->hash(key); \ + size_t hash = _map_->f_key->hash(key); \ \ struct SNAME##_entry *entry = \ _map_->buffer[hash % _map_->capacity][0]; \ \ while (entry != NULL) \ { \ - if (_map_->cmp(entry->key, key) == 0) \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ return entry; \ \ entry = entry->next; \ diff --git a/src/cmc/multiset.h b/src/cmc/multiset.h index 04b12d0..bcdbbbb 100644 --- a/src/cmc/multiset.h +++ b/src/cmc/multiset.h @@ -151,8 +151,8 @@ static const char *cmc_string_fmt_multiset = "struct %s<%s> " "count:%" PRIuMAX ", " "cardinality:%" PRIuMAX ", " "load:%lf, " - "cmp:%p, " - "hash:%p, " + "flag:%d, " + "f_val:%p, " "alloc:%p, " "callbacks:%p }"; @@ -204,23 +204,23 @@ struct cmc_callbacks_multiset /* Load factor in range (0.0, 1.0) */ \ double load; \ \ - /* Element comparison function */ \ - int (*cmp)(V, V); \ + /* Flags indicating errors or success */ \ + int flag; \ \ - /* Element hash function */ \ - size_t (*hash)(V); \ - \ - /* Function that returns an iterator to the start of the hashset */ \ - struct SNAME##_iter (*it_start)(struct SNAME *); \ - \ - /* Function that returns an iterator to the end of the hashset */ \ - struct SNAME##_iter (*it_end)(struct SNAME *); \ + /* Key function table */ \ + struct SNAME##_ftab_val *f_val; \ \ /* Custom allocation functions */ \ struct cmc_alloc_node *alloc; \ \ /* Custom callback functions */ \ struct cmc_callbacks_multiset *callbacks; \ + \ + /* Function that returns an iterator to the start of the hashset */ \ + struct SNAME##_iter (*it_start)(struct SNAME *); \ + \ + /* Function that returns an iterator to the end of the hashset */ \ + struct SNAME##_iter (*it_end)(struct SNAME *); \ }; \ \ struct SNAME##_entry \ @@ -239,6 +239,28 @@ struct cmc_callbacks_multiset enum cmc_entry_state state; \ }; \ \ + /* Value struct function table */ \ + struct SNAME##_ftab_val \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ /* Hashset Iterator */ \ struct SNAME##_iter \ { \ @@ -267,13 +289,13 @@ struct cmc_callbacks_multiset /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ struct SNAME *PFX##_new(size_t capacity, double load, \ - int (*compare)(V, V), size_t (*hash)(V)); \ + struct SNAME##_ftab_val *f_val); \ struct SNAME *PFX##_new_custom(size_t capacity, double load, \ - int (*compare)(V, V), size_t (*hash)(V), \ + struct SNAME##_ftab_val *f_val, \ struct cmc_alloc_node *alloc, \ struct cmc_callbacks_multiset *callbacks); \ - void PFX##_clear(struct SNAME *_set_, void (*deallocator)(V)); \ - void PFX##_free(struct SNAME *_set_, void (*deallocator)(V)); \ + void PFX##_clear(struct SNAME *_set_); \ + void PFX##_free(struct SNAME *_set_); \ /* Customization of Allocation and Callbacks */ \ void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ struct cmc_callbacks_multiset *callbacks); \ @@ -297,9 +319,8 @@ struct cmc_callbacks_multiset double PFX##_load(struct SNAME *_set_); \ /* Collection Utility */ \ bool PFX##_resize(struct SNAME *_set_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_, V (*copy_func)(V)); \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_, \ - bool ignore_multiplicity); \ + struct SNAME *PFX##_copy_of(struct SNAME *_set_); \ + bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \ struct cmc_string PFX##_to_string(struct SNAME *_set_); \ \ /* Set Operations */ \ @@ -354,7 +375,7 @@ struct cmc_callbacks_multiset static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_set_); \ \ struct SNAME *PFX##_new(size_t capacity, double load, \ - int (*compare)(V, V), size_t (*hash)(V)) \ + struct SNAME##_ftab_val *f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -365,6 +386,9 @@ struct cmc_callbacks_multiset if (capacity >= UINTMAX_MAX * load) \ return NULL; \ \ + if (!f_val) \ + return NULL; \ + \ size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ \ struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ @@ -385,20 +409,18 @@ struct cmc_callbacks_multiset _set_->cardinality = 0; \ _set_->capacity = real_capacity; \ _set_->load = load; \ - _set_->cmp = compare; \ - _set_->hash = hash; \ - \ - _set_->it_start = PFX##_impl_it_start; \ - _set_->it_end = PFX##_impl_it_end; \ - \ + _set_->flag = cmc_flags.OK; \ + _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = NULL; \ + _set_->it_start = PFX##_impl_it_start; \ + _set_->it_end = PFX##_impl_it_end; \ \ return _set_; \ } \ \ struct SNAME *PFX##_new_custom(size_t capacity, double load, \ - int (*compare)(V, V), size_t (*hash)(V), \ + struct SNAME##_ftab_val *f_val, \ struct cmc_alloc_node *alloc, \ struct cmc_callbacks_multiset *callbacks) \ { \ @@ -409,6 +431,9 @@ struct cmc_callbacks_multiset if (capacity >= UINTMAX_MAX * load) \ return NULL; \ \ + if (!f_val) \ + return NULL; \ + \ size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ \ if (!alloc) \ @@ -432,21 +457,19 @@ struct cmc_callbacks_multiset _set_->cardinality = 0; \ _set_->capacity = real_capacity; \ _set_->load = load; \ - _set_->cmp = compare; \ - _set_->hash = hash; \ - \ - _set_->it_start = PFX##_impl_it_start; \ - _set_->it_end = PFX##_impl_it_end; \ - \ + _set_->flag = cmc_flags.OK; \ + _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = callbacks; \ + _set_->it_start = PFX##_impl_it_start; \ + _set_->it_end = PFX##_impl_it_end; \ \ return _set_; \ } \ \ - void PFX##_clear(struct SNAME *_set_, void (*deallocator)(V)) \ + void PFX##_clear(struct SNAME *_set_) \ { \ - if (deallocator) \ + if (_set_->f_val->free) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ @@ -454,7 +477,7 @@ struct cmc_callbacks_multiset \ if (entry->state == CMC_ES_FILLED) \ { \ - deallocator(entry->value); \ + _set_->f_val->free(entry->value); \ } \ } \ } \ @@ -465,9 +488,9 @@ struct cmc_callbacks_multiset _set_->count = 0; \ } \ \ - void PFX##_free(struct SNAME *_set_, void (*deallocator)(V)) \ + void PFX##_free(struct SNAME *_set_) \ { \ - if (deallocator) \ + if (_set_->f_val->free) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ @@ -475,13 +498,13 @@ struct cmc_callbacks_multiset \ if (entry->state == CMC_ES_FILLED) \ { \ - deallocator(entry->value); \ + _set_->f_val->free(entry->value); \ } \ } \ } \ \ - free(_set_->buffer); \ - free(_set_); \ + _set_->alloc->free(_set_->buffer); \ + _set_->alloc->free(_set_); \ } \ \ void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ @@ -618,7 +641,7 @@ struct cmc_callbacks_multiset \ if (index == 0) \ *value = result; \ - else if (_set_->cmp(result, *value) > 0) \ + else if (_set_->f_val->cmp(result, *value) > 0) \ *value = result; \ } \ \ @@ -640,7 +663,7 @@ struct cmc_callbacks_multiset \ if (index == 0) \ *value = result; \ - else if (_set_->cmp(result, *value) < 0) \ + else if (_set_->f_val->cmp(result, *value) < 0) \ *value = result; \ } \ \ @@ -669,8 +692,7 @@ struct cmc_callbacks_multiset \ bool PFX##_full(struct SNAME *_set_) \ { \ - return (double)PFX##_capacity(_set_) * PFX##_load(_set_) <= \ - (double)PFX##_count(_set_); \ + return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ } \ \ size_t PFX##_count(struct SNAME *_set_) \ @@ -695,26 +717,26 @@ struct cmc_callbacks_multiset \ bool PFX##_resize(struct SNAME *_set_, size_t capacity) \ { \ - if (PFX##_capacity(_set_) == capacity) \ + if (_set_->capacity == capacity) \ return true; \ \ - if (PFX##_capacity(_set_) > capacity / PFX##_load(_set_)) \ + if (_set_->capacity > capacity / _set_->load) \ return true; \ \ /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * PFX##_load(_set_)) \ + if (capacity >= UINTMAX_MAX * _set_->load) \ return false; \ \ /* Calculate required capacity based on the prime numbers */ \ size_t theoretical_size = PFX##_impl_calculate_size(capacity); \ \ /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < PFX##_count(_set_) / PFX##_load(_set_)) \ + if (theoretical_size < _set_->count / _set_->load) \ return false; \ \ struct SNAME *_new_set_ = \ - PFX##_new_custom(capacity, PFX##_load(_set_), _set_->cmp, \ - _set_->hash, _set_->alloc, _set_->callbacks); \ + PFX##_new_custom(capacity, _set_->load, _set_->f_val, \ + _set_->alloc, _set_->callbacks); \ \ if (!_new_set_) \ return false; \ @@ -728,9 +750,9 @@ struct cmc_callbacks_multiset PFX##_iter_multiplicity(&iter)); \ } \ \ - if (PFX##_count(_set_) != PFX##_count(_new_set_)) \ + if (_set_->count != _new_set_->count) \ { \ - PFX##_free(_new_set_, NULL); \ + PFX##_free(_new_set_); \ return false; \ } \ \ @@ -742,21 +764,21 @@ struct cmc_callbacks_multiset _set_->capacity = _new_set_->capacity; \ _new_set_->capacity = tmp_c; \ \ - PFX##_free(_new_set_, NULL); \ + PFX##_free(_new_set_); \ \ return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_, V (*copy_func)(V)) \ + struct SNAME *PFX##_copy_of(struct SNAME *_set_) \ { \ struct SNAME *result = \ - PFX##_new_custom(_set_->capacity, _set_->load, _set_->cmp, \ - _set_->hash, _set_->alloc, _set_->callbacks); \ + PFX##_new_custom(_set_->capacity, _set_->load, _set_->f_val, \ + _set_->alloc, _set_->callbacks); \ \ if (!result) \ return NULL; \ \ - if (copy_func) \ + if (_set_->f_val->cpy) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ @@ -774,7 +796,7 @@ struct cmc_callbacks_multiset target->dist = scan->dist; \ target->multiplicity = scan->multiplicity; \ \ - target->value = copy_func(scan->value); \ + target->value = _set_->f_val->cpy(scan->value); \ } \ } \ } \ @@ -789,17 +811,15 @@ struct cmc_callbacks_multiset return result; \ } \ \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_, \ - bool ignore_multiplicity) \ + bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \ { \ - if (PFX##_count(_set1_) != PFX##_count(_set2_)) \ + if (_set1_->count != _set2_->count) \ return false; \ \ - if (!ignore_multiplicity && \ - PFX##_cardinality(_set1_) != PFX##_cardinality(_set2_)) \ + if (_set1_->cardinality != _set2_->cardinality) \ return false; \ \ - if (PFX##_count(_set1_) == 0) \ + if (_set1_->count == 0) \ return true; \ \ struct SNAME##_iter iter; \ @@ -814,8 +834,7 @@ struct cmc_callbacks_multiset if (entry == NULL) \ return false; \ \ - if (!ignore_multiplicity && \ - entry->multiplicity != PFX##_iter_multiplicity(&iter)) \ + if (entry->multiplicity != PFX##_iter_multiplicity(&iter)) \ return false; \ } \ \ @@ -829,22 +848,17 @@ struct cmc_callbacks_multiset \ int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_multiset, \ #SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \ - s_->cardinality, s_->load, s_->cmp, s_->hash, \ + s_->cardinality, s_->load, s_->flag, s_->f_val, \ s_->alloc, s_->callbacks); \ \ - if (n < 0 || n == (int)cmc_string_len) \ - return (struct cmc_string){ 0 }; \ - \ - str.s[n] = '\0'; \ - \ - return str; \ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \ { \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ - _set1_->hash, _set1_->alloc, _set1_->callbacks); \ + PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ + _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ @@ -884,8 +898,8 @@ struct cmc_callbacks_multiset struct SNAME *_set2_) \ { \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ - _set1_->hash, _set1_->alloc, _set1_->callbacks); \ + PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ + _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ @@ -915,8 +929,8 @@ struct cmc_callbacks_multiset struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \ { \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ - _set1_->hash, _set1_->alloc, _set1_->callbacks); \ + PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ + _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ @@ -942,8 +956,8 @@ struct cmc_callbacks_multiset struct SNAME *PFX##_summation(struct SNAME *_set1_, struct SNAME *_set2_) \ { \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ - _set1_->hash, _set1_->alloc, _set1_->callbacks); \ + PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ + _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ @@ -975,8 +989,8 @@ struct cmc_callbacks_multiset struct SNAME##_iter iter1, iter2; \ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ - _set1_->hash, _set1_->alloc, _set1_->callbacks); \ + PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ + _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ @@ -1023,7 +1037,7 @@ struct cmc_callbacks_multiset \ bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ { \ - if (PFX##_count(_set1_) > PFX##_count(_set2_)) \ + if (_set1_->count > _set2_->count) \ return false; \ \ if (PFX##_empty(_set1_)) \ @@ -1055,7 +1069,7 @@ struct cmc_callbacks_multiset \ bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ { \ - if (PFX##_count(_set1_) >= PFX##_count(_set2_)) \ + if (_set1_->count >= _set2_->count) \ return false; \ \ if (PFX##_empty(_set1_)) \ @@ -1126,7 +1140,7 @@ struct cmc_callbacks_multiset \ void PFX##_iter_free(struct SNAME##_iter *iter) \ { \ - free(iter); \ + iter->target->alloc->free(iter); \ } \ \ void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \ @@ -1198,7 +1212,7 @@ struct cmc_callbacks_multiset if (iter->end) \ return false; \ \ - if (iter->index + 1 == PFX##_count(iter->target)) \ + if (iter->index + 1 == iter->target->count) \ { \ iter->end = true; \ return false; \ @@ -1257,13 +1271,13 @@ struct cmc_callbacks_multiset if (iter->end) \ return false; \ \ - if (iter->index + 1 == PFX##_count(iter->target)) \ + if (iter->index + 1 == iter->target->count) \ { \ iter->end = true; \ return false; \ } \ \ - if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ return false; \ \ for (size_t i = 0; i < steps; i++) \ @@ -1297,7 +1311,7 @@ struct cmc_callbacks_multiset /* given index */ \ bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ { \ - if (index >= PFX##_count(iter->target)) \ + if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ @@ -1347,11 +1361,11 @@ struct cmc_callbacks_multiset \ if (PFX##_full(_set_)) \ { \ - if (!PFX##_resize(_set_, PFX##_capacity(_set_) + 1)) \ + if (!PFX##_resize(_set_, _set_->capacity + 1)) \ return NULL; \ } \ \ - size_t hash = _set_->hash(element); \ + size_t hash = _set_->f_val->hash(element); \ size_t original_pos = hash % _set_->capacity; \ size_t pos = original_pos; \ /* Current multiplicity. Might change due to robin hood hashing */ \ @@ -1409,7 +1423,7 @@ struct cmc_callbacks_multiset static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \ V element) \ { \ - size_t hash = _set_->hash(element); \ + size_t hash = _set_->f_val->hash(element); \ size_t pos = hash % _set_->capacity; \ \ struct SNAME##_entry *target = &(_set_->buffer[pos]); \ @@ -1417,7 +1431,7 @@ struct cmc_callbacks_multiset while (target->state == CMC_ES_FILLED || \ target->state == CMC_ES_DELETED) \ { \ - if (_set_->cmp(target->value, element) == 0) \ + if (_set_->f_val->cmp(target->value, element) == 0) \ return target; \ \ pos++; \ diff --git a/tests/main/unt/multimap.c b/tests/main/unt/multimap.c index 4604c9c..df3def0 100644 --- a/tests/main/unt/multimap.c +++ b/tests/main/unt/multimap.c @@ -7,32 +7,48 @@ CMC_GENERATE_MULTIMAP(mm, multimap, size_t, size_t) +struct multimap_ftab_key *mm_ftab_key = + &(struct multimap_ftab_key){ .cmp = cmp, + .cpy = copy, + .str = str, + .free = custom_free, + .hash = hash, + .pri = pri }; + +struct multimap_ftab_val *mm_ftab_val = + &(struct multimap_ftab_val){ .cmp = cmp, + .cpy = copy, + .str = str, + .free = custom_free, + .hash = hash, + .pri = pri }; + CMC_CREATE_UNIT(multimap_test, true, { CMC_CREATE_TEST(new, { - struct multimap *map = mm_new(943722, 0.8, cmp, hash); + struct multimap *map = mm_new(943722, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map->buffer); cmc_assert_equals(size_t, 0, mm_count(map)); cmc_assert_greater_equals(size_t, (943722 / 0.8), mm_capacity(map)); - mm_free(map, NULL); + mm_free(map); }); CMC_CREATE_TEST(new[capacity = 0], { - struct multimap *map = mm_new(0, 0.8, cmp, hash); + struct multimap *map = mm_new(0, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_equals(ptr, NULL, map); }); CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct multimap *map = mm_new(UINT64_MAX, 0.99, cmp, hash); + struct multimap *map = mm_new(UINT64_MAX, 0.99, mm_ftab_key, mm_ftab_val); cmc_assert_equals(ptr, NULL, map); }); CMC_CREATE_TEST(clear[count capacity], { - struct multimap *map = mm_new(100, 0.8, cmp, hash); + struct multimap *map = mm_new(100, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); @@ -41,15 +57,15 @@ CMC_CREATE_UNIT(multimap_test, true, { cmc_assert_equals(size_t, 50, mm_count(map)); - mm_clear(map, NULL); + mm_clear(map); cmc_assert_equals(size_t, 0, mm_count(map)); - mm_free(map, NULL); + mm_free(map); }); CMC_CREATE_TEST(insert[count], { - struct multimap *map = mm_new(100, 0.8, cmp, hash); + struct multimap *map = mm_new(100, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); @@ -58,11 +74,11 @@ CMC_CREATE_UNIT(multimap_test, true, { cmc_assert_equals(size_t, 100, mm_count(map)); - mm_free(map, NULL); + mm_free(map); }); CMC_CREATE_TEST(remove[count], { - struct multimap *map = mm_new(100, 0.8, cmp, hash); + struct multimap *map = mm_new(100, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); @@ -76,11 +92,11 @@ CMC_CREATE_UNIT(multimap_test, true, { cmc_assert_equals(size_t, 140, mm_count(map)); - mm_free(map, NULL); + mm_free(map); }); CMC_CREATE_TEST(remove[count = 0], { - struct multimap *map = mm_new(100, 0.8, cmp, hash); + struct multimap *map = mm_new(100, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); @@ -88,11 +104,11 @@ CMC_CREATE_UNIT(multimap_test, true, { cmc_assert(!mm_remove(map, 10, &r)); - mm_free(map, NULL); + mm_free(map); }); CMC_CREATE_TEST(remove[count = 1], { - struct multimap *map = mm_new(100, 0.8, cmp, hash); + struct multimap *map = mm_new(100, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); @@ -101,27 +117,27 @@ CMC_CREATE_UNIT(multimap_test, true, { cmc_assert(mm_insert(map, 10, 11)); cmc_assert(mm_remove(map, 10, &r)); - mm_free(map, NULL); + mm_free(map); }); CMC_CREATE_TEST(get[key ordering], { - struct multimap *map = mm_new(100, 0.8, cmp, hash); + struct multimap *map = mm_new(100, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); - /* Assert that the value 100 is accessed before the value 101 for the - * same key */ + /* Assert that the value 100 is accessed before the value 101 for */ + /* the same key */ cmc_assert(mm_insert(map, 10, 100)); cmc_assert(mm_insert(map, 20, 102)); cmc_assert(mm_insert(map, 10, 101)); cmc_assert_equals(size_t, 100, mm_get(map, 10)); - mm_free(map, NULL); + mm_free(map); }); CMC_CREATE_TEST(key_count, { - struct multimap *map = mm_new(50, 0.8, cmp, hash); + struct multimap *map = mm_new(50, 0.8, mm_ftab_key, mm_ftab_val); cmc_assert_not_equals(ptr, NULL, map); @@ -133,6 +149,6 @@ CMC_CREATE_UNIT(multimap_test, true, { for (size_t i = 0; i < 20; i++) cmc_assert_equals(size_t, 50, mm_key_count(map, i)); - mm_free(map, NULL); + mm_free(map); }); }); diff --git a/tests/main/unt/multiset.c b/tests/main/unt/multiset.c index cc122cf..7bf25db 100644 --- a/tests/main/unt/multiset.c +++ b/tests/main/unt/multiset.c @@ -7,9 +7,17 @@ CMC_GENERATE_MULTISET(ms, multiset, size_t) +struct multiset_ftab_val *ms_ftab_val = + &(struct multiset_ftab_val){ .cmp = cmp, + .cpy = copy, + .str = str, + .free = custom_free, + .hash = hash, + .pri = pri }; + CMC_CREATE_UNIT(multiset_test, true, { CMC_CREATE_TEST(new, { - struct multiset *set = ms_new(943722, 0.6, cmp, hash); + struct multiset *set = ms_new(943722, 0.6, ms_ftab_val); cmc_assert_not_equals(ptr, NULL, set); cmc_assert_not_equals(ptr, NULL, set->buffer); @@ -17,23 +25,23 @@ CMC_CREATE_UNIT(multiset_test, true, { cmc_assert_greater_equals(size_t, ((size_t)(943722 / 0.6)), ms_capacity(set)); - ms_free(set, NULL); + ms_free(set); }); CMC_CREATE_TEST(new[capacity = 0], { - struct multiset *set = ms_new(0, 0.6, cmp, hash); + struct multiset *set = ms_new(0, 0.6, ms_ftab_val); cmc_assert_equals(ptr, NULL, set); }); CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct multiset *set = ms_new(UINT64_MAX, 0.99, cmp, hash); + struct multiset *set = ms_new(UINT64_MAX, 0.99, ms_ftab_val); cmc_assert_equals(ptr, NULL, set); }); CMC_CREATE_TEST(clear[count capacity], { - struct multiset *set = ms_new(100, 0.6, cmp, hash); + struct multiset *set = ms_new(100, 0.6, ms_ftab_val); cmc_assert_not_equals(ptr, NULL, set); @@ -42,15 +50,15 @@ CMC_CREATE_UNIT(multiset_test, true, { cmc_assert_equals(size_t, 50, ms_count(set)); - ms_clear(set, NULL); + ms_clear(set); cmc_assert_equals(size_t, 0, ms_count(set)); - ms_free(set, NULL); + ms_free(set); }); CMC_CREATE_TEST(insert[count cardinality multiplicity], { - struct multiset *set = ms_new(100, 0.6, cmp, hash); + struct multiset *set = ms_new(100, 0.6, ms_ftab_val); cmc_assert_not_equals(ptr, NULL, set); @@ -67,11 +75,11 @@ CMC_CREATE_UNIT(multiset_test, true, { for (size_t i = 0; i <= 3; i++) cmc_assert_equals(size_t, i, ms_multiplicity_of(set, i)); - ms_free(set, NULL); + ms_free(set); }); CMC_CREATE_TEST(remove[count cardinality multiplicity], { - struct multiset *set = ms_new(100, 0.6, cmp, hash); + struct multiset *set = ms_new(100, 0.6, ms_ftab_val); cmc_assert_not_equals(ptr, NULL, set); @@ -100,11 +108,11 @@ CMC_CREATE_UNIT(multiset_test, true, { cmc_assert_equals(size_t, 1, ms_multiplicity_of(set, 2)); cmc_assert_equals(size_t, 2, ms_multiplicity_of(set, 3)); - ms_free(set, NULL); + ms_free(set); }); CMC_CREATE_TEST(remove_all[count cardinality multiplicity], { - struct multiset *set = ms_new(100, 0.6, cmp, hash); + struct multiset *set = ms_new(100, 0.6, ms_ftab_val); cmc_assert_not_equals(ptr, NULL, set); @@ -132,11 +140,11 @@ CMC_CREATE_UNIT(multiset_test, true, { cmc_assert_equals(size_t, 2, ms_multiplicity_of(set, 2)); cmc_assert_equals(size_t, 0, ms_multiplicity_of(set, 3)); - ms_free(set, NULL); + ms_free(set); }); CMC_CREATE_TEST(multiplicity, { - struct multiset *set = ms_new(50, 0.6, cmp, hash); + struct multiset *set = ms_new(50, 0.6, ms_ftab_val); cmc_assert_not_equals(ptr, NULL, set); @@ -149,6 +157,6 @@ CMC_CREATE_UNIT(multiset_test, true, { for (size_t i = 0; i < 20; i++) cmc_assert_equals(size_t, 50, ms_multiplicity_of(set, i)); - ms_free(set, NULL); + ms_free(set); }); });