ucx/cx/list.h

branch
newapi
changeset 324
ce13a778654a
parent 253
087cc9216f28
equal deleted inserted replaced
323:38cb8e3992e8 324:ce13a778654a
50 50
51 /** 51 /**
52 * Structure for holding the base data of a list. 52 * Structure for holding the base data of a list.
53 */ 53 */
54 struct cx_list_s { 54 struct cx_list_s {
55 CX_COLLECTION_MEMBERS 55 CX_COLLECTION_BASE;
56 /** 56 /**
57 * The list class definition. 57 * The list class definition.
58 */ 58 */
59 cx_list_class const *cl; 59 const cx_list_class *cl;
60 /** 60 /**
61 * The actual implementation in case the list class is delegating. 61 * The actual implementation in case the list class is delegating.
62 */ 62 */
63 cx_list_class const *climpl; 63 const cx_list_class *climpl;
64 }; 64 };
65 65
66 /** 66 /**
67 * The class definition for arbitrary lists. 67 * The class definition for arbitrary lists.
68 */ 68 */
69 struct cx_list_class_s { 69 struct cx_list_class_s {
70 /** 70 /**
71 * Destructor function. 71 * Destructor function.
72 * 72 *
73 * Implementations SHALL invoke the content destructor functions if provided 73 * Implementations SHALL invoke the content destructor functions if provided
74 * and SHALL deallocate the list memory, if an allocator is provided. 74 * and SHALL deallocate the list memory.
75 */ 75 */
76 void (*destructor)(struct cx_list_s *list); 76 void (*destructor)(struct cx_list_s *list);
77 77
78 /** 78 /**
79 * Member function for inserting a single element. 79 * Member function for inserting a single element.
80 * Implementors SHOULD see to performant implementations for corner cases. 80 * Implementors SHOULD see to performant implementations for corner cases.
81 */ 81 */
82 int (*insert_element)( 82 int (*insert_element)(
83 struct cx_list_s *list, 83 struct cx_list_s *list,
84 size_t index, 84 size_t index,
85 void const *data 85 const void *data
86 ); 86 );
87 87
88 /** 88 /**
89 * Member function for inserting multiple elements. 89 * Member function for inserting multiple elements.
90 * Implementors SHOULD see to performant implementations for corner cases. 90 * Implementors SHOULD see to performant implementations for corner cases.
91 * @see cx_list_default_insert_array()
91 */ 92 */
92 size_t (*insert_array)( 93 size_t (*insert_array)(
93 struct cx_list_s *list, 94 struct cx_list_s *list,
94 size_t index, 95 size_t index,
95 void const *data, 96 const void *data,
96 size_t n 97 size_t n
97 ); 98 );
98 99
99 /** 100 /**
101 * Member function for inserting sorted elements into a sorted list.
102 *
103 * @see cx_list_default_insert_sorted()
104 */
105 size_t (*insert_sorted)(
106 struct cx_list_s *list,
107 const void *sorted_data,
108 size_t n
109 );
110
111 /**
100 * Member function for inserting an element relative to an iterator position. 112 * Member function for inserting an element relative to an iterator position.
101 */ 113 */
102 int (*insert_iter)( 114 int (*insert_iter)(
103 struct cx_mut_iterator_s *iter, 115 struct cx_iterator_s *iter,
104 void const *elem, 116 const void *elem,
105 int prepend 117 int prepend
106 ); 118 );
107 119
108 /** 120 /**
109 * Member function for removing an element. 121 * Member function for removing an element.
118 */ 130 */
119 void (*clear)(struct cx_list_s *list); 131 void (*clear)(struct cx_list_s *list);
120 132
121 /** 133 /**
122 * Member function for swapping two elements. 134 * Member function for swapping two elements.
135 * @see cx_list_default_swap()
123 */ 136 */
124 int (*swap)( 137 int (*swap)(
125 struct cx_list_s *list, 138 struct cx_list_s *list,
126 size_t i, 139 size_t i,
127 size_t j 140 size_t j
129 142
130 /** 143 /**
131 * Member function for element lookup. 144 * Member function for element lookup.
132 */ 145 */
133 void *(*at)( 146 void *(*at)(
134 struct cx_list_s const *list, 147 const struct cx_list_s *list,
135 size_t index 148 size_t index
136 ); 149 );
137 150
138 /** 151 /**
139 * Member function for finding and optionally removing an element. 152 * Member function for finding and optionally removing an element.
140 */ 153 */
141 ssize_t (*find_remove)( 154 ssize_t (*find_remove)(
142 struct cx_list_s *list, 155 struct cx_list_s *list,
143 void const *elem, 156 const void *elem,
144 bool remove 157 bool remove
145 ); 158 );
146 159
147 /** 160 /**
148 * Member function for sorting the list in-place. 161 * Member function for sorting the list in-place.
162 * @see cx_list_default_sort()
149 */ 163 */
150 void (*sort)(struct cx_list_s *list); 164 void (*sort)(struct cx_list_s *list);
151 165
152 /** 166 /**
153 * Member function for comparing this list to another list of the same type. 167 * Optional member function for comparing this list
168 * to another list of the same type.
169 * If set to \c NULL, comparison won't be optimized.
154 */ 170 */
155 int (*compare)( 171 int (*compare)(
156 struct cx_list_s const *list, 172 const struct cx_list_s *list,
157 struct cx_list_s const *other 173 const struct cx_list_s *other
158 ); 174 );
159 175
160 /** 176 /**
161 * Member function for reversing the order of the items. 177 * Member function for reversing the order of the items.
162 */ 178 */
164 180
165 /** 181 /**
166 * Member function for returning an iterator pointing to the specified index. 182 * Member function for returning an iterator pointing to the specified index.
167 */ 183 */
168 struct cx_iterator_s (*iterator)( 184 struct cx_iterator_s (*iterator)(
169 struct cx_list_s const *list, 185 const struct cx_list_s *list,
170 size_t index, 186 size_t index,
171 bool backward 187 bool backward
172 ); 188 );
173 }; 189 };
190
191 /**
192 * Default implementation of an array insert.
193 *
194 * This function uses the element insert function for each element of the array.
195 *
196 * Use this in your own list class if you do not want to implement an optimized
197 * version for your list.
198 *
199 * @param list the list
200 * @param index the index where to insert the data
201 * @param data a pointer to the array of data to insert
202 * @param n the number of elements to insert
203 * @return the number of elements actually inserted
204 */
205 __attribute__((__nonnull__))
206 size_t cx_list_default_insert_array(
207 struct cx_list_s *list,
208 size_t index,
209 const void *data,
210 size_t n
211 );
212
213 /**
214 * Default implementation of a sorted insert.
215 *
216 * This function uses the array insert function to insert consecutive groups
217 * of sorted data.
218 *
219 * The source data \em must already be sorted wrt. the list's compare function.
220 *
221 * Use this in your own list class if you do not want to implement an optimized
222 * version for your list.
223 *
224 * @param list the list
225 * @param sorted_data a pointer to the array of pre-sorted data to insert
226 * @param n the number of elements to insert
227 * @return the number of elements actually inserted
228 */
229 __attribute__((__nonnull__))
230 size_t cx_list_default_insert_sorted(
231 struct cx_list_s *list,
232 const void *sorted_data,
233 size_t n
234 );
235
236 /**
237 * Default unoptimized sort implementation.
238 *
239 * This function will copy all data to an array, sort the array with standard
240 * qsort, and then copy the data back to the list memory.
241 *
242 * Use this in your own list class if you do not want to implement an optimized
243 * version for your list.
244 *
245 * @param list the list that shall be sorted
246 */
247 __attribute__((__nonnull__))
248 void cx_list_default_sort(struct cx_list_s *list);
249
250 /**
251 * Default unoptimized swap implementation.
252 *
253 * Use this in your own list class if you do not want to implement an optimized
254 * version for your list.
255 *
256 * @param list the list in which to swap
257 * @param i index of one element
258 * @param j index of the other element
259 * @return zero on success, non-zero when indices are out of bounds or memory
260 * allocation for the temporary buffer fails
261 */
262 __attribute__((__nonnull__))
263 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j);
174 264
175 /** 265 /**
176 * Common type for all list implementations. 266 * Common type for all list implementations.
177 */ 267 */
178 typedef struct cx_list_s CxList; 268 typedef struct cx_list_s CxList;
210 * @param list 300 * @param list
211 * @return true, if this list is storing pointers 301 * @return true, if this list is storing pointers
212 * @see cxListStorePointers() 302 * @see cxListStorePointers()
213 */ 303 */
214 __attribute__((__nonnull__)) 304 __attribute__((__nonnull__))
215 static inline bool cxListIsStoringPointers(CxList const *list) { 305 static inline bool cxListIsStoringPointers(const CxList *list) {
216 return list->store_pointer; 306 return list->collection.store_pointer;
217 } 307 }
218 308
219 /** 309 /**
220 * Returns the number of elements currently stored in the list. 310 * Returns the number of elements currently stored in the list.
221 * 311 *
222 * @param list the list 312 * @param list the list
223 * @return the number of currently stored elements 313 * @return the number of currently stored elements
224 */ 314 */
225 __attribute__((__nonnull__)) 315 __attribute__((__nonnull__))
226 static inline size_t cxListSize(CxList const *list) { 316 static inline size_t cxListSize(const CxList *list) {
227 return list->size; 317 return list->collection.size;
228 } 318 }
229 319
230 /** 320 /**
231 * Adds an item to the end of the list. 321 * Adds an item to the end of the list.
232 * 322 *
236 * @see cxListAddArray() 326 * @see cxListAddArray()
237 */ 327 */
238 __attribute__((__nonnull__)) 328 __attribute__((__nonnull__))
239 static inline int cxListAdd( 329 static inline int cxListAdd(
240 CxList *list, 330 CxList *list,
241 void const *elem 331 const void *elem
242 ) { 332 ) {
243 return list->cl->insert_element(list, list->size, elem); 333 return list->cl->insert_element(list, list->collection.size, elem);
244 } 334 }
245 335
246 /** 336 /**
247 * Adds multiple items to the end of the list. 337 * Adds multiple items to the end of the list.
248 * 338 *
260 * @return the number of added elements 350 * @return the number of added elements
261 */ 351 */
262 __attribute__((__nonnull__)) 352 __attribute__((__nonnull__))
263 static inline size_t cxListAddArray( 353 static inline size_t cxListAddArray(
264 CxList *list, 354 CxList *list,
265 void const *array, 355 const void *array,
266 size_t n 356 size_t n
267 ) { 357 ) {
268 return list->cl->insert_array(list, list->size, array, n); 358 return list->cl->insert_array(list, list->collection.size, array, n);
269 } 359 }
270 360
271 /** 361 /**
272 * Inserts an item at the specified index. 362 * Inserts an item at the specified index.
273 * 363 *
283 */ 373 */
284 __attribute__((__nonnull__)) 374 __attribute__((__nonnull__))
285 static inline int cxListInsert( 375 static inline int cxListInsert(
286 CxList *list, 376 CxList *list,
287 size_t index, 377 size_t index,
288 void const *elem 378 const void *elem
289 ) { 379 ) {
290 return list->cl->insert_element(list, index, elem); 380 return list->cl->insert_element(list, index, elem);
381 }
382
383 /**
384 * Inserts an item into a sorted list.
385 *
386 * @param list the list
387 * @param elem a pointer to the element to add
388 * @return zero on success, non-zero on memory allocation failure
389 */
390 __attribute__((__nonnull__))
391 static inline int cxListInsertSorted(
392 CxList *list,
393 const void *elem
394 ) {
395 const void *data = list->collection.store_pointer ? &elem : elem;
396 return list->cl->insert_sorted(list, data, 1) == 0;
291 } 397 }
292 398
293 /** 399 /**
294 * Inserts multiple items to the list at the specified index. 400 * Inserts multiple items to the list at the specified index.
295 * If \p index equals the list size, this is effectively cxListAddArray(). 401 * If \p index equals the list size, this is effectively cxListAddArray().
311 */ 417 */
312 __attribute__((__nonnull__)) 418 __attribute__((__nonnull__))
313 static inline size_t cxListInsertArray( 419 static inline size_t cxListInsertArray(
314 CxList *list, 420 CxList *list,
315 size_t index, 421 size_t index,
316 void const *array, 422 const void *array,
317 size_t n 423 size_t n
318 ) { 424 ) {
319 return list->cl->insert_array(list, index, array, n); 425 return list->cl->insert_array(list, index, array, n);
426 }
427
428 /**
429 * Inserts a sorted array into a sorted list.
430 *
431 * This method is usually more efficient than inserting each element separately,
432 * because consecutive chunks of sorted data are inserted in one pass.
433 *
434 * If there is not enough memory to add all elements, the returned value is
435 * less than \p n.
436 *
437 * If this list is storing pointers instead of objects \p array is expected to
438 * be an array of pointers.
439 *
440 * @param list the list
441 * @param array a pointer to the elements to add
442 * @param n the number of elements to add
443 * @return the number of added elements
444 */
445 __attribute__((__nonnull__))
446 static inline size_t cxListInsertSortedArray(
447 CxList *list,
448 const void *array,
449 size_t n
450 ) {
451 return list->cl->insert_sorted(list, array, n);
320 } 452 }
321 453
322 /** 454 /**
323 * Inserts an element after the current location of the specified iterator. 455 * Inserts an element after the current location of the specified iterator.
324 * 456 *
334 * @see cxListInsert() 466 * @see cxListInsert()
335 * @see cxListInsertBefore() 467 * @see cxListInsertBefore()
336 */ 468 */
337 __attribute__((__nonnull__)) 469 __attribute__((__nonnull__))
338 static inline int cxListInsertAfter( 470 static inline int cxListInsertAfter(
339 CxMutIterator *iter, 471 CxIterator *iter,
340 void const *elem 472 const void *elem
341 ) { 473 ) {
342 return ((struct cx_list_s *) iter->src_handle)->cl->insert_iter(iter, elem, 0); 474 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 0);
343 } 475 }
344 476
345 /** 477 /**
346 * Inserts an element before the current location of the specified iterator. 478 * Inserts an element before the current location of the specified iterator.
347 * 479 *
357 * @see cxListInsert() 489 * @see cxListInsert()
358 * @see cxListInsertAfter() 490 * @see cxListInsertAfter()
359 */ 491 */
360 __attribute__((__nonnull__)) 492 __attribute__((__nonnull__))
361 static inline int cxListInsertBefore( 493 static inline int cxListInsertBefore(
362 CxMutIterator *iter, 494 CxIterator *iter,
363 void const *elem 495 const void *elem
364 ) { 496 ) {
365 return ((struct cx_list_s *) iter->src_handle)->cl->insert_iter(iter, elem, 1); 497 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 1);
366 } 498 }
367 499
368 /** 500 /**
369 * Removes the element at the specified index. 501 * Removes the element at the specified index.
370 * 502 *
442 * @param index the index where the iterator shall point at 574 * @param index the index where the iterator shall point at
443 * @return a new iterator 575 * @return a new iterator
444 */ 576 */
445 __attribute__((__nonnull__, __warn_unused_result__)) 577 __attribute__((__nonnull__, __warn_unused_result__))
446 static inline CxIterator cxListIteratorAt( 578 static inline CxIterator cxListIteratorAt(
447 CxList const *list, 579 const CxList *list,
448 size_t index 580 size_t index
449 ) { 581 ) {
450 return list->cl->iterator(list, index, false); 582 return list->cl->iterator(list, index, false);
451 } 583 }
452 584
461 * @param index the index where the iterator shall point at 593 * @param index the index where the iterator shall point at
462 * @return a new iterator 594 * @return a new iterator
463 */ 595 */
464 __attribute__((__nonnull__, __warn_unused_result__)) 596 __attribute__((__nonnull__, __warn_unused_result__))
465 static inline CxIterator cxListBackwardsIteratorAt( 597 static inline CxIterator cxListBackwardsIteratorAt(
466 CxList const *list, 598 const CxList *list,
467 size_t index 599 size_t index
468 ) { 600 ) {
469 return list->cl->iterator(list, index, true); 601 return list->cl->iterator(list, index, true);
470 } 602 }
471 603
479 * @param list the list 611 * @param list the list
480 * @param index the index where the iterator shall point at 612 * @param index the index where the iterator shall point at
481 * @return a new iterator 613 * @return a new iterator
482 */ 614 */
483 __attribute__((__nonnull__, __warn_unused_result__)) 615 __attribute__((__nonnull__, __warn_unused_result__))
484 CxMutIterator cxListMutIteratorAt( 616 CxIterator cxListMutIteratorAt(
485 CxList *list, 617 CxList *list,
486 size_t index 618 size_t index
487 ); 619 );
488 620
489 /** 621 /**
497 * @param list the list 629 * @param list the list
498 * @param index the index where the iterator shall point at 630 * @param index the index where the iterator shall point at
499 * @return a new iterator 631 * @return a new iterator
500 */ 632 */
501 __attribute__((__nonnull__, __warn_unused_result__)) 633 __attribute__((__nonnull__, __warn_unused_result__))
502 CxMutIterator cxListMutBackwardsIteratorAt( 634 CxIterator cxListMutBackwardsIteratorAt(
503 CxList *list, 635 CxList *list,
504 size_t index 636 size_t index
505 ); 637 );
506 638
507 /** 639 /**
513 * 645 *
514 * @param list the list 646 * @param list the list
515 * @return a new iterator 647 * @return a new iterator
516 */ 648 */
517 __attribute__((__nonnull__, __warn_unused_result__)) 649 __attribute__((__nonnull__, __warn_unused_result__))
518 static inline CxIterator cxListIterator(CxList const *list) { 650 static inline CxIterator cxListIterator(const CxList *list) {
519 return list->cl->iterator(list, 0, false); 651 return list->cl->iterator(list, 0, false);
520 } 652 }
521 653
522 /** 654 /**
523 * Returns a mutating iterator pointing to the first item of the list. 655 * Returns a mutating iterator pointing to the first item of the list.
528 * 660 *
529 * @param list the list 661 * @param list the list
530 * @return a new iterator 662 * @return a new iterator
531 */ 663 */
532 __attribute__((__nonnull__, __warn_unused_result__)) 664 __attribute__((__nonnull__, __warn_unused_result__))
533 static inline CxMutIterator cxListMutIterator(CxList *list) { 665 static inline CxIterator cxListMutIterator(CxList *list) {
534 return cxListMutIteratorAt(list, 0); 666 return cxListMutIteratorAt(list, 0);
535 } 667 }
536 668
537 669
538 /** 670 /**
544 * 676 *
545 * @param list the list 677 * @param list the list
546 * @return a new iterator 678 * @return a new iterator
547 */ 679 */
548 __attribute__((__nonnull__, __warn_unused_result__)) 680 __attribute__((__nonnull__, __warn_unused_result__))
549 static inline CxIterator cxListBackwardsIterator(CxList const *list) { 681 static inline CxIterator cxListBackwardsIterator(const CxList *list) {
550 return list->cl->iterator(list, list->size - 1, true); 682 return list->cl->iterator(list, list->collection.size - 1, true);
551 } 683 }
552 684
553 /** 685 /**
554 * Returns a mutating backwards iterator pointing to the last item of the list. 686 * Returns a mutating backwards iterator pointing to the last item of the list.
555 * 687 *
559 * 691 *
560 * @param list the list 692 * @param list the list
561 * @return a new iterator 693 * @return a new iterator
562 */ 694 */
563 __attribute__((__nonnull__, __warn_unused_result__)) 695 __attribute__((__nonnull__, __warn_unused_result__))
564 static inline CxMutIterator cxListMutBackwardsIterator(CxList *list) { 696 static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
565 return cxListMutBackwardsIteratorAt(list, list->size - 1); 697 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
566 } 698 }
567 699
568 /** 700 /**
569 * Returns the index of the first element that equals \p elem. 701 * Returns the index of the first element that equals \p elem.
570 * 702 *
575 * @return the index of the element or a negative 707 * @return the index of the element or a negative
576 * value when the element is not found 708 * value when the element is not found
577 */ 709 */
578 __attribute__((__nonnull__)) 710 __attribute__((__nonnull__))
579 static inline ssize_t cxListFind( 711 static inline ssize_t cxListFind(
580 CxList const *list, 712 const CxList *list,
581 void const *elem 713 const void *elem
582 ) { 714 ) {
583 return list->cl->find_remove((CxList*)list, elem, false); 715 return list->cl->find_remove((CxList*)list, elem, false);
584 } 716 }
585 717
586 /** 718 /**
594 * value when the element is not found or could not be removed 726 * value when the element is not found or could not be removed
595 */ 727 */
596 __attribute__((__nonnull__)) 728 __attribute__((__nonnull__))
597 static inline ssize_t cxListFindRemove( 729 static inline ssize_t cxListFindRemove(
598 CxList *list, 730 CxList *list,
599 void const *elem 731 const void *elem
600 ) { 732 ) {
601 return list->cl->find_remove(list, elem, true); 733 return list->cl->find_remove(list, elem, true);
602 } 734 }
603 735
604 /** 736 /**
634 * @return zero, if both lists are equal element wise, 766 * @return zero, if both lists are equal element wise,
635 * negative if the first list is smaller, positive if the first list is larger 767 * negative if the first list is smaller, positive if the first list is larger
636 */ 768 */
637 __attribute__((__nonnull__)) 769 __attribute__((__nonnull__))
638 int cxListCompare( 770 int cxListCompare(
639 CxList const *list, 771 const CxList *list,
640 CxList const *other 772 const CxList *other
641 ); 773 );
642 774
643 /** 775 /**
644 * Deallocates the memory of the specified list structure. 776 * Deallocates the memory of the specified list structure.
645 * 777 *

mercurial