29 * \file array_list.h |
29 * \file array_list.h |
30 * \brief Array list implementation. |
30 * \brief Array list implementation. |
31 * \details Also provides several low-level functions for custom array list implementations. |
31 * \details Also provides several low-level functions for custom array list implementations. |
32 * \author Mike Becker |
32 * \author Mike Becker |
33 * \author Olaf Wintermann |
33 * \author Olaf Wintermann |
34 * \version 3.0 |
|
35 * \copyright 2-Clause BSD License |
34 * \copyright 2-Clause BSD License |
36 */ |
35 */ |
37 |
36 |
38 |
37 |
39 #ifndef UCX_ARRAY_LIST_H |
38 #ifndef UCX_ARRAY_LIST_H |
42 #include "list.h" |
41 #include "list.h" |
43 |
42 |
44 #ifdef __cplusplus |
43 #ifdef __cplusplus |
45 extern "C" { |
44 extern "C" { |
46 #endif |
45 #endif |
|
46 |
|
47 /** |
|
48 * The maximum item size in an array list that fits into stack buffer when swapped. |
|
49 */ |
|
50 extern unsigned cx_array_swap_sbo_size; |
47 |
51 |
48 /** |
52 /** |
49 * Defines a reallocation mechanism for arrays. |
53 * Defines a reallocation mechanism for arrays. |
50 */ |
54 */ |
51 struct cx_array_reallocator_s { |
55 struct cx_array_reallocator_s { |
52 /** |
56 /** |
53 * Re-allocates space for the given array. |
57 * Re-allocates space for the given array. |
54 * |
58 * |
55 * Implementations are not required to free the original array. |
59 * Implementations are not required to free the original array. |
56 * This allows re-allocation of static memory by allocating heap memory |
60 * This allows re-allocation of static memory by allocating heap memory |
57 * and copying the array contents. The information in \p data can keep |
61 * and copying the array contents. The information in the custom fields of |
58 * track of the state of the memory or other additional allocator info. |
62 * the referenced allocator can be used to track the state of the memory |
|
63 * or to transport other additional data. |
59 * |
64 * |
60 * @param array the array to reallocate |
65 * @param array the array to reallocate |
61 * @param capacity the new capacity (number of elements) |
66 * @param capacity the new capacity (number of elements) |
62 * @param elem_size the size of each element |
67 * @param elem_size the size of each element |
63 * @param alloc a reference to this allocator |
68 * @param alloc a reference to this allocator |
87 */ |
92 */ |
88 size_t int2; |
93 size_t int2; |
89 }; |
94 }; |
90 |
95 |
91 /** |
96 /** |
92 * Return codes for cx_array_copy(). |
97 * A default stdlib-based array reallocator. |
93 */ |
98 */ |
94 enum cx_array_copy_result { |
99 extern struct cx_array_reallocator_s *cx_array_default_reallocator; |
95 CX_ARRAY_COPY_SUCCESS, |
100 |
96 CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED, |
101 /** |
97 CX_ARRAY_COPY_REALLOC_FAILED, |
102 * Return codes for array functions. |
|
103 */ |
|
104 enum cx_array_result { |
|
105 CX_ARRAY_SUCCESS, |
|
106 CX_ARRAY_REALLOC_NOT_SUPPORTED, |
|
107 CX_ARRAY_REALLOC_FAILED, |
98 }; |
108 }; |
99 |
109 |
100 /** |
110 /** |
101 * Copies elements from one array to another. |
111 * Copies elements from one array to another. |
102 * |
112 * |
105 * the current array \p size. If the new index plus the number of elements added |
115 * the current array \p size. If the new index plus the number of elements added |
106 * would extend the array's size, and \p capacity is not \c NULL, the remaining |
116 * would extend the array's size, and \p capacity is not \c NULL, the remaining |
107 * capacity is used. |
117 * capacity is used. |
108 * |
118 * |
109 * If the capacity is insufficient to hold the new data, a reallocation |
119 * If the capacity is insufficient to hold the new data, a reallocation |
110 * attempt is made, unless the allocator is set to \c NULL, in which case |
120 * attempt is made, unless the \p reallocator is set to \c NULL, in which case |
111 * this function ultimately returns a failure. |
121 * this function ultimately returns a failure. |
112 * |
122 * |
113 * @param target the target array |
123 * @param target the target array |
114 * @param size a pointer to the size of the target array |
124 * @param size a pointer to the size of the target array |
115 * @param capacity a pointer to the target array's capacity - |
125 * @param capacity a pointer to the target array's capacity - |
120 * @param elem_count the number of elements to copy |
130 * @param elem_count the number of elements to copy |
121 * @param reallocator the array re-allocator to use, or \c NULL |
131 * @param reallocator the array re-allocator to use, or \c NULL |
122 * if re-allocation shall not happen |
132 * if re-allocation shall not happen |
123 * @return zero on success, non-zero error code on failure |
133 * @return zero on success, non-zero error code on failure |
124 */ |
134 */ |
125 enum cx_array_copy_result cx_array_copy( |
135 enum cx_array_result cx_array_copy( |
126 void **target, |
136 void **target, |
127 size_t *size, |
137 size_t *size, |
128 size_t *capacity, |
138 size_t *capacity, |
129 size_t index, |
139 size_t index, |
130 void const *src, |
140 void const *src, |
131 size_t elem_size, |
141 size_t elem_size, |
132 size_t elem_count, |
142 size_t elem_count, |
133 struct cx_array_reallocator_s *reallocator |
143 struct cx_array_reallocator_s *reallocator |
134 ) __attribute__((__nonnull__(1, 2, 5))); |
144 ) __attribute__((__nonnull__(1, 2, 5))); |
135 |
145 |
|
146 /** |
|
147 * Adds an element to an array with the possibility of allocating more space. |
|
148 * |
|
149 * The element \p elem is added to the end of the \p target array which containing |
|
150 * \p size elements, already. The \p capacity must not be \c NULL and point a |
|
151 * variable holding the current maximum number of elements the array can hold. |
|
152 * |
|
153 * If the capacity is insufficient to hold the new element, and the optional |
|
154 * \p reallocator is not \c NULL, an attempt increase the \p capacity is made |
|
155 * and the new capacity is written back. |
|
156 * |
|
157 * @param target the target array |
|
158 * @param size a pointer to the size of the target array |
|
159 * @param capacity a pointer to the target array's capacity - must not be \c NULL |
|
160 * @param elem_size the size of one element |
|
161 * @param elem the element to add |
|
162 * @param reallocator the array re-allocator to use, or \c NULL |
|
163 * if re-allocation shall not happen |
|
164 * @return zero on success, non-zero error code on failure |
|
165 */ |
|
166 #define cx_array_add(target, size, capacity, elem_size, elem, reallocator) \ |
|
167 cx_array_copy((void**)(target), size, capacity, *(size), elem, elem_size, 1, reallocator) |
136 |
168 |
137 /** |
169 /** |
138 * Swaps two array elements. |
170 * Swaps two array elements. |
139 * |
171 * |
140 * @param arr the array |
172 * @param arr the array |
151 |
183 |
152 /** |
184 /** |
153 * Allocates an array list for storing elements with \p item_size bytes each. |
185 * Allocates an array list for storing elements with \p item_size bytes each. |
154 * |
186 * |
155 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if |
187 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if |
156 * cxListStorePointers() was called immediately after creation. |
188 * cxListStorePointers() was called immediately after creation and the compare |
|
189 * function will be automatically set to cx_cmp_ptr(), if none is given. |
157 * |
190 * |
158 * @param allocator the allocator for allocating the list memory |
191 * @param allocator the allocator for allocating the list memory |
159 * (if \c NULL the cxDefaultAllocator will be used) |
192 * (if \c NULL the cxDefaultAllocator will be used) |
160 * @param comparator the comparator for the elements |
193 * @param comparator the comparator for the elements |
161 * (if \c NULL sort and find functions will not work) |
194 * (if \c NULL, and the list is not storing pointers, sort and find |
|
195 * functions will not work) |
162 * @param item_size the size of each element in bytes |
196 * @param item_size the size of each element in bytes |
163 * @param initial_capacity the initial number of elements the array can store |
197 * @param initial_capacity the initial number of elements the array can store |
164 * @return the created list |
198 * @return the created list |
165 */ |
199 */ |
166 CxList *cxArrayListCreate( |
200 CxList *cxArrayListCreate( |
176 * The list will use the cxDefaultAllocator and \em NO compare function. |
210 * The list will use the cxDefaultAllocator and \em NO compare function. |
177 * If you want to call functions that need a compare function, you have to |
211 * If you want to call functions that need a compare function, you have to |
178 * set it immediately after creation or use cxArrayListCreate(). |
212 * set it immediately after creation or use cxArrayListCreate(). |
179 * |
213 * |
180 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if |
214 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if |
181 * cxListStorePointers() was called immediately after creation. |
215 * cxListStorePointers() was called immediately after creation and the compare |
|
216 * function will be automatically set to cx_cmp_ptr(). |
182 * |
217 * |
183 * @param item_size the size of each element in bytes |
218 * @param item_size the size of each element in bytes |
184 * @param initial_capacity the initial number of elements the array can store |
219 * @param initial_capacity the initial number of elements the array can store |
185 * @return the created list |
220 * @return the created list |
186 */ |
221 */ |