src/array_list.c

changeset 953
581ad4fd01e9
parent 926
8fdd8d78c14b
equal deleted inserted replaced
952:dc53362bc5a7 953:581ad4fd01e9
35 35
36 static void *cx_array_default_realloc( 36 static void *cx_array_default_realloc(
37 void *array, 37 void *array,
38 size_t capacity, 38 size_t capacity,
39 size_t elem_size, 39 size_t elem_size,
40 __attribute__((__unused__)) struct cx_array_reallocator_s *alloc 40 __attribute__((__unused__)) CxArrayReallocator *alloc
41 ) { 41 ) {
42 return realloc(array, capacity * elem_size); 42 return realloc(array, capacity * elem_size);
43 } 43 }
44 44
45 struct cx_array_reallocator_s cx_array_default_reallocator_impl = { 45 CxArrayReallocator cx_array_default_reallocator_impl = {
46 cx_array_default_realloc, NULL, NULL, 0, 0 46 cx_array_default_realloc, NULL, NULL, 0, 0
47 }; 47 };
48 48
49 struct cx_array_reallocator_s *cx_array_default_reallocator = &cx_array_default_reallocator_impl; 49 CxArrayReallocator *cx_array_default_reallocator = &cx_array_default_reallocator_impl;
50
51 // Stack-aware array reallocator
52
53 static void *cx_array_advanced_realloc(
54 void *array,
55 size_t capacity,
56 size_t elem_size,
57 __attribute__((__unused__)) CxArrayReallocator *alloc
58 ) {
59 // retrieve the pointer to the actual allocator
60 const CxAllocator *al = alloc->ptr1;
61
62 // check if the array is still located on the stack
63 void *newmem;
64 if (array == alloc->ptr2) {
65 newmem = cxMalloc(al, capacity * elem_size);
66 if (newmem != NULL) {
67 memcpy(newmem, array, capacity * elem_size);
68 }
69 } else {
70 newmem = cxRealloc(al, array, capacity * elem_size);
71 }
72 return newmem;
73 }
74
75 struct cx_array_reallocator_s cx_array_reallocator(
76 const struct cx_allocator_s *allocator,
77 const void *stackmem
78 ) {
79 if (allocator == NULL) {
80 allocator = cxDefaultAllocator;
81 }
82 return (struct cx_array_reallocator_s) {
83 cx_array_advanced_realloc,
84 (void*) allocator, (void*) stackmem,
85 0, 0
86 };
87 }
50 88
51 // LOW LEVEL ARRAY LIST FUNCTIONS 89 // LOW LEVEL ARRAY LIST FUNCTIONS
52 90
53 enum cx_array_result cx_array_copy( 91 enum cx_array_result cx_array_copy(
54 void **target, 92 void **target,
56 size_t *capacity, 94 size_t *capacity,
57 size_t index, 95 size_t index,
58 const void *src, 96 const void *src,
59 size_t elem_size, 97 size_t elem_size,
60 size_t elem_count, 98 size_t elem_count,
61 struct cx_array_reallocator_s *reallocator 99 CxArrayReallocator *reallocator
62 ) { 100 ) {
63 // assert pointers 101 // assert pointers
64 assert(target != NULL); 102 assert(target != NULL);
65 assert(size != NULL); 103 assert(size != NULL);
66 assert(src != NULL); 104 assert(src != NULL);
126 size_t *capacity, 164 size_t *capacity,
127 cx_compare_func cmp_func, 165 cx_compare_func cmp_func,
128 const void *sorted_data, 166 const void *sorted_data,
129 size_t elem_size, 167 size_t elem_size,
130 size_t elem_count, 168 size_t elem_count,
131 struct cx_array_reallocator_s *reallocator 169 CxArrayReallocator *reallocator
132 ) { 170 ) {
133 // assert pointers 171 // assert pointers
134 assert(target != NULL); 172 assert(target != NULL);
135 assert(size != NULL); 173 assert(size != NULL);
136 assert(capacity != NULL); 174 assert(capacity != NULL);
335 373
336 typedef struct { 374 typedef struct {
337 struct cx_list_s base; 375 struct cx_list_s base;
338 void *data; 376 void *data;
339 size_t capacity; 377 size_t capacity;
340 struct cx_array_reallocator_s reallocator; 378 CxArrayReallocator reallocator;
341 } cx_array_list; 379 } cx_array_list;
342
343 static void *cx_arl_realloc(
344 void *array,
345 size_t capacity,
346 size_t elem_size,
347 struct cx_array_reallocator_s *alloc
348 ) {
349 // retrieve the pointer to the list allocator
350 const CxAllocator *al = alloc->ptr1;
351
352 // use the list allocator to reallocate the memory
353 return cxRealloc(al, array, capacity * elem_size);
354 }
355 380
356 static void cx_arl_destructor(struct cx_list_s *list) { 381 static void cx_arl_destructor(struct cx_list_s *list) {
357 cx_array_list *arl = (cx_array_list *) list; 382 cx_array_list *arl = (cx_array_list *) list;
358 383
359 char *ptr = arl->data; 384 char *ptr = arl->data;
781 cxFree(allocator, list); 806 cxFree(allocator, list);
782 return NULL; 807 return NULL;
783 } 808 }
784 809
785 // configure the reallocator 810 // configure the reallocator
786 list->reallocator.realloc = cx_arl_realloc; 811 list->reallocator = cx_array_reallocator(allocator, NULL);
787 list->reallocator.ptr1 = (void *) allocator;
788 812
789 return (CxList *) list; 813 return (CxList *) list;
790 } 814 }

mercurial