src/linked_list.c

Fri, 23 May 2025 12:44:24 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 23 May 2025 12:44:24 +0200
changeset 1327
ed75dc1db503
parent 1319
aa1f580f8f59
permissions
-rw-r--r--

make test-compile depend on both static and shared

the shared lib is not needed for the tests,
but when run with coverage, gcov will be confused
when outdated line information is available from
a previous shared build

398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 *
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 *
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 *
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 *
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 */
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29 #include "cx/linked_list.h"
763
741a2040fa33 make cx_cmp_ptr default comparator for pointer lists - relates to #340
Mike Becker <universe@uap-core.de>
parents: 735
diff changeset
30 #include "cx/compare.h"
401
e6a8f7fb0c45 copy list items when they are added to the list
Mike Becker <universe@uap-core.de>
parents: 400
diff changeset
31 #include <string.h>
453
bb144d08cd44 add some documentation and changes some signatures
Mike Becker <universe@uap-core.de>
parents: 451
diff changeset
32 #include <assert.h>
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
33
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 592
diff changeset
34 // LOW LEVEL LINKED LIST FUNCTIONS
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
35
592
bb69ef3ad1f3 enclose macro arguments in parenthesis
Mike Becker <universe@uap-core.de>
parents: 552
diff changeset
36 #define CX_LL_PTR(cur, off) (*(void**)(((char*)(cur))+(off)))
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
37 #define ll_prev(node) CX_LL_PTR(node, loc_prev)
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
38 #define ll_next(node) CX_LL_PTR(node, loc_next)
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
39 #define ll_advance(node) CX_LL_PTR(node, loc_advance)
639
309e8b08c60e temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents: 638
diff changeset
40 #define ll_data(node) (((char*)(node))+loc_data)
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
41
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
42 void *cx_linked_list_at(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
43 const void *start,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
44 size_t start_index,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
45 ptrdiff_t loc_advance,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
46 size_t index
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
47 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
48 assert(start != NULL);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
49 assert(loc_advance >= 0);
438
cd3069757010 add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents: 437
diff changeset
50 size_t i = start_index;
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
51 const void *cur = start;
438
cd3069757010 add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents: 437
diff changeset
52 while (i != index && cur != NULL) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
53 cur = ll_advance(cur);
438
cd3069757010 add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents: 437
diff changeset
54 i < index ? i++ : i--;
cd3069757010 add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents: 437
diff changeset
55 }
508
8aea65ae1eaf #168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents: 503
diff changeset
56 return (void *) cur;
438
cd3069757010 add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents: 437
diff changeset
57 }
cd3069757010 add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents: 437
diff changeset
58
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
59 void *cx_linked_list_find(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
60 const void *start,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
61 ptrdiff_t loc_advance,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
62 ptrdiff_t loc_data,
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
63 cx_compare_func cmp_func,
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
64 const void *elem,
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
65 size_t *found_index
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
66 ) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
67 assert(start != NULL);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
68 assert(loc_advance >= 0);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
69 assert(loc_data >= 0);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
70 assert(cmp_func);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
71
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
72 void *node = (void*) start;
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
73 size_t index = 0;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
74 do {
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
75 void *current = ll_data(node);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
76 if (cmp_func(current, elem) == 0) {
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
77 if (found_index != NULL) {
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
78 *found_index = index;
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
79 }
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
80 return node;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
81 }
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
82 node = ll_advance(node);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
83 index++;
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
84 } while (node != NULL);
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
85 return NULL;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
86 }
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
87
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
88 void *cx_linked_list_first(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
89 const void *node,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
90 ptrdiff_t loc_prev
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
91 ) {
475
31bf97fdbf71 add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents: 474
diff changeset
92 return cx_linked_list_last(node, loc_prev);
31bf97fdbf71 add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents: 474
diff changeset
93 }
31bf97fdbf71 add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents: 474
diff changeset
94
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
95 void *cx_linked_list_last(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
96 const void *node,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
97 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
98 ) {
478
599770bb6314 add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents: 477
diff changeset
99 assert(node != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
100 assert(loc_next >= 0);
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
101
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
102 const void *cur = node;
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
103 const void *last;
456
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
104 do {
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
105 last = cur;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
106 } while ((cur = ll_next(cur)) != NULL);
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
107
508
8aea65ae1eaf #168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents: 503
diff changeset
108 return (void *) last;
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
109 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
110
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
111 void *cx_linked_list_prev(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
112 const void *begin,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
113 ptrdiff_t loc_next,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
114 const void *node
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
115 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
116 assert(begin != NULL);
478
599770bb6314 add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents: 477
diff changeset
117 assert(node != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
118 assert(loc_next >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
119 if (begin == node) return NULL;
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
120 const void *cur = begin;
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
121 const void *next;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
122 while (1) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
123 next = ll_next(cur);
508
8aea65ae1eaf #168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents: 503
diff changeset
124 if (next == node) return (void *) cur;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
125 cur = next;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
126 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
127 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
128
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
129 void cx_linked_list_link(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
130 void *left,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
131 void *right,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
132 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
133 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
134 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
135 assert(loc_next >= 0);
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
136 ll_next(left) = right;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
137 if (loc_prev >= 0) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
138 ll_prev(right) = left;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
139 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
140 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
141
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
142 void cx_linked_list_unlink(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
143 void *left,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
144 void *right,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
145 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
146 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
147 ) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
148 assert (loc_next >= 0);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
149 assert(ll_next(left) == right);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
150 ll_next(left) = NULL;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
151 if (loc_prev >= 0) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
152 assert(ll_prev(right) == left);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
153 ll_prev(right) = NULL;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
154 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
155 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
156
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
157 void cx_linked_list_add(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
158 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
159 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
160 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
161 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
162 void *new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
163 ) {
456
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
164 void *last;
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
165 if (end == NULL) {
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
166 assert(begin != NULL);
478
599770bb6314 add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents: 477
diff changeset
167 last = *begin == NULL ? NULL : cx_linked_list_last(*begin, loc_next);
456
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
168 } else {
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
169 last = *end;
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
170 }
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
171 cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, last, new_node, new_node);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
172 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
173
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
174 void cx_linked_list_prepend(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
175 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
176 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
177 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
178 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
179 void *new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
180 ) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
181 cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, NULL, new_node, new_node);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
182 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
183
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
184 void cx_linked_list_insert(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
185 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
186 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
187 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
188 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
189 void *node,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
190 void *new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
191 ) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
192 cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, node, new_node, new_node);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
193 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
194
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
195 void cx_linked_list_insert_chain(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
196 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
197 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
198 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
199 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
200 void *node,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
201 void *insert_begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
202 void *insert_end
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
203 ) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
204 // find the end of the chain, if not specified
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
205 if (insert_end == NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
206 insert_end = cx_linked_list_last(insert_begin, loc_next);
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
207 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
208
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
209 // determine the successor
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
210 void *successor;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
211 if (node == NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
212 assert(begin != NULL || (end != NULL && loc_prev >= 0));
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
213 if (begin != NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
214 successor = *begin;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
215 *begin = insert_begin;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
216 } else {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
217 successor = *end == NULL ? NULL : cx_linked_list_first(*end, loc_prev);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
218 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
219 } else {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
220 successor = ll_next(node);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
221 cx_linked_list_link(node, insert_begin, loc_prev, loc_next);
408
dfdd571550f8 fixes cx_linked_list_add not recalculating end
Mike Becker <universe@uap-core.de>
parents: 407
diff changeset
222 }
428
da66264af8ad fix special cases for linked_list_add
Mike Becker <universe@uap-core.de>
parents: 423
diff changeset
223
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
224 if (successor == NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
225 // the list ends with the new chain
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
226 if (end != NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
227 *end = insert_end;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
228 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
229 } else {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
230 cx_linked_list_link(insert_end, successor, loc_prev, loc_next);
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
231 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
232 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
233
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
234 void cx_linked_list_insert_sorted(
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
235 void **begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
236 void **end,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
237 ptrdiff_t loc_prev,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
238 ptrdiff_t loc_next,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
239 void *new_node,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
240 cx_compare_func cmp_func
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
241 ) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
242 assert(ll_next(new_node) == NULL);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
243 cx_linked_list_insert_sorted_chain(
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
244 begin, end, loc_prev, loc_next, new_node, cmp_func);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
245 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
246
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
247 void cx_linked_list_insert_sorted_chain(
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
248 void **begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
249 void **end,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
250 ptrdiff_t loc_prev,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
251 ptrdiff_t loc_next,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
252 void *insert_begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
253 cx_compare_func cmp_func
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
254 ) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
255 assert(begin != NULL);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
256 assert(loc_next >= 0);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
257 assert(insert_begin != NULL);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
258
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
259 // track currently observed nodes
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
260 void *dest_prev = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
261 void *dest = *begin;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
262 void *src = insert_begin;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
263
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
264 // special case: list is empty
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
265 if (dest == NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
266 *begin = src;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
267 if (end != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
268 *end = cx_linked_list_last(src, loc_next);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
269 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
270 return;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
271 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
272
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
273 // search the list for insertion points
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
274 while (dest != NULL && src != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
275 // compare current list node with source node
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
276 // if less or equal, skip
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
277 if (cmp_func(dest, src) <= 0) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
278 dest_prev = dest;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
279 dest = ll_next(dest);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
280 continue;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
281 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
282
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
283 // determine chain of elements that can be inserted
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
284 void *end_of_chain = src;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
285 void *next_in_chain = ll_next(src);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
286 while (next_in_chain != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
287 // once we become larger than the list elem, break
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
288 if (cmp_func(dest, next_in_chain) <= 0) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
289 break;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
290 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
291 // otherwise, we can insert one more
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
292 end_of_chain = next_in_chain;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
293 next_in_chain = ll_next(next_in_chain);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
294 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
295
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
296 // insert the elements
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
297 if (dest_prev == NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
298 // new begin
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
299 *begin = src;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
300 } else {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
301 cx_linked_list_link(dest_prev, src, loc_prev, loc_next);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
302 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
303 cx_linked_list_link(end_of_chain, dest, loc_prev, loc_next);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
304
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
305 // continue with next
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
306 src = next_in_chain;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
307 dest_prev = dest;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
308 dest = ll_next(dest);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
309 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
310
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
311 // insert remaining items
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
312 if (src != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
313 cx_linked_list_link(dest_prev, src, loc_prev, loc_next);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
314 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
315
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
316 // determine new end of list, if requested
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
317 if (end != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
318 *end = cx_linked_list_last(
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
319 dest != NULL ? dest : dest_prev, loc_next);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
320 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
321 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
322
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
323 size_t cx_linked_list_remove_chain(
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
324 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
325 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
326 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
327 ptrdiff_t loc_next,
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
328 void *node,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
329 size_t num
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
330 ) {
477
73a93c7a56ae add more explicit documentation to cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 476
diff changeset
331 assert(node != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
332 assert(loc_next >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
333 assert(loc_prev >= 0 || begin != NULL);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
334
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
335 // easy exit
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
336 if (num == 0) return 0;
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
337
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
338 // find adjacent nodes
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
339 void *prev;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
340 if (loc_prev >= 0) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
341 prev = ll_prev(node);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
342 } else {
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
343 prev = cx_linked_list_prev(*begin, loc_next, node);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
344 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
345
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
346 void *next = ll_next(node);
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
347 size_t removed = 1;
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
348 for (; removed < num && next != NULL ; removed++) {
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
349 next = ll_next(next);
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
350 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
351
476
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
352 // update next pointer of prev node, or set begin
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
353 if (prev == NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
354 if (begin != NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
355 *begin = next;
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
356 }
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
357 } else {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
358 ll_next(prev) = next;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
359 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
360
476
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
361 // update prev pointer of next node, or set end
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
362 if (next == NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
363 if (end != NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
364 *end = prev;
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
365 }
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
366 } else if (loc_prev >= 0) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
367 ll_prev(next) = prev;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
368 }
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
369
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
370 return removed;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
371 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
372
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
373 size_t cx_linked_list_size(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
374 const void *node,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
375 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
376 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
377 assert(loc_next >= 0);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
378 size_t size = 0;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
379 while (node != NULL) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
380 node = ll_next(node);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
381 size++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
382 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
383 return size;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
384 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
385
661
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
386 #ifndef CX_LINKED_LIST_SORT_SBO_SIZE
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
387 #define CX_LINKED_LIST_SORT_SBO_SIZE 1024
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
388 #endif
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
389
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
390 static void cx_linked_list_sort_merge(
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
391 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
392 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
393 ptrdiff_t loc_data,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
394 size_t length,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
395 void *ls,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
396 void *le,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
397 void *re,
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
398 cx_compare_func cmp_func,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
399 void **begin,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
400 void **end
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
401 ) {
661
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
402 void *sbo[CX_LINKED_LIST_SORT_SBO_SIZE];
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
403 void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ?
1319
aa1f580f8f59 add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents: 1318
diff changeset
404 cxMallocDefault(sizeof(void *) * length) : sbo;
508
8aea65ae1eaf #168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents: 503
diff changeset
405 if (sorted == NULL) abort();
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
406 void *rc, *lc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
407
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
408 lc = ls;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
409 rc = le;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
410 size_t n = 0;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
411 while (lc && lc != le && rc != re) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
412 if (cmp_func(ll_data(lc), ll_data(rc)) <= 0) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
413 sorted[n] = lc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
414 lc = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
415 } else {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
416 sorted[n] = rc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
417 rc = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
418 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
419 n++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
420 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
421 while (lc && lc != le) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
422 sorted[n] = lc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
423 lc = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
424 n++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
425 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
426 while (rc && rc != re) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
427 sorted[n] = rc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
428 rc = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
429 n++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
430 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
431
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
432 // Update pointer
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
433 if (loc_prev >= 0) ll_prev(sorted[0]) = NULL;
962
cd418898af5c remove cx_for_n() macro - fixes #467
Mike Becker <universe@uap-core.de>
parents: 950
diff changeset
434 for (size_t i = 0 ; i < length - 1; i++) {
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
435 cx_linked_list_link(sorted[i], sorted[i + 1], loc_prev, loc_next);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
436 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
437 ll_next(sorted[length - 1]) = NULL;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
438
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
439 *begin = sorted[0];
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
440 *end = sorted[length - 1];
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
441 if (sorted != sbo) {
1319
aa1f580f8f59 add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents: 1318
diff changeset
442 cxFreeDefault(sorted);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
443 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
444 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
445
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 592
diff changeset
446 void cx_linked_list_sort( // NOLINT(misc-no-recursion) - purposely recursive function
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
447 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
448 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
449 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
450 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
451 ptrdiff_t loc_data,
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
452 cx_compare_func cmp_func
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
453 ) {
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
454 assert(begin != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
455 assert(loc_next >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
456 assert(loc_data >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
457 assert(cmp_func);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
458
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
459 void *lc, *ls, *le, *re;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
460
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
461 // set start node
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
462 ls = *begin;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
463
702
3390b58ad15a fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents: 699
diff changeset
464 // early exit when this list is empty
3390b58ad15a fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents: 699
diff changeset
465 if (ls == NULL) return;
3390b58ad15a fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents: 699
diff changeset
466
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
467 // check how many elements are already sorted
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
468 lc = ls;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
469 size_t ln = 1;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
470 while (ll_next(lc) != NULL && cmp_func(ll_data(ll_next(lc)), ll_data(lc)) > 0) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
471 lc = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
472 ln++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
473 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
474 le = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
475
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
476 // if first unsorted node is NULL, the list is already completely sorted
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
477 if (le != NULL) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
478 void *rc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
479 size_t rn = 1;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
480 rc = le;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
481 // skip already sorted elements
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
482 while (ll_next(rc) != NULL && cmp_func(ll_data(ll_next(rc)), ll_data(rc)) > 0) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
483 rc = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
484 rn++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
485 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
486 re = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
487
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
488 // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
489 void *sorted_begin, *sorted_end;
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
490 cx_linked_list_sort_merge(loc_prev, loc_next, loc_data,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
491 ln + rn, ls, le, re, cmp_func,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
492 &sorted_begin, &sorted_end);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
493
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
494 // Something left? Sort it!
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
495 size_t remainder_length = cx_linked_list_size(re, loc_next);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
496 if (remainder_length > 0) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
497 void *remainder = re;
639
309e8b08c60e temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents: 638
diff changeset
498 cx_linked_list_sort(&remainder, NULL, loc_prev, loc_next, loc_data, cmp_func);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
499
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
500 // merge sorted list with (also sorted) remainder
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
501 cx_linked_list_sort_merge(loc_prev, loc_next, loc_data,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
502 ln + rn + remainder_length,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
503 sorted_begin, remainder, NULL, cmp_func,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
504 &sorted_begin, &sorted_end);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
505 }
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
506 *begin = sorted_begin;
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
507 if (end) *end = sorted_end;
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
508 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
509 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
510
486
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
511 int cx_linked_list_compare(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
512 const void *begin_left,
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
513 const void *begin_right,
486
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
514 ptrdiff_t loc_advance,
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
515 ptrdiff_t loc_data,
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
516 cx_compare_func cmp_func
486
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
517 ) {
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
518 const void *left = begin_left, *right = begin_right;
486
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
519
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
520 while (left != NULL && right != NULL) {
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
521 const void *left_data = ll_data(left);
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
522 const void *right_data = ll_data(right);
552
4373c2a90066 #178 fix that lists of different kind cannot be compared
Mike Becker <universe@uap-core.de>
parents: 528
diff changeset
523 int result = cmp_func(left_data, right_data);
486
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
524 if (result != 0) return result;
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
525 left = ll_advance(left);
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
526 right = ll_advance(right);
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
527 }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
528
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
529 if (left != NULL) { return 1; }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
530 else if (right != NULL) { return -1; }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
531 else { return 0; }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
532 }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
533
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
534 void cx_linked_list_reverse(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
535 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
536 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
537 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
538 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
539 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
540 assert(begin != NULL);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
541 assert(loc_next >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
542
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
543 // swap all links
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
544 void *prev = NULL;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
545 void *cur = *begin;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
546 while (cur != NULL) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
547 void *next = ll_next(cur);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
548
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
549 ll_next(cur) = prev;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
550 if (loc_prev >= 0) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
551 ll_prev(cur) = next;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
552 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
553
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
554 prev = cur;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
555 cur = next;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
556 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
557
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
558 // update begin and end
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
559 if (end != NULL) {
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
560 *end = *begin;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
561 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
562 *begin = prev;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
563 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
564
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 592
diff changeset
565 // HIGH LEVEL LINKED LIST IMPLEMENTATION
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
566
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
567 typedef struct cx_linked_list_node cx_linked_list_node;
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
568 struct cx_linked_list_node {
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
569 cx_linked_list_node *prev;
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
570 cx_linked_list_node *next;
403
8fa43b732980 use C99 flexible array to mark the node's payload
Mike Becker <universe@uap-core.de>
parents: 402
diff changeset
571 char payload[];
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
572 };
402
a34b93911956 use named fields to access node memory
Mike Becker <universe@uap-core.de>
parents: 401
diff changeset
573
446
668757098b73 remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents: 441
diff changeset
574 #define CX_LL_LOC_PREV offsetof(cx_linked_list_node, prev)
668757098b73 remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents: 441
diff changeset
575 #define CX_LL_LOC_NEXT offsetof(cx_linked_list_node, next)
469
0458bff0b1cd add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents: 468
diff changeset
576 #define CX_LL_LOC_DATA offsetof(cx_linked_list_node, payload)
439
9a5adedd6de6 add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents: 438
diff changeset
577
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
578 typedef struct {
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
579 struct cx_list_s base;
446
668757098b73 remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents: 441
diff changeset
580 cx_linked_list_node *begin;
668757098b73 remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents: 441
diff changeset
581 cx_linked_list_node *end;
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
582 } cx_linked_list;
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
583
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
584 static cx_linked_list_node *cx_ll_node_at(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
585 const cx_linked_list *list,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
586 size_t index
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
587 ) {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
588 if (index >= list->base.collection.size) {
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
589 return NULL;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
590 } else if (index > list->base.collection.size / 2) {
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
591 return cx_linked_list_at(list->end, list->base.collection.size - 1, CX_LL_LOC_PREV, index);
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
592 } else {
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
593 return cx_linked_list_at(list->begin, 0, CX_LL_LOC_NEXT, index);
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
594 }
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
595 }
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
596
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
597 static cx_linked_list_node *cx_ll_malloc_node(const struct cx_list_s *list) {
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
598 return cxMalloc(list->collection.allocator,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
599 sizeof(cx_linked_list_node) + list->collection.elem_size);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
600 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
601
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
602 static int cx_ll_insert_at(
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
603 struct cx_list_s *list,
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
604 cx_linked_list_node *node,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
605 const void *elem
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
606 ) {
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
607
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
608 // create the new new_node
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
609 cx_linked_list_node *new_node = cx_ll_malloc_node(list);
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
610
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
611 // sortir if failed
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
612 if (new_node == NULL) return 1;
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
613
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
614 // initialize new new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
615 new_node->prev = new_node->next = NULL;
1316
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
616 if (elem != NULL) {
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
617 memcpy(new_node->payload, elem, list->collection.elem_size);
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
618 }
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
619
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
620 // insert
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
621 cx_linked_list *ll = (cx_linked_list *) list;
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
622 cx_linked_list_insert_chain(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
623 (void **) &ll->begin, (void **) &ll->end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
624 CX_LL_LOC_PREV, CX_LL_LOC_NEXT,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
625 node, new_node, new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
626 );
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
627
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
628 // increase the size and return
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
629 list->collection.size++;
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
630 return 0;
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
631 }
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
632
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
633 static size_t cx_ll_insert_array(
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
634 struct cx_list_s *list,
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
635 size_t index,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
636 const void *array,
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
637 size_t n
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
638 ) {
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
639 // out-of bounds and corner case check
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
640 if (index > list->collection.size || n == 0) return 0;
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
641
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
642 // find position efficiently
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
643 cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
644
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
645 // perform first insert
1065
6eb7b54975ee improve coverage metrics
Mike Becker <universe@uap-core.de>
parents: 962
diff changeset
646 if (0 != cx_ll_insert_at(list, node, array)) return 1;
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
647
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
648 // is there more?
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
649 if (n == 1) return 1;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
650
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
651 // we now know exactly where we are
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
652 node = node == NULL ? ((cx_linked_list *) list)->begin : node->next;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
653
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
654 // we can add the remaining nodes and immediately advance to the inserted node
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
655 const char *source = array;
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
656 for (size_t i = 1; i < n; i++) {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
657 source += list->collection.elem_size;
1065
6eb7b54975ee improve coverage metrics
Mike Becker <universe@uap-core.de>
parents: 962
diff changeset
658 if (0 != cx_ll_insert_at(list, node, source)) return i;
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
659 node = node->next;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
660 }
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
661 return n;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
662 }
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
663
1316
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
664 static void *cx_ll_insert_element(
641
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
665 struct cx_list_s *list,
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
666 size_t index,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
667 const void *element
641
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
668 ) {
1316
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
669 // out-of-bounds check
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
670 if (index > list->collection.size) return NULL;
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
671
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
672 // find position efficiently
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
673 cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
674
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
675 // perform first insert
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
676 if (cx_ll_insert_at(list, node, element)) return NULL;
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
677
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
678 // return a pointer to the data of the inserted node
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
679 if (node == NULL) {
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
680 return ((cx_linked_list *) list)->begin->payload;
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
681 } else {
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
682 return node->next->payload;
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
683 }
641
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
684 }
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
685
880
54133f14043f fix cx_ll_insert_sorted_cmp_func not being thread local
Mike Becker <universe@uap-core.de>
parents: 879
diff changeset
686 static _Thread_local cx_compare_func cx_ll_insert_sorted_cmp_func;
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
687
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
688 static int cx_ll_insert_sorted_cmp_helper(const void *l, const void *r) {
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
689 const cx_linked_list_node *left = l;
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
690 const cx_linked_list_node *right = r;
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
691 return cx_ll_insert_sorted_cmp_func(left->payload, right->payload);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
692 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
693
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
694 static size_t cx_ll_insert_sorted(
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
695 struct cx_list_s *list,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
696 const void *array,
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
697 size_t n
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
698 ) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
699 // special case
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
700 if (n == 0) return 0;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
701
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
702 // create a new chain of nodes
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
703 cx_linked_list_node *chain = cx_ll_malloc_node(list);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
704 if (chain == NULL) return 0;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
705
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
706 memcpy(chain->payload, array, list->collection.elem_size);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
707 chain->prev = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
708 chain->next = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
709
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
710 // add all elements from the array to that chain
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
711 cx_linked_list_node *prev = chain;
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
712 const char *src = array;
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
713 size_t inserted = 1;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
714 for (; inserted < n; inserted++) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
715 cx_linked_list_node *next = cx_ll_malloc_node(list);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
716 if (next == NULL) break;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
717 src += list->collection.elem_size;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
718 memcpy(next->payload, src, list->collection.elem_size);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
719 prev->next = next;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
720 next->prev = prev;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
721 prev = next;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
722 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
723 prev->next = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
724
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
725 // invoke the low level function
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
726 cx_linked_list *ll = (cx_linked_list *) list;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
727 cx_ll_insert_sorted_cmp_func = list->collection.cmpfunc;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
728 cx_linked_list_insert_sorted_chain(
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
729 (void **) &ll->begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
730 (void **) &ll->end,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
731 CX_LL_LOC_PREV,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
732 CX_LL_LOC_NEXT,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
733 chain,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
734 cx_ll_insert_sorted_cmp_helper
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
735 );
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
736
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
737 // adjust the list metadata
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
738 list->collection.size += inserted;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
739
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
740 return inserted;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
741 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
742
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
743 static size_t cx_ll_remove(
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
744 struct cx_list_s *list,
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
745 size_t index,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
746 size_t num,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
747 void *targetbuf
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
748 ) {
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
749 cx_linked_list *ll = (cx_linked_list *) list;
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
750 cx_linked_list_node *node = cx_ll_node_at(ll, index);
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
751
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
752 // out-of-bounds check
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
753 if (node == NULL) return 0;
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
754
476
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
755 // remove
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
756 size_t removed = cx_linked_list_remove_chain(
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
757 (void **) &ll->begin,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
758 (void **) &ll->end,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
759 CX_LL_LOC_PREV,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
760 CX_LL_LOC_NEXT,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
761 node,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
762 num
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
763 );
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
764
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
765 // adjust size
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
766 list->collection.size -= removed;
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
767
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
768 // copy or destroy the removed chain
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
769 if (targetbuf == NULL) {
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
770 cx_linked_list_node *n = node;
962
cd418898af5c remove cx_for_n() macro - fixes #467
Mike Becker <universe@uap-core.de>
parents: 950
diff changeset
771 for (size_t i = 0; i < removed; i++) {
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
772 // element destruction
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
773 cx_invoke_destructor(list, n->payload);
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
774
925
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
775 // free the node and advance
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
776 void *next = n->next;
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
777 cxFree(list->collection.allocator, n);
925
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
778 n = next;
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
779 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
780 } else {
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
781 char *dest = targetbuf;
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
782 cx_linked_list_node *n = node;
962
cd418898af5c remove cx_for_n() macro - fixes #467
Mike Becker <universe@uap-core.de>
parents: 950
diff changeset
783 for (size_t i = 0; i < removed; i++) {
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
784 // copy payload
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
785 memcpy(dest, n->payload, list->collection.elem_size);
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
786
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
787 // advance target buffer
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
788 dest += list->collection.elem_size;
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
789
925
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
790 // free the node and advance
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
791 void *next = n->next;
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
792 cxFree(list->collection.allocator, n);
925
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
793 n = next;
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
794 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
795 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
796
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
797 return removed;
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
798 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
799
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
800 static void cx_ll_clear(struct cx_list_s *list) {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
801 if (list->collection.size == 0) return;
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
802
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
803 cx_linked_list *ll = (cx_linked_list *) list;
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
804 cx_linked_list_node *node = ll->begin;
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
805 while (node != NULL) {
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
806 cx_invoke_destructor(list, node->payload);
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
807 cx_linked_list_node *next = node->next;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
808 cxFree(list->collection.allocator, node);
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
809 node = next;
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
810 }
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
811 ll->begin = ll->end = NULL;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
812 list->collection.size = 0;
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
813 }
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
814
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
815 static int cx_ll_swap(
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
816 struct cx_list_s *list,
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
817 size_t i,
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
818 size_t j
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
819 ) {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
820 if (i >= list->collection.size || j >= list->collection.size) return 1;
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
821 if (i == j) return 0;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
822
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
823 // perform an optimized search that finds both elements in one run
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
824 cx_linked_list *ll = (cx_linked_list *) list;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
825 size_t mid = list->collection.size / 2;
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
826 size_t left, right;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
827 if (i < j) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
828 left = i;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
829 right = j;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
830 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
831 left = j;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
832 right = i;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
833 }
950
37e7f92de46b fix missing pointer initializations
Mike Becker <universe@uap-core.de>
parents: 926
diff changeset
834 cx_linked_list_node *nleft = NULL, *nright = NULL;
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
835 if (left < mid && right < mid) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
836 // case 1: both items left from mid
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
837 nleft = cx_ll_node_at(ll, left);
807
c8d692131b1e remove flags to disable SBO in tests - fix #343 fix #358
Mike Becker <universe@uap-core.de>
parents: 764
diff changeset
838 assert(nleft != NULL);
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
839 nright = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
840 for (size_t c = left; c < right; c++) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
841 nright = nright->next;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
842 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
843 } else if (left >= mid && right >= mid) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
844 // case 2: both items right from mid
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
845 nright = cx_ll_node_at(ll, right);
807
c8d692131b1e remove flags to disable SBO in tests - fix #343 fix #358
Mike Becker <universe@uap-core.de>
parents: 764
diff changeset
846 assert(nright != NULL);
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
847 nleft = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
848 for (size_t c = right; c > left; c--) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
849 nleft = nleft->prev;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
850 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
851 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
852 // case 3: one item left, one item right
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
853
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
854 // chose the closest to begin / end
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
855 size_t closest;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
856 size_t other;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
857 size_t diff2boundary = list->collection.size - right - 1;
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
858 if (left <= diff2boundary) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
859 closest = left;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
860 other = right;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
861 nleft = cx_ll_node_at(ll, left);
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
862 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
863 closest = right;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
864 other = left;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
865 diff2boundary = left;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
866 nright = cx_ll_node_at(ll, right);
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
867 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
868
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
869 // is other element closer to us or closer to boundary?
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
870 if (right - left <= diff2boundary) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
871 // search other element starting from already found element
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
872 if (closest == left) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
873 nright = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
874 for (size_t c = left; c < right; c++) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
875 nright = nright->next;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
876 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
877 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
878 nleft = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
879 for (size_t c = right; c > left; c--) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
880 nleft = nleft->prev;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
881 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
882 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
883 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
884 // search other element starting at the boundary
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
885 if (closest == left) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
886 nright = cx_ll_node_at(ll, other);
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
887 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
888 nleft = cx_ll_node_at(ll, other);
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
889 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
890 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
891 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
892
1113
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
893 cx_linked_list_node *prev = nleft->prev;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
894 cx_linked_list_node *next = nright->next;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
895 cx_linked_list_node *midstart = nleft->next;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
896 cx_linked_list_node *midend = nright->prev;
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
897
1113
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
898 if (prev == NULL) {
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
899 ll->begin = nright;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
900 } else {
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
901 prev->next = nright;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
902 }
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
903 nright->prev = prev;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
904 if (midstart == nright) {
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
905 // special case: both nodes are adjacent
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
906 nright->next = nleft;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
907 nleft->prev = nright;
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
908 } else {
1113
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
909 // likely case: a chain is between the two nodes
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
910 nright->next = midstart;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
911 midstart->prev = nright;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
912 midend->next = nleft;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
913 nleft->prev = midend;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
914 }
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
915 nleft->next = next;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
916 if (next == NULL) {
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
917 ll->end = nleft;
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
918 } else {
dce04550fbef remove CX_LINKED_LIST_SWAP_SBO_SIZE - fixes #551
Mike Becker <universe@uap-core.de>
parents: 1111
diff changeset
919 next->prev = nleft;
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
920 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
921
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
922 return 0;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
923 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
924
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
925 static void *cx_ll_at(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
926 const struct cx_list_s *list,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
927 size_t index
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
928 ) {
439
9a5adedd6de6 add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents: 438
diff changeset
929 cx_linked_list *ll = (cx_linked_list *) list;
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
930 cx_linked_list_node *node = cx_ll_node_at(ll, index);
466
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
931 return node == NULL ? NULL : node->payload;
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
932 }
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
933
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
934 static size_t cx_ll_find_remove(
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
935 struct cx_list_s *list,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
936 const void *elem,
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
937 bool remove
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
938 ) {
1225
086e63c8dd06 fix cxListFind() crashing on empty linked lists
Mike Becker <universe@uap-core.de>
parents: 1162
diff changeset
939 if (list->collection.size == 0) return 0;
086e63c8dd06 fix cxListFind() crashing on empty linked lists
Mike Becker <universe@uap-core.de>
parents: 1162
diff changeset
940
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
941 size_t index;
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
942 cx_linked_list *ll = ((cx_linked_list *) list);
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
943 cx_linked_list_node *node = cx_linked_list_find(
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
944 ll->begin,
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
945 CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
946 list->collection.cmpfunc, elem,
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
947 &index
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
948 );
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
949 if (node == NULL) {
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
950 return list->collection.size;
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
951 }
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
952 if (remove) {
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
953 cx_invoke_destructor(list, node->payload);
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
954 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
955 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
956 list->collection.size--;
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
957 cxFree(list->collection.allocator, node);
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
958 }
1162
e3bb67b72d33 remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents: 1113
diff changeset
959 return index;
466
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
960 }
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
961
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
962 static void cx_ll_sort(struct cx_list_s *list) {
469
0458bff0b1cd add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents: 468
diff changeset
963 cx_linked_list *ll = (cx_linked_list *) list;
0458bff0b1cd add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents: 468
diff changeset
964 cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end,
0458bff0b1cd add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents: 468
diff changeset
965 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
966 list->collection.cmpfunc);
469
0458bff0b1cd add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents: 468
diff changeset
967 }
0458bff0b1cd add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents: 468
diff changeset
968
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
969 static void cx_ll_reverse(struct cx_list_s *list) {
490
e66551b47466 add cxListReverse()
Mike Becker <universe@uap-core.de>
parents: 489
diff changeset
970 cx_linked_list *ll = (cx_linked_list *) list;
521
e5dc54131d55 add test for cxListCompare
Mike Becker <universe@uap-core.de>
parents: 509
diff changeset
971 cx_linked_list_reverse((void **) &ll->begin, (void **) &ll->end, CX_LL_LOC_PREV, CX_LL_LOC_NEXT);
490
e66551b47466 add cxListReverse()
Mike Becker <universe@uap-core.de>
parents: 489
diff changeset
972 }
e66551b47466 add cxListReverse()
Mike Becker <universe@uap-core.de>
parents: 489
diff changeset
973
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
974 static int cx_ll_compare(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
975 const struct cx_list_s *list,
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
976 const struct cx_list_s *other
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
977 ) {
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
978 cx_linked_list *left = (cx_linked_list *) list;
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
979 cx_linked_list *right = (cx_linked_list *) other;
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
980 return cx_linked_list_compare(left->begin, right->begin,
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
981 CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
982 list->collection.cmpfunc);
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
983 }
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
984
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
985 static bool cx_ll_iter_valid(const void *it) {
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
986 const struct cx_iterator_s *iter = it;
495
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
987 return iter->elem_handle != NULL;
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
988 }
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
989
630
ac5e7f789048 separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents: 629
diff changeset
990 static void cx_ll_iter_next(void *it) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
991 struct cx_iterator_s *iter = it;
854
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
992 if (iter->base.remove) {
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
993 iter->base.remove = false;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
994 struct cx_list_s *list = iter->src_handle.m;
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
995 cx_linked_list *ll = iter->src_handle.m;
495
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
996 cx_linked_list_node *node = iter->elem_handle;
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
997 iter->elem_handle = node->next;
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
998 cx_invoke_destructor(list, node->payload);
495
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
999 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1000 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1001 list->collection.size--;
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1002 cxFree(list->collection.allocator, node);
495
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1003 } else {
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1004 iter->index++;
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1005 cx_linked_list_node *node = iter->elem_handle;
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1006 iter->elem_handle = node->next;
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1007 }
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1008 }
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1009
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1010 static void cx_ll_iter_prev(void *it) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1011 struct cx_iterator_s *iter = it;
854
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
1012 if (iter->base.remove) {
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
1013 iter->base.remove = false;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1014 struct cx_list_s *list = iter->src_handle.m;
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1015 cx_linked_list *ll = iter->src_handle.m;
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1016 cx_linked_list_node *node = iter->elem_handle;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1017 iter->elem_handle = node->prev;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1018 iter->index--;
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
1019 cx_invoke_destructor(list, node->payload);
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1020 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1021 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1022 list->collection.size--;
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1023 cxFree(list->collection.allocator, node);
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1024 } else {
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1025 iter->index--;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1026 cx_linked_list_node *node = iter->elem_handle;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1027 iter->elem_handle = node->prev;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1028 }
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1029 }
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1030
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1031 static void *cx_ll_iter_current(const void *it) {
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1032 const struct cx_iterator_s *iter = it;
495
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1033 cx_linked_list_node *node = iter->elem_handle;
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1034 return node->payload;
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1035 }
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1036
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1037 static CxIterator cx_ll_iterator(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1038 const struct cx_list_s *list,
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1039 size_t index,
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1040 bool backwards
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1041 ) {
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1042 CxIterator iter;
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1043 iter.index = index;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1044 iter.src_handle.c = list;
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1045 iter.elem_handle = cx_ll_node_at((const cx_linked_list *) list, index);
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1046 iter.elem_size = list->collection.elem_size;
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1047 iter.elem_count = list->collection.size;
854
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
1048 iter.base.valid = cx_ll_iter_valid;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
1049 iter.base.current = cx_ll_iter_current;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
1050 iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
1051 iter.base.mutating = false;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
1052 iter.base.remove = false;
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1053 return iter;
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1054 }
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1055
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1056 static int cx_ll_insert_iter(
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1057 CxIterator *iter,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1058 const void *elem,
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1059 int prepend
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1060 ) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1061 struct cx_list_s *list = iter->src_handle.m;
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1062 cx_linked_list_node *node = iter->elem_handle;
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1063 if (node != NULL) {
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1064 assert(prepend >= 0 && prepend <= 1);
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1065 cx_linked_list_node *choice[2] = {node, node->prev};
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1066 int result = cx_ll_insert_at(list, choice[prepend], elem);
874
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1067 if (result == 0) {
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1068 iter->elem_count++;
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1069 if (prepend) {
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1070 iter->index++;
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1071 }
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1072 }
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1073 return result;
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1074 } else {
1316
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
1075 if (cx_ll_insert_element(list, list->collection.size, elem) == NULL) {
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
1076 return 1;
874
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1077 }
1316
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
1078 iter->elem_count++;
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
1079 iter->index = list->collection.size;
c41538edfcef add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents: 1225
diff changeset
1080 return 0;
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1081 }
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1082 }
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1083
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1084 static void cx_ll_destructor(CxList *list) {
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1085 cx_linked_list *ll = (cx_linked_list *) list;
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1086
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1087 cx_linked_list_node *node = ll->begin;
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1088 while (node) {
708
1caed6c9ba68 fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents: 703
diff changeset
1089 cx_invoke_destructor(list, node->payload);
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1090 void *next = node->next;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1091 cxFree(list->collection.allocator, node);
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1092 node = next;
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1093 }
708
1caed6c9ba68 fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents: 703
diff changeset
1094
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1095 cxFree(list->collection.allocator, list);
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1096 }
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1097
451
db06dda7ac4d make cx_linked_list_class static
Mike Becker <universe@uap-core.de>
parents: 448
diff changeset
1098 static cx_list_class cx_linked_list_class = {
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1099 cx_ll_destructor,
641
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
1100 cx_ll_insert_element,
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
1101 cx_ll_insert_array,
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
1102 cx_ll_insert_sorted,
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1103 cx_ll_insert_iter,
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1104 cx_ll_remove,
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
1105 cx_ll_clear,
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
1106 cx_ll_swap,
439
9a5adedd6de6 add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents: 438
diff changeset
1107 cx_ll_at,
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
1108 cx_ll_find_remove,
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
1109 cx_ll_sort,
490
e66551b47466 add cxListReverse()
Mike Becker <universe@uap-core.de>
parents: 489
diff changeset
1110 cx_ll_compare,
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1111 cx_ll_reverse,
630
ac5e7f789048 separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents: 629
diff changeset
1112 cx_ll_iterator,
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1113 };
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1114
670
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1115 CxList *cxLinkedListCreate(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1116 const CxAllocator *allocator,
677
b09aae58bba4 refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents: 670
diff changeset
1117 cx_compare_func comparator,
855
35bcb3216c0d fix inconsistent use of item_size and elem_size
Mike Becker <universe@uap-core.de>
parents: 854
diff changeset
1118 size_t elem_size
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
1119 ) {
670
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1120 if (allocator == NULL) {
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1121 allocator = cxDefaultAllocator;
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1122 }
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1123
503
a89857072ace add new destructor API and apply it to CxList
Mike Becker <universe@uap-core.de>
parents: 500
diff changeset
1124 cx_linked_list *list = cxCalloc(allocator, 1, sizeof(cx_linked_list));
528
4fbfac557df8 #179 improve API for list content destruction
Mike Becker <universe@uap-core.de>
parents: 524
diff changeset
1125 if (list == NULL) return NULL;
1111
78eeeb950883 remove API for changing the store_pointer property after list creation
Mike Becker <universe@uap-core.de>
parents: 1065
diff changeset
1126 cx_list_init((CxList*)list, &cx_linked_list_class,
78eeeb950883 remove API for changing the store_pointer property after list creation
Mike Becker <universe@uap-core.de>
parents: 1065
diff changeset
1127 allocator, comparator, elem_size);
667
2f88a7c13a28 add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents: 666
diff changeset
1128
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
1129 return (CxList *) list;
406
9cbea761fbf7 adds cxLinkedListWrap and cxLinkedListRecalculateSize
Mike Becker <universe@uap-core.de>
parents: 404
diff changeset
1130 }

mercurial