diff --git a/tommyds/tommyarray.c b/tommyds/tommyarray.c index a8d946bb..d77db046 100644 --- a/tommyds/tommyarray.c +++ b/tommyds/tommyarray.c @@ -36,7 +36,7 @@ void tommy_array_init(tommy_array* array) /* fixed initial size */ array->bucket_bit = TOMMY_ARRAY_BIT; - array->bucket_max = 1 << array->bucket_bit; + array->bucket_max = (tommy_size_t)1 << array->bucket_bit; array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*))); for (i = 1; i < TOMMY_ARRAY_BIT; ++i) array->bucket[i] = array->bucket[0]; @@ -51,11 +51,11 @@ void tommy_array_done(tommy_array* array) tommy_free(array->bucket[0]); for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) { void** segment = array->bucket[i]; - tommy_free(&segment[((tommy_ptrdiff_t)1) << i]); + tommy_free(&segment[(tommy_ptrdiff_t)1 << i]); } } -void tommy_array_grow(tommy_array* array, tommy_count_t count) +void tommy_array_grow(tommy_array* array, tommy_size_t count) { if (array->count >= count) return; @@ -72,7 +72,7 @@ void tommy_array_grow(tommy_array* array, tommy_count_t count) array->bucket[array->bucket_bit] = &segment[-(tommy_ptrdiff_t)array->bucket_max]; ++array->bucket_bit; - array->bucket_max = 1 << array->bucket_bit; + array->bucket_max = (tommy_size_t)1 << array->bucket_bit; } } diff --git a/tommyds/tommyarray.h b/tommyds/tommyarray.h index c04193f8..bc124de9 100644 --- a/tommyds/tommyarray.h +++ b/tommyds/tommyarray.h @@ -53,20 +53,15 @@ */ #define TOMMY_ARRAY_BIT 6 -/** \internal - * Max number of elements as a power of 2. - */ -#define TOMMY_ARRAY_BIT_MAX 32 - /** * Array container type. * \note Don't use internal fields directly, but access the container only using functions. */ typedef struct tommy_array_struct { - void** bucket[TOMMY_ARRAY_BIT_MAX]; /**< Dynamic array of buckets. */ + void** bucket[TOMMY_SIZE_BIT]; /**< Dynamic array of buckets. */ + tommy_size_t bucket_max; /**< Number of buckets. */ + tommy_size_t count; /**< Number of initialized elements in the array. */ tommy_uint_t bucket_bit; /**< Bits used in the bit mask. */ - tommy_count_t bucket_max; /**< Number of buckets. */ - tommy_count_t count; /**< Number of initialized elements in the array. */ } tommy_array; /** @@ -83,21 +78,21 @@ void tommy_array_done(tommy_array* array); * Grows the size up to the specified value. * All the new elements in the array are initialized with the 0 value. */ -void tommy_array_grow(tommy_array* array, tommy_count_t size); +void tommy_array_grow(tommy_array* array, tommy_size_t size); /** * Gets a reference of the element at the specified position. * You must be sure that space for this position is already * allocated calling tommy_array_grow(). */ -tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos) +tommy_inline void** tommy_array_ref(tommy_array* array, tommy_size_t pos) { tommy_uint_t bsr; assert(pos < array->count); /* get the highest bit set, in case of all 0, return 0 */ - bsr = tommy_ilog2_u32(pos | 1); + bsr = tommy_ilog2(pos | 1); return &array->bucket[bsr][pos]; } @@ -107,7 +102,7 @@ tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos) * You must be sure that space for this position is already * allocated calling tommy_array_grow(). */ -tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element) +tommy_inline void tommy_array_set(tommy_array* array, tommy_size_t pos, void* element) { *tommy_array_ref(array, pos) = element; } @@ -117,7 +112,7 @@ tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* e * You must be sure that space for this position is already * allocated calling tommy_array_grow(). */ -tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos) +tommy_inline void* tommy_array_get(tommy_array* array, tommy_size_t pos) { return *tommy_array_ref(array, pos); } @@ -127,7 +122,7 @@ tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos) */ tommy_inline void tommy_array_insert(tommy_array* array, void* element) { - tommy_count_t pos = array->count; + tommy_size_t pos = array->count; tommy_array_grow(array, pos + 1); @@ -137,7 +132,7 @@ tommy_inline void tommy_array_insert(tommy_array* array, void* element) /** * Gets the initialized size of the array. */ -tommy_inline tommy_count_t tommy_array_size(tommy_array* array) +tommy_inline tommy_size_t tommy_array_size(tommy_array* array) { return array->count; } diff --git a/tommyds/tommyarrayblkof.c b/tommyds/tommyarrayblkof.c index 8a491a0f..11187bea 100644 --- a/tommyds/tommyarrayblkof.c +++ b/tommyds/tommyarrayblkof.c @@ -40,7 +40,7 @@ void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size) void tommy_arrayblkof_done(tommy_arrayblkof* array) { - tommy_count_t i; + tommy_size_t i; for (i = 0; i < tommy_array_size(&array->block); ++i) tommy_free(tommy_array_get(&array->block, i)); @@ -48,10 +48,10 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array) tommy_array_done(&array->block); } -void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count) +void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_size_t count) { - tommy_count_t block_max; - tommy_count_t block_mac; + tommy_size_t block_max; + tommy_size_t block_mac; if (array->count >= count) return; diff --git a/tommyds/tommyarrayblkof.h b/tommyds/tommyarrayblkof.h index fce6840c..16d70cbf 100644 --- a/tommyds/tommyarrayblkof.h +++ b/tommyds/tommyarrayblkof.h @@ -61,7 +61,7 @@ typedef struct tommy_arrayblkof_struct { tommy_array block; /**< Array of blocks. */ tommy_size_t element_size; /**< Size of the stored element in bytes. */ - tommy_count_t count; /**< Number of initialized elements in the array. */ + tommy_size_t count; /**< Number of initialized elements in the array. */ } tommy_arrayblkof; /** @@ -79,14 +79,14 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array); * Grows the size up to the specified value. * All the new elements in the array are initialized with the 0 value. */ -void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t size); +void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_size_t size); /** * Gets a reference of the element at the specified position. * You must be sure that space for this position is already * allocated calling tommy_arrayblkof_grow(). */ -tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos) +tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_size_t pos) { unsigned char* base; @@ -100,7 +100,7 @@ tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t p /** * Gets the initialized size of the array. */ -tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array) +tommy_inline tommy_size_t tommy_arrayblkof_size(tommy_arrayblkof* array) { return array->count; } diff --git a/tommyds/tommychain.h b/tommyds/tommychain.h index b15bc6ae..12d2514b 100644 --- a/tommyds/tommychain.h +++ b/tommyds/tommychain.h @@ -136,11 +136,6 @@ tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* tommy_chain_merge(first, second, cmp); } -/** - * Max number of elements as a power of 2. - */ -#define TOMMY_CHAIN_BIT_MAX 32 - /** * Sorts a chain. * It's a stable merge sort using power of 2 buckets, with O(N*log(N)) complexity, @@ -158,20 +153,20 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* /* * Bit buckets of chains. * Each bucket contains 2^i nodes or it's empty. - * The chain at address TOMMY_CHAIN_BIT_MAX is an independet variable operating as "carry". + * The chain at address TOMMY_BIT_MAX is an independet variable operating as "carry". * We keep it in the same "bit" vector to avoid reports from the valgrind tool sgcheck. */ - tommy_chain bit[TOMMY_CHAIN_BIT_MAX + 1]; + tommy_chain bit[TOMMY_SIZE_BIT + 1]; /** * Value stored inside the bit bucket. * It's used to know which bucket is empty of full. */ - tommy_count_t counter; + tommy_size_t counter; tommy_node* node = chain->head; tommy_node* tail = chain->tail; - tommy_count_t mask; - tommy_count_t i; + tommy_size_t mask; + tommy_size_t i; counter = 0; while (1) { @@ -179,9 +174,9 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* tommy_chain* last; /* carry bit to add */ - last = &bit[TOMMY_CHAIN_BIT_MAX]; - bit[TOMMY_CHAIN_BIT_MAX].head = node; - bit[TOMMY_CHAIN_BIT_MAX].tail = node; + last = &bit[TOMMY_SIZE_BIT]; + bit[TOMMY_SIZE_BIT].head = node; + bit[TOMMY_SIZE_BIT].tail = node; next = node->next; /* add the bit, propagating the carry */ @@ -206,7 +201,7 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* } /* merge the buckets */ - i = tommy_ctz_u32(counter); + i = tommy_ctz(counter); mask = counter >> i; while (mask != 1) { mask >>= 1; diff --git a/tommyds/tommyhash.h b/tommyds/tommyhash.h index 738e33d2..50d595c0 100644 --- a/tommyds/tommyhash.h +++ b/tommyds/tommyhash.h @@ -37,11 +37,6 @@ /******************************************************************************/ /* hash */ -/** - * Hash type used in hashtables. - */ -typedef tommy_key_t tommy_hash_t; - /** * Hash function with a 32 bits result. * Implementation of the Robert Jenkins "lookup3" hash 32 bits version, diff --git a/tommyds/tommyhashdyn.c b/tommyds/tommyhashdyn.c index 02ef4049..a00737e7 100644 --- a/tommyds/tommyhashdyn.c +++ b/tommyds/tommyhashdyn.c @@ -35,7 +35,7 @@ void tommy_hashdyn_init(tommy_hashdyn* hashdyn) { /* fixed initial size */ hashdyn->bucket_bit = TOMMY_HASHDYN_BIT; - hashdyn->bucket_max = 1 << hashdyn->bucket_bit; + hashdyn->bucket_max = (tommy_size_t)1 << hashdyn->bucket_bit; hashdyn->bucket_mask = hashdyn->bucket_max - 1; hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*))); @@ -50,18 +50,18 @@ void tommy_hashdyn_done(tommy_hashdyn* hashdyn) /** * Resize the bucket vector. */ -static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit) +static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_size_t new_bucket_bit) { - tommy_count_t bucket_bit; - tommy_count_t bucket_max; - tommy_count_t new_bucket_max; - tommy_count_t new_bucket_mask; + tommy_size_t bucket_bit; + tommy_size_t bucket_max; + tommy_size_t new_bucket_max; + tommy_size_t new_bucket_mask; tommy_hashdyn_node** new_bucket; bucket_bit = hashdyn->bucket_bit; bucket_max = hashdyn->bucket_max; - new_bucket_max = 1 << new_bucket_bit; + new_bucket_max = (tommy_size_t)1 << new_bucket_bit; new_bucket_mask = new_bucket_max - 1; /* allocate the new vector using malloc() and not calloc() */ @@ -70,7 +70,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucke /* reinsert all the elements */ if (new_bucket_bit > bucket_bit) { - tommy_count_t i; + tommy_size_t i; /* grow */ for (i = 0; i < bucket_max; ++i) { @@ -84,7 +84,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucke j = hashdyn->bucket[i]; while (j) { tommy_hashdyn_node* j_next = j->next; - tommy_count_t pos = j->key & new_bucket_mask; + tommy_size_t pos = j->index & new_bucket_mask; if (new_bucket[pos]) tommy_list_insert_tail_not_empty(new_bucket[pos], j); else @@ -93,7 +93,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucke } } } else { - tommy_count_t i; + tommy_size_t i; /* shrink */ for (i = 0; i < new_bucket_max; ++i) { @@ -136,11 +136,11 @@ tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn) void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) { - tommy_count_t pos = hash & hashdyn->bucket_mask; + tommy_size_t pos = hash & hashdyn->bucket_mask; tommy_list_insert_tail(&hashdyn->bucket[pos], node, data); - node->key = hash; + node->index = hash; ++hashdyn->count; @@ -149,7 +149,7 @@ void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) { - tommy_count_t pos = node->key & hashdyn->bucket_mask; + tommy_size_t pos = node->index & hashdyn->bucket_mask; tommy_list_remove_existing(&hashdyn->bucket[pos], node); @@ -162,12 +162,12 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) { - tommy_count_t pos = hash & hashdyn->bucket_mask; + tommy_size_t pos = hash & hashdyn->bucket_mask; tommy_hashdyn_node* node = hashdyn->bucket[pos]; while (node) { /* we first check if the hash matches, as in the same bucket we may have multiples hash values */ - if (node->key == hash && cmp(cmp_arg, node->data) == 0) { + if (node->index == hash && cmp(cmp_arg, node->data) == 0) { tommy_list_remove_existing(&hashdyn->bucket[pos], node); --hashdyn->count; @@ -184,9 +184,9 @@ void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func) { - tommy_count_t bucket_max = hashdyn->bucket_max; + tommy_size_t bucket_max = hashdyn->bucket_max; tommy_hashdyn_node** bucket = hashdyn->bucket; - tommy_count_t pos; + tommy_size_t pos; for (pos = 0; pos < bucket_max; ++pos) { tommy_hashdyn_node* node = bucket[pos]; @@ -201,9 +201,9 @@ void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func) void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg) { - tommy_count_t bucket_max = hashdyn->bucket_max; + tommy_size_t bucket_max = hashdyn->bucket_max; tommy_hashdyn_node** bucket = hashdyn->bucket; - tommy_count_t pos; + tommy_size_t pos; for (pos = 0; pos < bucket_max; ++pos) { tommy_hashdyn_node* node = bucket[pos]; diff --git a/tommyds/tommyhashdyn.h b/tommyds/tommyhashdyn.h index ed4a6074..73baba97 100644 --- a/tommyds/tommyhashdyn.h +++ b/tommyds/tommyhashdyn.h @@ -160,10 +160,10 @@ typedef tommy_node tommy_hashdyn_node; */ typedef struct tommy_hashdyn_struct { tommy_hashdyn_node** bucket; /**< Hash buckets. One list for each hash modulus. */ + tommy_size_t bucket_max; /**< Number of buckets. */ + tommy_size_t bucket_mask; /**< Bit mask to access the buckets. */ + tommy_size_t count; /**< Number of elements. */ tommy_uint_t bucket_bit; /**< Bits used in the bit mask. */ - tommy_count_t bucket_max; /**< Number of buckets. */ - tommy_count_t bucket_mask; /**< Bit mask to access the buckets. */ - tommy_count_t count; /**< Number of elements. */ } tommy_hashdyn; /** @@ -226,7 +226,7 @@ tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_fun while (i) { /* we first check if the hash matches, as in the same bucket we may have multiples hash values */ - if (i->key == hash && cmp(cmp_arg, i->data) == 0) + if (i->index == hash && cmp(cmp_arg, i->data) == 0) return i->data; i = i->next; } @@ -281,7 +281,7 @@ void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* f /** * Gets the number of elements. */ -tommy_inline tommy_count_t tommy_hashdyn_count(tommy_hashdyn* hashdyn) +tommy_inline tommy_size_t tommy_hashdyn_count(tommy_hashdyn* hashdyn) { return hashdyn->count; } diff --git a/tommyds/tommylist.h b/tommyds/tommylist.h index 368606a9..42ef3ad1 100644 --- a/tommyds/tommylist.h +++ b/tommyds/tommylist.h @@ -311,9 +311,9 @@ tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list) * Gets the number of elements. * \note This operation is O(n). */ -tommy_inline tommy_count_t tommy_list_count(tommy_list* list) +tommy_inline tommy_size_t tommy_list_count(tommy_list* list) { - tommy_count_t count = 0; + tommy_size_t count = 0; tommy_node* i = tommy_list_head(list); while (i) { diff --git a/tommyds/tommytree.c b/tommyds/tommytree.c index 6b2f1a99..8ef84783 100644 --- a/tommyds/tommytree.c +++ b/tommyds/tommytree.c @@ -39,10 +39,10 @@ void tommy_tree_init(tommy_tree* tree, tommy_compare_func* cmp) tree->cmp = cmp; } -static int tommy_tree_delta(tommy_tree_node* root) +static tommy_ssize_t tommy_tree_delta(tommy_tree_node* root) { - int left_height = root->prev ? root->prev->key : 0; - int right_height = root->next ? root->next->key : 0; + tommy_ssize_t left_height = root->prev ? root->prev->index : 0; + tommy_ssize_t right_height = root->next ? root->next->index : 0; return left_height - right_height; } @@ -84,7 +84,7 @@ static tommy_tree_node* tommy_tree_move_right(tommy_tree_node* root, tommy_tree_ static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root) { - int delta = tommy_tree_delta(root); + tommy_ssize_t delta = tommy_tree_delta(root); if (delta < -1) { if (tommy_tree_delta(root->next) > 0) @@ -99,16 +99,16 @@ static tommy_tree_node* tommy_tree_balance(tommy_tree_node* root) } /* recompute key */ - root->key = 0; + root->index = 0; - if (root->prev && root->prev->key > root->key) - root->key = root->prev->key; + if (root->prev && root->prev->index > root->index) + root->index = root->prev->index; - if (root->next && root->next->key > root->key) - root->key = root->next->key; + if (root->next && root->next->index > root->index) + root->index = root->next->index; /* count itself */ - root->key += 1; + root->index += 1; return root; } @@ -145,7 +145,7 @@ void* tommy_tree_insert(tommy_tree* tree, tommy_tree_node* node, void* data) insert->data = data; insert->prev = 0; insert->next = 0; - insert->key = 0; + insert->index = 0; tree->root = tommy_tree_insert_node(tree->cmp, tree->root, &insert); diff --git a/tommyds/tommytree.h b/tommyds/tommytree.h index 55e40060..ada12c06 100644 --- a/tommyds/tommytree.h +++ b/tommyds/tommytree.h @@ -117,8 +117,8 @@ typedef tommy_node tommy_tree_node; */ typedef struct tommy_tree_struct { tommy_tree_node* root; /**< Root node. */ - tommy_count_t count; /**< Number of elements. */ tommy_compare_func* cmp; /**< Comparison function. */ + tommy_size_t count; /**< Number of elements. */ } tommy_tree; /** @@ -213,7 +213,7 @@ void tommy_tree_foreach_arg(tommy_tree* tree, tommy_foreach_arg_func* func, void /** * Gets the number of elements. */ -tommy_inline tommy_count_t tommy_tree_count(tommy_tree* tree) +tommy_inline tommy_size_t tommy_tree_count(tommy_tree* tree) { return tree->count; } diff --git a/tommyds/tommytypes.h b/tommyds/tommytypes.h index ff834cf6..0608b15a 100644 --- a/tommyds/tommytypes.h +++ b/tommyds/tommytypes.h @@ -24,7 +24,6 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - /** \file * Generic types. */ @@ -37,17 +36,37 @@ #include -#if defined(_MSC_VER) +#ifdef _MSC_VER typedef unsigned tommy_uint32_t; /**< Generic uint32_t type. */ typedef unsigned _int64 tommy_uint64_t; /**< Generic uint64_t type. */ typedef size_t tommy_uintptr_t; /**< Generic uintptr_t type. */ +#ifdef _WIN64 +#define TOMMY_SIZE_BIT 64 +typedef unsigned _int64_t tommy_size_t; /**< Generic size_t type. */ +typedef _int64_t tommy_ssize_t; /**< Generic ssize_t type. */ +#else +#define TOMMY_SIZE_BIT 32 +typedef unsigned tommy_size_t; /**< Generic size_t type. */ +typedef int tommy_ssize_t; /**< Generic ssize_t type. */ +#endif #else #include typedef uint32_t tommy_uint32_t; /**< Generic uint32_t type. */ typedef uint64_t tommy_uint64_t; /**< Generic uint64_t type. */ typedef uintptr_t tommy_uintptr_t; /**< Generic uintptr_t type. */ +#if SIZE_MAX == UINT64_MAX +#define TOMMY_SIZE_BIT 64 +typedef uint64_t tommy_size_t; /**< Generic size_t type. */ +typedef int64_t tommy_ssize_t; /**< Generic ssize_t type. */ +#elif SIZE_MAX == UINT32_MAX +#define TOMMY_SIZE_BIT 32 +typedef uint32_t tommy_size_t; /**< Generic size_t type. */ +typedef int32_t tommy_ssize_t; /**< Generic ssize_t type. */ +#else +#error Unsupported SIZE_MAX #endif -typedef size_t tommy_size_t; /**< Generic size_t type. */ +#endif + typedef ptrdiff_t tommy_ptrdiff_t; /**< Generic ptrdiff_t type. */ typedef int tommy_bool_t; /**< Generic boolean type. */ @@ -59,13 +78,6 @@ typedef int tommy_bool_t; /**< Generic boolean type. */ */ typedef tommy_uint32_t tommy_uint_t; -/** - * Generic unsigned integer for counting objects. - * - * TommyDS doesn't support more than 2^32-1 objects. - */ -typedef tommy_uint32_t tommy_count_t; - /** \internal * Type cast required for the C++ compilation. * When compiling in C++ we cannot convert a void* pointer to another pointer. @@ -152,17 +164,17 @@ typedef tommy_uint32_t tommy_count_t; #endif /******************************************************************************/ -/* key */ +/* key/hash */ /** - * Key type used in indexed data structures to store the key or the hash value. + * Type used in indexed data structures to store the key of a object. */ -typedef tommy_uint32_t tommy_key_t; +typedef tommy_size_t tommy_key_t; /** - * Bits into the ::tommy_key_t type. + * Type used in hashtables to store the hash of a object. */ -#define TOMMY_KEY_BIT (sizeof(tommy_key_t) * 8) +typedef tommy_size_t tommy_hash_t; /******************************************************************************/ /* node */ @@ -200,11 +212,12 @@ typedef struct tommy_node_struct { void* data; /** - * Key used to store the node. + * Index of the node. + * With tries this field is used to store the key. * With hashtables this field is used to store the hash value. * With lists this field is not used. */ - tommy_key_t key; + tommy_size_t index; } tommy_node; /******************************************************************************/ @@ -302,6 +315,10 @@ typedef void tommy_foreach_arg_func(void* arg, void* obj); #include #pragma intrinsic(_BitScanReverse) #pragma intrinsic(_BitScanForward) +#if TOMMY_SIZE_BIT == 64 +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_BitScanForward64) +#endif #endif /** \internal @@ -363,6 +380,29 @@ tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value) #endif } +#if TOMMY_SIZE_BIT == 64 +/** + * Bit scan reverse or integer log2 for 64 bits. + */ +tommy_inline tommy_uint_t tommy_ilog2_u64(tommy_uint64_t value) +{ +#if defined(_MSC_VER) + unsigned long count; + _BitScanReverse64(&count, value); + return count; +#elif defined(__GNUC__) + return __builtin_clzll(value) ^ 63; +#else + uint32_t l = value & 0xFFFFFFFFU; + uint32_t h = value >> 32; + if (h) + return tommy_ilog2_u32(h) + 32; + else + return tommy_ilog2_u32(l); +#endif +} +#endif + /** * Bit scan forward or trailing zero count. * Return the bit index of the least significant 1 bit. @@ -391,6 +431,29 @@ tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value) #endif } +#if TOMMY_SIZE_BIT == 64 +/** + * Bit scan forward or trailing zero count for 64 bits. + */ +tommy_inline tommy_uint_t tommy_ctz_u64(tommy_uint64_t value) +{ +#if defined(_MSC_VER) + unsigned long count; + _BitScanForward64(&count, value); + return count; +#elif defined(__GNUC__) + return __builtin_ctzll(value); +#else + uint32_t l = value & 0xFFFFFFFFU; + uint32_t h = value >> 32; + if (l) + return tommy_ctz_u32(l); + else + return tommy_ctz_u32(h) + 32; +#endif +} +#endif + /** * Rounds up to the next power of 2. * For the value 0, the result is undefined. @@ -412,6 +475,23 @@ tommy_inline tommy_uint32_t tommy_roundup_pow2_u32(tommy_uint32_t value) return value; } +/** + * Rounds up to the next power of 2 for 64 bits. + */ +tommy_inline tommy_uint64_t tommy_roundup_pow2_u64(tommy_uint64_t value) +{ + --value; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value |= value >> 32; + ++value; + + return value; +} + /** * Check if the specified word has a byte at 0. * \return 0 or 1. @@ -420,5 +500,19 @@ tommy_inline int tommy_haszero_u32(tommy_uint32_t value) { return ((value - 0x01010101) & ~value & 0x80808080) != 0; } + +/* + * Bit depth mapping. + */ +#if TOMMY_SIZE_BIT == 64 +#define tommy_ilog2 tommy_ilog2_u64 +#define tommy_ctz tommy_ctz_u64 +#define tommy_roundup_pow2 tommy_roundup_pow2_u64 +#else +#define tommy_ilog2 tommy_ilog2_u32 +#define tommy_ctz tommy_ctz_u32 +#define tommy_roundup_pow2 tommy_roundup_pow2_u32 +#endif + #endif