ucx/list.c

branch
ucx-3.1
changeset 816
839fefbdedc7
parent 750
4d7a2238c5ac
equal deleted inserted replaced
815:1f40ca07ae1b 816:839fefbdedc7
45 return cx_pl_cmpfunc_impl(left, right); 45 return cx_pl_cmpfunc_impl(left, right);
46 } 46 }
47 47
48 static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) { 48 static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) {
49 // cast away const - this is the hacky thing 49 // cast away const - this is the hacky thing
50 struct cx_list_s *l = (struct cx_list_s *) list; 50 struct cx_collection_s *l = (struct cx_collection_s*) &list->collection;
51 cx_pl_cmpfunc_impl = l->cmpfunc; 51 cx_pl_cmpfunc_impl = l->cmpfunc;
52 l->cmpfunc = cx_pl_cmpfunc; 52 l->cmpfunc = cx_pl_cmpfunc;
53 } 53 }
54 54
55 static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) { 55 static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) {
56 // cast away const - this is the hacky thing 56 // cast away const - this is the hacky thing
57 struct cx_list_s *l = (struct cx_list_s *) list; 57 struct cx_collection_s *l = (struct cx_collection_s*) &list->collection;
58 l->cmpfunc = cx_pl_cmpfunc_impl; 58 l->cmpfunc = cx_pl_cmpfunc_impl;
59 } 59 }
60 60
61 static void cx_pl_destructor(struct cx_list_s *list) { 61 static void cx_pl_destructor(struct cx_list_s *list) {
62 list->climpl->destructor(list); 62 list->climpl->destructor(list);
78 ) { 78 ) {
79 return list->climpl->insert_array(list, index, array, n); 79 return list->climpl->insert_array(list, index, array, n);
80 } 80 }
81 81
82 static int cx_pl_insert_iter( 82 static int cx_pl_insert_iter(
83 struct cx_mut_iterator_s *iter, 83 struct cx_iterator_s *iter,
84 void const *elem, 84 void const *elem,
85 int prepend 85 int prepend
86 ) { 86 ) {
87 struct cx_list_s *list = iter->src_handle; 87 struct cx_list_s *list = iter->src_handle.m;
88 return list->climpl->insert_iter(iter, &elem, prepend); 88 return list->climpl->insert_iter(iter, &elem, prepend);
89 } 89 }
90 90
91 static int cx_pl_remove( 91 static int cx_pl_remove(
92 struct cx_list_s *list, 92 struct cx_list_s *list,
113 ) { 113 ) {
114 void **ptr = list->climpl->at(list, index); 114 void **ptr = list->climpl->at(list, index);
115 return ptr == NULL ? NULL : *ptr; 115 return ptr == NULL ? NULL : *ptr;
116 } 116 }
117 117
118 static ssize_t cx_pl_find( 118 static ssize_t cx_pl_find_remove(
119 struct cx_list_s const *list, 119 struct cx_list_s *list,
120 void const *elem 120 void const *elem,
121 bool remove
121 ) { 122 ) {
122 cx_pl_hack_cmpfunc(list); 123 cx_pl_hack_cmpfunc(list);
123 ssize_t ret = list->climpl->find(list, &elem); 124 ssize_t ret = list->climpl->find_remove(list, &elem, remove);
124 cx_pl_unhack_cmpfunc(list); 125 cx_pl_unhack_cmpfunc(list);
125 return ret; 126 return ret;
126 } 127 }
127 128
128 static void cx_pl_sort(struct cx_list_s *list) { 129 static void cx_pl_sort(struct cx_list_s *list) {
169 cx_pl_insert_iter, 170 cx_pl_insert_iter,
170 cx_pl_remove, 171 cx_pl_remove,
171 cx_pl_clear, 172 cx_pl_clear,
172 cx_pl_swap, 173 cx_pl_swap,
173 cx_pl_at, 174 cx_pl_at,
174 cx_pl_find, 175 cx_pl_find_remove,
175 cx_pl_sort, 176 cx_pl_sort,
176 cx_pl_compare, 177 cx_pl_compare,
177 cx_pl_reverse, 178 cx_pl_reverse,
178 cx_pl_iterator, 179 cx_pl_iterator,
179 }; 180 };
180 181
181 void cxListStoreObjects(CxList *list) { 182 void cxListStoreObjects(CxList *list) {
182 list->store_pointer = false; 183 list->collection.store_pointer = false;
183 if (list->climpl != NULL) { 184 if (list->climpl != NULL) {
184 list->cl = list->climpl; 185 list->cl = list->climpl;
185 list->climpl = NULL; 186 list->climpl = NULL;
186 } 187 }
187 } 188 }
188 189
189 void cxListStorePointers(CxList *list) { 190 void cxListStorePointers(CxList *list) {
190 list->item_size = sizeof(void *); 191 list->collection.elem_size = sizeof(void *);
191 list->store_pointer = true; 192 list->collection.store_pointer = true;
192 list->climpl = list->cl; 193 list->climpl = list->cl;
193 list->cl = &cx_pointer_list_class; 194 list->cl = &cx_pointer_list_class;
194 } 195 }
195 196
196 // </editor-fold> 197 // </editor-fold>
206 __attribute__((__unused__)) size_t index 207 __attribute__((__unused__)) size_t index
207 ) { 208 ) {
208 return NULL; 209 return NULL;
209 } 210 }
210 211
211 static ssize_t cx_emptyl_find( 212 static ssize_t cx_emptyl_find_remove(
212 __attribute__((__unused__)) struct cx_list_s const *list, 213 __attribute__((__unused__)) struct cx_list_s *list,
213 __attribute__((__unused__)) void const *elem 214 __attribute__((__unused__)) void const *elem,
215 __attribute__((__unused__)) bool remove
214 ) { 216 ) {
215 return -1; 217 return -1;
216 } 218 }
217 219
218 static int cx_emptyl_compare( 220 static int cx_emptyl_compare(
219 __attribute__((__unused__)) struct cx_list_s const *list, 221 __attribute__((__unused__)) struct cx_list_s const *list,
220 struct cx_list_s const *other 222 struct cx_list_s const *other
221 ) { 223 ) {
222 if (other->size == 0) return 0; 224 if (other->collection.size == 0) return 0;
223 return -1; 225 return -1;
224 } 226 }
225 227
226 static bool cx_emptyl_iter_valid(__attribute__((__unused__)) void const *iter) { 228 static bool cx_emptyl_iter_valid(__attribute__((__unused__)) void const *iter) {
227 return false; 229 return false;
231 struct cx_list_s const *list, 233 struct cx_list_s const *list,
232 size_t index, 234 size_t index,
233 __attribute__((__unused__)) bool backwards 235 __attribute__((__unused__)) bool backwards
234 ) { 236 ) {
235 CxIterator iter = {0}; 237 CxIterator iter = {0};
236 iter.src_handle = list; 238 iter.src_handle.c = list;
237 iter.index = index; 239 iter.index = index;
238 iter.base.valid = cx_emptyl_iter_valid; 240 iter.base.valid = cx_emptyl_iter_valid;
239 return iter; 241 return iter;
240 } 242 }
241 243
246 NULL, 248 NULL,
247 NULL, 249 NULL,
248 cx_emptyl_noop, 250 cx_emptyl_noop,
249 NULL, 251 NULL,
250 cx_emptyl_at, 252 cx_emptyl_at,
251 cx_emptyl_find, 253 cx_emptyl_find_remove,
252 cx_emptyl_noop, 254 cx_emptyl_noop,
253 cx_emptyl_compare, 255 cx_emptyl_compare,
254 cx_emptyl_noop, 256 cx_emptyl_noop,
255 cx_emptyl_iterator, 257 cx_emptyl_iterator,
256 }; 258 };
257 259
258 CxList cx_empty_list = { 260 CxList cx_empty_list = {
259 NULL, 261 {
260 NULL, 262 NULL,
261 0, 263 NULL,
262 0, 264 0,
263 NULL, 265 0,
264 NULL, 266 NULL,
265 NULL, 267 NULL,
266 false, 268 NULL,
269 false
270 },
267 &cx_empty_list_class, 271 &cx_empty_list_class,
268 NULL 272 NULL
269 }; 273 };
270 274
271 CxList *const cxEmptyList = &cx_empty_list; 275 CxList *const cxEmptyList = &cx_empty_list;
280 CxList const *list, 284 CxList const *list,
281 CxList const *other 285 CxList const *other
282 ) { 286 ) {
283 if ( 287 if (
284 // if one is storing pointers but the other is not 288 // if one is storing pointers but the other is not
285 (list->store_pointer ^ other->store_pointer) || 289 (list->collection.store_pointer ^ other->collection.store_pointer) ||
286 290
287 // if one class is wrapped but the other is not 291 // if one class is wrapped but the other is not
288 ((list->climpl == NULL) ^ (other->climpl == NULL)) || 292 ((list->climpl == NULL) ^ (other->climpl == NULL)) ||
289 293
290 // if the resolved compare functions are not the same 294 // if the resolved compare functions are not the same
291 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) != 295 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) !=
292 (other->climpl != NULL ? other->climpl->compare : other->cl->compare)) 296 (other->climpl != NULL ? other->climpl->compare : other->cl->compare))
293 ) { 297 ) {
294 // lists are definitely different - cannot use internal compare function 298 // lists are definitely different - cannot use internal compare function
295 if (list->size == other->size) { 299 if (list->collection.size == other->collection.size) {
296 CxIterator left = cxListIterator(list); 300 CxIterator left = list->cl->iterator(list, 0, false);
297 CxIterator right = cxListIterator(other); 301 CxIterator right = other->cl->iterator(other, 0, false);
298 for (size_t i = 0; i < list->size; i++) { 302 for (size_t i = 0; i < list->collection.size; i++) {
299 void *leftValue = cxIteratorCurrent(left); 303 void *leftValue = cxIteratorCurrent(left);
300 void *rightValue = cxIteratorCurrent(right); 304 void *rightValue = cxIteratorCurrent(right);
301 int d = list->cmpfunc(leftValue, rightValue); 305 int d = list->collection.cmpfunc(leftValue, rightValue);
302 if (d != 0) { 306 if (d != 0) {
303 return d; 307 return d;
304 } 308 }
305 cxIteratorNext(left); 309 cxIteratorNext(left);
306 cxIteratorNext(right); 310 cxIteratorNext(right);
307 } 311 }
308 return 0; 312 return 0;
309 } else { 313 } else {
310 return list->size < other->size ? -1 : 1; 314 return list->collection.size < other->collection.size ? -1 : 1;
311 } 315 }
312 } else { 316 } else {
313 // lists are compatible 317 // lists are compatible
314 return list->cl->compare(list, other); 318 return list->cl->compare(list, other);
315 } 319 }
316 } 320 }
317 321
318 CxMutIterator cxListMutIteratorAt( 322 CxIterator cxListMutIteratorAt(
319 CxList *list, 323 CxList *list,
320 size_t index 324 size_t index
321 ) { 325 ) {
322 CxIterator it = list->cl->iterator(list, index, false); 326 CxIterator it = list->cl->iterator(list, index, false);
323 it.base.mutating = true; 327 it.base.mutating = true;
324 328 return it;
325 // we know the iterators share the same memory layout 329 }
326 CxMutIterator iter; 330
327 memcpy(&iter, &it, sizeof(CxMutIterator)); 331 CxIterator cxListMutBackwardsIteratorAt(
328 return iter;
329 }
330
331 CxMutIterator cxListMutBackwardsIteratorAt(
332 CxList *list, 332 CxList *list,
333 size_t index 333 size_t index
334 ) { 334 ) {
335 CxIterator it = list->cl->iterator(list, index, true); 335 CxIterator it = list->cl->iterator(list, index, true);
336 it.base.mutating = true; 336 it.base.mutating = true;
337 337 return it;
338 // we know the iterators share the same memory layout 338 }
339 CxMutIterator iter;
340 memcpy(&iter, &it, sizeof(CxMutIterator));
341 return iter;
342 }

mercurial