]> git.buserror.net Git - polintos/scott/priv.git/blobdiff - include/c++/util/array.h
xfer to loki
[polintos/scott/priv.git] / include / c++ / util / array.h
index 80ba1c76965b47779ec6003b7f730cb0b6e84396..cc366d2bb9569a0c1dc09efce55e5de81248b52a 100644 (file)
@@ -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;
                        }
                };