Fast forward changes

This commit is contained in:
Leonardo committed 2020-01-29 23:58:56 -03:00
1 parent cbf24ab217
commit b2bef4e3cc
25 files changed
+650 -257

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
# This file is useful to format all the source files and header in this library using clang-format
.PHONY
main:
clang-format --style=file -i ./src/cmc/*.h
+3 -2
View File
@@ -8,12 +8,13 @@ TODO
[/] Tests [/] Tests
[/] Documentation [/] Documentation
[/] Add Function Tables that contains data type functions
(compare, copy, display, free, hash, priority)
[/] Add error codes that can be accessed from the collection's struct
#!! Medium Priority -------------------------------------------------------------------------------- #!! Medium Priority --------------------------------------------------------------------------------
[/] Callback utility [/] Callback utility
[ ] Add interface that contains data type functions
(compare, copy, display, free, hash, priority)
[ ] Add to iterators struct [ ] Add to iterators struct
[ ] get_value [ ] get_value
[ ] get_index [ ] get_index
+259 -92
View File
@@ -56,16 +56,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
@@ -136,10 +151,9 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> "
"capacity:%" PRIuMAX ", " "capacity:%" PRIuMAX ", "
"count:%" PRIuMAX ", " "count:%" PRIuMAX ", "
"load:%lf, " "load:%lf, "
"key_cmp:%p, " "flag:%d, "
"val_cmp:%p, " "f_key:%p, "
"key_hash:%p, " "f_val:%p, "
"val_hash:%p, "
"alloc:%p, " "alloc:%p, "
"callbacks:%p }"; "callbacks:%p }";
@@ -191,29 +205,27 @@ struct cmc_callbacks_bidimap
/* Load factor in range (0.0, 1.0) */ \ /* Load factor in range (0.0, 1.0) */ \
double load; \ double load; \
\ \
/* Key comparison function */ \ /* Flags indicating errors or success */ \
int (*key_cmp)(K, K); \ int flag; \
\ \
/* Value comparison function */ \ /* Key function table */ \
int (*val_cmp)(V, V); \ struct SNAME##_ftab_key *f_key; \
\ \
/* Key hash function */ \ /* Value function table */ \
size_t (*key_hash)(K); \ struct SNAME##_ftab_val *f_val; \
\
/* Value hash function */ \
size_t (*val_hash)(V); \
\
/* Function that returns an iterator to the start of the bidimap */ \
struct SNAME##_iter (*it_start)(struct SNAME *); \
\
/* Function that returns an iterator to the end of the bidimap */ \
struct SNAME##_iter (*it_end)(struct SNAME *); \
\ \
/* Custom allocation functions */ \ /* Custom allocation functions */ \
struct cmc_alloc_node *alloc; \ struct cmc_alloc_node *alloc; \
\ \
/* Custom callback functions */ \ /* Custom callback functions */ \
struct cmc_callbacks_bidimap *callbacks; \ struct cmc_callbacks_bidimap *callbacks; \
\
/* Methods */ \
/* Function that returns an iterator to the start of the bidimap */ \
struct SNAME##_iter (*it_start)(struct SNAME *); \
\
/* Function that returns an iterator to the end of the bidimap */ \
struct SNAME##_iter (*it_end)(struct SNAME *); \
}; \ }; \
\ \
/* BidiMap Entry */ \ /* BidiMap Entry */ \
@@ -234,6 +246,50 @@ struct cmc_callbacks_bidimap
size_t val_dist; \ size_t val_dist; \
}; \ }; \
\ \
/* 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 */ \
K (*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); \
}; \
\
/* BidiMap Iterator */ \ /* BidiMap Iterator */ \
struct SNAME##_iter \ struct SNAME##_iter \
{ \ { \
@@ -262,15 +318,14 @@ struct cmc_callbacks_bidimap
/* Collection Functions */ \ /* Collection Functions */ \
/* Collection Allocation and Deallocation */ \ /* Collection Allocation and Deallocation */ \
struct SNAME *PFX##_new(size_t capacity, double load, \ struct SNAME *PFX##_new(size_t capacity, double load, \
int (*key_cmp)(K, K), size_t (*key_hash)(K), \ struct SNAME##_ftab_key *f_key, \
int (*val_cmp)(V, V), size_t (*val_hash)(V)); \ struct SNAME##_ftab_val *f_val); \
struct SNAME *PFX##_new_custom( \ struct SNAME *PFX##_new_custom( \
size_t capacity, double load, int (*key_cmp)(K, K), \ size_t capacity, double load, struct SNAME##_ftab_key *f_key, \
size_t (*key_hash)(K), int (*val_cmp)(V, V), size_t (*val_hash)(V), \ struct SNAME##_ftab_val *f_val, struct cmc_alloc_node *alloc, \
struct cmc_alloc_node *alloc, \
struct cmc_callbacks_bidimap *callbacks); \ struct cmc_callbacks_bidimap *callbacks); \
void PFX##_clear(struct SNAME *_map_, void (*deallocator)(K, V)); \ void PFX##_clear(struct SNAME *_map_); \
void PFX##_free(struct SNAME *_map_, void (*deallocator)(K, V)); \ void PFX##_free(struct SNAME *_map_); \
/* Customization of Allocation and Callbacks */ \ /* Customization of Allocation and Callbacks */ \
void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
struct cmc_callbacks_bidimap *callbacks); \ struct cmc_callbacks_bidimap *callbacks); \
@@ -297,10 +352,10 @@ struct cmc_callbacks_bidimap
double PFX##_load(struct SNAME *_map_); \ double PFX##_load(struct SNAME *_map_); \
/* Collection Utility */ \ /* Collection Utility */ \
bool PFX##_resize(struct SNAME *_map_, size_t capacity); \ bool PFX##_resize(struct SNAME *_map_, size_t capacity); \
struct SNAME *PFX##_copy_of(struct SNAME *_map_, K (*key_copy_func)(K), \ struct SNAME *PFX##_copy_of(struct SNAME *_map_); \
V (*value_copy_func)(V)); \
bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \ bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \
struct cmc_string PFX##_to_string(struct SNAME *_map_); \ struct cmc_string PFX##_to_string(struct SNAME *_map_); \
bool PFX##_print(struct SNAME *_map_, FILE *fptr); \
\ \
/* Iterator Functions */ \ /* Iterator Functions */ \
/* Iterator Allocation and Deallocation */ \ /* Iterator Allocation and Deallocation */ \
@@ -345,8 +400,8 @@ struct cmc_callbacks_bidimap
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_); \ static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_); \
\ \
struct SNAME *PFX##_new(size_t capacity, double load, \ struct SNAME *PFX##_new(size_t capacity, double load, \
int (*key_cmp)(K, K), size_t (*key_hash)(K), \ struct SNAME##_ftab_key *f_key, \
int (*val_cmp)(V, V), size_t (*val_hash)(V)) \ struct SNAME##_ftab_val *f_val) \
{ \ { \
struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
\ \
@@ -380,24 +435,21 @@ struct cmc_callbacks_bidimap
_map_->count = 0; \ _map_->count = 0; \
_map_->capacity = real_capacity; \ _map_->capacity = real_capacity; \
_map_->load = load; \ _map_->load = load; \
_map_->key_cmp = key_cmp; \ _map_->flag = cmc_flags.OK; \
_map_->val_cmp = val_cmp; \ _map_->f_key = f_key; \
_map_->key_hash = key_hash; \ _map_->f_val = f_val; \
_map_->val_hash = val_hash; \
\
_map_->it_start = PFX##_impl_it_start; \
_map_->it_end = PFX##_impl_it_end; \
\
_map_->alloc = alloc; \ _map_->alloc = alloc; \
_map_->callbacks = NULL; \ _map_->callbacks = NULL; \
_map_->it_start = PFX##_impl_it_start; \
_map_->it_end = PFX##_impl_it_end; \
\ \
return _map_; \ return _map_; \
} \ } \
\ \
struct SNAME *PFX##_new_custom( \ struct SNAME *PFX##_new_custom( \
size_t capacity, double load, int (*key_cmp)(K, K), \ size_t capacity, double load, struct SNAME##_ftab_key *f_key, \
size_t (*key_hash)(K), int (*val_cmp)(V, V), size_t (*val_hash)(V), \ struct SNAME##_ftab_val *f_val, struct cmc_alloc_node *alloc, \
struct cmc_alloc_node *alloc, struct cmc_callbacks_bidimap *callbacks) \ struct cmc_callbacks_bidimap *callbacks) \
{ \ { \
if (capacity == 0 || load <= 0 || load >= 1) \ if (capacity == 0 || load <= 0 || load >= 1) \
return NULL; \ return NULL; \
@@ -432,21 +484,18 @@ struct cmc_callbacks_bidimap
_map_->count = 0; \ _map_->count = 0; \
_map_->capacity = real_capacity; \ _map_->capacity = real_capacity; \
_map_->load = load; \ _map_->load = load; \
_map_->key_cmp = key_cmp; \ _map_->f_key = f_key; \
_map_->val_cmp = val_cmp; \ _map_->f_val = f_val; \
_map_->key_hash = key_hash; \ _map_->flag = cmc_flags.OK; \
_map_->val_hash = val_hash; \
\
_map_->it_start = PFX##_impl_it_start; \
_map_->it_end = PFX##_impl_it_end; \
\
_map_->alloc = alloc; \ _map_->alloc = alloc; \
_map_->callbacks = callbacks; \ _map_->callbacks = callbacks; \
_map_->it_start = PFX##_impl_it_start; \
_map_->it_end = PFX##_impl_it_end; \
\ \
return _map_; \ return _map_; \
} \ } \
\ \
void PFX##_clear(struct SNAME *_map_, void (*deallocator)(K, V)) \ void PFX##_clear(struct SNAME *_map_) \
{ \ { \
for (size_t i = 0; i < _map_->capacity; i++) \ for (size_t i = 0; i < _map_->capacity; i++) \
{ \ { \
@@ -454,8 +503,10 @@ struct cmc_callbacks_bidimap
\ \
if (entry && entry != CMC_ENTRY_DELETED) \ if (entry && entry != CMC_ENTRY_DELETED) \
{ \ { \
if (deallocator) \ if (_map_->f_key->free) \
deallocator(entry->key, entry->value); \ _map_->f_key->free(entry->key); \
if (_map_->f_val->free) \
_map_->f_val->free(entry->value); \
\ \
_map_->alloc->free(entry); \ _map_->alloc->free(entry); \
} \ } \
@@ -465,11 +516,12 @@ struct cmc_callbacks_bidimap
} \ } \
\ \
_map_->count = 0; \ _map_->count = 0; \
_map_->flag = cmc_flags.OK; \
} \ } \
\ \
void PFX##_free(struct SNAME *_map_, void (*deallocator)(K, V)) \ void PFX##_free(struct SNAME *_map_) \
{ \ { \
PFX##_clear(_map_, deallocator); \ PFX##_clear(_map_); \
\ \
_map_->alloc->free(_map_->key_buffer); \ _map_->alloc->free(_map_->key_buffer); \
_map_->alloc->free(_map_->val_buffer); \ _map_->alloc->free(_map_->val_buffer); \
@@ -484,6 +536,8 @@ struct cmc_callbacks_bidimap
\ \
if (callbacks) \ if (callbacks) \
_map_->callbacks = callbacks; \ _map_->callbacks = callbacks; \
\
_map_->flag = cmc_flags.OK; \
} \ } \
\ \
bool PFX##_insert(struct SNAME *_map_, K key, V value) \ bool PFX##_insert(struct SNAME *_map_, K key, V value) \
@@ -496,7 +550,11 @@ struct cmc_callbacks_bidimap
\ \
if (PFX##_impl_get_entry_by_key(_map_, key) != NULL || \ if (PFX##_impl_get_entry_by_key(_map_, key) != NULL || \
PFX##_impl_get_entry_by_val(_map_, value) != NULL) \ PFX##_impl_get_entry_by_val(_map_, value) != NULL) \
{ \
_map_->flag = cmc_flags.DUPLICATE; \
\
return false; \ return false; \
} \
\ \
struct SNAME##_entry *entry = PFX##_impl_new_entry(_map_, key, value); \ struct SNAME##_entry *entry = PFX##_impl_new_entry(_map_, key, value); \
\ \
@@ -514,10 +572,13 @@ struct cmc_callbacks_bidimap
\ \
_map_->alloc->free(entry); \ _map_->alloc->free(entry); \
\ \
_map_->flag = cmc_flags.ERROR; \
\
return false; \ return false; \
} \ } \
\ \
_map_->count++; \ _map_->count++; \
_map_->flag = cmc_flags.OK; \
\ \
return true; \ return true; \
} \ } \
@@ -525,16 +586,25 @@ struct cmc_callbacks_bidimap
bool PFX##_update_key(struct SNAME *_map_, K key, K new_key) \ bool PFX##_update_key(struct SNAME *_map_, K key, K new_key) \
{ \ { \
if (PFX##_empty(_map_)) \ if (PFX##_empty(_map_)) \
{ \
_map_->flag = cmc_flags.EMPTY; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry **entry = \ struct SNAME##_entry **entry = \
PFX##_impl_get_entry_by_key(_map_, key); \ PFX##_impl_get_entry_by_key(_map_, key); \
\ \
if (!entry) \ if (!entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return false; \ return false; \
} \
\ \
if (PFX##_contains_key(_map_, new_key)) \ if (PFX##_impl_get_entry_by_key(_map_, new_key) != NULL) \
{ \
_map_->flag = cmc_flags.DUPLICATE; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry *to_add = *entry; \ struct SNAME##_entry *to_add = *entry; \
K tmp_key = to_add->key; \ K tmp_key = to_add->key; \
@@ -547,25 +617,37 @@ struct cmc_callbacks_bidimap
to_add->key = tmp_key; \ to_add->key = tmp_key; \
*entry = to_add; \ *entry = to_add; \
\ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \ } \
\ \
_map_->flag = cmc_flags.OK; \
\
return true; \ return true; \
} \ } \
\ \
bool PFX##_update_key_by_val(struct SNAME *_map_, V val, K new_key) \ bool PFX##_update_key_by_val(struct SNAME *_map_, V val, K new_key) \
{ \ { \
if (PFX##_empty(_map_)) \ if (PFX##_empty(_map_)) \
{ \
_map_->flag = cmc_flags.EMPTY; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry **entry = \ struct SNAME##_entry **entry = \
PFX##_impl_get_entry_by_val(_map_, val); \ PFX##_impl_get_entry_by_val(_map_, val); \
\ \
if (!entry) \ if (!entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return false; \ return false; \
} \
\ \
if (PFX##_contains_key(_map_, new_key)) \ if (PFX##_impl_get_entry_by_key(_map_, new_key) != NULL) \
{ \
_map_->flag = cmc_flags.DUPLICATE; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry *to_add = *entry; \ struct SNAME##_entry *to_add = *entry; \
K tmp_key = to_add->key; \ K tmp_key = to_add->key; \
@@ -578,25 +660,37 @@ struct cmc_callbacks_bidimap
to_add->key = tmp_key; \ to_add->key = tmp_key; \
*entry = to_add; \ *entry = to_add; \
\ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \ } \
\ \
_map_->flag = cmc_flags.OK; \
\
return true; \ return true; \
} \ } \
\ \
bool PFX##_update_val(struct SNAME *_map_, V val, V new_val) \ bool PFX##_update_val(struct SNAME *_map_, V val, V new_val) \
{ \ { \
if (PFX##_empty(_map_)) \ if (PFX##_empty(_map_)) \
{ \
_map_->flag = cmc_flags.EMPTY; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry **entry = \ struct SNAME##_entry **entry = \
PFX##_impl_get_entry_by_val(_map_, val); \ PFX##_impl_get_entry_by_val(_map_, val); \
\ \
if (!entry) \ if (!entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return false; \ return false; \
} \
\ \
if (PFX##_contains_val(_map_, new_val)) \ if (PFX##_impl_get_entry_by_val(_map_, new_val) != NULL) \
{ \
_map_->flag = cmc_flags.DUPLICATE; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry *to_add = *entry; \ struct SNAME##_entry *to_add = *entry; \
V tmp_val = to_add->value; \ V tmp_val = to_add->value; \
@@ -609,25 +703,37 @@ struct cmc_callbacks_bidimap
to_add->value = tmp_val; \ to_add->value = tmp_val; \
*entry = to_add; \ *entry = to_add; \
\ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \ } \
\ \
_map_->flag = cmc_flags.OK; \
\
return true; \ return true; \
} \ } \
\ \
bool PFX##_update_val_by_key(struct SNAME *_map_, K key, V new_val) \ bool PFX##_update_val_by_key(struct SNAME *_map_, K key, V new_val) \
{ \ { \
if (PFX##_empty(_map_)) \ if (PFX##_empty(_map_)) \
{ \
_map_->flag = cmc_flags.EMPTY; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry **entry = \ struct SNAME##_entry **entry = \
PFX##_impl_get_entry_by_key(_map_, key); \ PFX##_impl_get_entry_by_key(_map_, key); \
\ \
if (!entry) \ if (!entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return false; \ return false; \
} \
\ \
if (PFX##_contains_val(_map_, new_val)) \ if (PFX##_impl_get_entry_by_val(_map_, new_val) != NULL) \
{ \
_map_->flag = cmc_flags.DUPLICATE; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry *to_add = *entry; \ struct SNAME##_entry *to_add = *entry; \
V tmp_val = to_add->value; \ V tmp_val = to_add->value; \
@@ -640,9 +746,12 @@ struct cmc_callbacks_bidimap
to_add->value = tmp_val; \ to_add->value = tmp_val; \
*entry = to_add; \ *entry = to_add; \
\ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \ } \
\ \
_map_->flag = cmc_flags.OK; \
\
return true; \ return true; \
} \ } \
\ \
@@ -650,22 +759,34 @@ struct cmc_callbacks_bidimap
V *out_val) \ V *out_val) \
{ \ { \
if (PFX##_empty(_map_)) \ if (PFX##_empty(_map_)) \
{ \
_map_->flag = cmc_flags.EMPTY; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry **key_entry, **val_entry; \ struct SNAME##_entry **key_entry, **val_entry; \
\ \
key_entry = PFX##_impl_get_entry_by_key(_map_, key); \ key_entry = PFX##_impl_get_entry_by_key(_map_, key); \
\ \
if (!key_entry) \ if (!key_entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return false; \ return false; \
} \
\ \
val_entry = PFX##_impl_get_entry_by_val(_map_, (*key_entry)->value); \ val_entry = PFX##_impl_get_entry_by_val(_map_, (*key_entry)->value); \
\ \
if (!val_entry) \ if (!val_entry) \
{ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \
\ \
if (*val_entry != *key_entry) \ if (*val_entry != *key_entry) \
{ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \
\ \
if (out_key) \ if (out_key) \
*out_key = (*key_entry)->key; \ *out_key = (*key_entry)->key; \
@@ -678,6 +799,7 @@ struct cmc_callbacks_bidimap
*val_entry = CMC_ENTRY_DELETED; \ *val_entry = CMC_ENTRY_DELETED; \
\ \
_map_->count--; \ _map_->count--; \
_map_->flag = cmc_flags.OK; \
\ \
return true; \ return true; \
} \ } \
@@ -686,22 +808,34 @@ struct cmc_callbacks_bidimap
V *out_val) \ V *out_val) \
{ \ { \
if (PFX##_empty(_map_)) \ if (PFX##_empty(_map_)) \
{ \
_map_->flag = cmc_flags.EMPTY; \
return false; \ return false; \
} \
\ \
struct SNAME##_entry **key_entry, **val_entry; \ struct SNAME##_entry **key_entry, **val_entry; \
\ \
val_entry = PFX##_impl_get_entry_by_val(_map_, val); \ val_entry = PFX##_impl_get_entry_by_val(_map_, val); \
\ \
if (!val_entry) \ if (!val_entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return false; \ return false; \
} \
\ \
key_entry = PFX##_impl_get_entry_by_key(_map_, (*val_entry)->key); \ key_entry = PFX##_impl_get_entry_by_key(_map_, (*val_entry)->key); \
\ \
if (!key_entry) \ if (!key_entry) \
{ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \
\ \
if (*val_entry != *key_entry) \ if (*val_entry != *key_entry) \
{ \
_map_->flag = cmc_flags.ERROR; \
return false; \ return false; \
} \
\ \
if (out_key) \ if (out_key) \
*out_key = (*val_entry)->key; \ *out_key = (*val_entry)->key; \
@@ -714,6 +848,7 @@ struct cmc_callbacks_bidimap
*val_entry = CMC_ENTRY_DELETED; \ *val_entry = CMC_ENTRY_DELETED; \
\ \
_map_->count--; \ _map_->count--; \
_map_->flag = cmc_flags.OK; \
\ \
return true; \ return true; \
} \ } \
@@ -724,7 +859,10 @@ struct cmc_callbacks_bidimap
PFX##_impl_get_entry_by_val(_map_, val); \ PFX##_impl_get_entry_by_val(_map_, val); \
\ \
if (!entry) \ if (!entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return (V){ 0 }; \ return (V){ 0 }; \
} \
\ \
return (*entry)->key; \ return (*entry)->key; \
} \ } \
@@ -735,7 +873,10 @@ struct cmc_callbacks_bidimap
PFX##_impl_get_entry_by_key(_map_, key); \ PFX##_impl_get_entry_by_key(_map_, key); \
\ \
if (!entry) \ if (!entry) \
{ \
_map_->flag = cmc_flags.NOT_FOUND; \
return (V){ 0 }; \ return (V){ 0 }; \
} \
\ \
return (*entry)->value; \ return (*entry)->value; \
} \ } \
@@ -786,21 +927,33 @@ struct cmc_callbacks_bidimap
\ \
/* Prevent integer overflow */ \ /* Prevent integer overflow */ \
if (capacity >= UINTMAX_MAX * PFX##_load(_map_)) \ if (capacity >= UINTMAX_MAX * PFX##_load(_map_)) \
{ \
_map_->flag = cmc_flags.ERROR; \
\
return false; \ return false; \
} \
\ \
/* Calculate required capacity based on the prime numbers */ \ /* Calculate required capacity based on the prime numbers */ \
size_t new_cap = PFX##_impl_calculate_size(capacity); \ size_t new_cap = PFX##_impl_calculate_size(capacity); \
\ \
/* Not possible to shrink with current available prime numbers */ \ /* Not possible to shrink with current available prime numbers */ \
if (new_cap < PFX##_count(_map_) / PFX##_load(_map_)) \ if (new_cap < PFX##_count(_map_) / PFX##_load(_map_)) \
return false; \ { \
_map_->flag = cmc_flags.ERROR; \
\ \
struct SNAME *_new_map_ = PFX##_new_custom( \ return false; \
capacity, PFX##_load(_map_), _map_->key_cmp, _map_->key_hash, \ } \
_map_->val_cmp, _map_->val_hash, _map_->alloc, _map_->callbacks); \ \
struct SNAME *_new_map_ = \
PFX##_new_custom(capacity, PFX##_load(_map_), _map_->f_key, \
_map_->f_val, _map_->alloc, _map_->callbacks); \
\ \
if (!_new_map_) \ if (!_new_map_) \
{ \
_map_->flag = cmc_flags.ALLOC; \
\
return false; \ return false; \
} \
\ \
for (size_t i = 0; i < _map_->capacity; i++) \ for (size_t i = 0; i < _map_->capacity; i++) \
{ \ { \
@@ -819,6 +972,8 @@ struct cmc_callbacks_bidimap
_map_->alloc->free(_new_map_->val_buffer); \ _map_->alloc->free(_new_map_->val_buffer); \
_map_->alloc->free(_new_map_); \ _map_->alloc->free(_new_map_); \
\ \
_map_->flag = cmc_flags.ERROR; \
\
return false; \ return false; \
} \ } \
\ \
@@ -832,6 +987,8 @@ struct cmc_callbacks_bidimap
_map_->alloc->free(_new_map_->val_buffer); \ _map_->alloc->free(_new_map_->val_buffer); \
_map_->alloc->free(_new_map_); \ _map_->alloc->free(_new_map_); \
\ \
_map_->flag = cmc_flags.ERROR; \
\
return false; \ return false; \
} \ } \
\ \
@@ -849,14 +1006,12 @@ struct cmc_callbacks_bidimap
return true; \ return true; \
} \ } \
\ \
struct SNAME *PFX##_copy_of(struct SNAME *_map_, K (*key_copy_func)(K), \ struct SNAME *PFX##_copy_of(struct SNAME *_map_) \
V (*value_copy_func)(V)) \
{ \ { \
/* TODO this function can be optimized */ \ /* TODO this function can be optimized */ \
struct SNAME *result = \ struct SNAME *result = PFX##_new_custom( \
PFX##_new_custom(PFX##_capacity(_map_), PFX##_load(_map_), \ PFX##_capacity(_map_), PFX##_load(_map_), _map_->f_key, \
_map_->key_cmp, _map_->key_hash, _map_->val_cmp, \ _map_->f_val, _map_->alloc, _map_->callbacks); \
_map_->val_hash, _map_->alloc, _map_->callbacks); \
\ \
for (size_t i = 0; i < _map_->capacity; i++) \ for (size_t i = 0; i < _map_->capacity; i++) \
{ \ { \
@@ -867,16 +1022,17 @@ struct cmc_callbacks_bidimap
K tmp_key; \ K tmp_key; \
V tmp_val; \ V tmp_val; \
\ \
if (key_copy_func) \ if (_map_->f_key->cpy) \
tmp_key = key_copy_func(scan->key); \ tmp_key = _map_->f_key->cpy(scan->key); \
else \ else \
tmp_key = scan->key; \ tmp_key = scan->key; \
\ \
if (value_copy_func) \ if (_map_->f_val->cpy) \
tmp_val = value_copy_func(scan->value); \ tmp_val = _map_->f_val->cpy(scan->value); \
else \ else \
tmp_val = scan->value; \ tmp_val = scan->value; \
\ \
/* TODO should this be checked for failures? */ \
PFX##_insert(result, tmp_key, tmp_val); \ PFX##_insert(result, tmp_key, tmp_val); \
} \ } \
} \ } \
@@ -915,7 +1071,7 @@ struct cmc_callbacks_bidimap
if (!entry_B) \ if (!entry_B) \
return false; \ return false; \
\ \
if (_mapA_->val_cmp((*entry_B)->value, scan->value) != 0) \ if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) \
return false; \ return false; \
} \ } \
} \ } \
@@ -928,18 +1084,29 @@ struct cmc_callbacks_bidimap
struct cmc_string str; \ struct cmc_string str; \
struct SNAME *m_ = _map_; \ struct SNAME *m_ = _map_; \
\ \
int n = \ int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_bidimap, \
snprintf(str.s, cmc_string_len, cmc_string_fmt_bidimap, #SNAME, \ #SNAME, #K, #V, m_, m_->key_buffer, m_->val_buffer, \
#K, #V, m_, m_->key_buffer, m_->val_buffer, m_->capacity, \ m_->capacity, m_->count, m_->load, m_->f_key, \
m_->count, m_->load, m_->key_cmp, m_->val_cmp, \ m_->f_val, m_->alloc, m_->callbacks); \
m_->key_hash, m_->val_hash, m_->alloc, m_->callbacks); \
\ \
if (n < 0 || n == (int)cmc_string_len) \ return n >= 0 ? str : (struct cmc_string){ 0 }; \
return (struct cmc_string){ 0 }; \ } \
\ \
str.s[n] = '\0'; \ bool PFX##_print(struct SNAME *_map_, FILE *fptr) \
{ \
for (size_t i = 0; i < _map_->capacity; i++) \
{ \
struct SNAME##_entry *target = _map_->key_buffer[i]; \
\ \
return str; \ if (target && target != CMC_ENTRY_DELETED) \
{ \
if (!_map_->f_key->str(fptr, target->key) || \
!_map_->f_val->str(fptr, target->value)) \
return false; \
} \
} \
\
return true; \
} \ } \
\ \
struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
@@ -1184,7 +1351,7 @@ struct cmc_callbacks_bidimap
static struct SNAME##_entry **PFX##_impl_get_entry_by_key( \ static struct SNAME##_entry **PFX##_impl_get_entry_by_key( \
struct SNAME *_map_, K key) \ struct SNAME *_map_, K key) \
{ \ { \
size_t hash = _map_->key_hash(key); \ size_t hash = _map_->f_key->hash(key); \
size_t pos = hash % _map_->capacity; \ size_t pos = hash % _map_->capacity; \
\ \
struct SNAME##_entry *target = _map_->key_buffer[pos]; \ struct SNAME##_entry *target = _map_->key_buffer[pos]; \
@@ -1192,7 +1359,7 @@ struct cmc_callbacks_bidimap
while (target != NULL) \ while (target != NULL) \
{ \ { \
if (target != CMC_ENTRY_DELETED && \ if (target != CMC_ENTRY_DELETED && \
_map_->key_cmp(target->key, key) == 0) \ _map_->f_key->cmp(target->key, key) == 0) \
return &(_map_->key_buffer[pos % _map_->capacity]); \ return &(_map_->key_buffer[pos % _map_->capacity]); \
\ \
pos++; \ pos++; \
@@ -1205,7 +1372,7 @@ struct cmc_callbacks_bidimap
static struct SNAME##_entry **PFX##_impl_get_entry_by_val( \ static struct SNAME##_entry **PFX##_impl_get_entry_by_val( \
struct SNAME *_map_, V val) \ struct SNAME *_map_, V val) \
{ \ { \
size_t hash = _map_->val_hash(val); \ size_t hash = _map_->f_val->hash(val); \
size_t pos = hash % _map_->capacity; \ size_t pos = hash % _map_->capacity; \
\ \
struct SNAME##_entry *target = _map_->val_buffer[pos]; \ struct SNAME##_entry *target = _map_->val_buffer[pos]; \
@@ -1213,7 +1380,7 @@ struct cmc_callbacks_bidimap
while (target != NULL) \ while (target != NULL) \
{ \ { \
if (target != CMC_ENTRY_DELETED && \ if (target != CMC_ENTRY_DELETED && \
_map_->val_cmp(target->value, val) == 0) \ _map_->f_val->cmp(target->value, val) == 0) \
return &(_map_->val_buffer[pos % _map_->capacity]); \ return &(_map_->val_buffer[pos % _map_->capacity]); \
\ \
pos++; \ pos++; \
@@ -1228,7 +1395,7 @@ struct cmc_callbacks_bidimap
{ \ { \
struct SNAME##_entry **to_return = NULL; \ struct SNAME##_entry **to_return = NULL; \
\ \
size_t hash = _map_->key_hash(entry->key); \ size_t hash = _map_->f_key->hash(entry->key); \
size_t original_pos = hash % _map_->capacity; \ size_t original_pos = hash % _map_->capacity; \
size_t pos = original_pos; \ size_t pos = original_pos; \
\ \
@@ -1282,7 +1449,7 @@ struct cmc_callbacks_bidimap
{ \ { \
struct SNAME##_entry **to_return = NULL; \ struct SNAME##_entry **to_return = NULL; \
\ \
size_t hash = _map_->val_hash(entry->value); \ size_t hash = _map_->f_val->hash(entry->value); \
size_t original_pos = hash % _map_->capacity; \ size_t original_pos = hash % _map_->capacity; \
size_t pos = original_pos; \ size_t pos = original_pos; \
\ \
+19 -4
View File
@@ -61,16 +61,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -49,16 +49,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -49,16 +49,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -60,16 +60,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -51,16 +51,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -58,16 +58,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+21 -24
View File
@@ -73,16 +73,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
@@ -175,7 +190,6 @@ struct cmc_callbacks_list
struct SNAME *PFX##_new_custom(size_t capacity, \ struct SNAME *PFX##_new_custom(size_t capacity, \
struct cmc_alloc_node *alloc, \ struct cmc_alloc_node *alloc, \
struct cmc_callbacks_list *callbacks); \ struct cmc_callbacks_list *callbacks); \
struct SNAME *PFX##_new_from(V *elements, size_t size); \
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \ void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)); \
void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \ void PFX##_free(struct SNAME *_list_, void (*deallocator)(V)); \
/* Customization of Allocation and Callbacks */ \ /* Customization of Allocation and Callbacks */ \
@@ -316,23 +330,6 @@ struct cmc_callbacks_list
return _list_; \ return _list_; \
} \ } \
\ \
struct SNAME *PFX##_new_from(V *elements, size_t size) \
{ \
if (size == 0) \
return NULL; \
\
struct SNAME *_list_ = PFX##_new(size + size / 2); \
\
if (!_list_) \
return NULL; \
\
memcpy(_list_->buffer, elements, size * sizeof(V)); \
\
_list_->count = size; \
\
return _list_; \
} \
\
void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)) \ void PFX##_clear(struct SNAME *_list_, void (*deallocator)(V)) \
{ \ { \
if (deallocator) \ if (deallocator) \
@@ -428,7 +425,7 @@ struct cmc_callbacks_list
return false; \ return false; \
\ \
memmove(_list_->buffer, _list_->buffer + 1, \ memmove(_list_->buffer, _list_->buffer + 1, \
_list_->count * sizeof(V)); \ (_list_->count - 1) * sizeof(V)); \
\ \
_list_->buffer[--_list_->count] = (V){ 0 }; \ _list_->buffer[--_list_->count] = (V){ 0 }; \
\ \
@@ -441,7 +438,7 @@ struct cmc_callbacks_list
return false; \ return false; \
\ \
memmove(_list_->buffer + index, _list_->buffer + index + 1, \ memmove(_list_->buffer + index, _list_->buffer + index + 1, \
(_list_->count - index) * sizeof(V)); \ (_list_->count - index - 1) * sizeof(V)); \
\ \
_list_->buffer[--_list_->count] = (V){ 0 }; \ _list_->buffer[--_list_->count] = (V){ 0 }; \
\ \
+19 -4
View File
@@ -73,16 +73,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+24 -9
View File
@@ -51,16 +51,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
@@ -829,7 +844,7 @@ struct cmc_callbacks_multiset
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \
_set1_->hash, _set1_->alloc, _set1_->callbacks); \ _set1_->hash, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
@@ -870,7 +885,7 @@ struct cmc_callbacks_multiset
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \
_set1_->hash, _set1_->alloc, _set1_->callbacks); \ _set1_->hash, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
@@ -901,7 +916,7 @@ struct cmc_callbacks_multiset
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \
_set1_->hash, _set1_->alloc, _set1_->callbacks); \ _set1_->hash, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
@@ -928,7 +943,7 @@ struct cmc_callbacks_multiset
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \
_set1_->hash, _set1_->alloc, _set1_->callbacks); \ _set1_->hash, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
@@ -961,7 +976,7 @@ struct cmc_callbacks_multiset
\ \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \ PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->cmp, \
_set1_->hash, _set1_->alloc, _set1_->callbacks); \ _set1_->hash, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
+19 -4
View File
@@ -73,16 +73,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -52,16 +52,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -58,16 +58,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+19 -4
View File
@@ -49,16 +49,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
+23 -8
View File
@@ -49,16 +49,31 @@ static const size_t cmc_string_len = 400;
* Custom allocation node. Allows collections to use custom allocation * Custom allocation node. Allows collections to use custom allocation
* functions. * functions.
*/ */
struct cmc_alloc_node static struct cmc_alloc_node
{ {
void *(*malloc)(size_t); void *(*malloc)(size_t);
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t); void *(*realloc)(void *, size_t);
void (*free)(void *); void (*free)(void *);
}; } cmc_alloc_node_default = { malloc, calloc, realloc, free };
static struct cmc_alloc_node cmc_alloc_node_default = { malloc, calloc, realloc, /**
free }; * enum cmc_flags
*
* Defines common error codes used by all collections. These are flags that
* indicate if something went wrong in the last operation by the collection.
*/
static struct
{
int OK; // Everything went as expected
int ALLOC; // Allocation failed
int EMPTY; // The collection is empty and the operation could not proceed
int NOT_FOUND; // Key or value not found
int INVALID; // Something is invalid
int OUT_OF_RANGE; // Index out of array range
int DUPLICATE; // Duplicate key or value
int ERROR; // Generic error, usually caused by unexpected behaviour
} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7 };
#endif /* CMC_CORE_H */ #endif /* CMC_CORE_H */
@@ -677,7 +692,7 @@ struct cmc_callbacks_treeset
struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \ struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \ PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
@@ -705,7 +720,7 @@ struct cmc_callbacks_treeset
struct SNAME *_set2_) \ struct SNAME *_set2_) \
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \ PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
@@ -732,7 +747,7 @@ struct cmc_callbacks_treeset
struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \ struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \ PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
@@ -756,7 +771,7 @@ struct cmc_callbacks_treeset
struct SNAME *_set2_) \ struct SNAME *_set2_) \
{ \ { \
struct SNAME *_set_r_ = \ struct SNAME *_set_r_ = \
PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \ PFX##_new_custom(_set1_->cmp, _set1_->alloc, _set1_->callbacks); \
\ \
if (!_set_r_) \ if (!_set_r_) \
return NULL; \ return NULL; \
+2 -5
View File
@@ -1,6 +1,6 @@
CC = gcc CC = gcc
CFLAGS = -std=c11 -Wall -Wextra CFLAGS = -std=c11 -Wall -Wextra
CFLAGS += -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-unused-label CFLAGS += -Wno-unused -Wno-missing-braces
main: FORCE main: FORCE
$(CC) foreach.c -o foreach.exe $(CFLAGS) $(CC) foreach.c -o foreach.exe $(CFLAGS)
@@ -11,10 +11,7 @@ main: FORCE
./contains.exe ./contains.exe
$(CC) types.c -o types.exe $(CFLAGS) $(CC) types.c -o types.exe $(CFLAGS)
./types.exe ./types.exe
$(CC) -c ./sep/collections.c -o ./sep/collections.o $(CFLAGS) make -C ./sep
$(CC) -c ./sep/main.c -o ./sep/main.o $(CFLAGS)
$(CC) ./sep/collections.o ./sep/main.o -o ./sep/sep.exe
./sep/sep.exe
dev: main dev: main
rm *.exe ./sep/*.o ./sep/*.exe rm *.exe ./sep/*.o ./sep/*.exe
+1 -1
View File
@@ -1,6 +1,6 @@
CC = gcc CC = gcc
CFLAGS = -std=c11 -Wall -Wextra CFLAGS = -std=c11 -Wall -Wextra
CFLAGS += -Wno-unused CFLAGS += -Wno-unused -Wno-missing-braces
CFLAGS += -DCMC_TEST_COLOR CFLAGS += -DCMC_TEST_COLOR
INCLUDE = ../../src/ INCLUDE = ../../src/
+60 -39
View File
@@ -7,17 +7,36 @@
CMC_GENERATE_BIDIMAP(bm, bidimap, size_t, size_t) CMC_GENERATE_BIDIMAP(bm, bidimap, size_t, size_t)
struct bidimap_ftab_key *bm_ftab_key = &(struct bidimap_ftab_key) {
.cmp = cmp,
.cpy = copy,
.str = to_string,
.free = custom_free,
.hash = hash,
.pri = priority
};
struct bidimap_ftab_val *bm_ftab_val = &(struct bidimap_ftab_val) {
.cmp = cmp,
.cpy = copy,
.str = to_string,
.free = custom_free,
.hash = hash,
.pri = priority
};
CMC_CREATE_UNIT(bidimap_test, true, { CMC_CREATE_UNIT(bidimap_test, true, {
CMC_CREATE_TEST(new, { CMC_CREATE_TEST(new, {
struct bidimap *map = bm_new(100, 0.6, cmp, hash, cmp, hash); struct bidimap *map = bm_new(100, 0.6, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(new[null buffer], { CMC_CREATE_TEST(new[null buffer], {
struct bidimap *map = bm_new(100, 0.6, cmp, hash, cmp, hash); struct bidimap *map = bm_new(100, 0.6, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
@@ -27,11 +46,11 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(ptr, NULL, map->val_buffer[i]); cmc_assert_equals(ptr, NULL, map->val_buffer[i]);
} }
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(new_custom, { CMC_CREATE_TEST(new_custom, {
struct bidimap *map = bm_new_custom(100, 0.6, cmp, hash, cmp, hash, struct bidimap *map = bm_new_custom(100, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ &(struct cmc_alloc_node){
.malloc = malloc, .malloc = malloc,
.calloc = calloc, .calloc = calloc,
@@ -41,11 +60,11 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(new_custom[insert remove], { CMC_CREATE_TEST(new_custom[insert remove], {
struct bidimap *map = bm_new_custom(500, 0.6, cmp, hash, cmp, hash, struct bidimap *map = bm_new_custom(500, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ &(struct cmc_alloc_node){
.malloc = malloc, .malloc = malloc,
.calloc = calloc, .calloc = calloc,
@@ -74,11 +93,11 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(size_t, 0, bm_count(map)); cmc_assert_equals(size_t, 0, bm_count(map));
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(clear[count], { CMC_CREATE_TEST(clear[count], {
struct bidimap *map = bm_new(100, 0.6, cmp, hash, cmp, hash); struct bidimap *map = bm_new(100, 0.6, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
@@ -87,15 +106,15 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(size_t, 500, bm_count(map)); cmc_assert_equals(size_t, 500, bm_count(map));
bm_clear(map, NULL); bm_clear(map);
cmc_assert_equals(size_t, 0, bm_count(map)); cmc_assert_equals(size_t, 0, bm_count(map));
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(buffer_growth[capacity = 1], { CMC_CREATE_TEST(buffer_growth[capacity = 1], {
struct bidimap *map = bm_new(1, 0.7, cmp, hash, cmp, hash); struct bidimap *map = bm_new(1, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
@@ -114,11 +133,11 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(size_t, 50005000, sum); cmc_assert_equals(size_t, 50005000, sum);
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(insert, { CMC_CREATE_TEST(insert, {
struct bidimap *map = bm_new(100, 0.7, cmp, hash, cmp, hash); struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
@@ -130,11 +149,11 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(size_t, 2, bm_count(map)); cmc_assert_equals(size_t, 2, bm_count(map));
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(insert[growth remove clear], { CMC_CREATE_TEST(insert[growth remove clear], {
struct bidimap *map = bm_new(100, 0.7, cmp, hash, cmp, hash); struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
@@ -159,17 +178,18 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(size_t, 1000, bm_count(map)); cmc_assert_equals(size_t, 1000, bm_count(map));
bm_clear(map, NULL); bm_clear(map);
cmc_assert_equals(size_t, 0, bm_count(map)); cmc_assert_equals(size_t, 0, bm_count(map));
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(update_key, { CMC_CREATE_TEST(update_key, {
struct bidimap *map = bm_new(100, 0.7, cmp, hash, cmp, hash); struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
for (size_t i = 1; i <= 100; i++) for (size_t i = 1; i <= 100; i++)
cmc_assert(bm_insert(map, i, i)); cmc_assert(bm_insert(map, i, i));
@@ -186,11 +206,11 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(size_t, 100, bm_count(map)); cmc_assert_equals(size_t, 100, bm_count(map));
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(update_val, { CMC_CREATE_TEST(update_val, {
struct bidimap *map = bm_new(100, 0.7, cmp, hash, cmp, hash); struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map);
@@ -209,11 +229,11 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert_equals(size_t, 100, bm_count(map)); cmc_assert_equals(size_t, 100, bm_count(map));
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(remove_by_key[cleanup custom], { CMC_CREATE_TEST(remove_by_key[cleanup custom], {
struct bidimap *map = bm_new_custom(10000, 0.6, cmp, hash, cmp, hash, struct bidimap *map = bm_new_custom(10000, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ &(struct cmc_alloc_node){
.malloc = malloc, .malloc = malloc,
.calloc = calloc, .calloc = calloc,
@@ -238,14 +258,15 @@ CMC_CREATE_UNIT(bidimap_test, true, {
struct bidimap_entry *k = map->key_buffer[i]; struct bidimap_entry *k = map->key_buffer[i];
struct bidimap_entry *v = map->val_buffer[i]; struct bidimap_entry *v = map->val_buffer[i];
cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED)); cmc_assert((k == NULL || k == CMC_ENTRY_DELETED)
&& (v == NULL || v == CMC_ENTRY_DELETED));
} }
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(remove_by_val[cleanup custom], { CMC_CREATE_TEST(remove_by_val[cleanup custom], {
struct bidimap *map = bm_new_custom(10000, 0.6, cmp, hash, cmp, hash, struct bidimap *map = bm_new_custom(10000, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ &(struct cmc_alloc_node){
.malloc = malloc, .malloc = malloc,
.calloc = calloc, .calloc = calloc,
@@ -273,16 +294,16 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED)); cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED));
} }
bm_free(map, NULL); bm_free(map);
}); });
CMC_CREATE_TEST(copy_of, { CMC_CREATE_TEST(copy_of, {
struct bidimap *map1 = bm_new(100, 0.7, cmp, hash, cmp, hash); struct bidimap *map1 = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
for (size_t i = 0; i < 100; i++) for (size_t i = 0; i < 100; i++)
cmc_assert(bm_insert(map1, i, i)); cmc_assert(bm_insert(map1, i, i));
struct bidimap *map2 = bm_copy_of(map1, NULL, NULL); struct bidimap *map2 = bm_copy_of(map1);
cmc_assert_not_equals(ptr, NULL, map2); cmc_assert_not_equals(ptr, NULL, map2);
cmc_assert_equals(size_t, bm_count(map1), bm_count(map2)); cmc_assert_equals(size_t, bm_count(map1), bm_count(map2));
@@ -293,13 +314,13 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i)); cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i));
} }
bm_free(map1, NULL); bm_free(map1);
bm_free(map2, NULL); bm_free(map2);
}); });
CMC_CREATE_TEST(equals, { CMC_CREATE_TEST(equals, {
struct bidimap *map1 = bm_new(100, 0.7, cmp, hash, cmp, hash); struct bidimap *map1 = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
struct bidimap *map2 = bm_new(1000, 0.9, cmp, hash, cmp, hash); struct bidimap *map2 = bm_new(1000, 0.9, bm_ftab_key, bm_ftab_val);
for (size_t i = 0; i < 100; i++) for (size_t i = 0; i < 100; i++)
{ {
@@ -317,23 +338,23 @@ CMC_CREATE_UNIT(bidimap_test, true, {
cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i)); cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i));
} }
bm_free(map1, NULL); bm_free(map1);
bm_free(map2, NULL); bm_free(map2);
}); });
CMC_CREATE_TEST(equals[from copy], { CMC_CREATE_TEST(equals[from copy], {
struct bidimap *map1 = bm_new(100, 0.7, cmp, hash, cmp, hash); struct bidimap *map1 = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
for (size_t i = 0; i < 100; i++) for (size_t i = 0; i < 100; i++)
cmc_assert(bm_insert(map1, i, i)); cmc_assert(bm_insert(map1, i, i));
struct bidimap *map2 = bm_copy_of(map1, NULL, NULL); struct bidimap *map2 = bm_copy_of(map1);
cmc_assert_not_equals(ptr, NULL, map2); cmc_assert_not_equals(ptr, NULL, map2);
cmc_assert(bm_equals(map1, map2)); cmc_assert(bm_equals(map1, map2));
bm_free(map1, NULL); bm_free(map1);
bm_free(map2, NULL); bm_free(map2);
}); });
}); });
-30
View File
@@ -31,36 +31,6 @@ CMC_CREATE_UNIT(list_test, true, {
cmc_assert_equals(ptr, NULL, l); cmc_assert_equals(ptr, NULL, l);
}); });
CMC_CREATE_TEST(new_from[count and item preservation], {
size_t v[5];
for (size_t i = 0; i < 5; i++)
{
v[i] = i;
}
struct list *l = l_new_from(v, 5);
cmc_assert_not_equals(ptr, NULL, l);
for (size_t i = 0; i < 5; i++)
cmc_assert_equals(size_t, i, l_get(l, i));
l_free(l, NULL);
});
CMC_CREATE_TEST(new_from[size = 1], {
size_t a = 10;
size_t *values = &a;
struct list *l = l_new_from(values, 1);
cmc_assert_not_equals(ptr, NULL, l);
l_free(l, NULL);
});
CMC_CREATE_TEST(clear[count capacity], { CMC_CREATE_TEST(clear[count capacity], {
struct list *l = l_new(100); struct list *l = l_new(100);
+23
View File
@@ -3,6 +3,7 @@
#define CMC_UNIT_TEST_UTL__ #define CMC_UNIT_TEST_UTL__
#include <stdlib.h> #include <stdlib.h>
#include <inttypes.h>
#include <cmc/hashmap.h> #include <cmc/hashmap.h>
int cmp(size_t a, size_t b) int cmp(size_t a, size_t b)
@@ -10,6 +11,22 @@ int cmp(size_t a, size_t b)
return (a > b) - (a < b); return (a > b) - (a < b);
} }
size_t copy(size_t a)
{
return a;
}
bool to_string(FILE *fptr, size_t a)
{
return fprintf(fptr, "%" PRIuMAX " ", a) > 0;
}
void custom_free(size_t a)
{
// blank
// Free any resources if necessary
}
size_t hash(size_t a) size_t hash(size_t a)
{ {
a += ~(a << 15); a += ~(a << 15);
@@ -21,6 +38,12 @@ size_t hash(size_t a)
return a; return a;
} }
int priority(size_t a, size_t b)
{
// Could contain different logic
return cmp(a, b);
}
size_t numhash(size_t a) size_t numhash(size_t a)
{ {
return a; return a;
+15
View File
@@ -0,0 +1,15 @@
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra
CFLAGS += -Wno-unused -Wno-missing-braces
main:
$(CC) -c collections.c -o collections.o $(CFLAGS)
$(CC) -c main.c -o main.o $(CFLAGS)
$(CC) collections.o main.o -o sep.exe
./sep.exe
clean:
rm *.o
clear:
rm *.o *.exe
+4 -2
View File
@@ -20,7 +20,9 @@ size_t inthash(int t)
int main(void) int main(void)
{ {
struct bmap *bm = bm_new_custom(100, 0.7, NULL, NULL, NULL, NULL, NULL, NULL); struct bmap *bm =
bm_new_custom(100, 0.7, &(struct bmap_ftab_key){ 0 },
&(struct bmap_ftab_val){ 0 }, NULL, NULL);
struct deque *d = d_new_custom(100, NULL, NULL); struct deque *d = d_new_custom(100, NULL, NULL);
struct hmap *hm = hm_new_custom(100, 0.6, NULL, NULL, NULL, NULL); struct hmap *hm = hm_new_custom(100, 0.6, NULL, NULL, NULL, NULL);
struct hset *hs = hs_new_custom(100, 0.6, NULL, NULL, NULL, NULL); struct hset *hs = hs_new_custom(100, 0.6, NULL, NULL, NULL, NULL);
@@ -40,7 +42,7 @@ int main(void)
printf("| Separate Header and Source is Working |\n"); printf("| Separate Header and Source is Working |\n");
printf("+--------------------------------------------------+\n"); printf("+--------------------------------------------------+\n");
bm_free(bm, NULL); bm_free(bm);
d_free(d, NULL); d_free(d, NULL);
hm_free(hm, NULL); hm_free(hm, NULL);
hs_free(hs, NULL); hs_free(hs, NULL);
+1 -1
View File
@@ -20,7 +20,7 @@ CMC_COLLECTION_GENERATE( TREEMAP, tm, tmap, int, int)
int main(void) int main(void)
{ {
struct bmap *bm = bm_new_custom(100, 0.7, NULL, NULL, NULL, NULL, NULL, NULL); struct bmap *bm = bm_new_custom(100, 0.7, NULL, NULL, NULL, NULL);
struct deque *d = d_new_custom(100, NULL, NULL); struct deque *d = d_new_custom(100, NULL, NULL);
struct hmap *hm = hm_new_custom(100, 0.6, NULL, NULL, NULL, NULL); struct hmap *hm = hm_new_custom(100, 0.6, NULL, NULL, NULL, NULL);
struct hset *hs = hs_new_custom(100, 0.6, NULL, NULL, NULL, NULL); struct hset *hs = hs_new_custom(100, 0.6, NULL, NULL, NULL, NULL);