src/array_list.c

changeset 638
eafb45eefc51
parent 630
ac5e7f789048
child 640
55cc3b373c5e
equal deleted inserted replaced
637:ceadf0792ded 638:eafb45eefc51
183 1, 183 1,
184 &arl->reallocator 184 &arl->reallocator
185 ); 185 );
186 } 186 }
187 187
188 static size_t cx_arl_add_array( 188 static size_t cx_arl_insert_array(
189 struct cx_list_s *list, 189 struct cx_list_s *list,
190 size_t index,
190 void const *array, 191 void const *array,
191 size_t n 192 size_t n
192 ) { 193 ) {
194 // out of bounds and special case check
195 if (index > list->size || n == 0) return 0;
196
197 // get a correctly typed pointer to the list
193 cx_array_list *arl = (cx_array_list *) list; 198 cx_array_list *arl = (cx_array_list *) list;
199
200 // do we need to move some elements?
201 if (index < list->size) {
202 char const *first_to_move = (char const *) arl->data;
203 first_to_move += index * list->itemsize;
204 size_t elems_to_move = list->size - index;
205 size_t start_of_moved = index + n;
206
207 if (CX_ARRAY_COPY_SUCCESS != cx_array_copy(
208 &arl->data,
209 &list->size,
210 &list->capacity,
211 start_of_moved,
212 first_to_move,
213 list->itemsize,
214 elems_to_move,
215 &arl->reallocator
216 )) {
217 // if moving existing elems is unsuccessful, abort
218 return 0;
219 }
220 }
221
222 // note that if we had to move the elements, the following operation
223 // is guaranteed to succeed, because we have the memory already allocated
224 // therefore, it is impossible to leave this function with an invalid array
225
226 // place the new elements
194 if (CX_ARRAY_COPY_SUCCESS == cx_array_copy( 227 if (CX_ARRAY_COPY_SUCCESS == cx_array_copy(
195 &arl->data, 228 &arl->data,
196 &list->size, 229 &list->size,
197 &list->capacity, 230 &list->capacity,
198 list->size, 231 index,
199 array, 232 array,
200 list->itemsize, 233 list->itemsize,
201 n, 234 n,
202 &arl->reallocator 235 &arl->reallocator
203 )) { 236 )) {
204 return n; 237 return n;
205 } else { 238 } else {
206 // array list implementation is "all or nothing" 239 // array list implementation is "all or nothing"
207 return 0; 240 return 0;
208 } 241 }
242 }
243
244 static size_t cx_arl_add_array(
245 struct cx_list_s *list,
246 void const *array,
247 size_t n
248 ) {
249 return cx_arl_insert_array(list, list->size, array, n);
209 } 250 }
210 251
211 static int cx_arl_insert( 252 static int cx_arl_insert(
212 struct cx_list_s *list, 253 struct cx_list_s *list,
213 size_t index, 254 size_t index,
438 static cx_list_class cx_array_list_class = { 479 static cx_list_class cx_array_list_class = {
439 cx_arl_destructor, 480 cx_arl_destructor,
440 cx_arl_add, 481 cx_arl_add,
441 cx_arl_add_array, 482 cx_arl_add_array,
442 cx_arl_insert, 483 cx_arl_insert,
484 cx_arl_insert_array,
443 cx_arl_insert_iter, 485 cx_arl_insert_iter,
444 cx_arl_remove, 486 cx_arl_remove,
445 cx_arl_at, 487 cx_arl_at,
446 cx_arl_find, 488 cx_arl_find,
447 cx_arl_sort, 489 cx_arl_sort,

mercurial