99 |
99 |
100 /* return successfully */ |
100 /* return successfully */ |
101 return CX_ARRAY_COPY_SUCCESS; |
101 return CX_ARRAY_COPY_SUCCESS; |
102 } |
102 } |
103 |
103 |
|
104 #define CX_ARRAY_SWAP_SBO_SIZE 512 |
|
105 |
|
106 void cx_array_swap( |
|
107 void *arr, |
|
108 size_t elem_size, |
|
109 size_t idx1, |
|
110 size_t idx2 |
|
111 ) { |
|
112 /* short circuit */ |
|
113 if (idx1 == idx2) return; |
|
114 |
|
115 char sbo_mem[CX_ARRAY_SWAP_SBO_SIZE]; |
|
116 void *tmp; |
|
117 |
|
118 /* decide if we can use the local buffer */ |
|
119 if (elem_size > CX_ARRAY_SWAP_SBO_SIZE) { |
|
120 tmp = malloc(elem_size); |
|
121 /* we don't want to enforce error handling */ |
|
122 if (tmp == NULL) abort(); |
|
123 } else { |
|
124 tmp = sbo_mem; |
|
125 } |
|
126 |
|
127 /* calculate memory locations */ |
|
128 char *left = arr, *right = arr; |
|
129 left += idx1 * elem_size; |
|
130 right += idx2 * elem_size; |
|
131 |
|
132 /* three-way swap */ |
|
133 memcpy(tmp, left, elem_size); |
|
134 memcpy(left, right, elem_size); |
|
135 memcpy(right, tmp, elem_size); |
|
136 |
|
137 /* free dynamic memory, if it was needed */ |
|
138 if (tmp != sbo_mem) { |
|
139 free(tmp); |
|
140 } |
|
141 } |
|
142 |
104 /* HIGH LEVEL ARRAY LIST FUNCTIONS */ |
143 /* HIGH LEVEL ARRAY LIST FUNCTIONS */ |
105 |
144 |
106 typedef struct { |
145 typedef struct { |
107 struct cx_list_s base; |
146 struct cx_list_s base; |
108 void *data; |
147 void *data; |
288 return list->size < other->size ? -1 : 1; |
327 return list->size < other->size ? -1 : 1; |
289 } |
328 } |
290 } |
329 } |
291 |
330 |
292 static void cx_arl_reverse(struct cx_list_s *list) { |
331 static void cx_arl_reverse(struct cx_list_s *list) { |
293 |
332 if (list->size < 2) return; |
|
333 void *data = ((cx_array_list const *) list)->data; |
|
334 size_t half = list->size / 2; |
|
335 for (size_t i = 0; i < half; i++) { |
|
336 cx_array_swap(data, list->itemsize, i, list->size - 1 - i); |
|
337 } |
294 } |
338 } |
295 |
339 |
296 static bool cx_arl_iter_valid(struct cx_iterator_s const *iter) { |
340 static bool cx_arl_iter_valid(struct cx_iterator_s const *iter) { |
297 struct cx_list_s const *list = iter->src_handle; |
341 struct cx_list_s const *list = iter->src_handle; |
298 return iter->index < list->size; |
342 return iter->index < list->size; |