Updates to latest TommyDS version.

This commit is contained in:
Andrea Mazzoleni 2014-10-25 17:28:41 +02:00
parent acb1bad9b0
commit aff9f97d50
11 changed files with 188 additions and 117 deletions

View file

@ -27,14 +27,12 @@
#include "tommyarray.h"
#include <stddef.h> /* for ptrdiff_t */
/******************************************************************************/
/* array */
void tommy_array_init(tommy_array* array)
{
unsigned i;
tommy_uint_t i;
/* fixed initial size */
array->bucket_bit = TOMMY_ARRAY_BIT;
@ -43,28 +41,27 @@ void tommy_array_init(tommy_array* array)
for (i = 1; i < TOMMY_ARRAY_BIT; ++i)
array->bucket[i] = array->bucket[0];
array->bucket_mac = TOMMY_ARRAY_BIT;
array->size = 0;
array->count = 0;
}
void tommy_array_done(tommy_array* array)
{
unsigned i;
tommy_uint_t i;
tommy_free(array->bucket[0]);
for (i = TOMMY_ARRAY_BIT; i < array->bucket_mac; ++i) {
for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) {
void** segment = array->bucket[i];
tommy_free(&segment[1 << i]);
tommy_free(&segment[((tommy_ptrdiff_t)1) << i]);
}
}
void tommy_array_grow(tommy_array* array, unsigned size)
void tommy_array_grow(tommy_array* array, tommy_count_t count)
{
if (array->size >= size)
if (array->count >= count)
return;
array->size = size;
array->count = count;
while (size > array->bucket_max) {
while (count > array->bucket_max) {
void** segment;
/* allocate one more segment */
@ -72,9 +69,8 @@ void tommy_array_grow(tommy_array* array, unsigned size)
/* store it adjusting the offset */
/* cast to ptrdiff_t to ensure to get a negative value */
array->bucket[array->bucket_mac] = &segment[-(ptrdiff_t)array->bucket_max];
array->bucket[array->bucket_bit] = &segment[-(tommy_ptrdiff_t)array->bucket_max];
++array->bucket_mac;
++array->bucket_bit;
array->bucket_max = 1 << array->bucket_bit;
}

View file

@ -28,11 +28,11 @@
/** \file
* Dynamic array based on segments of exponential growing size.
*
* This array is able to grow dynamically upon request.
* This array is able to grow dynamically upon request, without any reallocation.
*
* The resize involve an allocation of a new array segment, without reallocating
* the already allocated memory, and then not increasing the heap fragmentation.
* This means that the address of the allocated segments never change.
* The grow operation involves an allocation of a new array segment, without reallocating
* the already used memory, and then not increasing the heap fragmentation.
* This also implies that the address of the stored elements never change.
*
* Allocated segments grow in size exponentially.
*/
@ -59,14 +59,14 @@
#define TOMMY_ARRAY_BIT_MAX 32
/**
* Array.
* 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. */
unsigned bucket_bit; /**< Bits used in the bit mask. */
unsigned bucket_max; /**< Number of buckets. */
unsigned bucket_mac; /**< Number of vectors allocated. */
unsigned size; /**< Currently allocated and initialized size. */
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;
/**
@ -80,21 +80,21 @@ void tommy_array_init(tommy_array* array);
void tommy_array_done(tommy_array* array);
/**
* Grow the size up to the specified value.
* 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, unsigned size);
void tommy_array_grow(tommy_array* array, tommy_count_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, unsigned pos)
tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos)
{
unsigned bsr;
tommy_uint_t bsr;
assert(pos < array->size);
assert(pos < array->count);
/* get the highest bit set, in case of all 0, return 0 */
bsr = tommy_ilog2_u32(pos | 1);
@ -107,7 +107,7 @@ tommy_inline void** tommy_array_ref(tommy_array* array, unsigned 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, unsigned pos, void* element)
tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element)
{
*tommy_array_ref(array, pos) = element;
}
@ -117,7 +117,7 @@ tommy_inline void tommy_array_set(tommy_array* array, unsigned pos, void* elemen
* 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, unsigned pos)
tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos)
{
return *tommy_array_ref(array, pos);
}
@ -127,7 +127,7 @@ tommy_inline void* tommy_array_get(tommy_array* array, unsigned pos)
*/
tommy_inline void tommy_array_insert(tommy_array* array, void* element)
{
unsigned pos = array->size;
tommy_count_t pos = array->count;
tommy_array_grow(array, pos + 1);
@ -137,9 +137,9 @@ tommy_inline void tommy_array_insert(tommy_array* array, void* element)
/**
* Gets the initialized size of the array.
*/
tommy_inline unsigned tommy_array_size(tommy_array* array)
tommy_inline tommy_count_t tommy_array_size(tommy_array* array)
{
return array->size;
return array->count;
}
/**

View file

@ -34,12 +34,12 @@ void tommy_arrayblk_init(tommy_arrayblk* array)
{
tommy_array_init(&array->block);
array->size = 0;
array->count = 0;
}
void tommy_arrayblk_done(tommy_arrayblk* array)
{
unsigned i;
tommy_count_t i;
for (i = 0; i < tommy_array_size(&array->block); ++i)
tommy_free(tommy_array_get(&array->block, i));
@ -47,16 +47,16 @@ void tommy_arrayblk_done(tommy_arrayblk* array)
tommy_array_done(&array->block);
}
void tommy_arrayblk_grow(tommy_arrayblk* array, unsigned size)
void tommy_arrayblk_grow(tommy_arrayblk* array, tommy_count_t count)
{
unsigned block_max;
unsigned block_mac;
tommy_count_t block_max;
tommy_count_t block_mac;
if (array->size >= size)
if (array->count >= count)
return;
array->size = size;
array->count = count;
block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
block_max = (count + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
block_mac = tommy_array_size(&array->block);
if (block_mac < block_max) {

View file

@ -26,16 +26,16 @@
*/
/** \file
* Dynamic array based on blocks of fixed sizes.
* Dynamic array based on blocks of fixed size.
*
* This array is able to grow dynamically upon request.
* This array is able to grow dynamically upon request, without any reallocation.
*
* The resize involve an allocation of a new array block, without reallocating
* the already allocated memory, and then not increasing the heap fragmentation,
* The grow operation involves an allocation of a new array block, without reallocating
* the already used memory, and then not increasing the heap fragmentation,
* and minimize the space occupation.
* This means that the address of the allocated blocks never change.
* This also implies that the address of the stored elements never change.
*
* Allocated blocks are always of the same fixed size of 64 Ki pointers.
* Allocated blocks are always of the same fixed size of 4 Ki pointers.
*/
#ifndef __TOMMYARRAYBLK_H
@ -55,11 +55,12 @@
#define TOMMY_ARRAYBLK_SIZE (4 * 1024)
/**
* Array.
* Array container type.
* \note Don't use internal fields directly, but access the container only using functions.
*/
typedef struct tommy_arrayblk_struct {
tommy_array block; /**< Array of blocks. */
unsigned size; /**< Currently allocated and initialized size. */
tommy_count_t count; /**< Number of initialized elements in the array. */
} tommy_arrayblk;
/**
@ -73,21 +74,21 @@ void tommy_arrayblk_init(tommy_arrayblk* array);
void tommy_arrayblk_done(tommy_arrayblk* array);
/**
* Grow the size up to the specified value.
* Grows the size up to the specified value.
* All the new elements in the array are initialized with the 0 value.
*/
void tommy_arrayblk_grow(tommy_arrayblk* array, unsigned size);
void tommy_arrayblk_grow(tommy_arrayblk* array, tommy_count_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_arrayblk_grow().
*/
tommy_inline void** tommy_arrayblk_ref(tommy_arrayblk* array, unsigned pos)
tommy_inline void** tommy_arrayblk_ref(tommy_arrayblk* array, tommy_count_t pos)
{
void** ptr;
assert(pos < array->size);
assert(pos < array->count);
ptr = tommy_cast(void**, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLK_SIZE));
@ -99,7 +100,7 @@ tommy_inline void** tommy_arrayblk_ref(tommy_arrayblk* array, unsigned pos)
* You must be sure that space for this position is already
* allocated calling tommy_arrayblk_grow().
*/
tommy_inline void tommy_arrayblk_set(tommy_arrayblk* array, unsigned pos, void* element)
tommy_inline void tommy_arrayblk_set(tommy_arrayblk* array, tommy_count_t pos, void* element)
{
*tommy_arrayblk_ref(array, pos) = element;
}
@ -109,7 +110,7 @@ tommy_inline void tommy_arrayblk_set(tommy_arrayblk* array, unsigned pos, void*
* You must be sure that space for this position is already
* allocated calling tommy_arrayblk_grow().
*/
tommy_inline void* tommy_arrayblk_get(tommy_arrayblk* array, unsigned pos)
tommy_inline void* tommy_arrayblk_get(tommy_arrayblk* array, tommy_count_t pos)
{
return *tommy_arrayblk_ref(array, pos);
}
@ -119,7 +120,7 @@ tommy_inline void* tommy_arrayblk_get(tommy_arrayblk* array, unsigned pos)
*/
tommy_inline void tommy_arrayblk_insert(tommy_arrayblk* array, void* element)
{
unsigned pos = array->size;
tommy_count_t pos = array->count;
tommy_arrayblk_grow(array, pos + 1);
@ -129,9 +130,9 @@ tommy_inline void tommy_arrayblk_insert(tommy_arrayblk* array, void* element)
/**
* Gets the initialized size of the array.
*/
tommy_inline unsigned tommy_arrayblk_size(tommy_arrayblk* array)
tommy_inline tommy_count_t tommy_arrayblk_size(tommy_arrayblk* array)
{
return array->size;
return array->count;
}
/**

View file

@ -30,16 +30,17 @@
/******************************************************************************/
/* array */
void tommy_arrayblkof_init(tommy_arrayblkof* array, unsigned element_size)
void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size)
{
tommy_array_init(&array->block);
array->element_size = element_size;
array->size = 0;
array->count = 0;
}
void tommy_arrayblkof_done(tommy_arrayblkof* array)
{
unsigned i;
tommy_count_t i;
for (i = 0; i < tommy_array_size(&array->block); ++i)
tommy_free(tommy_array_get(&array->block, i));
@ -47,16 +48,16 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array)
tommy_array_done(&array->block);
}
void tommy_arrayblkof_grow(tommy_arrayblkof* array, unsigned size)
void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count)
{
unsigned block_max;
unsigned block_mac;
tommy_count_t block_max;
tommy_count_t block_mac;
if (array->size >= size)
if (array->count >= count)
return;
array->size = size;
array->count = count;
block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
block_max = (count + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
block_mac = tommy_array_size(&array->block);
if (block_mac < block_max) {

View file

@ -26,15 +26,16 @@
*/
/** \file
* Dynamic array based on blocks of fixed sizes.
* Dynamic array based on blocks of fixed size.
*
* This array is able to grow dynamically upon request.
* This array is able to grow dynamically upon request, without any reallocation.
*
* This is very similar at ::tommy_arrayblk, but it allows to store elements of any
* size and not just pointers.
*
* Note that in this case tommy_arrayblkof_ref() returns a pointer at the element,
* and it should be used for both get() and set() operation.
* that should be used for getting and setting elements in the array,
* as generic getter and setter are not available.
*/
#ifndef __TOMMYARRAYBLKOF_H
@ -54,19 +55,20 @@
#define TOMMY_ARRAYBLKOF_SIZE (4 * 1024)
/**
* Array.
* Array container type.
* \note Don't use internal fields directly, but access the container only using functions.
*/
typedef struct tommy_arrayblkof_struct {
tommy_array block; /**< Array of blocks. */
unsigned element_size; /**< Size of the stored element in bytes. */
unsigned size; /**< Currently allocated and initialized size. */
tommy_size_t element_size; /**< Size of the stored element in bytes. */
tommy_count_t count; /**< Number of initialized elements in the array. */
} tommy_arrayblkof;
/**
* Initializes the array.
* \param element_size Size in byte of the element to store in the array.
*/
void tommy_arrayblkof_init(tommy_arrayblkof* array, unsigned element_size);
void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size);
/**
* Deinitializes the array.
@ -74,21 +76,21 @@ void tommy_arrayblkof_init(tommy_arrayblkof* array, unsigned element_size);
void tommy_arrayblkof_done(tommy_arrayblkof* array);
/**
* Grow the size up to the specified value.
* 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, unsigned size);
void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_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, unsigned pos)
tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos)
{
unsigned char* base;
assert(pos < array->size);
assert(pos < array->count);
base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE));
@ -98,9 +100,9 @@ tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, unsigned pos)
/**
* Gets the initialized size of the array.
*/
tommy_inline unsigned tommy_arrayblkof_size(tommy_arrayblkof* array)
tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array)
{
return array->size;
return array->count;
}
/**

View file

@ -167,11 +167,11 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func*
* Value stored inside the bit bucket.
* It's used to know which bucket is empty of full.
*/
unsigned counter;
tommy_count_t counter;
tommy_node* node = chain->head;
tommy_node* tail = chain->tail;
unsigned mask;
unsigned i;
tommy_count_t mask;
tommy_count_t i;
counter = 0;
while (1) {

View file

@ -50,12 +50,12 @@ void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
/**
* Resize the bucket vector.
*/
static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit)
static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit)
{
unsigned bucket_bit;
unsigned bucket_max;
unsigned new_bucket_max;
unsigned new_bucket_mask;
tommy_count_t bucket_bit;
tommy_count_t bucket_max;
tommy_count_t new_bucket_max;
tommy_count_t new_bucket_mask;
tommy_hashdyn_node** new_bucket;
bucket_bit = hashdyn->bucket_bit;
@ -70,7 +70,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit
/* reinsert all the elements */
if (new_bucket_bit > bucket_bit) {
unsigned i;
tommy_count_t i;
/* grow */
for (i = 0; i < bucket_max; ++i) {
@ -84,7 +84,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit
j = hashdyn->bucket[i];
while (j) {
tommy_hashdyn_node* j_next = j->next;
unsigned index = j->key & new_bucket_mask;
tommy_count_t index = j->key & new_bucket_mask;
if (new_bucket[index])
tommy_list_insert_tail_not_empty(new_bucket[index], j);
else
@ -93,7 +93,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit
}
}
} else {
unsigned i;
tommy_count_t i;
/* shrink */
for (i = 0; i < new_bucket_max; ++i) {
@ -138,7 +138,7 @@ 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)
{
unsigned pos = hash & hashdyn->bucket_mask;
tommy_count_t pos = hash & hashdyn->bucket_mask;
tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
@ -151,7 +151,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)
{
unsigned pos = node->key & hashdyn->bucket_mask;
tommy_count_t pos = node->key & hashdyn->bucket_mask;
tommy_list_remove_existing(&hashdyn->bucket[pos], node);
@ -164,7 +164,7 @@ 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)
{
unsigned pos = hash % hashdyn->bucket_max;
tommy_count_t pos = hash % hashdyn->bucket_max;
tommy_hashdyn_node* node = hashdyn->bucket[pos];
while (node) {
@ -186,9 +186,9 @@ void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const
void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
{
unsigned bucket_max = hashdyn->bucket_max;
tommy_count_t bucket_max = hashdyn->bucket_max;
tommy_hashdyn_node** bucket = hashdyn->bucket;
unsigned pos;
tommy_count_t pos;
for (pos = 0; pos < bucket_max; ++pos) {
tommy_hashdyn_node* node = bucket[pos];
@ -203,9 +203,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)
{
unsigned bucket_max = hashdyn->bucket_max;
tommy_count_t bucket_max = hashdyn->bucket_max;
tommy_hashdyn_node** bucket = hashdyn->bucket;
unsigned pos;
tommy_count_t pos;
for (pos = 0; pos < bucket_max; ++pos) {
tommy_hashdyn_node* node = bucket[pos];

View file

@ -114,7 +114,7 @@
* and remove.
*
* \code
* struct object* obj = tommy_trie_remove(&hashtable, compare, &value_to_remove, tommy_inthash_u32(value_to_remove));
* struct object* obj = tommy_hashdyn_remove(&hashdyn, compare, &value_to_remove, tommy_inthash_u32(value_to_remove));
* if (obj) {
* free(obj); // frees the object allocated memory
* }
@ -127,9 +127,11 @@
* tommy_hashdyn_done(&hashdyn);
* \endcode
*
* Note that you cannot iterates over all the elements in the hashtable using the
* hashtable itself. You have to insert all the elements also in a ::tommy_list,
* and use the list to iterate. See the \ref multiindex example for more detail.
* If you need to iterate over all the elements in the hashtable, you can use
* tommy_hashdyn_foreach() or tommy_hashdyn_foreach_arg().
* If you need a more precise control with a real iteration, you have to insert
* all the elements also in a ::tommy_list, and use the list to iterate.
* See the \ref multiindex example for more detail.
*/
#ifndef __TOMMYHASHDYN_H
@ -147,20 +149,21 @@
#define TOMMY_HASHDYN_BIT 4
/**
* Dynamic hashtable node.
* Hashtable node.
* This is the node that you have to include inside your objects.
*/
typedef tommy_node tommy_hashdyn_node;
/**
* Dynamic chained hashtable.
* Hashtable container type.
* \note Don't use internal fields directly, but access the container only using functions.
*/
typedef struct tommy_hashdyn_struct {
tommy_hashdyn_node** bucket; /**< Hash buckets. One list for each hash modulus. */
unsigned bucket_bit; /**< Bits used in the bit mask. */
unsigned bucket_max; /**< Number of buckets. */
unsigned bucket_mask; /**< Bit mask to access the buckets. */
unsigned 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;
/**
@ -240,6 +243,33 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node*
/**
* Calls the specified function for each element in the hashtable.
*
* You can use this function to deallocate all the elements inserted.
*
* \code
* tommy_hashdyn hashdyn;
*
* // initializes the hashtable
* tommy_hashdyn_init(&hashdyn);
*
* ...
*
* // creates an object
* struct object* obj = malloc(sizeof(struct object));
*
* ...
*
* // insert it in the hashtable
* tommy_hashdyn_insert(&hashdyn, &obj->node, obj, tommy_inthash_u32(obj->value));
*
* ...
*
* // deallocates all the objects iterating the hashtable
* tommy_hashdyn_foreach(&hashdyn, free);
*
* // deallocates the hashtable
* tommy_hashdyn_done(&hashdyn);
* \endcode
*/
void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func);
@ -251,7 +281,7 @@ void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* f
/**
* Gets the number of elements.
*/
tommy_inline unsigned tommy_hashdyn_count(tommy_hashdyn* hashdyn)
tommy_inline tommy_count_t tommy_hashdyn_count(tommy_hashdyn* hashdyn)
{
return hashdyn->count;
}

View file

@ -108,7 +108,7 @@
/* list */
/**
* Double linked list for collisions into hashtables.
* Double linked list type.
*/
typedef tommy_node* tommy_list;
@ -309,6 +309,31 @@ tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
/**
* Calls the specified function for each element in the list.
*
* You can use this function to deallocate all the elements
* inserted in a list.
*
* \code
* tommy_list list;
*
* // initializes the list
* tommy_list_init(&list);
*
* ...
*
* // creates an object
* struct object* obj = malloc(sizeof(struct object));
*
* ...
*
* // insert it in the list
* tommy_list_insert_tail(&list, &obj->node, obj);
*
* ...
*
* // deallocates all the objects iterating the list
* tommy_list_foreach(&list, free);
* \endcode
*/
tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func)
{

View file

@ -35,21 +35,37 @@
/******************************************************************************/
/* types */
#if defined(_MSC_VER)
#include <stddef.h>
#if defined(_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_size_t; /**< Generic size_t type. */
typedef size_t tommy_uintptr_t; /**< Generic uintptr_t type. */
#else
#include <stdint.h>
typedef uint32_t tommy_uint32_t; /**< Generic uint32_t type. */
typedef uint64_t tommy_uint64_t; /**< Generic uint64_t type. */
typedef uintptr_t tommy_size_t; /**< Generic size_t type. */
typedef uintptr_t tommy_uintptr_t; /**< Generic uintptr_t type. */
#endif
typedef size_t tommy_size_t; /**< Generic size_t type. */
typedef ptrdiff_t tommy_ptrdiff_t; /**< Generic ptrdiff_t type. */
typedef int tommy_bool_t; /**< Generic boolean type. */
/**
* Generic unsigned integer type.
*
* It has no specific size, as is used to store only small values.
* To make the code more efficient, a full 32 bit integer is used.
*/
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.
@ -307,7 +323,7 @@ typedef void tommy_foreach_arg_func(void* arg, void* obj);
* \param value Value to scan. 0 is not allowed.
* \return The index of the most significan bit set.
*/
tommy_inline unsigned tommy_ilog2_u32(tommy_uint32_t value)
tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
{
#if defined(_MSC_VER)
unsigned long count;
@ -326,7 +342,7 @@ tommy_inline unsigned tommy_ilog2_u32(tommy_uint32_t value)
#else
/* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */
/* from http://graphics.stanford.edu/~seander/bithacks.html */
static const int TOMMY_DE_BRUIJN_INDEX_ILOG2[32] = {
static unsigned char TOMMY_DE_BRUIJN_INDEX_ILOG2[32] = {
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
@ -349,7 +365,7 @@ tommy_inline unsigned tommy_ilog2_u32(tommy_uint32_t value)
* \param value Value to scan. 0 is not allowed.
* \return The index of the least significant bit set.
*/
tommy_inline unsigned tommy_ctz_u32(tommy_uint32_t value)
tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value)
{
#if defined(_MSC_VER)
unsigned long count;
@ -360,7 +376,7 @@ tommy_inline unsigned tommy_ctz_u32(tommy_uint32_t value)
#else
/* Count the consecutive zero bits (trailing) on the right with multiply and lookup */
/* from http://graphics.stanford.edu/~seander/bithacks.html */
static const tommy_uint32_t TOMMY_DE_BRUIJN_INDEX_CTZ[32] = {
static const unsigned char TOMMY_DE_BRUIJN_INDEX_CTZ[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};