From: Michael D. Lowis Date: Wed, 3 Feb 2016 01:39:08 +0000 (-0500) Subject: Merged data structure source files with headers in order to ease reuse in other projects X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=4388ec6d41130083cd10622627874c6912ef26d9;p=archive%2Fcarl.git Merged data structure source files with headers in order to ease reuse in other projects --- diff --git a/Makefile b/Makefile index 02411f5..fc2a365 100644 --- a/Makefile +++ b/Makefile @@ -31,12 +31,7 @@ CLEAN = @rm -f LIBNAME = carl LIB = lib${LIBNAME}.a DEPS = ${OBJS:.o=.d} -OBJS = source/data/bstree.o \ - source/data/hash.o \ - source/data/list.o \ - source/data/slist.o \ - source/data/vec.o \ - source/main.o \ +OBJS = source/main.o \ source/refcount.o \ source/utf/chartorune.o \ source/utf/fullrune.o \ diff --git a/source/data/bstree.c b/source/data/bstree.c deleted file mode 100644 index 882cd91..0000000 --- a/source/data/bstree.c +++ /dev/null @@ -1,62 +0,0 @@ -#include - - - -void bstree_init(bstree_t* tree, bstree_cmpfn_t cmpfn, bool allow_dups) -{ - tree->root = NULL; - tree->cmpfn = cmpfn; - tree->allow_dups = allow_dups; -} - -bool bstree_empty(bstree_t* tree) -{ - return (tree->root == NULL); -} - -static size_t subtree_size(bstree_node_t* node) -{ - if (node == NULL) - return 0; - else - return (1 + subtree_size(node->left) + subtree_size(node->right)); -} - -size_t bstree_size(bstree_t* tree) -{ - return subtree_size(tree->root); -} - -static bstree_node_t** find_node(bstree_cmpfn_t cmpfn, bstree_node_t** root, bstree_node_t* node, bool allow_dups) -{ - bstree_node_t** curr = root; - while(*curr != NULL) { - int cmp = cmpfn(node, *curr); - if (cmp < 0) - curr = &((*curr)->left); - else if (cmp > 0) - curr = &((*curr)->right); - else if (allow_dups) - curr = &((*curr)->right); - else - break; - } - return curr; -} - -void bstree_insert(bstree_t* tree, bstree_node_t* node) -{ - bstree_node_t** curr = find_node(tree->cmpfn, &(tree->root), node, tree->allow_dups); - if (*curr == NULL) { - *curr = node; - node->left = NULL; - node->right = NULL; - } -} - -bstree_node_t* bstree_lookup(bstree_t* tree, bstree_node_t* node) -{ - bstree_node_t** curr = find_node(tree->cmpfn, &(tree->root), node, false); - return *curr; -} - diff --git a/source/data/bstree.h b/source/data/bstree.h index c8cbd88..3d0fd40 100644 --- a/source/data/bstree.h +++ b/source/data/bstree.h @@ -20,14 +20,62 @@ typedef struct { bool allow_dups; } bstree_t; -void bstree_init(bstree_t* bstree, bstree_cmpfn_t cmpfn, bool allow_dups); +static void bstree_init(bstree_t* tree, bstree_cmpfn_t cmpfn, bool allow_dups) +{ + tree->root = NULL; + tree->cmpfn = cmpfn; + tree->allow_dups = allow_dups; +} -bool bstree_empty(bstree_t* bstree); +static bool bstree_empty(bstree_t* tree) +{ + return (tree->root == NULL); +} -size_t bstree_size(bstree_t* bstree); +static size_t subtree_size(bstree_node_t* node) +{ + if (node == NULL) + return 0; + else + return (1 + subtree_size(node->left) + subtree_size(node->right)); +} -void bstree_insert(bstree_t* bstree, bstree_node_t* node); +static size_t bstree_size(bstree_t* tree) +{ + return subtree_size(tree->root); +} -bstree_node_t* bstree_lookup(bstree_t* bstree, bstree_node_t* node); +static bstree_node_t** find_node(bstree_cmpfn_t cmpfn, bstree_node_t** root, bstree_node_t* node, bool allow_dups) +{ + bstree_node_t** curr = root; + while(*curr != NULL) { + int cmp = cmpfn(node, *curr); + if (cmp < 0) + curr = &((*curr)->left); + else if (cmp > 0) + curr = &((*curr)->right); + else if (allow_dups) + curr = &((*curr)->right); + else + break; + } + return curr; +} + +static void bstree_insert(bstree_t* tree, bstree_node_t* node) +{ + bstree_node_t** curr = find_node(tree->cmpfn, &(tree->root), node, tree->allow_dups); + if (*curr == NULL) { + *curr = node; + node->left = NULL; + node->right = NULL; + } +} + +static bstree_node_t* bstree_lookup(bstree_t* tree, bstree_node_t* node) +{ + bstree_node_t** curr = find_node(tree->cmpfn, &(tree->root), node, false); + return *curr; +} #endif /* BSTREE_H */ diff --git a/source/data/hash.c b/source/data/hash.c deleted file mode 100644 index 67388b5..0000000 --- a/source/data/hash.c +++ /dev/null @@ -1,185 +0,0 @@ -/** - @file hash.c - @brief See header for details - $Revision$ - $HeadURL$ - */ -#include -#include - -#define NUM_PRIMES (sizeof(Primes)/sizeof(unsigned int)) - -static unsigned int Primes[] = { - 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, - 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, - 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, - 805306457, 1610612741 -}; - -static inline unsigned int num_buckets(unsigned int idx) { - return Primes[idx]; -} - -static void find_entry(hash_t* hash, hash_entry_t** parent, hash_entry_t** current, hash_entry_t* entry) -{ - while(*current != NULL) { - if (((*current)->hash == entry->hash) && - (0 == hash->cmpfn(*current, entry))) - break; - *parent = *current; - *current = (*current)->next; - } -} - -static void rehash(hash_t* hash) -{ - if ((hash->bkt_count+1) < NUM_PRIMES) { - unsigned int oldcount = hash->bkt_count++; - hash_entry_t** oldbuckets = hash->buckets; - hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash->bkt_count)); - hash->size = 0; - /* Iterate over all of the old buckets */ - for (unsigned int i = 0; i < num_buckets(oldcount); i++) { - hash_entry_t* node = oldbuckets[i]; - /* re-insert all entries in the bucket into the new bucket table */ - while (node != NULL) { - hash_entry_t* entry = node; - node = entry->next; - hash_set(hash, entry); - } - } - /* Free the old bucket table */ - free(oldbuckets); - } -} - -uint32_t hash_bytes(uint8_t* key, size_t len) -{ - uint32_t a=31415u, b=27183u, hash; - for (hash=0; len > 0; key++, len--, a*=b) - hash = (a * hash) + *key; - return hash32(hash); -} - -uint64_t hash64(uint64_t key) -{ - key = (~key) + (key << 21); // key = (key << 21) - key - 1; - key = key ^ (key >> 24); - key = (key + (key << 3)) + (key << 8); // key * 265 - key = key ^ (key >> 14); - key = (key + (key << 2)) + (key << 4); // key * 21 - key = key ^ (key >> 28); - key = key + (key << 31); - return key; -} - -uint32_t hash32(uint32_t key) -{ - key = (key+0x7ed55d16) + (key<<12); - key = (key^0xc761c23c) ^ (key>>19); - key = (key+0x165667b1) + (key<<5); - key = (key+0xd3a2646c) ^ (key<<9); - key = (key+0xfd7046c5) + (key<<3); - key = (key^0xb55a4f09) ^ (key>>16); - return key; -} - -void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn) -{ - hash->size = 0; - hash->bkt_count = 0; - hash->hashfn = hashfn; - hash->cmpfn = cmpfn; - hash->delfn = delfn; - hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash->bkt_count)); -} - -void hash_deinit(hash_t* hash) -{ - hash_clr(hash); - free(hash->buckets); -} - -size_t hash_size(hash_t* hash) -{ - return hash->size; -} - -void hash_set(hash_t* hash, hash_entry_t* entry) -{ - if (hash->size >= num_buckets(hash->bkt_count)) - rehash(hash); - entry->hash = hash->hashfn(entry); - unsigned int index = (entry->hash % num_buckets(hash->bkt_count)); - hash_entry_t* parent = NULL; - hash_entry_t* node = hash->buckets[index]; - hash_entry_t* deadite = NULL; - find_entry(hash, &parent, &node, entry); - if ((parent == NULL) && (node == NULL)) { - hash->buckets[index] = entry; - entry->next = NULL; - hash->size++; - } else if (node == NULL) { - parent->next = entry; - entry->next = NULL; - hash->size++; - } else if (parent == NULL) { - deadite = node; - entry->next = deadite->next; - hash->buckets[index] = entry; - } else { - deadite = node; - entry->next = deadite->next; - parent->next = entry; - } - if (deadite != NULL) - hash->delfn(deadite); -} - -hash_entry_t* hash_get(hash_t* hash, hash_entry_t* entry) -{ - entry->hash = hash->hashfn(entry); - unsigned int index = (entry->hash % num_buckets(hash->bkt_count)); - hash_entry_t* parent = NULL; - hash_entry_t* node = hash->buckets[index]; - find_entry(hash, &parent, &node, entry); - (void)parent; - return node; -} - -bool hash_del(hash_t* hash, hash_entry_t* entry) -{ - bool ret = false; - entry->hash = hash->hashfn(entry); - unsigned int index = (entry->hash % num_buckets(hash->bkt_count)); - hash_entry_t* parent = NULL; - hash_entry_t* node = hash->buckets[index]; - find_entry(hash, &parent, &node, entry); - if (node != NULL) { - hash_entry_t* deadite = node; - node = node->next; - if (parent != NULL) - parent->next = node; - else - hash->buckets[index] = node; - hash->delfn(deadite); - ret = true; - hash->size--; - } - return ret; -} - -void hash_clr(hash_t* hash) -{ - /* Delete all the entries in the hash */ - for (unsigned int i = 0; i < num_buckets(hash->bkt_count); i++) { - hash_entry_t* node = hash->buckets[i]; - hash->buckets[i] = NULL; - while (node != NULL) { - hash_entry_t* deadite = node; - node = node->next; - hash->delfn(deadite); - } - } -} - diff --git a/source/data/hash.h b/source/data/hash.h index f720b57..5a924ce 100644 --- a/source/data/hash.h +++ b/source/data/hash.h @@ -8,6 +8,7 @@ #include #include #include +#include typedef struct hash_entry_t { unsigned int hash; @@ -29,24 +30,184 @@ typedef struct { hash_freefn_t delfn; } hash_t; -uint32_t hash_bytes(uint8_t* key, size_t len); - -uint64_t hash64(uint64_t key); - -uint32_t hash32(uint32_t a); - -void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn); - -void hash_deinit(hash_t* hash); - -size_t hash_size(hash_t* hash); - -void hash_set(hash_t* hash, hash_entry_t* entry); - -hash_entry_t* hash_get(hash_t* hash, hash_entry_t* entry); - -bool hash_del(hash_t* hash, hash_entry_t* entry); - -void hash_clr(hash_t* hash); +#define NUM_PRIMES (sizeof(Primes)/sizeof(unsigned int)) + +static unsigned int Primes[] = { + 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, + 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, + 805306457, 1610612741 +}; + +static inline unsigned int num_buckets(unsigned int idx) { + return Primes[idx]; +} + +static void rehash(hash_t* hash); +static void hash_set(hash_t* hash, hash_entry_t* entry); + +static uint64_t hash64(uint64_t key) +{ + key = (~key) + (key << 21); // key = (key << 21) - key - 1; + key = key ^ (key >> 24); + key = (key + (key << 3)) + (key << 8); // key * 265 + key = key ^ (key >> 14); + key = (key + (key << 2)) + (key << 4); // key * 21 + key = key ^ (key >> 28); + key = key + (key << 31); + return key; +} + +static uint32_t hash32(uint32_t key) +{ + key = (key+0x7ed55d16) + (key<<12); + key = (key^0xc761c23c) ^ (key>>19); + key = (key+0x165667b1) + (key<<5); + key = (key+0xd3a2646c) ^ (key<<9); + key = (key+0xfd7046c5) + (key<<3); + key = (key^0xb55a4f09) ^ (key>>16); + return key; +} + +static uint32_t hash_bytes(uint8_t* key, size_t len) +{ + uint32_t a=31415u, b=27183u, hash; + for (hash=0; len > 0; key++, len--, a*=b) + hash = (a * hash) + *key; + return hash32(hash); +} + + +static void find_entry(hash_t* hash, hash_entry_t** parent, hash_entry_t** current, hash_entry_t* entry) +{ + while(*current != NULL) { + if (((*current)->hash == entry->hash) && + (0 == hash->cmpfn(*current, entry))) + break; + *parent = *current; + *current = (*current)->next; + } +} + +static void rehash(hash_t* hash) +{ + if ((hash->bkt_count+1) < NUM_PRIMES) { + unsigned int oldcount = hash->bkt_count++; + hash_entry_t** oldbuckets = hash->buckets; + hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash->bkt_count)); + hash->size = 0; + /* Iterate over all of the old buckets */ + for (unsigned int i = 0; i < num_buckets(oldcount); i++) { + hash_entry_t* node = oldbuckets[i]; + /* re-insert all entries in the bucket into the new bucket table */ + while (node != NULL) { + hash_entry_t* entry = node; + node = entry->next; + hash_set(hash, entry); + } + } + /* Free the old bucket table */ + free(oldbuckets); + } +} + +static void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn) +{ + hash->size = 0; + hash->bkt_count = 0; + hash->hashfn = hashfn; + hash->cmpfn = cmpfn; + hash->delfn = delfn; + hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash->bkt_count)); +} + +static void hash_clr(hash_t* hash) +{ + /* Delete all the entries in the hash */ + for (unsigned int i = 0; i < num_buckets(hash->bkt_count); i++) { + hash_entry_t* node = hash->buckets[i]; + hash->buckets[i] = NULL; + while (node != NULL) { + hash_entry_t* deadite = node; + node = node->next; + hash->delfn(deadite); + } + } +} + +static void hash_deinit(hash_t* hash) +{ + hash_clr(hash); + free(hash->buckets); +} + +static size_t hash_size(hash_t* hash) +{ + return hash->size; +} + +static void hash_set(hash_t* hash, hash_entry_t* entry) +{ + if (hash->size >= num_buckets(hash->bkt_count)) + rehash(hash); + entry->hash = hash->hashfn(entry); + unsigned int index = (entry->hash % num_buckets(hash->bkt_count)); + hash_entry_t* parent = NULL; + hash_entry_t* node = hash->buckets[index]; + hash_entry_t* deadite = NULL; + find_entry(hash, &parent, &node, entry); + if ((parent == NULL) && (node == NULL)) { + hash->buckets[index] = entry; + entry->next = NULL; + hash->size++; + } else if (node == NULL) { + parent->next = entry; + entry->next = NULL; + hash->size++; + } else if (parent == NULL) { + deadite = node; + entry->next = deadite->next; + hash->buckets[index] = entry; + } else { + deadite = node; + entry->next = deadite->next; + parent->next = entry; + } + if (deadite != NULL) + hash->delfn(deadite); +} + +static hash_entry_t* hash_get(hash_t* hash, hash_entry_t* entry) +{ + entry->hash = hash->hashfn(entry); + unsigned int index = (entry->hash % num_buckets(hash->bkt_count)); + hash_entry_t* parent = NULL; + hash_entry_t* node = hash->buckets[index]; + find_entry(hash, &parent, &node, entry); + (void)parent; + return node; +} + +static bool hash_del(hash_t* hash, hash_entry_t* entry) +{ + bool ret = false; + entry->hash = hash->hashfn(entry); + unsigned int index = (entry->hash % num_buckets(hash->bkt_count)); + hash_entry_t* parent = NULL; + hash_entry_t* node = hash->buckets[index]; + find_entry(hash, &parent, &node, entry); + if (node != NULL) { + hash_entry_t* deadite = node; + node = node->next; + if (parent != NULL) + parent->next = node; + else + hash->buckets[index] = node; + hash->delfn(deadite); + ret = true; + hash->size--; + } + return ret; +} #endif /* HASH_H */ diff --git a/source/data/list.c b/source/data/list.c deleted file mode 100644 index 4ef2583..0000000 --- a/source/data/list.c +++ /dev/null @@ -1,92 +0,0 @@ -#include - -void list_init(list_t* list) -{ - list->head = NULL; - list->tail = NULL; -} - -bool list_empty(list_t* list) -{ - return (list->head == NULL); -} - -size_t list_size(list_t* list) -{ - size_t sz = 0; - list_node_t* node = list->head; - while (node != NULL) { - sz++; - node = node->next; - } - return sz; -} - -list_node_t* list_front(list_t* list) -{ - return list->head; -} - -void list_push_front(list_t* list, list_node_t* node) -{ - node->prev = NULL; - node->next = list->head; - list->head = node; - if (list->tail == NULL) - list->tail = node; -} - -list_node_t* list_pop_front(list_t* list) -{ - list_node_t* node = list->head; - list->head = node->next; - if (list->head == NULL) - list->tail = NULL; - node->next = NULL; - return node; -} - -list_node_t* list_back(list_t* list) -{ - return list->tail; -} - -void list_push_back(list_t* list, list_node_t* node) -{ - node->next = NULL; - node->prev = list->tail; - list->tail = node; - if (list->head == NULL) - list->head = node; -} - -list_node_t* list_pop_back(list_t* list) -{ - list_node_t* node = list->tail; - list->tail = node->prev; - if (list->tail == NULL) - list->head = NULL; - node->prev = NULL; - return node; -} - -bool list_node_has_next(list_node_t* node) -{ - return (node->next != NULL); -} - -list_node_t* list_node_next(list_node_t* node) -{ - return node->next; -} - -bool list_node_has_prev(list_node_t* node) -{ - return (node->prev != NULL); -} - -list_node_t* list_node_prev(list_node_t* node) -{ - return node->prev; -} - diff --git a/source/data/list.h b/source/data/list.h index 544be63..54d347d 100644 --- a/source/data/list.h +++ b/source/data/list.h @@ -17,30 +17,94 @@ typedef struct { list_node_t* tail; } list_t; -void list_init(list_t* list); - -bool list_empty(list_t* list); - -size_t list_size(list_t* list); - -list_node_t* list_front(list_t* list); - -void list_push_front(list_t* list, list_node_t* node); - -list_node_t* list_pop_front(list_t* list); - -list_node_t* list_back(list_t* list); - -void list_push_back(list_t* list, list_node_t* node); - -list_node_t* list_pop_back(list_t* list); - -bool list_node_has_next(list_node_t* node); - -list_node_t* list_node_next(list_node_t* node); - -bool list_node_has_prev(list_node_t* node); - -list_node_t* list_node_prev(list_node_t* node); +static void list_init(list_t* list) +{ + list->head = NULL; + list->tail = NULL; +} + +static bool list_empty(list_t* list) +{ + return (list->head == NULL); +} + +static size_t list_size(list_t* list) +{ + size_t sz = 0; + list_node_t* node = list->head; + while (node != NULL) { + sz++; + node = node->next; + } + return sz; +} + +static list_node_t* list_front(list_t* list) +{ + return list->head; +} + +static void list_push_front(list_t* list, list_node_t* node) +{ + node->prev = NULL; + node->next = list->head; + list->head = node; + if (list->tail == NULL) + list->tail = node; +} + +static list_node_t* list_pop_front(list_t* list) +{ + list_node_t* node = list->head; + list->head = node->next; + if (list->head == NULL) + list->tail = NULL; + node->next = NULL; + return node; +} + +static list_node_t* list_back(list_t* list) +{ + return list->tail; +} + +static void list_push_back(list_t* list, list_node_t* node) +{ + node->next = NULL; + node->prev = list->tail; + list->tail = node; + if (list->head == NULL) + list->head = node; +} + +static list_node_t* list_pop_back(list_t* list) +{ + list_node_t* node = list->tail; + list->tail = node->prev; + if (list->tail == NULL) + list->head = NULL; + node->prev = NULL; + return node; +} + +static bool list_node_has_next(list_node_t* node) +{ + return (node->next != NULL); +} + +static list_node_t* list_node_next(list_node_t* node) +{ + return node->next; +} + +static bool list_node_has_prev(list_node_t* node) +{ + return (node->prev != NULL); +} + +static list_node_t* list_node_prev(list_node_t* node) +{ + return node->prev; +} #endif /* LIST_H */ diff --git a/source/data/slist.c b/source/data/slist.c deleted file mode 100644 index ef5ed27..0000000 --- a/source/data/slist.c +++ /dev/null @@ -1,85 +0,0 @@ -#include - -void slist_init(slist_t* list) -{ - list->head = NULL; -} - -bool slist_empty(slist_t* list) -{ - return (list->head == NULL); -} - -size_t slist_size(slist_t* list) -{ - size_t sz = 0; - slist_node_t* node = list->head; - while (node != NULL) { - sz++; - node = node->next; - } - return sz; -} - -slist_node_t* slist_front(slist_t* list) -{ - return list->head; -} - -void slist_push_front(slist_t* list, slist_node_t* node) -{ - node->next = list->head; - list->head = node; -} - -slist_node_t* slist_pop_front(slist_t* list) -{ - slist_node_t* node = list->head; - list->head = node->next; - node->next = NULL; - return node; -} - -slist_node_t* slist_back(slist_t* list) -{ - slist_node_t* node = list->head; - while (node && node->next != NULL) - node = node->next; - return (node) ? node : NULL; -} - -void slist_push_back(slist_t* list, slist_node_t* node) -{ - slist_node_t* back = slist_back(list); - if (NULL != back) - back->next = node; - else - list->head = node; - node->next = NULL; -} - -slist_node_t* slist_pop_back(slist_t* list) -{ - slist_node_t* prev = NULL; - slist_node_t* curr = list->head; - while (curr && curr->next != NULL) { - prev = curr; - curr = curr->next; - } - if (prev != NULL) - prev->next = NULL; - if (list->head == curr) - list->head = NULL; - return curr; -} - -bool slist_node_has_next(slist_node_t* node) -{ - return (node->next != NULL); -} - -slist_node_t* slist_node_next(slist_node_t* node) -{ - return node->next; -} - diff --git a/source/data/slist.h b/source/data/slist.h index b441e56..7ab01e9 100644 --- a/source/data/slist.h +++ b/source/data/slist.h @@ -15,27 +15,88 @@ typedef struct { slist_node_t* head; } slist_t; -void slist_init(slist_t* list); - -bool slist_empty(slist_t* list); - -size_t slist_size(slist_t* list); - -slist_node_t* slist_front(slist_t* list); - -void slist_push_front(slist_t* list, slist_node_t* node); - -slist_node_t* slist_pop_front(slist_t* list); - -slist_node_t* slist_back(slist_t* list); - -void slist_push_back(slist_t* list, slist_node_t* node); - -slist_node_t* slist_pop_back(slist_t* list); - -bool slist_node_has_next(slist_node_t* node); - -slist_node_t* slist_node_next(slist_node_t* node); +static void slist_init(slist_t* list) +{ + list->head = NULL; +} + +static bool slist_empty(slist_t* list) +{ + return (list->head == NULL); +} + +static size_t slist_size(slist_t* list) +{ + size_t sz = 0; + slist_node_t* node = list->head; + while (node != NULL) { + sz++; + node = node->next; + } + return sz; +} + +static slist_node_t* slist_front(slist_t* list) +{ + return list->head; +} + +static void slist_push_front(slist_t* list, slist_node_t* node) +{ + node->next = list->head; + list->head = node; +} + +static slist_node_t* slist_pop_front(slist_t* list) +{ + slist_node_t* node = list->head; + list->head = node->next; + node->next = NULL; + return node; +} + +static slist_node_t* slist_back(slist_t* list) +{ + slist_node_t* node = list->head; + while (node && node->next != NULL) + node = node->next; + return (node) ? node : NULL; +} + +static void slist_push_back(slist_t* list, slist_node_t* node) +{ + slist_node_t* back = slist_back(list); + if (NULL != back) + back->next = node; + else + list->head = node; + node->next = NULL; +} + +static slist_node_t* slist_pop_back(slist_t* list) +{ + slist_node_t* prev = NULL; + slist_node_t* curr = list->head; + while (curr && curr->next != NULL) { + prev = curr; + curr = curr->next; + } + if (prev != NULL) + prev->next = NULL; + if (list->head == curr) + list->head = NULL; + return curr; +} + +static bool slist_node_has_next(slist_node_t* node) +{ + return (node->next != NULL); +} + +static slist_node_t* slist_node_next(slist_node_t* node) +{ + return node->next; +} #define slist_foreach(elem, list) \ for(slist_node_t* elem = slist_front(list); elem != NULL; elem = elem->next) diff --git a/source/data/vec.c b/source/data/vec.c deleted file mode 100644 index 23374f7..0000000 --- a/source/data/vec.c +++ /dev/null @@ -1,119 +0,0 @@ -/** - @file vec.c -*/ -#include -#include -#include - -#ifndef DEFAULT_VEC_CAPACITY -#define DEFAULT_VEC_CAPACITY (size_t)8 -#endif - -void vec_init(vec_t* vec, size_t elem_size) -{ - vec->elem_size = elem_size; - vec->elem_count = 0; - vec->elem_capacity = DEFAULT_VEC_CAPACITY; - vec->elem_buffer = malloc(elem_size * vec->elem_capacity); -} - -size_t vec_size(vec_t* vec) -{ - return vec->elem_count; -} - -bool vec_empty(vec_t* vec) -{ - return (vec->elem_count == 0); -} - -size_t vec_capacity(vec_t* vec) -{ - return vec->elem_capacity; -} - -void vec_resize(vec_t* vec, size_t count, void* fillval) -{ - if (count > vec->elem_count) - { - vec_reserve(vec, vec_next_capacity(count+1)); - for (; vec->elem_count < count; vec->elem_count++) - memcpy(&(vec->elem_buffer[vec->elem_count * vec->elem_size]), fillval, vec->elem_size); - } - else if (count < vec->elem_count) - { - vec->elem_count = count; - } -} - -size_t vec_next_capacity(size_t req_size) -{ - size_t next_power = req_size; - size_t num_bits = sizeof(size_t) * 8; - size_t bit_n; - - /* Find the next highest power of 2 */ - next_power--; - for (bit_n = 1; bit_n < num_bits; bit_n = bit_n << 1) - { - next_power = next_power | (next_power >> bit_n); - } - next_power++; - - return next_power; -} - -void vec_shrink_to_fit(vec_t* vec) -{ - vec->elem_buffer = realloc(vec->elem_buffer, vec->elem_count * vec->elem_size); - vec->elem_capacity = vec->elem_count; -} - -void vec_reserve(vec_t* vec, size_t size) -{ - vec->elem_buffer = realloc(vec->elem_buffer, size * vec->elem_size); - vec->elem_count = size; -} - -void* vec_at(vec_t* vec, size_t index) -{ - return &(vec->elem_buffer[index * vec->elem_size]); -} - -void vec_set(vec_t* vec, size_t index, void* data) -{ - memcpy(&(vec->elem_buffer[index * vec->elem_size]), data, vec->elem_size); -} - -bool vec_insert(vec_t* vec, size_t index, size_t num_elements, ...) -{ - (void)vec; - (void)index; - (void)num_elements; - return false; -} - -bool vec_erase(vec_t* vec, size_t start_idx, size_t end_idx) -{ - (void)vec; - (void)start_idx; - (void)end_idx; - return false; -} - -void vec_push_back(vec_t* vec, void* data) -{ - vec_resize(vec, vec->elem_count+1, data); -} - -void vec_pop_back(vec_t* vec, void* outdata) -{ - vec->elem_count--; - memcpy(outdata, &(vec->elem_buffer[vec->elem_count * vec->elem_size]), vec->elem_size); -} - -void vec_clear(vec_t* vec) -{ - vec->elem_count = 0; -} - diff --git a/source/data/vec.h b/source/data/vec.h index e902947..c7a9121 100644 --- a/source/data/vec.h +++ b/source/data/vec.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include typedef struct { size_t elem_count; @@ -15,34 +17,116 @@ typedef struct { uint8_t* elem_buffer; } vec_t; -void vec_init(vec_t* vec, size_t elem_size); - -size_t vec_size(vec_t* vec); - -bool vec_empty(vec_t* vec); - -size_t vec_capacity(vec_t* vec); - -void vec_resize(vec_t* vec, size_t size, void* data); - -size_t vec_next_capacity(size_t req_size); - -void vec_shrink_to_fit(vec_t* vec); - -void vec_reserve(vec_t* vec, size_t size); - -void* vec_at(vec_t* vec, size_t index); - -void vec_set(vec_t* vec, size_t index, void* data); - -bool vec_insert(vec_t* vec, size_t index, size_t num_elements, ...); - -bool vec_erase(vec_t* vec, size_t start_idx, size_t end_idx); - -void vec_push_back(vec_t* vec, void* data); - -void vec_pop_back(vec_t* vec, void* outdata); - -void vec_clear(vec_t* vec); +#ifndef DEFAULT_VEC_CAPACITY +#define DEFAULT_VEC_CAPACITY (size_t)8 +#endif + +static void vec_init(vec_t* vec, size_t elem_size) +{ + vec->elem_size = elem_size; + vec->elem_count = 0; + vec->elem_capacity = DEFAULT_VEC_CAPACITY; + vec->elem_buffer = malloc(elem_size * vec->elem_capacity); +} + +static size_t vec_size(vec_t* vec) +{ + return vec->elem_count; +} + +static bool vec_empty(vec_t* vec) +{ + return (vec->elem_count == 0); +} + +static size_t vec_capacity(vec_t* vec) +{ + return vec->elem_capacity; +} + +static size_t vec_next_capacity(size_t req_size) +{ + size_t next_power = req_size; + size_t num_bits = sizeof(size_t) * 8; + size_t bit_n; + + /* Find the next highest power of 2 */ + next_power--; + for (bit_n = 1; bit_n < num_bits; bit_n = bit_n << 1) + { + next_power = next_power | (next_power >> bit_n); + } + next_power++; + + return next_power; +} + +static void vec_reserve(vec_t* vec, size_t size) +{ + vec->elem_buffer = realloc(vec->elem_buffer, size * vec->elem_size); + vec->elem_count = size; +} + +static void vec_resize(vec_t* vec, size_t count, void* fillval) +{ + if (count > vec->elem_count) + { + vec_reserve(vec, vec_next_capacity(count+1)); + for (; vec->elem_count < count; vec->elem_count++) + memcpy(&(vec->elem_buffer[vec->elem_count * vec->elem_size]), fillval, vec->elem_size); + } + else if (count < vec->elem_count) + { + vec->elem_count = count; + } +} + +static void vec_shrink_to_fit(vec_t* vec) +{ + vec->elem_buffer = realloc(vec->elem_buffer, vec->elem_count * vec->elem_size); + vec->elem_capacity = vec->elem_count; +} + +static void* vec_at(vec_t* vec, size_t index) +{ + return &(vec->elem_buffer[index * vec->elem_size]); +} + +static void vec_set(vec_t* vec, size_t index, void* data) +{ + memcpy(&(vec->elem_buffer[index * vec->elem_size]), data, vec->elem_size); +} + +static bool vec_insert(vec_t* vec, size_t index, size_t num_elements, ...) +{ + (void)vec; + (void)index; + (void)num_elements; + return false; +} + +static bool vec_erase(vec_t* vec, size_t start_idx, size_t end_idx) +{ + (void)vec; + (void)start_idx; + (void)end_idx; + return false; +} + +static void vec_push_back(vec_t* vec, void* data) +{ + vec_resize(vec, vec->elem_count+1, data); +} + +static void vec_pop_back(vec_t* vec, void* outdata) +{ + vec->elem_count--; + memcpy(outdata, &(vec->elem_buffer[vec->elem_count * vec->elem_size]), vec->elem_size); +} + +static void vec_clear(vec_t* vec) +{ + vec->elem_count = 0; +} #endif /* VEC_H */