X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=include%2Fc%2B%2B%2Futil%2Farray.h;fp=include%2Fc%2B%2B%2Futil%2Farray.h;h=cc366d2bb9569a0c1dc09efce55e5de81248b52a;hp=80ba1c76965b47779ec6003b7f730cb0b6e84396;hb=39d6852ead7a839f9e15e21e517dfd7a795e5cdd;hpb=cc1bee96fd874ff2c85c765f81ec2f4ba4584b9d diff --git a/include/c++/util/array.h b/include/c++/util/array.h index 80ba1c7..cc366d2 100644 --- a/include/c++/util/array.h +++ b/include/c++/util/array.h @@ -146,6 +146,7 @@ namespace Util { bufsize = count; } + // FIXME: use realloc void grow(size_t newsize) { if (newsize <= bufsize) @@ -155,6 +156,7 @@ namespace Util { T *newptr = new(Alloc()) T[newsize]; memcpy(newptr, ptr, count * sizeof(T)); + memset(newptr + count, 0, (newsize - count) * sizeof(T)); ptr = newptr; ll_smp_membar_store_after_store(); @@ -164,19 +166,41 @@ namespace Util { Alloc::release(oldptr); } - // Caller must sync against all writers. - void append(T *newptr, size_t len, size_t max = ULONG_MAX) + T *grow_by(size_t len, size_t max = ULONG_MAX) { + size_t oldcount = count; + if (count + len < count) throw ArrayException(); - + if (count + len > max) throw ArrayException(); - + if (count + len > bufsize) grow(ll_get_order_round_up(count + len)); - - memcpy(ptr + count, newptr, len * sizeof(T)); + + return ptr + oldcount; + } + + // align must be power-of-two + void align_to(size_t align, size_t max = ULONG_MAX) + { + size_t newcount = (count + align - 1) & ~(align - 1); + + if (newcount < count) + throw ArrayException(); + + if (newcount > max) + throw ArrayException(); + + if (newcount > bufsize) + grow(ll_get_order_round_up(newcount)); + } + + // Caller must sync against all writers. + void append(T *newptr, size_t len, size_t max = ULONG_MAX) + { + memcpy(ptr + grow_by(len, max), newptr, len * sizeof(T)); count += len; } };