Major API revision
[convexer.git] / cxr / cxr_mem.h
diff --git a/cxr/cxr_mem.h b/cxr/cxr_mem.h
new file mode 100644 (file)
index 0000000..4378314
--- /dev/null
@@ -0,0 +1,101 @@
+typedef struct cxr_abuffer cxr_abuffer;
+
+struct cxr_abuffer
+{
+   u8 *arr;
+   u32 esize,
+       count,
+       capacity;
+};
+
+#ifdef CXR_DEBUG_ALLOCATORS
+ #define CXR_STR_PRE(x) #x
+ #define CXR_STR(x) CXR_STR_PRE(x)
+ #define cxr_ab_ptr(b,i) __cxr_ab_ptr(b,i, __FILE__ ":L" CXR_STR(__LINE__) )
+#else 
+ #define cxr_ab_ptr(b,i) __cxr_ab_ptr(b,i)
+#endif
+
+static void *__cxr_ab_ptr( struct cxr_abuffer *buffer, u32 index
+
+#ifdef CXR_DEBUG_ALLOCATORS
+      ,const char *debug_str 
+#endif
+
+)
+{
+
+#ifdef CXR_DEBUG_ALLOCATORS
+   if( index >= buffer->capacity || index < 0 )
+   {
+      printf( "index out of capactity (%d /: [0->%d (cap)]) (%s)\n", index, buffer->capacity, debug_str );
+      exit(1);
+   }
+#endif
+
+   return buffer->arr + buffer->esize*index;
+}
+
+static void cxr_ab_reserve( struct cxr_abuffer *buffer, u32 count )
+{
+   if( buffer->count + count > buffer->capacity )
+   {
+      buffer->capacity = cxr_max(buffer->capacity*2, buffer->capacity+count);
+      buffer->arr = realloc( buffer->arr, buffer->capacity*buffer->esize );
+   }
+}
+
+static void *cxr_ab_empty( struct cxr_abuffer *buffer )
+{
+   cxr_ab_reserve( buffer, 1 );
+   return cxr_ab_ptr( buffer, buffer->count ++ );
+}
+
+static void *cxr_ab_empty_at( struct cxr_abuffer *buffer, int at )
+{
+   cxr_ab_reserve( buffer, 1 );
+   
+   if( at == buffer->count )
+   {
+      buffer->count ++;
+      return cxr_ab_ptr( buffer, at );
+   }
+
+   /* Shift buffer to make room */
+   memmove
+   ( 
+      cxr_ab_ptr( buffer, at+1 ), 
+      cxr_ab_ptr( buffer, at ), 
+      (buffer->count-at)*buffer->esize 
+   );
+
+   buffer->count ++;
+   return cxr_ab_ptr( buffer, at );
+}
+
+static void cxr_ab_push( struct cxr_abuffer *buffer, void *em )
+{
+   cxr_ab_reserve( buffer, 1 );
+
+   memcpy( buffer->arr+buffer->count*buffer->esize, em, buffer->esize );
+   buffer->count ++;
+}
+
+static void cxr_ab_init( struct cxr_abuffer *buffer, u32 esize, u32 cap )
+{
+   buffer->esize = esize;
+   buffer->capacity = cxr_max(1,cap);
+   buffer->count = 0;
+
+   buffer->arr = malloc( buffer->esize*buffer->capacity );
+}
+
+static void cxr_ab_clear( struct cxr_abuffer *buffer )
+{
+   buffer->count = 0;
+}
+
+static void cxr_ab_free( struct cxr_abuffer *buffer )
+{
+   free( buffer->arr );
+}