src/linked_list.c

Sun, 22 Dec 2024 22:10:04 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 22 Dec 2024 22:10:04 +0100
changeset 1047
40aad3f0bc9e
parent 962
cd418898af5c
permissions
-rw-r--r--

don't trust that size_t always has word width

it should be the case on all platforms supported by UCX, but it's not strictly defined in POSIX that it must be the case

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
699
35b2b99ee523 make list find return a negative value when elem not found
Mike Becker <universe@uap-core.de>
parents: 677
diff changeset
59 ssize_t 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,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
64 const void *elem
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
65 ) {
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
66 void *dummy;
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
67 return cx_linked_list_find_node(
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
68 &dummy, start,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
69 loc_advance, loc_data,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
70 cmp_func, elem
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
71 );
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
72 }
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
73
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
74 ssize_t cx_linked_list_find_node(
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
75 void **result,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
76 const void *start,
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
77 ptrdiff_t loc_advance,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
78 ptrdiff_t loc_data,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
79 cx_compare_func cmp_func,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
80 const void *elem
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
81 ) {
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
82 assert(result != NULL);
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
83 assert(start != NULL);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
84 assert(loc_advance >= 0);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
85 assert(loc_data >= 0);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
86 assert(cmp_func);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
87
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
88 const void *node = start;
699
35b2b99ee523 make list find return a negative value when elem not found
Mike Becker <universe@uap-core.de>
parents: 677
diff changeset
89 ssize_t index = 0;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
90 do {
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
91 void *current = ll_data(node);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
92 if (cmp_func(current, elem) == 0) {
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
93 *result = (void *) node;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
94 return index;
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
95 }
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
96 node = ll_advance(node);
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
97 index++;
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
98 } while (node != NULL);
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
99 *result = NULL;
699
35b2b99ee523 make list find return a negative value when elem not found
Mike Becker <universe@uap-core.de>
parents: 677
diff changeset
100 return -1;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
101 }
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
102
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
103 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
104 const void *node,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
105 ptrdiff_t loc_prev
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
106 ) {
475
31bf97fdbf71 add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents: 474
diff changeset
107 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
108 }
31bf97fdbf71 add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents: 474
diff changeset
109
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
110 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
111 const void *node,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
112 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
113 ) {
478
599770bb6314 add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents: 477
diff changeset
114 assert(node != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
115 assert(loc_next >= 0);
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
116
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
117 const void *cur = node;
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
118 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
119 do {
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
120 last = cur;
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
121 } while ((cur = ll_next(cur)) != NULL);
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
122
508
8aea65ae1eaf #168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents: 503
diff changeset
123 return (void *) last;
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
124 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
125
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
126 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
127 const void *begin,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
128 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
129 const void *node
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
130 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
131 assert(begin != NULL);
478
599770bb6314 add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents: 477
diff changeset
132 assert(node != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
133 assert(loc_next >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
134 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
135 const void *cur = begin;
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
136 const void *next;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
137 while (1) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
138 next = ll_next(cur);
508
8aea65ae1eaf #168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents: 503
diff changeset
139 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
140 cur = next;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
141 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
142 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
143
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
144 void cx_linked_list_link(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
145 void *left,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
146 void *right,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
147 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
148 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
149 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
150 assert(loc_next >= 0);
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
151 ll_next(left) = right;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
152 if (loc_prev >= 0) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
153 ll_prev(right) = left;
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_unlink(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
158 void *left,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
159 void *right,
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 ) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
163 assert (loc_next >= 0);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
164 assert(ll_next(left) == right);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
165 ll_next(left) = NULL;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
166 if (loc_prev >= 0) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
167 assert(ll_prev(right) == left);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
168 ll_prev(right) = NULL;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
169 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
170 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
171
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
172 void cx_linked_list_add(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
173 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
174 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
175 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
176 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
177 void *new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
178 ) {
456
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
179 void *last;
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
180 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
181 assert(begin != NULL);
478
599770bb6314 add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents: 477
diff changeset
182 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
183 } else {
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
184 last = *end;
227c2eabbef8 change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents: 453
diff changeset
185 }
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
186 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
187 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
188
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
189 void cx_linked_list_prepend(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
190 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
191 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
192 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
193 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
194 void *new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
195 ) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
196 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
197 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
198
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
199 void cx_linked_list_insert(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
200 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
201 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
202 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
203 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
204 void *node,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
205 void *new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
206 ) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
207 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
208 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
209
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
210 void cx_linked_list_insert_chain(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
211 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
212 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
213 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
214 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
215 void *node,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
216 void *insert_begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
217 void *insert_end
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 // 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
220 if (insert_end == NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
221 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
222 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
223
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
224 // determine the successor
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
225 void *successor;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
226 if (node == NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
227 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
228 if (begin != NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
229 successor = *begin;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
230 *begin = insert_begin;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
231 } else {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
232 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
233 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
234 } else {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
235 successor = ll_next(node);
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
236 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
237 }
428
da66264af8ad fix special cases for linked_list_add
Mike Becker <universe@uap-core.de>
parents: 423
diff changeset
238
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
239 if (successor == NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
240 // the list ends with the new chain
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
241 if (end != NULL) {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
242 *end = insert_end;
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
243 }
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
244 } else {
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
245 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
246 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
247 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
248
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
249 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
250 void **begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
251 void **end,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
252 ptrdiff_t loc_prev,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
253 ptrdiff_t loc_next,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
254 void *new_node,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
255 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
256 ) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
257 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
258 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
259 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
260 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
261
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
262 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
263 void **begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
264 void **end,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
265 ptrdiff_t loc_prev,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
266 ptrdiff_t loc_next,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
267 void *insert_begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
268 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
269 ) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
270 assert(begin != NULL);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
271 assert(loc_next >= 0);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
272 assert(insert_begin != NULL);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
273
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
274 // track currently observed nodes
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
275 void *dest_prev = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
276 void *dest = *begin;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
277 void *src = insert_begin;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
278
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
279 // 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
280 if (dest == NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
281 *begin = src;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
282 if (end != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
283 *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
284 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
285 return;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
286 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
287
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
288 // 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
289 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
290 // 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
291 // 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
292 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
293 dest_prev = dest;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
294 dest = ll_next(dest);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
295 continue;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
296 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
297
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
298 // 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
299 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
300 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
301 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
302 // 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
303 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
304 break;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
305 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
306 // 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
307 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
308 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
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 the elements
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
312 if (dest_prev == NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
313 // new begin
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
314 *begin = src;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
315 } else {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
316 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
317 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
318 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
319
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
320 // continue with next
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
321 src = next_in_chain;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
322 dest_prev = dest;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
323 dest = ll_next(dest);
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
324 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
325
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
326 // insert remaining items
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
327 if (src != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
328 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
329 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
330
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
331 // 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
332 if (end != NULL) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
333 *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
334 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
335 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
336 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
337
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
338 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
339 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
340 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
341 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
342 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
343 void *node,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
344 size_t num
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
345 ) {
477
73a93c7a56ae add more explicit documentation to cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 476
diff changeset
346 assert(node != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
347 assert(loc_next >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
348 assert(loc_prev >= 0 || begin != NULL);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
349
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
350 // easy exit
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
351 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
352
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
353 // find adjacent nodes
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
354 void *prev;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
355 if (loc_prev >= 0) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
356 prev = ll_prev(node);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
357 } else {
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
358 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
359 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
360
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
361 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
362 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
363 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
364 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
365 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
366
476
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
367 // 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
368 if (prev == NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
369 if (begin != NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
370 *begin = next;
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
371 }
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
372 } else {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
373 ll_next(prev) = next;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
374 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
375
476
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
376 // 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
377 if (next == NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
378 if (end != NULL) {
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
379 *end = prev;
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
380 }
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
381 } else if (loc_prev >= 0) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
382 ll_prev(next) = prev;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
383 }
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
384
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
385 return removed;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
386 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
387
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
388 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
389 const void *node,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
390 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
391 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
392 assert(loc_next >= 0);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
393 size_t size = 0;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
394 while (node != NULL) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
395 node = ll_next(node);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
396 size++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
397 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
398 return size;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
399 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
400
661
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
401 #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
402 #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
403 #endif
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
404
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
405 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
406 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
407 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
408 ptrdiff_t loc_data,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
409 size_t length,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
410 void *ls,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
411 void *le,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
412 void *re,
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
413 cx_compare_func cmp_func,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
414 void **begin,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
415 void **end
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
416 ) {
661
0a71ac9547fd add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents: 655
diff changeset
417 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
418 void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ?
662
d0d95740071b add simple functions for creating lists
Mike Becker <universe@uap-core.de>
parents: 661
diff changeset
419 malloc(sizeof(void *) * length) : sbo;
508
8aea65ae1eaf #168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents: 503
diff changeset
420 if (sorted == NULL) abort();
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
421 void *rc, *lc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
422
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
423 lc = ls;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
424 rc = le;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
425 size_t n = 0;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
426 while (lc && lc != le && rc != re) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
427 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
428 sorted[n] = lc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
429 lc = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
430 } else {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
431 sorted[n] = rc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
432 rc = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
433 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
434 n++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
435 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
436 while (lc && lc != le) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
437 sorted[n] = lc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
438 lc = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
439 n++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
440 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
441 while (rc && rc != re) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
442 sorted[n] = rc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
443 rc = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
444 n++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
445 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
446
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
447 // Update pointer
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
448 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
449 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
450 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
451 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
452 ll_next(sorted[length - 1]) = NULL;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
453
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
454 *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
455 *end = sorted[length - 1];
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
456 if (sorted != sbo) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
457 free(sorted);
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 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
460
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 592
diff changeset
461 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
462 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
463 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
464 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
465 ptrdiff_t loc_next,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
466 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
467 cx_compare_func cmp_func
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
468 ) {
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
469 assert(begin != NULL);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
470 assert(loc_next >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
471 assert(loc_data >= 0);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
472 assert(cmp_func);
468
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 void *lc, *ls, *le, *re;
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 // set start node
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
477 ls = *begin;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
478
702
3390b58ad15a fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents: 699
diff changeset
479 // 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
480 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
481
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
482 // check how many elements are already sorted
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
483 lc = ls;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
484 size_t ln = 1;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
485 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
486 lc = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
487 ln++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
488 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
489 le = ll_next(lc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
490
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
491 // 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
492 if (le != NULL) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
493 void *rc;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
494 size_t rn = 1;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
495 rc = le;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
496 // skip already sorted elements
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
497 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
498 rc = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
499 rn++;
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
500 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
501 re = ll_next(rc);
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
502
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
503 // {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
504 void *sorted_begin, *sorted_end;
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
505 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
506 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
507 &sorted_begin, &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 // Something left? Sort it!
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
510 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
511 if (remainder_length > 0) {
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
512 void *remainder = re;
639
309e8b08c60e temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents: 638
diff changeset
513 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
514
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
515 // 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
516 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
517 ln + rn + remainder_length,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
518 sorted_begin, remainder, NULL, cmp_func,
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
519 &sorted_begin, &sorted_end);
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
520 }
703
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
521 *begin = sorted_begin;
425d4279856f improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents: 702
diff changeset
522 if (end) *end = sorted_end;
468
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
523 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
524 }
75ae1dccd101 add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents: 467
diff changeset
525
486
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
526 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
527 const void *begin_left,
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
528 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
529 ptrdiff_t loc_advance,
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
530 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
531 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
532 ) {
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
533 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
534
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
535 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
536 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
537 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
538 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
539 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
540 left = ll_advance(left);
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
541 right = ll_advance(right);
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
542 }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
543
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
544 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
545 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
546 else { return 0; }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
547 }
d7ca126eab7f add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents: 481
diff changeset
548
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
549 void cx_linked_list_reverse(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
550 void **begin,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
551 void **end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
552 ptrdiff_t loc_prev,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
553 ptrdiff_t loc_next
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
554 ) {
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
555 assert(begin != NULL);
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
556 assert(loc_next >= 0);
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 // swap all links
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
559 void *prev = NULL;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
560 void *cur = *begin;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
561 while (cur != NULL) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
562 void *next = ll_next(cur);
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
563
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
564 ll_next(cur) = prev;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
565 if (loc_prev >= 0) {
480
e3be53a3354f add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents: 478
diff changeset
566 ll_prev(cur) = next;
473
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
567 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
568
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
569 prev = cur;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
570 cur = next;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
571 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
572
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
573 // update begin and end
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
574 if (end != NULL) {
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
575 *end = *begin;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
576 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
577 *begin = prev;
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
578 }
1bd4b8c28722 add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents: 469
diff changeset
579
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 592
diff changeset
580 // HIGH LEVEL LINKED LIST IMPLEMENTATION
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
581
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
582 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
583 struct cx_linked_list_node {
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
584 cx_linked_list_node *prev;
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
585 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
586 char payload[];
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
587 };
402
a34b93911956 use named fields to access node memory
Mike Becker <universe@uap-core.de>
parents: 401
diff changeset
588
446
668757098b73 remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents: 441
diff changeset
589 #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
590 #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
591 #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
592
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
593 typedef struct {
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
594 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
595 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
596 cx_linked_list_node *end;
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
597 } cx_linked_list;
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
598
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
599 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
600 const cx_linked_list *list,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
601 size_t index
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
602 ) {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
603 if (index >= list->base.collection.size) {
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
604 return NULL;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
605 } 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
606 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
607 } else {
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
608 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
609 }
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
610 }
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
611
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
612 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
613 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
614 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
615 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
616
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
617 static int cx_ll_insert_at(
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
618 struct cx_list_s *list,
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
619 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
620 const void *elem
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
621 ) {
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
622
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
623 // 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
624 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
625
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
626 // sortir if failed
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
627 if (new_node == NULL) return 1;
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
628
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
629 // initialize new new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
630 new_node->prev = new_node->next = NULL;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
631 memcpy(new_node->payload, elem, list->collection.elem_size);
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
632
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
633 // insert
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
634 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
635 cx_linked_list_insert_chain(
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
636 (void **) &ll->begin, (void **) &ll->end,
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
637 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
638 node, new_node, new_node
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
639 );
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
640
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
641 // 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
642 list->collection.size++;
448
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
643 return 0;
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
644 }
37c5d2fdb36b implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents: 447
diff changeset
645
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
646 static size_t cx_ll_insert_array(
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
647 struct cx_list_s *list,
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
648 size_t index,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
649 const void *array,
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
650 size_t n
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
651 ) {
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
652 // 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
653 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
654
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
655 // find position efficiently
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
656 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
657
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
658 // perform first insert
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
659 if (0 != cx_ll_insert_at(list, node, array)) {
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
660 return 1;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
661 }
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 // is there more?
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
664 if (n == 1) return 1;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
665
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
666 // we now know exactly where we are
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
667 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
668
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
669 // 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
670 const char *source = array;
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
671 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
672 source += list->collection.elem_size;
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
673 if (0 != cx_ll_insert_at(list, node, source)) {
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
674 return i;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
675 }
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
676 node = node->next;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
677 }
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
678 return n;
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
679 }
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
680
641
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
681 static int cx_ll_insert_element(
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
682 struct cx_list_s *list,
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
683 size_t index,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
684 const void *element
641
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
685 ) {
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
686 return 1 != cx_ll_insert_array(list, index, element, 1);
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
687 }
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
688
880
54133f14043f fix cx_ll_insert_sorted_cmp_func not being thread local
Mike Becker <universe@uap-core.de>
parents: 879
diff changeset
689 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
690
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
691 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
692 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
693 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
694 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
695 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
696
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
697 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
698 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
699 const void *array,
879
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
700 size_t n
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 // special case
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
703 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
704
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
705 // 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
706 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
707 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
708
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
709 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
710 chain->prev = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
711 chain->next = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
712
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
713 // 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
714 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
715 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
716 size_t inserted = 1;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
717 for (; inserted < n; inserted++) {
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
718 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
719 if (next == NULL) break;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
720 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
721 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
722 prev->next = next;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
723 next->prev = prev;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
724 prev = next;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
725 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
726 prev->next = NULL;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
727
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
728 // 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
729 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
730 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
731 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
732 (void **) &ll->begin,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
733 (void **) &ll->end,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
734 CX_LL_LOC_PREV,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
735 CX_LL_LOC_NEXT,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
736 chain,
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
737 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
738 );
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 // adjust the list metadata
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
741 list->collection.size += inserted;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
742
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
743 return inserted;
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
744 }
9c24a4eb5ac9 implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents: 876
diff changeset
745
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
746 static size_t cx_ll_remove(
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
747 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
748 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
749 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
750 void *targetbuf
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
751 ) {
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
752 cx_linked_list *ll = (cx_linked_list *) list;
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
753 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
754
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
755 // 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
756 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
757
476
60ff4561dc04 change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents: 475
diff changeset
758 // remove
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
759 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
760 (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
761 (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
762 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
763 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
764 node,
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
765 num
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
766 );
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
767
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
768 // 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
769 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
770
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
771 // 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
772 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
773 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
774 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
775 // element destruction
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
776 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
777
925
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
778 // free the node and advance
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
779 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
780 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
781 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
782 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
783 } else {
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
784 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
785 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
786 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
787 // copy payload
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
788 memcpy(dest, n->payload, list->collection.elem_size);
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
789
919
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
790 // 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
791 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
792
925
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
793 // free the node and advance
fd6e191f3268 fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents: 919
diff changeset
794 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
795 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
796 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
797 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
798 }
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
799
75da57d4634e add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
800 return removed;
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
801 }
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
802
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
803 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
804 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
805
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
806 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
807 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
808 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
809 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
810 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
811 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
812 node = next;
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 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
815 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
816 }
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
817
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
818 #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE
735
b686d0c98c62 unify the list swap SBO sizes
Mike Becker <universe@uap-core.de>
parents: 708
diff changeset
819 #define CX_LINKED_LIST_SWAP_SBO_SIZE 128
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
820 #endif
926
8fdd8d78c14b fix several survivors of east-const and some missing consts
Mike Becker <universe@uap-core.de>
parents: 925
diff changeset
821 const unsigned cx_linked_list_swap_sbo_size = CX_LINKED_LIST_SWAP_SBO_SIZE;
647
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 static int cx_ll_swap(
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
824 struct cx_list_s *list,
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
825 size_t i,
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
826 size_t j
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
827 ) {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
828 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
829 if (i == j) return 0;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
830
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
831 // 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
832 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
833 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
834 size_t left, right;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
835 if (i < j) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
836 left = i;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
837 right = j;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
838 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
839 left = j;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
840 right = i;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
841 }
950
37e7f92de46b fix missing pointer initializations
Mike Becker <universe@uap-core.de>
parents: 926
diff changeset
842 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
843 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 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
845 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
846 assert(nleft != NULL);
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
847 nright = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
848 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
849 nright = nright->next;
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 if (left >= mid && right >= mid) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
852 // 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
853 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
854 assert(nright != NULL);
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
855 nleft = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
856 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
857 nleft = nleft->prev;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
858 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
859 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
860 // 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
861
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
862 // 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
863 size_t closest;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
864 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
865 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
866 if (left <= diff2boundary) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
867 closest = left;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
868 other = right;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
869 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
870 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
871 closest = right;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
872 other = left;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
873 diff2boundary = left;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
874 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
875 }
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 // 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
878 if (right - left <= diff2boundary) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
879 // 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
880 if (closest == left) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
881 nright = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
882 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
883 nright = nright->next;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
884 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
885 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
886 nleft = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
887 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
888 nleft = nleft->prev;
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 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
892 // 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
893 if (closest == left) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
894 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
895 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
896 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
897 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
898 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
899 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
900
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
901 if (list->collection.elem_size > CX_LINKED_LIST_SWAP_SBO_SIZE) {
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
902 cx_linked_list_node *prev = nleft->prev;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
903 cx_linked_list_node *next = nright->next;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
904 cx_linked_list_node *midstart = nleft->next;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
905 cx_linked_list_node *midend = nright->prev;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
906
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
907 if (prev == NULL) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
908 ll->begin = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
909 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
910 prev->next = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
911 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
912 nright->prev = prev;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
913 if (midstart == nright) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
914 // special case: both nodes are adjacent
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
915 nright->next = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
916 nleft->prev = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
917 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
918 // likely case: a chain is between the two nodes
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
919 nright->next = midstart;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
920 midstart->prev = nright;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
921 midend->next = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
922 nleft->prev = midend;
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 nleft->next = next;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
925 if (next == NULL) {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
926 ll->end = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
927 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
928 next->prev = nleft;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
929 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
930 } else {
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
931 // swap payloads to avoid relinking
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
932 char buf[CX_LINKED_LIST_SWAP_SBO_SIZE];
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
933 memcpy(buf, nleft->payload, 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
934 memcpy(nleft->payload, nright->payload, 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
935 memcpy(nright->payload, buf, list->collection.elem_size);
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
936 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
937
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
938 return 0;
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
939 }
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
940
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
941 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
942 const struct cx_list_s *list,
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
943 size_t index
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
944 ) {
439
9a5adedd6de6 add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents: 438
diff changeset
945 cx_linked_list *ll = (cx_linked_list *) list;
447
87b2cdd668ed implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents: 446
diff changeset
946 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
947 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
948 }
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
949
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
950 static ssize_t cx_ll_find_remove(
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
951 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
952 const void *elem,
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
953 bool remove
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
954 ) {
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
955 if (remove) {
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
956 cx_linked_list *ll = ((cx_linked_list *) list);
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
957 cx_linked_list_node *node;
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
958 ssize_t index = cx_linked_list_find_node(
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
959 (void **) &node,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
960 ll->begin,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
961 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
962 list->collection.cmpfunc, elem
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
963 );
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
964 if (node != NULL) {
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
965 cx_invoke_destructor(list, node->payload);
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
966 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
967 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
968 list->collection.size--;
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
969 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
970 }
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
971 return index;
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
972 } else {
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
973 return cx_linked_list_find(
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
974 ((cx_linked_list *) list)->begin,
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
975 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
976 list->collection.cmpfunc, elem
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
977 );
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
978 }
466
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
979 }
28bc3e10ac28 add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents: 457
diff changeset
980
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
981 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
982 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
983 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
984 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
985 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
986 }
0458bff0b1cd add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents: 468
diff changeset
987
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
988 static void cx_ll_reverse(struct cx_list_s *list) {
490
e66551b47466 add cxListReverse()
Mike Becker <universe@uap-core.de>
parents: 489
diff changeset
989 cx_linked_list *ll = (cx_linked_list *) list;
521
e5dc54131d55 add test for cxListCompare
Mike Becker <universe@uap-core.de>
parents: 509
diff changeset
990 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
991 }
e66551b47466 add cxListReverse()
Mike Becker <universe@uap-core.de>
parents: 489
diff changeset
992
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
993 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
994 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
995 const struct cx_list_s *other
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
996 ) {
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
997 cx_linked_list *left = (cx_linked_list *) list;
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
998 cx_linked_list *right = (cx_linked_list *) other;
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
999 return cx_linked_list_compare(left->begin, right->begin,
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
1000 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
1001 list->collection.cmpfunc);
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
1002 }
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
1003
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1004 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
1005 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
1006 return iter->elem_handle != NULL;
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1007 }
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1008
630
ac5e7f789048 separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents: 629
diff changeset
1009 static void cx_ll_iter_next(void *it) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1010 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
1011 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
1012 iter->base.remove = false;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1013 struct cx_list_s *list = iter->src_handle.m;
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1014 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
1015 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
1016 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
1017 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
1018 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
1019 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
1020 list->collection.size--;
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1021 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
1022 } else {
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1023 iter->index++;
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1024 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
1025 iter->elem_handle = node->next;
2856c74e18ba add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents: 494
diff changeset
1026 }
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1027 }
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1028
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1029 static void cx_ll_iter_prev(void *it) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1030 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
1031 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
1032 iter->base.remove = false;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1033 struct cx_list_s *list = iter->src_handle.m;
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1034 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
1035 cx_linked_list_node *node = iter->elem_handle;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1036 iter->elem_handle = node->prev;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1037 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
1038 cx_invoke_destructor(list, node->payload);
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1039 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
1040 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
1041 list->collection.size--;
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1042 cxFree(list->collection.allocator, node);
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1043 } else {
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1044 iter->index--;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1045 cx_linked_list_node *node = iter->elem_handle;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1046 iter->elem_handle = node->prev;
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1047 }
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1048 }
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1049
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1050 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
1051 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
1052 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
1053 return node->payload;
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
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1056 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
1057 const struct cx_list_s *list,
655
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1058 size_t index,
7340c4255f1f implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents: 654
diff changeset
1059 bool backwards
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1060 ) {
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1061 CxIterator iter;
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1062 iter.index = index;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1063 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
1064 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
1065 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
1066 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
1067 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
1068 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
1069 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
1070 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
1071 iter.base.remove = false;
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1072 return iter;
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1073 }
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1074
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1075 static int cx_ll_insert_iter(
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1076 CxIterator *iter,
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1077 const void *elem,
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1078 int prepend
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1079 ) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
1080 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
1081 cx_linked_list_node *node = iter->elem_handle;
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1082 if (node != NULL) {
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1083 assert(prepend >= 0 && prepend <= 1);
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1084 cx_linked_list_node *choice[2] = {node, node->prev};
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1085 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
1086 if (result == 0) {
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1087 iter->elem_count++;
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1088 if (prepend) {
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1089 iter->index++;
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1090 }
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1091 }
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1092 return result;
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1093 } else {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1094 int result = cx_ll_insert_element(list, list->collection.size, elem);
874
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1095 if (result == 0) {
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1096 iter->elem_count++;
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1097 iter->index = list->collection.size;
cdce47f34d48 fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents: 856
diff changeset
1098 }
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1099 return result;
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1100 }
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1101 }
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1102
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1103 static void cx_ll_destructor(CxList *list) {
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1104 cx_linked_list *ll = (cx_linked_list *) list;
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1105
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1106 cx_linked_list_node *node = ll->begin;
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1107 while (node) {
708
1caed6c9ba68 fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents: 703
diff changeset
1108 cx_invoke_destructor(list, node->payload);
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1109 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
1110 cxFree(list->collection.allocator, node);
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1111 node = next;
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1112 }
708
1caed6c9ba68 fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents: 703
diff changeset
1113
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1114 cxFree(list->collection.allocator, list);
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1115 }
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1116
451
db06dda7ac4d make cx_linked_list_class static
Mike Becker <universe@uap-core.de>
parents: 448
diff changeset
1117 static cx_list_class cx_linked_list_class = {
524
e98b09018d32 remove list destructor
Mike Becker <universe@uap-core.de>
parents: 521
diff changeset
1118 cx_ll_destructor,
641
d402fead3386 add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents: 640
diff changeset
1119 cx_ll_insert_element,
638
eafb45eefc51 add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents: 630
diff changeset
1120 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
1121 cx_ll_insert_sorted,
499
3dc9075df822 add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents: 495
diff changeset
1122 cx_ll_insert_iter,
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1123 cx_ll_remove,
664
af5bf4603a5d add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents: 662
diff changeset
1124 cx_ll_clear,
647
2e6e9d9f2159 implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents: 641
diff changeset
1125 cx_ll_swap,
439
9a5adedd6de6 add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents: 438
diff changeset
1126 cx_ll_at,
764
ccbdbd088455 add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents: 763
diff changeset
1127 cx_ll_find_remove,
488
9138acaa494b add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents: 487
diff changeset
1128 cx_ll_sort,
490
e66551b47466 add cxListReverse()
Mike Becker <universe@uap-core.de>
parents: 489
diff changeset
1129 cx_ll_compare,
494
6ce8cfa10a96 add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents: 490
diff changeset
1130 cx_ll_reverse,
630
ac5e7f789048 separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents: 629
diff changeset
1131 cx_ll_iterator,
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1132 };
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1133
670
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1134 CxList *cxLinkedListCreate(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 880
diff changeset
1135 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
1136 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
1137 size_t elem_size
481
eef025d82a34 add several new linked list functions
Mike Becker <universe@uap-core.de>
parents: 480
diff changeset
1138 ) {
670
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1139 if (allocator == NULL) {
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1140 allocator = cxDefaultAllocator;
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1141 }
4ad8ea3aee49 allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents: 667
diff changeset
1142
503
a89857072ace add new destructor API and apply it to CxList
Mike Becker <universe@uap-core.de>
parents: 500
diff changeset
1143 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
1144 if (list == NULL) return NULL;
398
8d506ed6c1c0 adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1145
435
0fe204d50f54 change inheritance model for lists
Mike Becker <universe@uap-core.de>
parents: 428
diff changeset
1146 list->base.cl = &cx_linked_list_class;
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1147 list->base.collection.allocator = allocator;
406
9cbea761fbf7 adds cxLinkedListWrap and cxLinkedListRecalculateSize
Mike Becker <universe@uap-core.de>
parents: 404
diff changeset
1148
855
35bcb3216c0d fix inconsistent use of item_size and elem_size
Mike Becker <universe@uap-core.de>
parents: 854
diff changeset
1149 if (elem_size > 0) {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1150 list->base.collection.elem_size = elem_size;
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1151 list->base.collection.cmpfunc = comparator;
667
2f88a7c13a28 add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents: 666
diff changeset
1152 } else {
856
6bbbf219251d fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents: 855
diff changeset
1153 list->base.collection.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
667
2f88a7c13a28 add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents: 666
diff changeset
1154 cxListStorePointers((CxList *) list);
2f88a7c13a28 add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents: 666
diff changeset
1155 }
2f88a7c13a28 add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents: 666
diff changeset
1156
500
eb9e7bd40a8e do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents: 499
diff changeset
1157 return (CxList *) list;
406
9cbea761fbf7 adds cxLinkedListWrap and cxLinkedListRecalculateSize
Mike Becker <universe@uap-core.de>
parents: 404
diff changeset
1158 }

mercurial