rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 3b842a9edf5ed77150331560b805f367d7b95ce0
parent 329b872bef8fa8997d024fab6f5699061d711035
Author: vaplv <vaplv@free.fr>
Date:   Tue, 18 Feb 2014 16:44:34 +0100

Test and fix the dynamic arrays

Add basic mathematic functions

Diffstat:
Msrc/dynamic_array.h | 30+++++++++++++++---------------
Asrc/math.h | 38++++++++++++++++++++++++++++++++++++++
Msrc/test_dynamic_array.c | 21++++++++++++++++++---
3 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/src/dynamic_array.h b/src/dynamic_array.h @@ -2,6 +2,7 @@ #ifndef DYNAMIC_ARRAY_H #define DYNAMIC_ARRAY_H +#include "math.h" #include "mem_allocator.h" #include "rsys.h" #include <string.h> @@ -26,6 +27,7 @@ struct DARRAY_TYPE__ { DARRAY_DATA_TYPE* data; + DARRAY_DATA_TYPE buf[16]; /* Static buffer. Avoid mem alloc on small arrays */ size_t size; size_t capacity; struct mem_allocator* allocator; @@ -37,9 +39,9 @@ DARRAY_FUNC__(init) struct DARRAY_TYPE__* darray) { ASSERT(darray); - darray->data = NULL; + darray->data = darray->buf; darray->size = 0; - darray->capacity = 0; + darray->capacity = sizeof(darray->buf)/sizeof(DARRAY_DATA_TYPE); darray->allocator = allocator ? allocator : &mem_default_allocator; } @@ -47,7 +49,8 @@ static FINLINE void DARRAY_FUNC__(release)(struct DARRAY_TYPE__* darray) { ASSERT(darray); - MEM_FREE(darray->allocator, darray->data); + if( darray->data != darray->buf ) + MEM_FREE(darray->allocator, darray->data); } static FINLINE void @@ -58,33 +61,30 @@ DARRAY_FUNC__(clear)(struct DARRAY_TYPE__* darray) } static FINLINE char -DARRAY_FUNC__(is_empty)(struct DARRAY_TYPE__* darray) -{ - ASSERT(darray); - return darray->size == 0; -} - -static FINLINE char DARRAY_FUNC__(reserve)(struct DARRAY_TYPE__* darray, const size_t sz) { DARRAY_DATA_TYPE* data = NULL; + size_t sz_adjusted; ASSERT(darray); + if(sz <= darray->capacity) return 0; + sz_adjusted = round_up_pow2(sz); data = MEM_ALLOC_ALIGNED (darray->allocator, - sz * sizeof(DARRAY_DATA_TYPE), + sz_adjusted * sizeof(DARRAY_DATA_TYPE), ALIGNOF(DARRAY_DATA_TYPE)); if(!data) return -1; - if(darray->data) { + if(darray->size) memcpy(data, darray->data, darray->size * sizeof(DARRAY_DATA_TYPE)); + if(darray->data != darray->buf) MEM_FREE(darray->allocator, darray->data); - } + darray->data = data; - darray->capacity = sz; + darray->capacity = sz_adjusted; return 0; } @@ -98,7 +98,7 @@ DARRAY_FUNC__(push_back) i = darray->size + 1; if(DARRAY_FUNC__(reserve)(darray, i)) return -1; - darray->data[i] = *data; + darray->data[darray->size] = *data; darray->size = i; return 0; } diff --git a/src/math.h b/src/math.h @@ -0,0 +1,38 @@ +#ifndef MATH_H +#define MATH_H + +#include "rsys.h" + +static FINLINE char +is_power_of_2(const size_t i) +{ + return (i & (i-1)) == 0 && i > 0; +} + +static FINLINE size_t +round_up_pow2(const size_t i) +{ + size_t j = i - 1; + unsigned k; + for(k = 1; k < sizeof(int)*8; k <<= 1) { + j |= j >> k; + } + return j + 1; +} + +static FINLINE float +absf(const float flt) +{ + union { float f; int32_t i; } ucast; + ucast.f = flt; + ucast.i &= 0x7FFFFFFF; + return ucast.f; +} + +static FINLINE char +eq_eps(const float a, const float b, const float eps) +{ + return absf(a - b) <= eps; +} + +#endif /* MATH_H */ diff --git a/src/test_dynamic_array.c b/src/test_dynamic_array.c @@ -28,13 +28,28 @@ main(int argc, char** argv) mem_init_proxy_allocator(&allocator_proxy, &mem_default_allocator); - darray_str_init(&mem_default_allocator, &darray); - CHECK(darray_str_is_empty(&darray), 1); + darray_str_init(NULL, &darray); + CHECK(darray_str_size_get(&darray), 0); + darray_str_clear(&darray); + CHECK(darray_str_size_get(&darray), 0); - FOR_EACH(i, 0, nstrs) { + FOR_EACH(i, 0, 4) { darray_str_push_back(&darray, str + i); } + CHECK(darray_str_size_get(&darray), 4); + darray_str_clear(&darray); + CHECK(darray_str_size_get(&darray), 0); + darray_str_release(&darray); + darray_str_init(&mem_default_allocator, &darray); + FOR_EACH(i, 0, nstrs) { + darray_str_push_back(&darray, str + i); + } + FOR_EACH(i, 0, nstrs) { + CHECK(strcmp(darray_str_cdata_get(&darray)[i], str[i]), 0); + } + darray_str_clear(&darray); + CHECK(darray_str_size_get(&darray), 0); darray_str_release(&darray); if(MEM_ALLOCATED_SIZE(&allocator_proxy)) {