src/ucx/linked_list.c

Sun, 30 Nov 2025 18:25:55 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 30 Nov 2025 18:25:55 +0100
changeset 645
0c85c4cd0dd8
parent 621
956c03c25edd
permissions
-rw-r--r--

update ucx to version 3.2

415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include "cx/linked_list.h"
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
30 #include "cx/compare.h"
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <string.h>
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include <assert.h>
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33
645
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
34 #if __STDC_VERSION__ < 202311L
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
35 // we cannot simply include stdalign.h
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
36 // because Solaris is not entirely C11 complaint
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
37 #ifndef __alignof_is_defined
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
38 #define alignof _Alignof
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
39 #define __alignof_is_defined 1
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
40 #endif
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
41 #endif
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
42
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
43 // LOW LEVEL LINKED LIST FUNCTIONS
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 #define CX_LL_PTR(cur, off) (*(void**)(((char*)(cur))+(off)))
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 #define ll_prev(node) CX_LL_PTR(node, loc_prev)
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 #define ll_next(node) CX_LL_PTR(node, loc_next)
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 #define ll_advance(node) CX_LL_PTR(node, loc_advance)
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
49 #define ll_data(node) (((char*)(node))+loc_data)
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 void *cx_linked_list_at(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
52 const void *start,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 size_t start_index,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 ptrdiff_t loc_advance,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 size_t index
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 assert(start != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 assert(loc_advance >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 size_t i = start_index;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
60 const void *cur = start;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 while (i != index && cur != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 cur = ll_advance(cur);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 i < index ? i++ : i--;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 return (void *) cur;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
68 void *cx_linked_list_find(
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
69 const void *start,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 ptrdiff_t loc_advance,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 ptrdiff_t loc_data,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
72 cx_compare_func cmp_func,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
73 const void *elem,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
74 size_t *found_index
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 assert(start != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 assert(loc_advance >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 assert(loc_data >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 assert(cmp_func);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
81 void *node = (void*) start;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
82 size_t index = 0;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 do {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 void *current = ll_data(node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 if (cmp_func(current, elem) == 0) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
86 if (found_index != NULL) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
87 *found_index = index;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
88 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
89 return node;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 node = ll_advance(node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 index++;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 } while (node != NULL);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
94 return NULL;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 void *cx_linked_list_first(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
98 const void *node,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 ptrdiff_t loc_prev
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 return cx_linked_list_last(node, loc_prev);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 void *cx_linked_list_last(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
105 const void *node,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 ptrdiff_t loc_next
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 assert(node != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 assert(loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
111 const void *cur = node;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
112 const void *last;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 do {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 last = cur;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 } while ((cur = ll_next(cur)) != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 return (void *) last;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 void *cx_linked_list_prev(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
121 const void *begin,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 ptrdiff_t loc_next,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
123 const void *node
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 assert(begin != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 assert(node != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 assert(loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 if (begin == node) return NULL;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
129 const void *cur = begin;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
130 const void *next;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 while (1) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 next = ll_next(cur);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 if (next == node) return (void *) cur;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 cur = next;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138 void cx_linked_list_link(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 void *left,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 void *right,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
142 ptrdiff_t loc_next
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 assert(loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145 ll_next(left) = right;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 if (loc_prev >= 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 ll_prev(right) = left;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 void cx_linked_list_unlink(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 void *left,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153 void *right,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 ptrdiff_t loc_next
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 assert (loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 assert(ll_next(left) == right);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 ll_next(left) = NULL;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 if (loc_prev >= 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 assert(ll_prev(right) == left);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 ll_prev(right) = NULL;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 void cx_linked_list_add(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 void **begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 void **end,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170 ptrdiff_t loc_next,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 void *new_node
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 void *last;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 if (end == NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 assert(begin != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 last = *begin == NULL ? NULL : cx_linked_list_last(*begin, loc_next);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 last = *end;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, last, new_node, new_node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 void cx_linked_list_prepend(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 void **begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 void **end,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 ptrdiff_t loc_next,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 void *new_node
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, NULL, new_node, new_node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 void cx_linked_list_insert(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 void **begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 void **end,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 ptrdiff_t loc_next,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 void *node,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 void *new_node
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, node, new_node, new_node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 void cx_linked_list_insert_chain(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 void **begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 void **end,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 ptrdiff_t loc_next,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209 void *node,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210 void *insert_begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 void *insert_end
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 // find the end of the chain, if not specified
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 if (insert_end == NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 insert_end = cx_linked_list_last(insert_begin, loc_next);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 // determine the successor
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 void *successor;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 if (node == NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 assert(begin != NULL || (end != NULL && loc_prev >= 0));
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 if (begin != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 successor = *begin;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 *begin = insert_begin;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 successor = *end == NULL ? NULL : cx_linked_list_first(*end, loc_prev);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 successor = ll_next(node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 cx_linked_list_link(node, insert_begin, loc_prev, loc_next);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 if (successor == NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 // the list ends with the new chain
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 if (end != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 *end = insert_end;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 cx_linked_list_link(insert_end, successor, loc_prev, loc_next);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
243 void cx_linked_list_insert_sorted(
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
244 void **begin,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
245 void **end,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
246 ptrdiff_t loc_prev,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
247 ptrdiff_t loc_next,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
248 void *new_node,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
249 cx_compare_func cmp_func
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
250 ) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
251 assert(ll_next(new_node) == NULL);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
252 cx_linked_list_insert_sorted_chain(
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
253 begin, end, loc_prev, loc_next, new_node, cmp_func);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
254 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
255
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
256 static void *cx_linked_list_insert_sorted_chain_impl(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
257 void **begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
258 void **end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
259 ptrdiff_t loc_prev,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
260 ptrdiff_t loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
261 void *insert_begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
262 cx_compare_func cmp_func,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
263 bool allow_duplicates
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
264 ) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
265 assert(begin != NULL);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
266 assert(loc_next >= 0);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
267 assert(insert_begin != NULL);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
268
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
269 // strategy: build completely new chains from scratch
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
270 void *source_original = *begin;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
271 void *source_argument = insert_begin;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
272 void *new_begin = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
273 void *new_end = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
274 void *dup_begin = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
275 void *dup_end = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
276
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
277 // determine the new start
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
278 {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
279 int d = source_original == NULL ? 1 : cmp_func(source_original, source_argument);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
280 if (d <= 0) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
281 // the new chain starts with the original chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
282 new_begin = new_end = source_original;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
283 source_original = ll_next(source_original);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
284 if (d == 0) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
285 if (allow_duplicates) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
286 // duplicate allowed, append it to the chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
287 cx_linked_list_link(new_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
288 new_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
289 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
290 // duplicate is not allowed, start a duplicate chain with the argument
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
291 dup_begin = dup_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
292 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
293 source_argument = ll_next(source_argument);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
294 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
295 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
296 // input is smaller, or there is no original chain;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
297 // start the new chain with the source argument
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
298 new_begin = new_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
299 source_argument = ll_next(source_argument);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
300 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
301 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
302
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
303 // now successively compare the elements and add them to the correct chains
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
304 while (source_original != NULL && source_argument != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
305 int d = cmp_func(source_original, source_argument);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
306 if (d <= 0) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
307 // the original is not larger, add it to the chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
308 cx_linked_list_link(new_end, source_original, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
309 new_end = source_original;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
310 source_original = ll_next(source_original);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
311 if (d == 0) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
312 if (allow_duplicates) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
313 // duplicate allowed, append it to the chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
314 cx_linked_list_link(new_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
315 new_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
316 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
317 // duplicate is not allowed, append it to the duplicate chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
318 if (dup_end == NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
319 dup_begin = dup_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
320 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
321 cx_linked_list_link(dup_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
322 dup_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
323 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
324 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
325 source_argument = ll_next(source_argument);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
326 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
327 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
328 // the original is larger, append the source argument to the chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
329 // check if we must discard the source argument as duplicate
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
330 if (!allow_duplicates && cmp_func(new_end, source_argument) == 0) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
331 if (dup_end == NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
332 dup_begin = dup_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
333 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
334 cx_linked_list_link(dup_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
335 dup_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
336 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
337 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
338 // no duplicate or duplicates allowed
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
339 cx_linked_list_link(new_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
340 new_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
341 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
342 source_argument = ll_next(source_argument);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
343 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
344 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
345
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
346 if (source_original != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
347 // something is left from the original chain, append it
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
348 cx_linked_list_link(new_end, source_original, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
349 new_end = cx_linked_list_last(source_original, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
350 } else if (source_argument != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
351 // something is left from the input chain;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
352 // when we allow duplicates, append it
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
353 if (allow_duplicates) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
354 cx_linked_list_link(new_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
355 new_end = cx_linked_list_last(source_argument, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
356 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
357 // otherwise we must check one-by-one
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
358 while (source_argument != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
359 if (cmp_func(new_end, source_argument) == 0) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
360 if (dup_end == NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
361 dup_begin = dup_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
362 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
363 cx_linked_list_link(dup_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
364 dup_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
365 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
366 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
367 cx_linked_list_link(new_end, source_argument, loc_prev, loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
368 new_end = source_argument;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
369 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
370 source_argument = ll_next(source_argument);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
371 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
372 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
373 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
374
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
375 // null the next pointers at the end of the chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
376 ll_next(new_end) = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
377 if (dup_end != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
378 ll_next(dup_end) = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
379 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
380
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
381 // null the optional prev pointers
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
382 if (loc_prev >= 0) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
383 ll_prev(new_begin) = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
384 if (dup_begin != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
385 ll_prev(dup_begin) = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
386 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
387 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
388
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
389 // output
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
390 *begin = new_begin;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
391 if (end != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
392 *end = new_end;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
393 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
394 return dup_begin;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
395 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
396
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
397 void cx_linked_list_insert_sorted_chain(
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
398 void **begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
399 void **end,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
400 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
401 ptrdiff_t loc_next,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
402 void *insert_begin,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
403 cx_compare_func cmp_func
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
404 ) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
405 cx_linked_list_insert_sorted_chain_impl(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
406 begin, end, loc_prev, loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
407 insert_begin, cmp_func, true);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
408 }
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
409
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
410 int cx_linked_list_insert_unique(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
411 void **begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
412 void **end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
413 ptrdiff_t loc_prev,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
414 ptrdiff_t loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
415 void *new_node,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
416 cx_compare_func cmp_func
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
417 ) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
418 assert(ll_next(new_node) == NULL);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
419 return NULL != cx_linked_list_insert_unique_chain(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
420 begin, end, loc_prev, loc_next, new_node, cmp_func);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
421 }
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
422
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
423 void *cx_linked_list_insert_unique_chain(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
424 void **begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
425 void **end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
426 ptrdiff_t loc_prev,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
427 ptrdiff_t loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
428 void *insert_begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
429 cx_compare_func cmp_func
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
430 ) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
431 return cx_linked_list_insert_sorted_chain_impl(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
432 begin, end, loc_prev, loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
433 insert_begin, cmp_func, false);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
434 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
435
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
436 size_t cx_linked_list_remove_chain(
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
437 void **begin,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
438 void **end,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
439 ptrdiff_t loc_prev,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
440 ptrdiff_t loc_next,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
441 void *node,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
442 size_t num
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
443 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
444 assert(node != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 assert(loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
446 assert(loc_prev >= 0 || begin != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
447
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
448 // easy exit
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
449 if (num == 0) return 0;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
450
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
451 // find adjacent nodes
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
452 void *prev;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
453 if (loc_prev >= 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
454 prev = ll_prev(node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
455 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
456 prev = cx_linked_list_prev(*begin, loc_next, node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
457 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
458
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
459 void *next = ll_next(node);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
460 size_t removed = 1;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
461 for (; removed < num && next != NULL ; removed++) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
462 next = ll_next(next);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
463 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
464
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
465 // update next pointer of prev node, or set begin
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
466 if (prev == NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
467 if (begin != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
468 *begin = next;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
469 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
470 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
471 ll_next(prev) = next;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
472 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
473
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
474 // update prev pointer of next node, or set end
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
475 if (next == NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
476 if (end != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
477 *end = prev;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
478 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
479 } else if (loc_prev >= 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
480 ll_prev(next) = prev;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
481 }
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
482
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
483 return removed;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
484 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
485
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
486 void cx_linked_list_remove(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
487 void **begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
488 void **end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
489 ptrdiff_t loc_prev,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
490 ptrdiff_t loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
491 void *node
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
492 ) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
493 cx_linked_list_remove_chain(begin, end, loc_prev, loc_next, node, 1);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
494 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
495
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
496 size_t cx_linked_list_size(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
497 const void *node,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
498 ptrdiff_t loc_next
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
499 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
500 assert(loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
501 size_t size = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
502 while (node != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
503 node = ll_next(node);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
504 size++;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
505 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
506 return size;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
507 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
508
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
509 #ifndef CX_LINKED_LIST_SORT_SBO_SIZE
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
510 #define CX_LINKED_LIST_SORT_SBO_SIZE 1024
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
511 #endif
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
512
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
513 static void cx_linked_list_sort_merge(
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
514 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
515 ptrdiff_t loc_next,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
516 ptrdiff_t loc_data,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
517 size_t length,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
518 void *ls,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
519 void *le,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
520 void *re,
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
521 cx_compare_func cmp_func,
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
522 void **begin,
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
523 void **end
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
524 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
525 void *sbo[CX_LINKED_LIST_SORT_SBO_SIZE];
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
526 void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ?
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
527 cxMallocDefault(sizeof(void *) * length) : sbo;
645
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
528 if (sorted == NULL) abort(); // LCOV_EXCL_LINE
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
529 void *rc, *lc;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
530
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
531 lc = ls;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
532 rc = le;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
533 size_t n = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
534 while (lc && lc != le && rc != re) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
535 if (cmp_func(ll_data(lc), ll_data(rc)) <= 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
536 sorted[n] = lc;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
537 lc = ll_next(lc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
538 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
539 sorted[n] = rc;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
540 rc = ll_next(rc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
541 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
542 n++;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
543 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
544 while (lc && lc != le) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
545 sorted[n] = lc;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
546 lc = ll_next(lc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
547 n++;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
548 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
549 while (rc && rc != re) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
550 sorted[n] = rc;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
551 rc = ll_next(rc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
552 n++;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
553 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
554
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
555 // Update pointer
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
556 if (loc_prev >= 0) ll_prev(sorted[0]) = NULL;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
557 for (size_t i = 0 ; i < length - 1; i++) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
558 cx_linked_list_link(sorted[i], sorted[i + 1], loc_prev, loc_next);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
559 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
560 ll_next(sorted[length - 1]) = NULL;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
561
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
562 *begin = sorted[0];
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
563 *end = sorted[length - 1];
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
564 if (sorted != sbo) {
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
565 cxFreeDefault(sorted);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
566 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
567 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
568
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
569 void cx_linked_list_sort( // NOLINT(misc-no-recursion) - purposely recursive function
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
570 void **begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
571 void **end,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
572 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
573 ptrdiff_t loc_next,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
574 ptrdiff_t loc_data,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
575 cx_compare_func cmp_func
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
576 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
577 assert(begin != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
578 assert(loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
579 assert(loc_data >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
580 assert(cmp_func);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
581
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
582 void *lc, *ls, *le, *re;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
583
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
584 // set start node
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
585 ls = *begin;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
586
491
5454ae7bf86b update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
587 // early exit when this list is empty
5454ae7bf86b update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
588 if (ls == NULL) return;
5454ae7bf86b update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
589
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
590 // check how many elements are already sorted
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
591 lc = ls;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
592 size_t ln = 1;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
593 while (ll_next(lc) != NULL && cmp_func(ll_data(ll_next(lc)), ll_data(lc)) > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
594 lc = ll_next(lc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
595 ln++;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
596 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
597 le = ll_next(lc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
598
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
599 // if first unsorted node is NULL, the list is already completely sorted
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
600 if (le != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
601 void *rc;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
602 size_t rn = 1;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
603 rc = le;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
604 // skip already sorted elements
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
605 while (ll_next(rc) != NULL && cmp_func(ll_data(ll_next(rc)), ll_data(rc)) > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
606 rc = ll_next(rc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
607 rn++;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
608 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
609 re = ll_next(rc);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
610
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
611 // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
612 void *sorted_begin, *sorted_end;
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
613 cx_linked_list_sort_merge(loc_prev, loc_next, loc_data,
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
614 ln + rn, ls, le, re, cmp_func,
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
615 &sorted_begin, &sorted_end);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
616
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
617 // Something left? Sort it!
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
618 size_t remainder_length = cx_linked_list_size(re, loc_next);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
619 if (remainder_length > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
620 void *remainder = re;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
621 cx_linked_list_sort(&remainder, NULL, loc_prev, loc_next, loc_data, cmp_func);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
622
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
623 // merge sorted list with (also sorted) remainder
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
624 cx_linked_list_sort_merge(loc_prev, loc_next, loc_data,
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
625 ln + rn + remainder_length,
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
626 sorted_begin, remainder, NULL, cmp_func,
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
627 &sorted_begin, &sorted_end);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
628 }
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
629 *begin = sorted_begin;
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
630 if (end) *end = sorted_end;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
631 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
632 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
633
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
634 int cx_linked_list_compare(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
635 const void *begin_left,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
636 const void *begin_right,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
637 ptrdiff_t loc_advance,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
638 ptrdiff_t loc_data,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
639 cx_compare_func cmp_func
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
640 ) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
641 const void *left = begin_left, *right = begin_right;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
642
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
643 while (left != NULL && right != NULL) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
644 const void *left_data = ll_data(left);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
645 const void *right_data = ll_data(right);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
646 int result = cmp_func(left_data, right_data);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
647 if (result != 0) return result;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
648 left = ll_advance(left);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
649 right = ll_advance(right);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
650 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
651
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
652 if (left != NULL) { return 1; }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
653 else if (right != NULL) { return -1; }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
654 else { return 0; }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
655 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
656
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
657 void cx_linked_list_reverse(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
658 void **begin,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
659 void **end,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
660 ptrdiff_t loc_prev,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
661 ptrdiff_t loc_next
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
662 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
663 assert(begin != NULL);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
664 assert(loc_next >= 0);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
665
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
666 // swap all links
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
667 void *prev = NULL;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
668 void *cur = *begin;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
669 while (cur != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
670 void *next = ll_next(cur);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
671
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
672 ll_next(cur) = prev;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
673 if (loc_prev >= 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
674 ll_prev(cur) = next;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
675 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
676
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
677 prev = cur;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
678 cur = next;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
679 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
680
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
681 // update begin and end
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
682 if (end != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
683 *end = *begin;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
684 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
685 *begin = prev;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
686 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
687
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
688 // HIGH LEVEL LINKED LIST IMPLEMENTATION
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
689
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
690 static void *cx_ll_node_at(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
691 const cx_linked_list *list,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
692 size_t index
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
693 ) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
694 if (index >= list->base.collection.size) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
695 return NULL;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
696 } else if (index > list->base.collection.size / 2) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
697 return cx_linked_list_at(list->end, list->base.collection.size - 1, list->loc_prev, index);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
698 } else {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
699 return cx_linked_list_at(list->begin, 0, list->loc_next, index);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
700 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
701 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
702
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
703 static void *cx_ll_malloc_node(const cx_linked_list *list) {
645
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
704 size_t n;
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
705 if (list->extra_data_len == 0) {
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
706 n = list->loc_data + list->base.collection.elem_size;
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
707 } else {
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
708 n = list->loc_extra + list->extra_data_len;
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
709 }
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
710 return cxZalloc(list->base.collection.allocator, n);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
711 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
712
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
713 static int cx_ll_insert_at(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
714 struct cx_list_s *list,
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
715 void *node,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
716 const void *elem
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
717 ) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
718 cx_linked_list *ll = (cx_linked_list *) list;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
719
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
720 // create the new new_node
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
721 void *new_node = cx_ll_malloc_node(ll);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
722
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
723 // sortir if failed
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
724 if (new_node == NULL) return 1;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
725
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
726 // copy the data
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
727 if (elem != NULL) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
728 memcpy((char*)new_node + ll->loc_data, elem, list->collection.elem_size);
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
729 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
730
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
731 // insert
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
732 cx_linked_list_insert_chain(
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
733 &ll->begin, &ll->end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
734 ll->loc_prev, ll->loc_next,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
735 node, new_node, new_node
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
736 );
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
737
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
738 // increase the size and return
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
739 list->collection.size++;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
740 return 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
741 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
742
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
743 static size_t cx_ll_insert_array(
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
744 struct cx_list_s *list,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
745 size_t index,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
746 const void *array,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
747 size_t n
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
748 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
749 // out-of bounds and corner case check
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
750 if (index > list->collection.size || n == 0) return 0;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
751
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
752 // find position efficiently
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
753 void *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
754
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
755 // perform first insert
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
756 if (0 != cx_ll_insert_at(list, node, array)) return 1;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
757
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
758 // is there more?
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
759 if (n == 1) return 1;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
760
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
761 // we now know exactly where we are
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
762 cx_linked_list *ll = (cx_linked_list *) list;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
763 node = node == NULL ? ((cx_linked_list *) list)->begin : CX_LL_PTR(node, ll->loc_next);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
764
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
765 // we can add the remaining nodes and immediately advance to the inserted node
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
766 const char *source = array;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
767 for (size_t i = 1; i < n; i++) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
768 if (source != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
769 source += list->collection.elem_size;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
770 }
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
771 if (0 != cx_ll_insert_at(list, node, source)) return i;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
772 node = CX_LL_PTR(node, ll->loc_next);
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
773 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
774 return n;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
775 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
776
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
777 static void *cx_ll_insert_element(
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
778 struct cx_list_s *list,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
779 size_t index,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
780 const void *element
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
781 ) {
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
782 // out-of-bounds check
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
783 if (index > list->collection.size) return NULL;
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
784
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
785 // find position efficiently
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
786 void *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
787
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
788 // perform first insert
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
789 if (cx_ll_insert_at(list, node, element)) return NULL;
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
790
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
791 // return a pointer to the data of the inserted node
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
792 cx_linked_list *ll = (cx_linked_list *) list;
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
793 if (node == NULL) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
794 return (char*)(ll->begin) + ll->loc_data;
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
795 } else {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
796 char *next = CX_LL_PTR(node, ll->loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
797 return next + ll->loc_data;
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
798 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
799 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
800
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
801 static _Thread_local cx_compare_func cx_ll_insert_sorted_cmp_func;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
802 static _Thread_local off_t cx_ll_insert_sorted_loc_data;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
803
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
804 static int cx_ll_insert_sorted_cmp_helper(const void *l, const void *r) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
805 const char *left = (const char*)l + cx_ll_insert_sorted_loc_data;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
806 const char *right = (const char*)r + cx_ll_insert_sorted_loc_data;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
807 return cx_ll_insert_sorted_cmp_func(left, right);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
808 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
809
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
810 static size_t cx_ll_insert_sorted_impl(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
811 struct cx_list_s *list,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
812 const void *array,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
813 size_t n,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
814 bool allow_duplicates
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
815 ) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
816 cx_linked_list *ll = (cx_linked_list *) list;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
817
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
818 // special case
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
819 if (n == 0) return 0;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
820
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
821 // create a new chain of nodes
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
822 void *chain = cx_ll_malloc_node(ll);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
823 if (chain == NULL) return 0;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
824
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
825 memcpy((char*)chain + ll->loc_data, array, list->collection.elem_size);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
826
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
827 // add all elements from the array to that chain
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
828 void *prev = chain;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
829 const char *src = array;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
830 size_t inserted = 1;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
831 for (; inserted < n; inserted++) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
832 void *next = cx_ll_malloc_node(ll);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
833 if (next == NULL) break;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
834 src += list->collection.elem_size;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
835 memcpy((char*)next + ll->loc_data, src, list->collection.elem_size);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
836 CX_LL_PTR(prev, ll->loc_next) = next;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
837 CX_LL_PTR(next, ll->loc_prev) = prev;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
838 prev = next;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
839 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
840 CX_LL_PTR(prev, ll->loc_next) = NULL;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
841
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
842 // invoke the low level function
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
843 cx_ll_insert_sorted_cmp_func = list->collection.cmpfunc;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
844 cx_ll_insert_sorted_loc_data = ll->loc_data;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
845 if (allow_duplicates) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
846 cx_linked_list_insert_sorted_chain(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
847 &ll->begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
848 &ll->end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
849 ll->loc_prev,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
850 ll->loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
851 chain,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
852 cx_ll_insert_sorted_cmp_helper
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
853 );
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
854 list->collection.size += inserted;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
855 } else {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
856 void *duplicates = cx_linked_list_insert_unique_chain(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
857 &ll->begin,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
858 &ll->end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
859 ll->loc_prev,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
860 ll->loc_next,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
861 chain,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
862 cx_ll_insert_sorted_cmp_helper
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
863 );
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
864 list->collection.size += inserted;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
865 // free the nodes that did not make it into the list
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
866 while (duplicates != NULL) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
867 void *next = CX_LL_PTR(duplicates, ll->loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
868 cxFree(list->collection.allocator, duplicates);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
869 duplicates = next;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
870 list->collection.size--;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
871 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
872 }
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
873
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
874 return inserted;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
875 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
876
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
877 static size_t cx_ll_insert_sorted(
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
878 struct cx_list_s *list,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
879 const void *array,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
880 size_t n
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
881 ) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
882 return cx_ll_insert_sorted_impl(list, array, n, true);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
883 }
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
884
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
885 static size_t cx_ll_insert_unique(
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
886 struct cx_list_s *list,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
887 const void *array,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
888 size_t n
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
889 ) {
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
890 return cx_ll_insert_sorted_impl(list, array, n, false);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
891 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
892
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
893 static size_t cx_ll_remove(
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
894 struct cx_list_s *list,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
895 size_t index,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
896 size_t num,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
897 void *targetbuf
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
898 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
899 cx_linked_list *ll = (cx_linked_list *) list;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
900 void *node = cx_ll_node_at(ll, index);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
901
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
902 // out-of-bounds check
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
903 if (node == NULL) return 0;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
904
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
905 // remove
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
906 size_t removed = cx_linked_list_remove_chain(
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
907 (void **) &ll->begin,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
908 (void **) &ll->end,
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
909 ll->loc_prev,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
910 ll->loc_next,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
911 node,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
912 num
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
913 );
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
914
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
915 // adjust size
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
916 list->collection.size -= removed;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
917
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
918 // copy or destroy the removed chain
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
919 if (targetbuf == NULL) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
920 char *n = node;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
921 for (size_t i = 0; i < removed; i++) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
922 // element destruction
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
923 cx_invoke_destructor(list, n + ll->loc_data);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
924
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
925 // free the node and advance
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
926 void *next = CX_LL_PTR(n, ll->loc_next);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
927 cxFree(list->collection.allocator, n);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
928 n = next;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
929 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
930 } else {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
931 char *dest = targetbuf;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
932 char *n = node;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
933 for (size_t i = 0; i < removed; i++) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
934 // copy payload
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
935 memcpy(dest, n + ll->loc_data, list->collection.elem_size);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
936
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
937 // advance target buffer
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
938 dest += list->collection.elem_size;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
939
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
940 // free the node and advance
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
941 void *next = CX_LL_PTR(n, ll->loc_next);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
942 cxFree(list->collection.allocator, n);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
943 n = next;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
944 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
945 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
946
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
947 return removed;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
948 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
949
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
950 static void cx_ll_clear(struct cx_list_s *list) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
951 if (list->collection.size == 0) return;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
952
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
953 cx_linked_list *ll = (cx_linked_list *) list;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
954 char *node = ll->begin;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
955 while (node != NULL) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
956 cx_invoke_destructor(list, node + ll->loc_data);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
957 void *next = CX_LL_PTR(node, ll->loc_next);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
958 cxFree(list->collection.allocator, node);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
959 node = next;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
960 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
961 ll->begin = ll->end = NULL;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
962 list->collection.size = 0;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
963 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
964
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
965 static int cx_ll_swap(
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
966 struct cx_list_s *list,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
967 size_t i,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
968 size_t j
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
969 ) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
970 if (i >= list->collection.size || j >= list->collection.size) return 1;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
971 if (i == j) return 0;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
972
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
973 // perform an optimized search that finds both elements in one run
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
974 cx_linked_list *ll = (cx_linked_list *) list;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
975 size_t mid = list->collection.size / 2;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
976 size_t left, right;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
977 if (i < j) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
978 left = i;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
979 right = j;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
980 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
981 left = j;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
982 right = i;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
983 }
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
984 void *nleft = NULL, *nright = NULL;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
985 if (left < mid && right < mid) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
986 // case 1: both items left from mid
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
987 nleft = cx_ll_node_at(ll, left);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
988 assert(nleft != NULL);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
989 nright = nleft;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
990 for (size_t c = left; c < right; c++) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
991 nright = CX_LL_PTR(nright, ll->loc_next);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
992 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
993 } else if (left >= mid && right >= mid) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
994 // case 2: both items right from mid
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
995 nright = cx_ll_node_at(ll, right);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
996 assert(nright != NULL);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
997 nleft = nright;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
998 for (size_t c = right; c > left; c--) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
999 nleft = CX_LL_PTR(nleft, ll->loc_prev);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1000 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1001 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1002 // case 3: one item left, one item right
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1003
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1004 // chose the closest to begin / end
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1005 size_t closest;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1006 size_t other;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1007 size_t diff2boundary = list->collection.size - right - 1;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1008 if (left <= diff2boundary) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1009 closest = left;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1010 other = right;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1011 nleft = cx_ll_node_at(ll, left);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1012 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1013 closest = right;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1014 other = left;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1015 diff2boundary = left;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1016 nright = cx_ll_node_at(ll, right);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1017 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1018
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1019 // is other element closer to us or closer to boundary?
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1020 if (right - left <= diff2boundary) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1021 // search other element starting from already found element
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1022 if (closest == left) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1023 nright = nleft;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1024 for (size_t c = left; c < right; c++) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1025 nright = CX_LL_PTR(nright, ll->loc_next);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1026 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1027 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1028 nleft = nright;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1029 for (size_t c = right; c > left; c--) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1030 nleft = CX_LL_PTR(nleft, ll->loc_prev);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1031 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1032 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1033 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1034 // search other element starting at the boundary
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1035 if (closest == left) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1036 nright = cx_ll_node_at(ll, other);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1037 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1038 nleft = cx_ll_node_at(ll, other);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1039 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1040 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1041 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1042
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1043 void *prev = CX_LL_PTR(nleft, ll->loc_prev);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1044 void *next = CX_LL_PTR(nright, ll->loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1045 void *midstart = CX_LL_PTR(nleft, ll->loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1046 void *midend = CX_LL_PTR(nright, ll->loc_prev);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1047
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1048 if (prev == NULL) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1049 ll->begin = nright;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1050 } else {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1051 CX_LL_PTR(prev, ll->loc_next) = nright;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1052 }
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1053 CX_LL_PTR(nright, ll->loc_prev) = prev;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1054 if (midstart == nright) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1055 // special case: both nodes are adjacent
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1056 CX_LL_PTR(nright, ll->loc_next) = nleft;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1057 CX_LL_PTR(nleft, ll->loc_prev) = nright;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1058 } else {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1059 // likely case: a chain is between the two nodes
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1060 CX_LL_PTR(nright, ll->loc_next) = midstart;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1061 CX_LL_PTR(midstart, ll->loc_prev) = nright;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1062 CX_LL_PTR(midend, ll->loc_next) = nleft;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1063 CX_LL_PTR(nleft, ll->loc_prev) = midend;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1064 }
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1065 CX_LL_PTR(nleft, ll->loc_next) = next;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1066 if (next == NULL) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1067 ll->end = nleft;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1068 } else {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1069 CX_LL_PTR(next, ll->loc_prev) = nleft;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1070 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1071
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1072 return 0;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1073 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1074
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1075 static void *cx_ll_at(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1076 const struct cx_list_s *list,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1077 size_t index
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1078 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1079 cx_linked_list *ll = (cx_linked_list *) list;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1080 char *node = cx_ll_node_at(ll, index);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1081 return node == NULL ? NULL : node + ll->loc_data;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1082 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1083
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1084 static size_t cx_ll_find_remove(
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1085 struct cx_list_s *list,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1086 const void *elem,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1087 bool remove
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1088 ) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1089 if (list->collection.size == 0) return 0;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1090
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1091 size_t index;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1092 cx_linked_list *ll = (cx_linked_list *) list;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1093 char *node = cx_linked_list_find(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1094 ll->begin,
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1095 ll->loc_next, ll->loc_data,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1096 list->collection.cmpfunc, elem,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1097 &index
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1098 );
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1099 if (node == NULL) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1100 return list->collection.size;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1101 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1102 if (remove) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1103 cx_invoke_destructor(list, node + ll->loc_data);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1104 cx_linked_list_remove(&ll->begin, &ll->end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1105 ll->loc_prev, ll->loc_next, node);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1106 list->collection.size--;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1107 cxFree(list->collection.allocator, node);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1108 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1109 return index;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1110 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1111
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1112 static void cx_ll_sort(struct cx_list_s *list) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1113 cx_linked_list *ll = (cx_linked_list *) list;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1114 cx_linked_list_sort(&ll->begin, &ll->end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1115 ll->loc_prev, ll->loc_next, ll->loc_data,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1116 list->collection.cmpfunc);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1117 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1118
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1119 static void cx_ll_reverse(struct cx_list_s *list) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1120 cx_linked_list *ll = (cx_linked_list *) list;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1121 cx_linked_list_reverse(&ll->begin, &ll->end, ll->loc_prev, ll->loc_next);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1122 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1123
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1124 static int cx_ll_compare(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1125 const struct cx_list_s *list,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1126 const struct cx_list_s *other
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1127 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1128 cx_linked_list *left = (cx_linked_list *) list;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1129 cx_linked_list *right = (cx_linked_list *) other;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1130 assert(left->loc_next == right->loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1131 assert(left->loc_data == right->loc_data);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1132 return cx_linked_list_compare(left->begin, right->begin,
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1133 left->loc_next, left->loc_data,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1134 list->collection.cmpfunc);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1135 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1136
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1137 static bool cx_ll_iter_valid(const void *it) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1138 const struct cx_iterator_s *iter = it;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1139 return iter->elem_handle != NULL;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1140 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1141
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
1142 static void cx_ll_iter_next(void *it) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1143 struct cx_iterator_s *iter = it;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1144 cx_linked_list *ll = iter->src_handle;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1145 if (iter->base.remove) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1146 iter->base.remove = false;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1147 struct cx_list_s *list = iter->src_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1148 char *node = iter->elem_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1149 iter->elem_handle = CX_LL_PTR(node, ll->loc_next);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1150 cx_invoke_destructor(list, node + ll->loc_data);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1151 cx_linked_list_remove(&ll->begin, &ll->end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1152 ll->loc_prev, ll->loc_next, node);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1153 list->collection.size--;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1154 iter->elem_count--;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1155 cxFree(list->collection.allocator, node);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1156 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1157 iter->index++;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1158 void *node = iter->elem_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1159 iter->elem_handle = CX_LL_PTR(node, ll->loc_next);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1160 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1161 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1162
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1163 static void cx_ll_iter_prev(void *it) {
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1164 struct cx_iterator_s *iter = it;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1165 cx_linked_list *ll = iter->src_handle;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1166 if (iter->base.remove) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1167 iter->base.remove = false;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1168 struct cx_list_s *list = iter->src_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1169 char *node = iter->elem_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1170 iter->elem_handle = CX_LL_PTR(node, ll->loc_prev);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1171 iter->index--;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1172 cx_invoke_destructor(list, node + ll->loc_data);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1173 cx_linked_list_remove(&ll->begin, &ll->end,
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1174 ll->loc_prev, ll->loc_next, node);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1175 list->collection.size--;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1176 iter->elem_count--;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1177 cxFree(list->collection.allocator, node);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1178 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1179 iter->index--;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1180 char *node = iter->elem_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1181 iter->elem_handle = CX_LL_PTR(node, ll->loc_prev);
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1182 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1183 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1184
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1185 static void *cx_ll_iter_current(const void *it) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1186 const struct cx_iterator_s *iter = it;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1187 const cx_linked_list *ll = iter->src_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1188 char *node = iter->elem_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1189 return node + ll->loc_data;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1190 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1191
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1192 static CxIterator cx_ll_iterator(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1193 const struct cx_list_s *list,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1194 size_t index,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1195 bool backwards
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1196 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1197 CxIterator iter;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1198 iter.index = index;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1199 iter.src_handle = (void*)list;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1200 iter.elem_handle = cx_ll_node_at((const cx_linked_list *) list, index);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1201 iter.elem_size = list->collection.elem_size;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1202 iter.elem_count = list->collection.size;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
1203 iter.base.valid = cx_ll_iter_valid;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
1204 iter.base.current = cx_ll_iter_current;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1205 iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1206 iter.base.allow_remove = true;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
1207 iter.base.remove = false;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1208 return iter;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1209 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1210
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1211 static int cx_ll_insert_iter(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1212 CxIterator *iter,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1213 const void *elem,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1214 int prepend
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1215 ) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1216 struct cx_list_s *list = iter->src_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1217 cx_linked_list *ll = iter->src_handle;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1218 void *node = iter->elem_handle;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1219 if (node != NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1220 assert(prepend >= 0 && prepend <= 1);
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1221 void *choice[2] = {node, CX_LL_PTR(node, ll->loc_prev)};
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1222 int result = cx_ll_insert_at(list, choice[prepend], elem);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1223 if (result == 0) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1224 iter->elem_count++;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1225 if (prepend) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1226 iter->index++;
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1227 }
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1228 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1229 return result;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1230 } else {
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
1231 if (cx_ll_insert_element(list, list->collection.size, elem) == NULL) {
645
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1232 return 1; // LCOV_EXCL_LINE
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1233 }
582
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
1234 iter->elem_count++;
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
1235 iter->index = list->collection.size;
82b60a8dd55c update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
1236 return 0;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1237 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1238 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1239
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1240 static void cx_ll_destructor(CxList *list) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1241 cx_linked_list *ll = (cx_linked_list *) list;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1242
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1243 char *node = ll->begin;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1244 while (node) {
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1245 cx_invoke_destructor(list, node + ll->loc_data);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1246 void *next = CX_LL_PTR(node, ll->loc_next);
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1247 cxFree(list->collection.allocator, node);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1248 node = next;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1249 }
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 491
diff changeset
1250
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1251 cxFree(list->collection.allocator, list);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1252 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1253
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1254 static cx_list_class cx_linked_list_class = {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1255 cx_ll_destructor,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1256 cx_ll_insert_element,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1257 cx_ll_insert_array,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1258 cx_ll_insert_sorted,
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1259 cx_ll_insert_unique,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1260 cx_ll_insert_iter,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1261 cx_ll_remove,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1262 cx_ll_clear,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1263 cx_ll_swap,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1264 cx_ll_at,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1265 cx_ll_find_remove,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1266 cx_ll_sort,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1267 cx_ll_compare,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1268 cx_ll_reverse,
645
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1269 NULL, // no overallocation supported
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
1270 cx_ll_iterator,
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1271 };
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1272
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1273 CxList *cxLinkedListCreate(
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1274 const CxAllocator *allocator,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1275 cx_compare_func comparator,
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1276 size_t elem_size
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1277 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1278 if (allocator == NULL) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1279 allocator = cxDefaultAllocator;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1280 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
1281
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1282 cx_linked_list *list = cxCalloc(allocator, 1, sizeof(cx_linked_list));
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1283 if (list == NULL) return NULL;
621
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1284 list->loc_prev = 0;
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1285 list->loc_next = sizeof(void*);
956c03c25edd update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 582
diff changeset
1286 list->loc_data = sizeof(void*)*2;
645
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1287 list->loc_extra = -1;
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1288 list->extra_data_len = 0;
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1289 cx_list_init((CxList*)list, &cx_linked_list_class,
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 504
diff changeset
1290 allocator, comparator, elem_size);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1291
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1292 return (CxList *) list;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1293 }
645
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1294
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1295 void cx_linked_list_extra_data(cx_linked_list *list, size_t len) {
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1296 list->extra_data_len = len;
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1297
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1298 off_t loc_extra = list->loc_data + list->base.collection.elem_size;
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1299 size_t alignment = alignof(void*);
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1300 size_t padding = alignment - (loc_extra % alignment);
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1301 list->loc_extra = loc_extra + padding;
0c85c4cd0dd8 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 621
diff changeset
1302 }

mercurial