diff options
Diffstat (limited to 'Alc/vector.h')
-rw-r--r-- | Alc/vector.h | 99 |
1 files changed, 44 insertions, 55 deletions
diff --git a/Alc/vector.h b/Alc/vector.h index c1fc925d..ed9acfb0 100644 --- a/Alc/vector.h +++ b/Alc/vector.h @@ -5,11 +5,8 @@ #include <AL/al.h> -/* "Base" vector type, designed to alias with the actual vector types. */ -typedef struct vector__s { - size_t Capacity; - size_t Size; -} *vector_; +#include "almalloc.h" + #define TYPEDEF_VECTOR(T, N) typedef struct { \ size_t Capacity; \ @@ -27,38 +24,48 @@ typedef const _##N* const_##N; #define VECTOR_INIT(_x) do { (_x) = NULL; } while(0) #define VECTOR_INIT_STATIC() NULL -#define VECTOR_DEINIT(_x) do { free((_x)); (_x) = NULL; } while(0) - -/* Helper to increase a vector's reserve. Do not call directly. */ -ALboolean vector_reserve(char *ptr, size_t base_size, size_t obj_size, size_t obj_count, ALboolean exact); -#define VECTOR_RESERVE(_x, _c) (vector_reserve((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_c), AL_TRUE)) - -ALboolean vector_resize(char *ptr, size_t base_size, size_t obj_size, size_t obj_count); -#define VECTOR_RESIZE(_x, _c) (vector_resize((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_c))) +#define VECTOR_DEINIT(_x) do { al_free((_x)); (_x) = NULL; } while(0) + +#define VECTOR_RESIZE(_x, _s, _c) do { \ + size_t _size = (_s); \ + size_t _cap = (_c); \ + if(_size > _cap) \ + _cap = _size; \ + \ + if(!(_x) && _cap == 0) \ + break; \ + \ + if(((_x) ? (_x)->Capacity : 0) < _cap) \ + { \ + ptrdiff_t data_offset = (_x) ? (char*)((_x)->Data) - (char*)(_x) : \ + sizeof(*(_x)); \ + size_t old_size = ((_x) ? (_x)->Size : 0); \ + void *temp; \ + \ + temp = al_calloc(16, data_offset + sizeof((_x)->Data[0])*_cap); \ + assert(temp != NULL); \ + if((_x)) \ + memcpy(((char*)temp)+data_offset, (_x)->Data, \ + sizeof((_x)->Data[0])*old_size); \ + \ + al_free((_x)); \ + (_x) = temp; \ + (_x)->Capacity = _cap; \ + } \ + (_x)->Size = _size; \ +} while(0) \ #define VECTOR_CAPACITY(_x) ((_x) ? (_x)->Capacity : 0) #define VECTOR_SIZE(_x) ((_x) ? (_x)->Size : 0) -#define VECTOR_ITER_BEGIN(_x) ((_x) ? (_x)->Data + 0 : NULL) -#define VECTOR_ITER_END(_x) ((_x) ? (_x)->Data + (_x)->Size : NULL) - -ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_pos, const void *datstart, const void *datend); -#ifdef __GNUC__ -#define TYPE_CHECK(T1, T2) __builtin_types_compatible_p(T1, T2) -#define VECTOR_INSERT(_x, _i, _s, _e) __extension__({ \ - ALboolean _r; \ - static_assert(TYPE_CHECK(__typeof((_x)->Data[0]), __typeof(*(_i))), "Incompatible insertion iterator"); \ - static_assert(TYPE_CHECK(__typeof((_x)->Data[0]), __typeof(*(_s))), "Incompatible insertion source type"); \ - static_assert(TYPE_CHECK(__typeof(*(_s)), __typeof(*(_e))), "Incompatible iterator sources"); \ - _r = vector_insert((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_i), (_s), (_e)); \ - _r; \ -}) -#else -#define VECTOR_INSERT(_x, _i, _s, _e) (vector_insert((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_i), (_s), (_e))) -#endif - -#define VECTOR_PUSH_BACK(_x, _obj) (vector_reserve((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), VECTOR_SIZE(_x)+1, AL_FALSE) && \ - (((_x)->Data[(_x)->Size++] = (_obj)),AL_TRUE)) +#define VECTOR_BEGIN(_x) ((_x) ? (_x)->Data + 0 : NULL) +#define VECTOR_END(_x) ((_x) ? (_x)->Data + (_x)->Size : NULL) + +#define VECTOR_PUSH_BACK(_x, _obj) do { \ + size_t _pbsize = VECTOR_SIZE(_x)+1; \ + VECTOR_RESIZE(_x, _pbsize, _pbsize); \ + (_x)->Data[(_x)->Size-1] = (_obj); \ +} while(0) #define VECTOR_POP_BACK(_x) ((void)((_x)->Size--)) #define VECTOR_BACK(_x) ((_x)->Data[(_x)->Size-1]) @@ -67,22 +74,15 @@ ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_ #define VECTOR_ELEM(_x, _o) ((_x)->Data[(_o)]) #define VECTOR_FOR_EACH(_t, _x, _f) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ + _t *_iter = VECTOR_BEGIN((_x)); \ + _t *_end = VECTOR_END((_x)); \ for(;_iter != _end;++_iter) \ _f(_iter); \ } while(0) -#define VECTOR_FOR_EACH_PARAMS(_t, _x, _f, ...) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ - for(;_iter != _end;++_iter) \ - _f(__VA_ARGS__, _iter); \ -} while(0) - #define VECTOR_FIND_IF(_i, _t, _x, _f) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ + _t *_iter = VECTOR_BEGIN((_x)); \ + _t *_end = VECTOR_END((_x)); \ for(;_iter != _end;++_iter) \ { \ if(_f(_iter)) \ @@ -91,15 +91,4 @@ ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_ (_i) = _iter; \ } while(0) -#define VECTOR_FIND_IF_PARMS(_i, _t, _x, _f, ...) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ - for(;_iter != _end;++_iter) \ - { \ - if(_f(__VA_ARGS__, _iter)) \ - break; \ - } \ - (_i) = _iter; \ -} while(0) - #endif /* AL_VECTOR_H */ |