Browse Source

misc: add grow_array.h

ambrop7 13 years ago
parent
commit
f87e0c7eeb
1 changed files with 81 additions and 0 deletions
  1. 81 0
      misc/grow_array.h

+ 81 - 0
misc/grow_array.h

@@ -0,0 +1,81 @@
+// Preprocessor inputs:
+// GROWARRAY_NAME - prefix of of functions to define
+// GROWARRAY_OBJECT_TYPE - type of structure where array and capacity sizes are
+// GROWARRAY_ARRAY_MEMBER - array member
+// GROWARRAY_CAPACITY_MEMBER - capacity member
+// GROWARRAY_MAX_CAPACITY - max value of capacity member
+
+#include <limits.h>
+#include <string.h>
+#include <stddef.h>
+
+#include <misc/debug.h>
+#include <misc/balloc.h>
+#include <misc/merge.h>
+
+#define GrowArrayObject GROWARRAY_OBJECT_TYPE
+#define GrowArray_Init MERGE(GROWARRAY_NAME, _Init)
+#define GrowArray_Free MERGE(GROWARRAY_NAME, _Free)
+#define GrowArray_DoubleUp MERGE(GROWARRAY_NAME, _DoubleUp)
+
+static int GrowArray_Init (GrowArrayObject *o, size_t capacity) WARN_UNUSED;
+static void GrowArray_Free (GrowArrayObject *o);
+static int GrowArray_DoubleUp (GrowArrayObject *o) WARN_UNUSED;
+
+static int GrowArray_Init (GrowArrayObject *o, size_t capacity)
+{
+    ASSERT(capacity > 0)
+    
+    if (capacity > GROWARRAY_MAX_CAPACITY) {
+        return 0;
+    }
+    
+    if (!(o->GROWARRAY_ARRAY_MEMBER = BAllocArray(capacity, sizeof(o->GROWARRAY_ARRAY_MEMBER[0])))) {
+        return 0;
+    }
+        
+    o->GROWARRAY_CAPACITY_MEMBER = capacity;
+    
+    return 1;
+}
+
+static void GrowArray_Free (GrowArrayObject *o)
+{
+    BFree(o->GROWARRAY_ARRAY_MEMBER);
+}
+
+static int GrowArray_DoubleUp (GrowArrayObject *o)
+{
+    ASSERT(o->GROWARRAY_CAPACITY_MEMBER > 0)
+    
+    if (o->GROWARRAY_CAPACITY_MEMBER > SIZE_MAX / 2 || o->GROWARRAY_CAPACITY_MEMBER > GROWARRAY_MAX_CAPACITY / 2) {
+        return 0;
+    }
+    
+    size_t newcap = 2 * o->GROWARRAY_CAPACITY_MEMBER;
+    
+    void *newarr = BAllocArray(newcap, sizeof(o->GROWARRAY_ARRAY_MEMBER[0]));
+    if (!newarr) {
+        return 0;
+    }
+    
+    memcpy(newarr, o->GROWARRAY_ARRAY_MEMBER, o->GROWARRAY_CAPACITY_MEMBER * sizeof(o->GROWARRAY_ARRAY_MEMBER[0]));
+    
+    BFree(o->GROWARRAY_ARRAY_MEMBER);
+    
+    o->GROWARRAY_ARRAY_MEMBER = newarr;
+    o->GROWARRAY_CAPACITY_MEMBER = newcap;
+    
+    return 1;
+}
+
+#undef GROWARRAY_NAME
+#undef GROWARRAY_OBJECT_TYPE
+#undef GROWARRAY_ARRAY_MEMBER
+#undef GROWARRAY_CAPACITY_MEMBER
+#undef GROWARRAY_MAX_CAPACITY
+
+#undef GrowArrayObject
+#undef GrowArray_Init
+#undef GrowArray_Free
+#undef GrowArray_DoubleUp