X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Farray%2Farray.h;h=69b25ec6677ae18dcc87db7ac7949318e7f3ca58;hp=5054b297fe13a81188e75010faed402045bc5f6a;hb=c1daa044b22fce3ca80d3430e3e1ad9360f8a4f1;hpb=09e4858bdbd026244ab250ef11d82a2189d46e49 diff --git a/ccan/array/array.h b/ccan/array/array.h index 5054b297..69b25ec6 100644 --- a/ccan/array/array.h +++ b/ccan/array/array.h @@ -28,42 +28,166 @@ #ifndef CCAN_ARRAY_H #define CCAN_ARRAY_H +#define ARRAY_USE_TALLOC + #include #include #include "config.h" - -#define Array(type) struct {type *item; size_t size; size_t allocSize;} -#define NewArray() {0,0,0} -#define AInit(array) do {(array).item=0; (array).size=0; (array).allocSize=0;} while(0) -#define AFree(array) do {free((array).item);} while(0) -#define AResize(array, newSize) do {size_t __newSize=(newSize); if (__newSize > (array).allocSize) {(array).allocSize = (__newSize+63)&~63; (array).item = realloc((array).item, (array).allocSize*sizeof(*(array).item));} (array).size = __newSize; } while(0) -#define AResize0(array, newSize) do {size_t __oldSize=(array).size, __newSize=(newSize); if (__newSize <= __oldSize) (array).size = __newSize; else {AResize(array,newSize); memset((array).item+__oldSize,0,(__newSize-__oldSize)*sizeof(*(array).item));} } while(0) -#define ASetAllocSize(array, newAlloc) do {(array).item = realloc((array).item, ((array).allocSize = (newAlloc))*sizeof(*(array).item));} while(0) -#define AFromC(array, c_array) AFromItems(array, c_array, sizeof(c_array)/sizeof(*(c_array))) -#define AFromLit(array, stringLiteral) do {AFromItems(array, stringLiteral, sizeof(stringLiteral)); (array).size--;} while(0) -#define AFromString(array, str) do {const char *__str = (str); AFromItems(array, __str, strlen(__str)+1); (array).size--;} while(0) -#define AFromItems(array, items, count) do {size_t __count = (count); AResize(array, __count); memcpy((array).item, items, __count*sizeof(*(array).item));} while(0) -#define AAppend(array, newItem...) do {AResize(array, (array).size+1); (array).item[(array).size-1] = (newItem);} while(0) -#define AAppendString(array, str) do {const char *__str = (str); AAppendItems(array, __str, strlen(__str)+1); (array).size--;} while(0) -#define AAppendLit(array, stringLiteral) do {AAppendItems(array, stringLiteral, sizeof(stringLiteral)); (array).size--;} while(0) -#define AAppendItems(array, items, count) do {size_t __count = (count); AResize(array, (array).size+__count); memcpy((array).item+(array).size-__count, items, __count*sizeof(*(array).item));} while(0) -#define APrepend(array, newItem...) do {AResize(array, (array).size+1); memmove((array).item+1, (array).item, ((array).size-1)*sizeof(*(array).item)); *(array).item = (newItem);} while(0) -#define APrependItems(array, items, count) do {AResize(array, (array).size+(count)); memmove((array).item+(count), (array).item, ((array).size-(count))*sizeof(*(array).item)); memcpy((array).item, items, (count)*sizeof(*(array).item)); } while(0) -#define APush(array, value...) AAppend(array, value) -#define APop(array) ((array).item[--(array).size]) +#ifdef ARRAY_USE_TALLOC +#include +#endif + +#define HAVE_ATTRIBUTE_MAY_ALIAS 1 + +//Use the array_alias macro to indicate that a pointer has changed but strict aliasing rules are too stupid to know it +#if HAVE_ATTRIBUTE_MAY_ALIAS==1 +#define array_alias(ptr) /* nothing */ +#define array(type) struct {type *item; size_t size; size_t alloc;} __attribute__((__may_alias__)) +#else +#define array_alias(ptr) qsort(ptr, 0, 1, array_alias_helper) //hack +#define array(type) struct {type *item; size_t size; size_t alloc;} +#endif + +//We call allocator functions directly +#ifndef ARRAY_USE_TALLOC + +#define array_new() {0,0,0} +#define array_init(array) do {(array).item=0; (array).size=0; (array).alloc=0;} while(0) +#define array_realloc(array, newAlloc) do {(array).item = realloc((array).item, ((array).alloc = (newAlloc))*sizeof(*(array).item));} while(0) +#define array_free(array) do {free((array).item);} while(0) + +#else + +//note: the allocations are given an extra byte to prevent free (and thus loss of ctx) on realloc to size 0 + +#define array_new(ctx) {talloc_size(ctx,1), 0,0} +#define array_init(array, ctx) do {(array).item=talloc_size(ctx,1); (array).size=0; (array).alloc=0;} while(0) +#define array_realloc(array, newAlloc) do {(array).item = talloc_realloc_size(NULL, (array).item, ((array).alloc = (newAlloc))*sizeof(*(array).item) +1);} while(0) +#define array_free(array) do {talloc_free((array).item);} while(0) + +#endif + + +//We call helper functions +#define array_resize(array, newSize) do {(array).size = (newSize); if ((array).size > (array).alloc) { array_resize_helper((array_char*)&(array), sizeof(*(array).item)); array_alias(&(array));}} while(0) +#define array_resize0(array, newSize) do {array_resize0_helper((array_char*)&(array), sizeof(*(array).item), newSize);} while(0) +#define array_prepend_lit(array, stringLiteral) do {array_insert_items_helper((array_char*)&(array), sizeof(*(array).item), 0, stringLiteral, sizeof(stringLiteral)-1, 1); array_alias(&(array)); (array).item[--(array).size] = 0;} while(0) +#define array_prepend_string(array, str) do {const char *__str = (str); size_t __len = strlen(__str); array_insert_items_helper((array_char*)&(array), sizeof(*(array).item), 0, __str, __len, 1); array_alias(&(array)); (array).item[--(array).size] = 0;} while(0) +#define array_prepend_items(array, items, count) do {array_insert_items_helper((array_char*)&(array), sizeof(*(array).item), 0, items, count, 0); array_alias(&(array));} while(0) + + +//We call other array_* macros +#define array_from_c(array, c_array) array_from_items(array, c_array, sizeof(c_array)/sizeof(*(c_array))) +#define array_from_lit(array, stringLiteral) do {array_from_items(array, stringLiteral, sizeof(stringLiteral)); (array).size--;} while(0) +#define array_from_string(array, str) do {const char *__str = (str); array_from_items(array, __str, strlen(__str)+1); (array).size--;} while(0) +#define array_from_items(array, items, count) do {size_t __count = (count); array_resize(array, __count); memcpy((array).item, items, __count*sizeof(*(array).item));} while(0) +#define array_append(array, ...) do {array_resize(array, (array).size+1); (array).item[(array).size-1] = (__VA_ARGS__);} while(0) +#define array_append_string(array, str) do {const char *__str = (str); array_append_items(array, __str, strlen(__str)+1); (array).size--;} while(0) +#define array_append_lit(array, stringLiteral) do {array_append_items(array, stringLiteral, sizeof(stringLiteral)); (array).size--;} while(0) +#define array_append_items(array, items, count) do {size_t __count = (count); array_resize(array, (array).size+__count); memcpy((array).item+(array).size-__count, items, __count*sizeof(*(array).item));} while(0) +#define array_prepend(array, ...) do {array_resize(array, (array).size+1); memmove((array).item+1, (array).item, ((array).size-1)*sizeof(*(array).item)); *(array).item = (__VA_ARGS__);} while(0) +#define array_push(array, ...) array_append(array, __VA_ARGS__) +#define array_pop(array) ((array).size ? array_pop_nocheck(array) : NULL) + +#define array_growalloc(array, newAlloc) do {size_t __newAlloc=(newAlloc); if (__newAlloc > (array).alloc) array_realloc(array, (__newAlloc+63)&~63); } while(0) #if HAVE_STATEMENT_EXPR==1 -#define AMakeRoom(array, room) ({size_t newAlloc = (array).size+(room); if ((array).allocSizen, i->d)); +array_free(fractions); +*/ + +/* + +Direct tests: + +array_push +array_prepend +array_from_c +array_for +array_rof +array_from_lit +array_append_lit +array_prepend_lit +array_append_string +array_prepend_string +array_from_string +array_resize0 +array_pop_nocheck +array_realloc +array_growalloc +array_make_room +array_pop +array_appends +array_prepends + +Indirect tests: + +array_append <- array_push +array_resize <- array_append +array_from_items <- array_from_c, array_from_lit, array_from_string +array_append_items <- array_append_string, array_append_lit +array_prepend_items <- array_prepends + +Untested: + +*/