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