--- /dev/null
+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 );
+}