src/ucx/array_list.c

Wed, 05 Jun 2024 19:50:44 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 05 Jun 2024 19:50:44 +0200
changeset 537
ad44e72fbf50
parent 504
c094afcdfb27
permissions
-rw-r--r--

add extra nullptr check in the event loop to handle the case when the finish ptr is set to NULL after it was already scheduled

436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1260fad21be7 update ucx
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
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include "cx/array_list.h"
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30 #include <assert.h>
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <string.h>
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
33 // LOW LEVEL ARRAY LIST FUNCTIONS
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
35 enum cx_array_copy_result cx_array_copy(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36 void **target,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37 size_t *size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38 size_t *capacity,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39 size_t index,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 void const *src,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 size_t elem_size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 size_t elem_count,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 struct cx_array_reallocator_s *reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
45 // assert pointers
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 assert(target != NULL);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 assert(size != NULL);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 assert(src != NULL);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
50 // determine capacity
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 size_t cap = capacity == NULL ? *size : *capacity;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
53 // check if resize is required
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
54 size_t minsize = index + elem_count;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
55 size_t newsize = *size < minsize ? minsize : *size;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 bool needrealloc = newsize > cap;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
58 // reallocate if possible
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 if (needrealloc) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
60 // a reallocator and a capacity variable must be available
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 if (reallocator == NULL || capacity == NULL) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
65 // check, if we need to repair the src pointer
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 uintptr_t targetaddr = (uintptr_t) *target;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67 uintptr_t srcaddr = (uintptr_t) src;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 bool repairsrc = targetaddr <= srcaddr
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 && srcaddr < targetaddr + cap * elem_size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
71 // calculate new capacity (next number divisible by 16)
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
72 cap = newsize - (newsize % 16) + 16;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
73 assert(cap > newsize);
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
75 // perform reallocation
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 void *newmem = reallocator->realloc(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 *target, cap, elem_size, reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 );
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 if (newmem == NULL) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 return CX_ARRAY_COPY_REALLOC_FAILED;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
83 // repair src pointer, if necessary
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 if (repairsrc) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 src = ((char *) newmem) + (srcaddr - targetaddr);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
88 // store new pointer and capacity
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 *target = newmem;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 *capacity = cap;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
93 // determine target pointer
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 char *start = *target;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 start += index * elem_size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
97 // copy elements and set new size
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 memmove(start, src, elem_count * elem_size);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 *size = newsize;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
101 // return successfully
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 return CX_ARRAY_COPY_SUCCESS;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
105 #ifndef CX_ARRAY_SWAP_SBO_SIZE
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
106 #define CX_ARRAY_SWAP_SBO_SIZE 128
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
107 #endif
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
108
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
109 void cx_array_swap(
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
110 void *arr,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
111 size_t elem_size,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
112 size_t idx1,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
113 size_t idx2
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
114 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
115 assert(arr != NULL);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
116
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
117 // short circuit
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
118 if (idx1 == idx2) return;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
119
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
120 char sbo_mem[CX_ARRAY_SWAP_SBO_SIZE];
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
121 void *tmp;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
122
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
123 // decide if we can use the local buffer
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
124 if (elem_size > CX_ARRAY_SWAP_SBO_SIZE) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
125 tmp = malloc(elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
126 // we don't want to enforce error handling
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
127 if (tmp == NULL) abort();
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
128 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
129 tmp = sbo_mem;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
130 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
131
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
132 // calculate memory locations
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
133 char *left = arr, *right = arr;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
134 left += idx1 * elem_size;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
135 right += idx2 * elem_size;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
136
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
137 // three-way swap
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
138 memcpy(tmp, left, elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
139 memcpy(left, right, elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
140 memcpy(right, tmp, elem_size);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
141
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
142 // free dynamic memory, if it was needed
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
143 if (tmp != sbo_mem) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
144 free(tmp);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
145 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
146 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
147
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
148 // HIGH LEVEL ARRAY LIST FUNCTIONS
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 typedef struct {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 struct cx_list_s base;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 void *data;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
153 size_t capacity;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 struct cx_array_reallocator_s reallocator;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 } cx_array_list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 static void *cx_arl_realloc(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 void *array,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 size_t capacity,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 size_t elem_size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 struct cx_array_reallocator_s *alloc
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
163 // retrieve the pointer to the list allocator
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 CxAllocator const *al = alloc->ptr1;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
166 // use the list allocator to reallocate the memory
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 return cxRealloc(al, array, capacity * elem_size);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170 static void cx_arl_destructor(struct cx_list_s *list) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 cx_array_list *arl = (cx_array_list *) list;
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
172
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
173 char *ptr = arl->data;
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
174
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
175 if (list->simple_destructor) {
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
176 for (size_t i = 0; i < list->size; i++) {
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
177 cx_invoke_simple_destructor(list, ptr);
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
178 ptr += list->item_size;
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
179 }
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
180 }
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
181 if (list->advanced_destructor) {
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
182 for (size_t i = 0; i < list->size; i++) {
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
183 cx_invoke_advanced_destructor(list, ptr);
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
184 ptr += list->item_size;
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
185 }
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
186 }
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
187
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 cxFree(list->allocator, arl->data);
504
c094afcdfb27 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 490
diff changeset
189 cxFree(list->allocator, list);
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
192 static size_t cx_arl_insert_array(
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 struct cx_list_s *list,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
194 size_t index,
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
195 void const *array,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
196 size_t n
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
197 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
198 // out of bounds and special case check
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
199 if (index > list->size || n == 0) return 0;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
200
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
201 // get a correctly typed pointer to the list
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
202 cx_array_list *arl = (cx_array_list *) list;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
203
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
204 // do we need to move some elements?
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
205 if (index < list->size) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
206 char const *first_to_move = (char const *) arl->data;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
207 first_to_move += index * list->item_size;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
208 size_t elems_to_move = list->size - index;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
209 size_t start_of_moved = index + n;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
210
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
211 if (CX_ARRAY_COPY_SUCCESS != cx_array_copy(
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
212 &arl->data,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
213 &list->size,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
214 &arl->capacity,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
215 start_of_moved,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
216 first_to_move,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
217 list->item_size,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
218 elems_to_move,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
219 &arl->reallocator
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
220 )) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
221 // if moving existing elems is unsuccessful, abort
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
222 return 0;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
223 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
224 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
225
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
226 // note that if we had to move the elements, the following operation
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
227 // is guaranteed to succeed, because we have the memory already allocated
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
228 // therefore, it is impossible to leave this function with an invalid array
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
229
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
230 // place the new elements
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
231 if (CX_ARRAY_COPY_SUCCESS == cx_array_copy(
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
232 &arl->data,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
233 &list->size,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
234 &arl->capacity,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
235 index,
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
236 array,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
237 list->item_size,
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
238 n,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
239 &arl->reallocator
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
240 )) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
241 return n;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
242 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
243 // array list implementation is "all or nothing"
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
244 return 0;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
245 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
246 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
247
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
248 static int cx_arl_insert_element(
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 struct cx_list_s *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 size_t index,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
251 void const *element
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
253 return 1 != cx_arl_insert_array(list, index, element, 1);
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 static int cx_arl_insert_iter(
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
257 struct cx_mut_iterator_s *iter,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 void const *elem,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 int prepend
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 ) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
261 struct cx_list_s *list = iter->src_handle;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
262 if (iter->index < list->size) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
263 int result = cx_arl_insert_element(
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
264 list,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
265 iter->index + 1 - prepend,
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
266 elem
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
267 );
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
268 if (result == 0 && prepend != 0) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
269 iter->index++;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
270 iter->elem_handle = ((char *) iter->elem_handle) + list->item_size;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
271 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
272 return result;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
273 } else {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
274 int result = cx_arl_insert_element(list, list->size, elem);
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
275 iter->index = list->size;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
276 return result;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
277 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 static int cx_arl_remove(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281 struct cx_list_s *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
282 size_t index
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
284 cx_array_list *arl = (cx_array_list *) list;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
285
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
286 // out-of-bounds check
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287 if (index >= list->size) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 return 1;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
291 // content destruction
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
292 cx_invoke_destructor(list, ((char *) arl->data) + index * list->item_size);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
293
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
294 // short-circuit removal of last element
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
295 if (index == list->size - 1) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
296 list->size--;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
297 return 0;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
298 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
300 // just move the elements starting at index to the left
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 int result = cx_array_copy(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 &arl->data,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 &list->size,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
304 &arl->capacity,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 index,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
306 ((char *) arl->data) + (index + 1) * list->item_size,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
307 list->item_size,
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
308 list->size - index - 1,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 &arl->reallocator
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 );
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 if (result == 0) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
312 // decrease the size
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 list->size--;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 return result;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
318 static void cx_arl_clear(struct cx_list_s *list) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
319 if (list->size == 0) return;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
320
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
321 cx_array_list *arl = (cx_array_list *) list;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
322 char *ptr = arl->data;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
323
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
324 if (list->simple_destructor) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
325 for (size_t i = 0; i < list->size; i++) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
326 cx_invoke_simple_destructor(list, ptr);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
327 ptr += list->item_size;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
328 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
329 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
330 if (list->advanced_destructor) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
331 for (size_t i = 0; i < list->size; i++) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
332 cx_invoke_advanced_destructor(list, ptr);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
333 ptr += list->item_size;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
334 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
335 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
336
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
337 memset(arl->data, 0, list->size * list->item_size);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
338 list->size = 0;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
339 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
340
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
341 static int cx_arl_swap(
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
342 struct cx_list_s *list,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
343 size_t i,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
344 size_t j
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
345 ) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
346 if (i >= list->size || j >= list->size) return 1;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
347 cx_array_list *arl = (cx_array_list *) list;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
348 cx_array_swap(arl->data, list->item_size, i, j);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
349 return 0;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
350 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
351
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
352 static void *cx_arl_at(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
353 struct cx_list_s const *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
354 size_t index
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
355 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
356 if (index < list->size) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
357 cx_array_list const *arl = (cx_array_list const *) list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
358 char *space = arl->data;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
359 return space + index * list->item_size;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
360 } else {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
361 return NULL;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
362 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
363 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
364
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
365 static ssize_t cx_arl_find(
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
366 struct cx_list_s const *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
367 void const *elem
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
368 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
369 assert(list->cmpfunc != NULL);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
370 assert(list->size < SIZE_MAX / 2);
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
371 char *cur = ((cx_array_list const *) list)->data;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
372
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
373 for (ssize_t i = 0; i < (ssize_t) list->size; i++) {
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
374 if (0 == list->cmpfunc(elem, cur)) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
375 return i;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
376 }
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
377 cur += list->item_size;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
378 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
379
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
380 return -1;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
381 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
382
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
383 static void cx_arl_sort(struct cx_list_s *list) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
384 assert(list->cmpfunc != NULL);
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
385 qsort(((cx_array_list *) list)->data,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
386 list->size,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
387 list->item_size,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
388 list->cmpfunc
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
389 );
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
390 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
391
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
392 static int cx_arl_compare(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
393 struct cx_list_s const *list,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
394 struct cx_list_s const *other
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
395 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
396 assert(list->cmpfunc != NULL);
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
397 if (list->size == other->size) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
398 char const *left = ((cx_array_list const *) list)->data;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
399 char const *right = ((cx_array_list const *) other)->data;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
400 for (size_t i = 0; i < list->size; i++) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
401 int d = list->cmpfunc(left, right);
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
402 if (d != 0) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
403 return d;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
404 }
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
405 left += list->item_size;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
406 right += other->item_size;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
407 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
408 return 0;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
409 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
410 return list->size < other->size ? -1 : 1;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
411 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
412 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
413
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
414 static void cx_arl_reverse(struct cx_list_s *list) {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
415 if (list->size < 2) return;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
416 void *data = ((cx_array_list const *) list)->data;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
417 size_t half = list->size / 2;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
418 for (size_t i = 0; i < half; i++) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
419 cx_array_swap(data, list->item_size, i, list->size - 1 - i);
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
420 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
421 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
422
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
423 static bool cx_arl_iter_valid(void const *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
424 struct cx_iterator_s const *iter = it;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
425 struct cx_list_s const *list = iter->src_handle;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
426 return iter->index < list->size;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
427 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
428
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
429 static void *cx_arl_iter_current(void const *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
430 struct cx_iterator_s const *iter = it;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
431 return iter->elem_handle;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
432 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
433
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
434 static void cx_arl_iter_next(void *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
435 struct cx_iterator_base_s *itbase = it;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
436 if (itbase->remove) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
437 struct cx_mut_iterator_s *iter = it;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
438 itbase->remove = false;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
439 cx_arl_remove(iter->src_handle, iter->index);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
440 } else {
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
441 struct cx_iterator_s *iter = it;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
442 iter->index++;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
443 iter->elem_handle =
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
444 ((char *) iter->elem_handle)
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
445 + ((struct cx_list_s const *) iter->src_handle)->item_size;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
446 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
447 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
448
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
449 static void cx_arl_iter_prev(void *it) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
450 struct cx_iterator_base_s *itbase = it;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
451 struct cx_mut_iterator_s *iter = it;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
452 cx_array_list *const list = iter->src_handle;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
453 if (itbase->remove) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
454 itbase->remove = false;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
455 cx_arl_remove(iter->src_handle, iter->index);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
456 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
457 iter->index--;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
458 if (iter->index < list->base.size) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
459 iter->elem_handle = ((char *) list->data)
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
460 + iter->index * list->base.item_size;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
461 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
462 }
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
463
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
464 static bool cx_arl_iter_flag_rm(void *it) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
465 struct cx_iterator_base_s *iter = it;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
466 if (iter->mutating) {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
467 iter->remove = true;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
468 return true;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
469 } else {
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
470 return false;
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
471 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
472 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
473
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
474 static struct cx_iterator_s cx_arl_iterator(
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
475 struct cx_list_s const *list,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
476 size_t index,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
477 bool backwards
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
478 ) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
479 struct cx_iterator_s iter;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
480
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
481 iter.index = index;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
482 iter.src_handle = list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
483 iter.elem_handle = cx_arl_at(list, index);
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
484 iter.base.valid = cx_arl_iter_valid;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
485 iter.base.current = cx_arl_iter_current;
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
486 iter.base.next = backwards ? cx_arl_iter_prev : cx_arl_iter_next;
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
487 iter.base.flag_removal = cx_arl_iter_flag_rm;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
488 iter.base.remove = false;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
489 iter.base.mutating = false;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
490
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
491 return iter;
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
492 }
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
493
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
494 static cx_list_class cx_array_list_class = {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
495 cx_arl_destructor,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
496 cx_arl_insert_element,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
497 cx_arl_insert_array,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
498 cx_arl_insert_iter,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
499 cx_arl_remove,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
500 cx_arl_clear,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
501 cx_arl_swap,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
502 cx_arl_at,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
503 cx_arl_find,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
504 cx_arl_sort,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
505 cx_arl_compare,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
506 cx_arl_reverse,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
507 cx_arl_iterator,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
508 };
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
509
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
510 CxList *cxArrayListCreate(
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
511 CxAllocator const *allocator,
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
512 cx_compare_func comparator,
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
513 size_t item_size,
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
514 size_t initial_capacity
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
515 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
516 if (allocator == NULL) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
517 allocator = cxDefaultAllocator;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
518 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
519
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
520 cx_array_list *list = cxCalloc(allocator, 1, sizeof(cx_array_list));
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
521 if (list == NULL) return NULL;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
522
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
523 list->base.cl = &cx_array_list_class;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
524 list->base.allocator = allocator;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
525 list->base.cmpfunc = comparator;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
526 list->capacity = initial_capacity;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
527
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
528 if (item_size > 0) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
529 list->base.item_size = item_size;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
530 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
531 item_size = sizeof(void *);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
532 cxListStorePointers((CxList *) list);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
533 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
534
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 438
diff changeset
535 // allocate the array after the real item_size is known
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
536 list->data = cxCalloc(allocator, initial_capacity, item_size);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
537 if (list->data == NULL) {
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
538 cxFree(allocator, list);
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
539 return NULL;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
540 }
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
541
438
22eca559aded refactore http listener creation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 436
diff changeset
542 // configure the reallocator
436
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
543 list->reallocator.realloc = cx_arl_realloc;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
544 list->reallocator.ptr1 = (void *) allocator;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
545
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
546 return (CxList *) list;
1260fad21be7 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
547 }

mercurial