437831489ce2c741a810b00401730467abf9b38d
[convexer.git] / cxr / cxr_mem.h
1 typedef struct cxr_abuffer cxr_abuffer;
2
3 struct cxr_abuffer
4 {
5 u8 *arr;
6 u32 esize,
7 count,
8 capacity;
9 };
10
11 #ifdef CXR_DEBUG_ALLOCATORS
12 #define CXR_STR_PRE(x) #x
13 #define CXR_STR(x) CXR_STR_PRE(x)
14 #define cxr_ab_ptr(b,i) __cxr_ab_ptr(b,i, __FILE__ ":L" CXR_STR(__LINE__) )
15 #else
16 #define cxr_ab_ptr(b,i) __cxr_ab_ptr(b,i)
17 #endif
18
19 static void *__cxr_ab_ptr( struct cxr_abuffer *buffer, u32 index
20
21 #ifdef CXR_DEBUG_ALLOCATORS
22 ,const char *debug_str
23 #endif
24
25 )
26 {
27
28 #ifdef CXR_DEBUG_ALLOCATORS
29 if( index >= buffer->capacity || index < 0 )
30 {
31 printf( "index out of capactity (%d /: [0->%d (cap)]) (%s)\n", index, buffer->capacity, debug_str );
32 exit(1);
33 }
34 #endif
35
36 return buffer->arr + buffer->esize*index;
37 }
38
39 static void cxr_ab_reserve( struct cxr_abuffer *buffer, u32 count )
40 {
41 if( buffer->count + count > buffer->capacity )
42 {
43 buffer->capacity = cxr_max(buffer->capacity*2, buffer->capacity+count);
44 buffer->arr = realloc( buffer->arr, buffer->capacity*buffer->esize );
45 }
46 }
47
48 static void *cxr_ab_empty( struct cxr_abuffer *buffer )
49 {
50 cxr_ab_reserve( buffer, 1 );
51 return cxr_ab_ptr( buffer, buffer->count ++ );
52 }
53
54 static void *cxr_ab_empty_at( struct cxr_abuffer *buffer, int at )
55 {
56 cxr_ab_reserve( buffer, 1 );
57
58 if( at == buffer->count )
59 {
60 buffer->count ++;
61 return cxr_ab_ptr( buffer, at );
62 }
63
64 /* Shift buffer to make room */
65 memmove
66 (
67 cxr_ab_ptr( buffer, at+1 ),
68 cxr_ab_ptr( buffer, at ),
69 (buffer->count-at)*buffer->esize
70 );
71
72 buffer->count ++;
73 return cxr_ab_ptr( buffer, at );
74 }
75
76 static void cxr_ab_push( struct cxr_abuffer *buffer, void *em )
77 {
78 cxr_ab_reserve( buffer, 1 );
79
80 memcpy( buffer->arr+buffer->count*buffer->esize, em, buffer->esize );
81 buffer->count ++;
82 }
83
84 static void cxr_ab_init( struct cxr_abuffer *buffer, u32 esize, u32 cap )
85 {
86 buffer->esize = esize;
87 buffer->capacity = cxr_max(1,cap);
88 buffer->count = 0;
89
90 buffer->arr = malloc( buffer->esize*buffer->capacity );
91 }
92
93 static void cxr_ab_clear( struct cxr_abuffer *buffer )
94 {
95 buffer->count = 0;
96 }
97
98 static void cxr_ab_free( struct cxr_abuffer *buffer )
99 {
100 free( buffer->arr );
101 }