exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / gl_list.h
blob986be84fad0043b7796977ee2a6b3983cbcffae5
1 /* Abstract sequential list data type. -*- coding: utf-8 -*-
2 Copyright (C) 2006-2024 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
10 This file is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 #ifndef _GL_LIST_H
19 #define _GL_LIST_H
21 /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE,
22 _GL_ATTRIBUTE_NODISCARD. */
23 #if !_GL_CONFIG_H_INCLUDED
24 #error "Please include config.h first."
25 #endif
27 #include <stddef.h>
29 _GL_INLINE_HEADER_BEGIN
30 #ifndef GL_LIST_INLINE
31 # define GL_LIST_INLINE _GL_INLINE
32 #endif
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
39 /* gl_list is an abstract list data type. It can contain any number of
40 objects ('void *' or 'const void *' pointers) in any given order.
41 Duplicates are allowed, but can optionally be forbidden.
43 There are several implementations of this list datatype, optimized for
44 different operations or for memory. You can start using the simplest list
45 implementation, GL_ARRAY_LIST, and switch to a different implementation
46 later, when you realize which operations are performed the most frequently.
47 The API of the different implementations is exactly the same; when
48 switching to a different implementation, you only have to change the
49 gl_list_create call.
51 The implementations are:
52 GL_ARRAY_LIST a growable array
53 GL_CARRAY_LIST a growable circular array
54 GL_LINKED_LIST a linked list
55 GL_AVLTREE_LIST a binary tree (AVL tree)
56 GL_RBTREE_LIST a binary tree (red-black tree)
57 GL_LINKEDHASH_LIST a hash table with a linked list
58 GL_AVLTREEHASH_LIST a hash table with a binary tree (AVL tree)
59 GL_RBTREEHASH_LIST a hash table with a binary tree (red-black tree)
61 The memory consumption is asymptotically the same: O(1) for every object
62 in the list. When looking more closely at the average memory consumed
63 for an object, GL_ARRAY_LIST is the most compact representation, and
64 GL_LINKEDHASH_LIST and GL_TREEHASH_LIST need more memory.
66 The guaranteed average performance of the operations is, for a list of
67 n elements:
69 Operation ARRAY LINKED TREE LINKEDHASH TREEHASH
70 CARRAY with|without with|without
71 duplicates duplicates
73 gl_list_size O(1) O(1) O(1) O(1) O(1)
74 gl_list_node_value O(1) O(1) O(1) O(1) O(1)
75 gl_list_node_set_value O(1) O(1) O(1) O(1) O((log n)²)/O(1)
76 gl_list_next_node O(1) O(1) O(log n) O(1) O(log n)
77 gl_list_previous_node O(1) O(1) O(log n) O(1) O(log n)
78 gl_list_first_node O(1) O(1) O(log n) O(1) O(log n)
79 gl_list_last_node O(1) O(1) O(log n) O(1) O(log n)
80 gl_list_get_at O(1) O(n) O(log n) O(n) O(log n)
81 gl_list_get_first O(1) O(1) O(log n) O(1) O(log n)
82 gl_list_get_last O(1) O(1) O(log n) O(1) O(log n)
83 gl_list_set_at O(1) O(n) O(log n) O(n) O((log n)²)/O(log n)
84 gl_list_set_first O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
85 gl_list_set_last O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
86 gl_list_search O(n) O(n) O(n) O(n)/O(1) O(log n)/O(1)
87 gl_list_search_from O(n) O(n) O(n) O(n)/O(1) O((log n)²)/O(log n)
88 gl_list_search_from_to O(n) O(n) O(n) O(n)/O(1) O((log n)²)/O(log n)
89 gl_list_indexof O(n) O(n) O(n) O(n) O(log n)
90 gl_list_indexof_from O(n) O(n) O(n) O(n) O((log n)²)/O(log n)
91 gl_list_indexof_from_to O(n) O(n) O(n) O(n) O((log n)²)/O(log n)
92 gl_list_add_first O(n)/O(1) O(1) O(log n) O(1) O((log n)²)/O(log n)
93 gl_list_add_last O(1) O(1) O(log n) O(1) O((log n)²)/O(log n)
94 gl_list_add_before O(n) O(1) O(log n) O(1) O((log n)²)/O(log n)
95 gl_list_add_after O(n) O(1) O(log n) O(1) O((log n)²)/O(log n)
96 gl_list_add_at O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
97 gl_list_remove_node O(n) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
98 gl_list_remove_at O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
99 gl_list_remove_first O(n)/O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
100 gl_list_remove_last O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
101 gl_list_remove O(n) O(n) O(n) O(n)/O(1) O((log n)²)/O(log n)
102 gl_list_iterator O(1) O(1) O(log n) O(1) O(log n)
103 gl_list_iterator_from_to O(1) O(n) O(log n) O(n) O(log n)
104 gl_list_iterator_next O(1) O(1) O(log n) O(1) O(log n)
105 gl_sortedlist_search O(log n) O(n) O(log n) O(n) O(log n)
106 gl_sortedlist_search_from O(log n) O(n) O(log n) O(n) O(log n)
107 gl_sortedlist_indexof O(log n) O(n) O(log n) O(n) O(log n)
108 gl_sortedlist_indexof_fro O(log n) O(n) O(log n) O(n) O(log n)
109 gl_sortedlist_add O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
110 gl_sortedlist_remove O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
113 /* -------------------------- gl_list_t Data Type -------------------------- */
115 /* Type of function used to compare two elements.
116 NULL denotes pointer comparison. */
117 typedef bool (*gl_listelement_equals_fn) (const void *elt1, const void *elt2);
119 /* Type of function used to compute a hash code.
120 NULL denotes a function that depends only on the pointer itself. */
121 typedef size_t (*gl_listelement_hashcode_fn) (const void *elt);
123 /* Type of function used to dispose an element once it's removed from a list.
124 NULL denotes a no-op. */
125 typedef void (*gl_listelement_dispose_fn) (const void *elt);
127 struct gl_list_impl;
128 /* Type representing an entire list. */
129 typedef struct gl_list_impl * gl_list_t;
131 struct gl_list_node_impl;
132 /* Type representing the position of an element in the list, in a way that
133 is more adapted to the list implementation than a plain index.
134 Note: It is invalidated by insertions and removals! */
135 typedef struct gl_list_node_impl * gl_list_node_t;
137 struct gl_list_implementation;
138 /* Type representing a list datatype implementation. */
139 typedef const struct gl_list_implementation * gl_list_implementation_t;
141 #if 0 /* Unless otherwise specified, these are defined inline below. */
143 /* Creates an empty list.
144 IMPLEMENTATION is one of GL_ARRAY_LIST, GL_CARRAY_LIST, GL_LINKED_LIST,
145 GL_AVLTREE_LIST, GL_RBTREE_LIST, GL_LINKEDHASH_LIST, GL_AVLTREEHASH_LIST,
146 GL_RBTREEHASH_LIST.
147 EQUALS_FN is an element comparison function or NULL.
148 HASHCODE_FN is an element hash code function or NULL.
149 DISPOSE_FN is an element disposal function or NULL.
150 ALLOW_DUPLICATES is false if duplicate elements shall not be allowed in
151 the list. The implementation may verify this at runtime. */
152 /* declared in gl_xlist.h */
153 extern gl_list_t gl_list_create_empty (gl_list_implementation_t implementation,
154 gl_listelement_equals_fn equals_fn,
155 gl_listelement_hashcode_fn hashcode_fn,
156 gl_listelement_dispose_fn dispose_fn,
157 bool allow_duplicates)
158 /*_GL_ATTRIBUTE_DEALLOC (gl_list_free, 1)*/
159 _GL_ATTRIBUTE_RETURNS_NONNULL;
160 /* Likewise. Returns NULL upon out-of-memory. */
161 extern gl_list_t gl_list_nx_create_empty (gl_list_implementation_t implementation,
162 gl_listelement_equals_fn equals_fn,
163 gl_listelement_hashcode_fn hashcode_fn,
164 gl_listelement_dispose_fn dispose_fn,
165 bool allow_duplicates)
166 /*_GL_ATTRIBUTE_DEALLOC (gl_list_free, 1)*/;
168 /* Creates a list with given contents.
169 IMPLEMENTATION is one of GL_ARRAY_LIST, GL_CARRAY_LIST, GL_LINKED_LIST,
170 GL_AVLTREE_LIST, GL_RBTREE_LIST, GL_LINKEDHASH_LIST, GL_AVLTREEHASH_LIST,
171 GL_RBTREEHASH_LIST.
172 EQUALS_FN is an element comparison function or NULL.
173 HASHCODE_FN is an element hash code function or NULL.
174 DISPOSE_FN is an element disposal function or NULL.
175 ALLOW_DUPLICATES is false if duplicate elements shall not be allowed in
176 the list. The implementation may verify this at runtime.
177 COUNT is the number of initial elements.
178 CONTENTS[0..COUNT-1] is the initial contents. */
179 /* declared in gl_xlist.h */
180 extern gl_list_t gl_list_create (gl_list_implementation_t implementation,
181 gl_listelement_equals_fn equals_fn,
182 gl_listelement_hashcode_fn hashcode_fn,
183 gl_listelement_dispose_fn dispose_fn,
184 bool allow_duplicates,
185 size_t count, const void **contents)
186 /*_GL_ATTRIBUTE_DEALLOC (gl_list_free, 1)*/
187 _GL_ATTRIBUTE_RETURNS_NONNULL;
188 /* Likewise. Returns NULL upon out-of-memory. */
189 extern gl_list_t gl_list_nx_create (gl_list_implementation_t implementation,
190 gl_listelement_equals_fn equals_fn,
191 gl_listelement_hashcode_fn hashcode_fn,
192 gl_listelement_dispose_fn dispose_fn,
193 bool allow_duplicates,
194 size_t count, const void **contents)
195 /*_GL_ATTRIBUTE_DEALLOC (gl_list_free, 1)*/;
197 /* Returns the current number of elements in a list. */
198 extern size_t gl_list_size (gl_list_t list);
200 /* Returns the element value represented by a list node. */
201 extern const void * gl_list_node_value (gl_list_t list, gl_list_node_t node);
203 /* Replaces the element value represented by a list node. */
204 /* declared in gl_xlist.h */
205 extern void gl_list_node_set_value (gl_list_t list, gl_list_node_t node,
206 const void *elt);
207 /* Likewise. Returns 0 upon success, -1 upon out-of-memory. */
208 _GL_ATTRIBUTE_NODISCARD
209 extern int gl_list_node_nx_set_value (gl_list_t list, gl_list_node_t node,
210 const void *elt);
212 /* Returns the node immediately after the given node in the list, or NULL
213 if the given node is the last (rightmost) one in the list. */
214 extern gl_list_node_t gl_list_next_node (gl_list_t list, gl_list_node_t node);
216 /* Returns the node immediately before the given node in the list, or NULL
217 if the given node is the first (leftmost) one in the list. */
218 extern gl_list_node_t gl_list_previous_node (gl_list_t list, gl_list_node_t node);
220 /* Returns the first node in the list, or NULL if the list is empty.
221 This function is useful for iterating through the list like this:
222 gl_list_node_t node;
223 for (node = gl_list_first_node (list); node != NULL; node = gl_list_next_node (node))
226 extern gl_list_node_t gl_list_first_node (gl_list_t list);
228 /* Returns the last node in the list, or NULL if the list is empty.
229 This function is useful for iterating through the list in backward order,
230 like this:
231 gl_list_node_t node;
232 for (node = gl_list_last_node (list); node != NULL; node = gl_list_previous_node (node))
235 extern gl_list_node_t gl_list_last_node (gl_list_t list);
237 /* Returns the element at a given position in the list.
238 POSITION must be >= 0 and < gl_list_size (list). */
239 extern const void * gl_list_get_at (gl_list_t list, size_t position);
241 /* Returns the element at the first position in the list.
242 The list must be non-empty. */
243 extern const void * gl_list_get_first (gl_list_t list);
245 /* Returns the element at the last position in the list.
246 The list must be non-empty. */
247 extern const void * gl_list_get_last (gl_list_t list);
249 /* Replaces the element at a given position in the list.
250 POSITION must be >= 0 and < gl_list_size (list).
251 Returns its node. */
252 /* declared in gl_xlist.h */
253 extern gl_list_node_t gl_list_set_at (gl_list_t list, size_t position,
254 const void *elt);
255 /* Likewise. Returns NULL upon out-of-memory. */
256 _GL_ATTRIBUTE_NODISCARD
257 extern gl_list_node_t gl_list_nx_set_at (gl_list_t list, size_t position,
258 const void *elt);
260 /* Replaces the element at the first position in the list.
261 Returns its node.
262 The list must be non-empty. */
263 /* declared in gl_xlist.h */
264 extern gl_list_node_t gl_list_set_first (gl_list_t list, const void *elt);
265 /* Likewise. Returns NULL upon out-of-memory. */
266 _GL_ATTRIBUTE_NODISCARD
267 extern gl_list_node_t gl_list_nx_set_first (gl_list_t list, const void *elt);
269 /* Replaces the element at the last position in the list.
270 Returns its node.
271 The list must be non-empty. */
272 /* declared in gl_xlist.h */
273 extern gl_list_node_t gl_list_set_last (gl_list_t list, const void *elt);
274 /* Likewise. Returns NULL upon out-of-memory. */
275 _GL_ATTRIBUTE_NODISCARD
276 extern gl_list_node_t gl_list_nx_set_last (gl_list_t list, const void *elt);
278 /* Searches whether an element is already in the list.
279 Returns its node if found, or NULL if not present in the list. */
280 extern gl_list_node_t gl_list_search (gl_list_t list, const void *elt);
282 /* Searches whether an element is already in the list,
283 at a position >= START_INDEX.
284 Returns its node if found, or NULL if not present in the list. */
285 extern gl_list_node_t gl_list_search_from (gl_list_t list, size_t start_index,
286 const void *elt);
288 /* Searches whether an element is already in the list,
289 at a position >= START_INDEX and < END_INDEX.
290 Returns its node if found, or NULL if not present in the list. */
291 extern gl_list_node_t gl_list_search_from_to (gl_list_t list,
292 size_t start_index,
293 size_t end_index,
294 const void *elt);
296 /* Searches whether an element is already in the list.
297 Returns its position if found, or (size_t)(-1) if not present in the list. */
298 extern size_t gl_list_indexof (gl_list_t list, const void *elt);
300 /* Searches whether an element is already in the list,
301 at a position >= START_INDEX.
302 Returns its position if found, or (size_t)(-1) if not present in the list. */
303 extern size_t gl_list_indexof_from (gl_list_t list, size_t start_index,
304 const void *elt);
306 /* Searches whether an element is already in the list,
307 at a position >= START_INDEX and < END_INDEX.
308 Returns its position if found, or (size_t)(-1) if not present in the list. */
309 extern size_t gl_list_indexof_from_to (gl_list_t list,
310 size_t start_index, size_t end_index,
311 const void *elt);
313 /* Adds an element as the first element of the list.
314 Returns its node. */
315 /* declared in gl_xlist.h */
316 extern gl_list_node_t gl_list_add_first (gl_list_t list, const void *elt);
317 /* Likewise. Returns NULL upon out-of-memory. */
318 _GL_ATTRIBUTE_NODISCARD
319 extern gl_list_node_t gl_list_nx_add_first (gl_list_t list, const void *elt);
321 /* Adds an element as the last element of the list.
322 Returns its node. */
323 /* declared in gl_xlist.h */
324 extern gl_list_node_t gl_list_add_last (gl_list_t list, const void *elt);
325 /* Likewise. Returns NULL upon out-of-memory. */
326 _GL_ATTRIBUTE_NODISCARD
327 extern gl_list_node_t gl_list_nx_add_last (gl_list_t list, const void *elt);
329 /* Adds an element before a given element node of the list.
330 Returns its node. */
331 /* declared in gl_xlist.h */
332 extern gl_list_node_t gl_list_add_before (gl_list_t list, gl_list_node_t node,
333 const void *elt);
334 /* Likewise. Returns NULL upon out-of-memory. */
335 _GL_ATTRIBUTE_NODISCARD
336 extern gl_list_node_t gl_list_nx_add_before (gl_list_t list,
337 gl_list_node_t node,
338 const void *elt);
340 /* Adds an element after a given element node of the list.
341 Returns its node. */
342 /* declared in gl_xlist.h */
343 extern gl_list_node_t gl_list_add_after (gl_list_t list, gl_list_node_t node,
344 const void *elt);
345 /* Likewise. Returns NULL upon out-of-memory. */
346 _GL_ATTRIBUTE_NODISCARD
347 extern gl_list_node_t gl_list_nx_add_after (gl_list_t list, gl_list_node_t node,
348 const void *elt);
350 /* Adds an element at a given position in the list.
351 POSITION must be >= 0 and <= gl_list_size (list). */
352 /* declared in gl_xlist.h */
353 extern gl_list_node_t gl_list_add_at (gl_list_t list, size_t position,
354 const void *elt);
355 /* Likewise. Returns NULL upon out-of-memory. */
356 _GL_ATTRIBUTE_NODISCARD
357 extern gl_list_node_t gl_list_nx_add_at (gl_list_t list, size_t position,
358 const void *elt);
360 /* Removes an element from the list.
361 Returns true. */
362 extern bool gl_list_remove_node (gl_list_t list, gl_list_node_t node);
364 /* Removes an element at a given position from the list.
365 POSITION must be >= 0 and < gl_list_size (list).
366 Returns true. */
367 extern bool gl_list_remove_at (gl_list_t list, size_t position);
369 /* Removes the element at the first position from the list.
370 Returns true if it was found and removed, or false if the list was empty. */
371 extern bool gl_list_remove_first (gl_list_t list);
373 /* Removes the element at the last position from the list.
374 Returns true if it was found and removed, or false if the list was empty. */
375 extern bool gl_list_remove_last (gl_list_t list);
377 /* Searches and removes an element from the list.
378 Returns true if it was found and removed. */
379 extern bool gl_list_remove (gl_list_t list, const void *elt);
381 /* Frees an entire list.
382 (But this call does not free the elements of the list. It only invokes
383 the DISPOSE_FN on each of the elements of the list, and only if the list
384 is not a sublist.) */
385 extern void gl_list_free (gl_list_t list);
387 #endif /* End of inline and gl_xlist.h-defined functions. */
389 /* --------------------- gl_list_iterator_t Data Type --------------------- */
391 /* Functions for iterating through a list. */
393 /* Type of an iterator that traverses a list.
394 This is a fixed-size struct, so that creation of an iterator doesn't need
395 memory allocation on the heap. */
396 typedef struct
398 /* For fast dispatch of gl_list_iterator_next. */
399 const struct gl_list_implementation *vtable;
400 /* For detecting whether the last returned element was removed. */
401 gl_list_t list;
402 size_t count;
403 /* Other, implementation-private fields. */
404 void *p; void *q;
405 size_t i; size_t j;
406 } gl_list_iterator_t;
408 #if 0 /* These are defined inline below. */
410 /* Creates an iterator traversing a list.
411 The list contents must not be modified while the iterator is in use,
412 except for replacing or removing the last returned element. */
413 extern gl_list_iterator_t gl_list_iterator (gl_list_t list);
415 /* Creates an iterator traversing the element with indices i,
416 start_index <= i < end_index, of a list.
417 The list contents must not be modified while the iterator is in use,
418 except for replacing or removing the last returned element. */
419 extern gl_list_iterator_t gl_list_iterator_from_to (gl_list_t list,
420 size_t start_index,
421 size_t end_index);
423 /* If there is a next element, stores the next element in *ELTP, stores its
424 node in *NODEP if NODEP is non-NULL, advances the iterator and returns true.
425 Otherwise, returns false. */
426 extern bool gl_list_iterator_next (gl_list_iterator_t *iterator,
427 const void **eltp, gl_list_node_t *nodep);
429 /* Frees an iterator. */
430 extern void gl_list_iterator_free (gl_list_iterator_t *iterator);
432 #endif /* End of inline functions. */
434 /* ---------------------- Sorted gl_list_t Data Type ---------------------- */
436 /* The following functions are for lists without duplicates where the
437 order is given by a sort criterion. */
439 /* Type of function used to compare two elements. Same as for qsort().
440 NULL denotes pointer comparison. */
441 typedef int (*gl_listelement_compar_fn) (const void *elt1, const void *elt2);
443 #if 0 /* Unless otherwise specified, these are defined inline below. */
445 /* Searches whether an element is already in the list.
446 The list is assumed to be sorted with COMPAR.
447 Returns its node if found, or NULL if not present in the list.
448 If the list contains several copies of ELT, the node of the leftmost one is
449 returned. */
450 extern gl_list_node_t gl_sortedlist_search (gl_list_t list,
451 gl_listelement_compar_fn compar,
452 const void *elt);
454 /* Searches whether an element is already in the list.
455 The list is assumed to be sorted with COMPAR.
456 Only list elements with indices >= START_INDEX and < END_INDEX are
457 considered; the implementation uses these bounds to minimize the number
458 of COMPAR invocations.
459 Returns its node if found, or NULL if not present in the list.
460 If the list contains several copies of ELT, the node of the leftmost one is
461 returned. */
462 extern gl_list_node_t gl_sortedlist_search_from_to (gl_list_t list,
463 gl_listelement_compar_fn compar,
464 size_t start_index,
465 size_t end_index,
466 const void *elt);
468 /* Searches whether an element is already in the list.
469 The list is assumed to be sorted with COMPAR.
470 Returns its position if found, or (size_t)(-1) if not present in the list.
471 If the list contains several copies of ELT, the position of the leftmost one
472 is returned. */
473 extern size_t gl_sortedlist_indexof (gl_list_t list,
474 gl_listelement_compar_fn compar,
475 const void *elt);
477 /* Searches whether an element is already in the list.
478 The list is assumed to be sorted with COMPAR.
479 Only list elements with indices >= START_INDEX and < END_INDEX are
480 considered; the implementation uses these bounds to minimize the number
481 of COMPAR invocations.
482 Returns its position if found, or (size_t)(-1) if not present in the list.
483 If the list contains several copies of ELT, the position of the leftmost one
484 is returned. */
485 extern size_t gl_sortedlist_indexof_from_to (gl_list_t list,
486 gl_listelement_compar_fn compar,
487 size_t start_index,
488 size_t end_index,
489 const void *elt);
491 /* Adds an element at the appropriate position in the list.
492 The list is assumed to be sorted with COMPAR.
493 Returns its node. */
494 /* declared in gl_xlist.h */
495 extern gl_list_node_t gl_sortedlist_add (gl_list_t list,
496 gl_listelement_compar_fn compar,
497 const void *elt);
498 /* Likewise. Returns NULL upon out-of-memory. */
499 _GL_ATTRIBUTE_NODISCARD
500 extern gl_list_node_t gl_sortedlist_nx_add (gl_list_t list,
501 gl_listelement_compar_fn compar,
502 const void *elt);
504 /* Searches and removes an element from the list.
505 The list is assumed to be sorted with COMPAR.
506 Returns true if it was found and removed.
507 If the list contains several copies of ELT, only the leftmost one is
508 removed. */
509 extern bool gl_sortedlist_remove (gl_list_t list,
510 gl_listelement_compar_fn compar,
511 const void *elt);
513 #endif /* End of inline and gl_xlist.h-defined functions. */
515 /* ------------------------ Implementation Details ------------------------ */
517 struct gl_list_implementation
519 /* gl_list_t functions. */
520 gl_list_t (*nx_create_empty) (gl_list_implementation_t implementation,
521 gl_listelement_equals_fn equals_fn,
522 gl_listelement_hashcode_fn hashcode_fn,
523 gl_listelement_dispose_fn dispose_fn,
524 bool allow_duplicates);
525 gl_list_t (*nx_create) (gl_list_implementation_t implementation,
526 gl_listelement_equals_fn equals_fn,
527 gl_listelement_hashcode_fn hashcode_fn,
528 gl_listelement_dispose_fn dispose_fn,
529 bool allow_duplicates,
530 size_t count, const void **contents);
531 size_t (*size) (gl_list_t list);
532 const void * (*node_value) (gl_list_t list, gl_list_node_t node);
533 int (*node_nx_set_value) (gl_list_t list, gl_list_node_t node,
534 const void *elt);
535 gl_list_node_t (*next_node) (gl_list_t list, gl_list_node_t node);
536 gl_list_node_t (*previous_node) (gl_list_t list, gl_list_node_t node);
537 gl_list_node_t (*first_node) (gl_list_t list);
538 gl_list_node_t (*last_node) (gl_list_t list);
539 const void * (*get_at) (gl_list_t list, size_t position);
540 gl_list_node_t (*nx_set_at) (gl_list_t list, size_t position,
541 const void *elt);
542 gl_list_node_t (*search_from_to) (gl_list_t list, size_t start_index,
543 size_t end_index, const void *elt);
544 size_t (*indexof_from_to) (gl_list_t list, size_t start_index,
545 size_t end_index, const void *elt);
546 gl_list_node_t (*nx_add_first) (gl_list_t list, const void *elt);
547 gl_list_node_t (*nx_add_last) (gl_list_t list, const void *elt);
548 gl_list_node_t (*nx_add_before) (gl_list_t list, gl_list_node_t node,
549 const void *elt);
550 gl_list_node_t (*nx_add_after) (gl_list_t list, gl_list_node_t node,
551 const void *elt);
552 gl_list_node_t (*nx_add_at) (gl_list_t list, size_t position,
553 const void *elt);
554 bool (*remove_node) (gl_list_t list, gl_list_node_t node);
555 bool (*remove_at) (gl_list_t list, size_t position);
556 bool (*remove_elt) (gl_list_t list, const void *elt);
557 void (*list_free) (gl_list_t list);
558 /* gl_list_iterator_t functions. */
559 gl_list_iterator_t (*iterator) (gl_list_t list);
560 gl_list_iterator_t (*iterator_from_to) (gl_list_t list,
561 size_t start_index,
562 size_t end_index);
563 bool (*iterator_next) (gl_list_iterator_t *iterator,
564 const void **eltp, gl_list_node_t *nodep);
565 void (*iterator_free) (gl_list_iterator_t *iterator);
566 /* Sorted gl_list_t functions. */
567 gl_list_node_t (*sortedlist_search) (gl_list_t list,
568 gl_listelement_compar_fn compar,
569 const void *elt);
570 gl_list_node_t (*sortedlist_search_from_to) (gl_list_t list,
571 gl_listelement_compar_fn compar,
572 size_t start_index,
573 size_t end_index,
574 const void *elt);
575 size_t (*sortedlist_indexof) (gl_list_t list,
576 gl_listelement_compar_fn compar,
577 const void *elt);
578 size_t (*sortedlist_indexof_from_to) (gl_list_t list,
579 gl_listelement_compar_fn compar,
580 size_t start_index, size_t end_index,
581 const void *elt);
582 gl_list_node_t (*sortedlist_nx_add) (gl_list_t list,
583 gl_listelement_compar_fn compar,
584 const void *elt);
585 bool (*sortedlist_remove) (gl_list_t list,
586 gl_listelement_compar_fn compar,
587 const void *elt);
590 struct gl_list_impl_base
592 const struct gl_list_implementation *vtable;
593 gl_listelement_equals_fn equals_fn;
594 gl_listelement_hashcode_fn hashcode_fn;
595 gl_listelement_dispose_fn dispose_fn;
596 bool allow_duplicates;
599 /* Define all functions of this file as accesses to the
600 struct gl_list_implementation. */
602 GL_LIST_INLINE
603 /*_GL_ATTRIBUTE_DEALLOC (gl_list_free, 1)*/
604 gl_list_t
605 gl_list_nx_create_empty (gl_list_implementation_t implementation,
606 gl_listelement_equals_fn equals_fn,
607 gl_listelement_hashcode_fn hashcode_fn,
608 gl_listelement_dispose_fn dispose_fn,
609 bool allow_duplicates)
611 return implementation->nx_create_empty (implementation, equals_fn,
612 hashcode_fn, dispose_fn,
613 allow_duplicates);
616 GL_LIST_INLINE
617 /*_GL_ATTRIBUTE_DEALLOC (gl_list_free, 1)*/
618 gl_list_t
619 gl_list_nx_create (gl_list_implementation_t implementation,
620 gl_listelement_equals_fn equals_fn,
621 gl_listelement_hashcode_fn hashcode_fn,
622 gl_listelement_dispose_fn dispose_fn,
623 bool allow_duplicates,
624 size_t count, const void **contents)
626 return implementation->nx_create (implementation, equals_fn, hashcode_fn,
627 dispose_fn, allow_duplicates, count,
628 contents);
631 GL_LIST_INLINE size_t
632 gl_list_size (gl_list_t list)
634 return ((const struct gl_list_impl_base *) list)->vtable
635 ->size (list);
638 GL_LIST_INLINE const void *
639 gl_list_node_value (gl_list_t list, gl_list_node_t node)
641 return ((const struct gl_list_impl_base *) list)->vtable
642 ->node_value (list, node);
645 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE int
646 gl_list_node_nx_set_value (gl_list_t list, gl_list_node_t node,
647 const void *elt)
649 return ((const struct gl_list_impl_base *) list)->vtable
650 ->node_nx_set_value (list, node, elt);
653 GL_LIST_INLINE gl_list_node_t
654 gl_list_next_node (gl_list_t list, gl_list_node_t node)
656 return ((const struct gl_list_impl_base *) list)->vtable
657 ->next_node (list, node);
660 GL_LIST_INLINE gl_list_node_t
661 gl_list_previous_node (gl_list_t list, gl_list_node_t node)
663 return ((const struct gl_list_impl_base *) list)->vtable
664 ->previous_node (list, node);
667 GL_LIST_INLINE gl_list_node_t
668 gl_list_first_node (gl_list_t list)
670 return ((const struct gl_list_impl_base *) list)->vtable
671 ->first_node (list);
674 GL_LIST_INLINE gl_list_node_t
675 gl_list_last_node (gl_list_t list)
677 return ((const struct gl_list_impl_base *) list)->vtable
678 ->last_node (list);
681 GL_LIST_INLINE const void *
682 gl_list_get_at (gl_list_t list, size_t position)
684 return ((const struct gl_list_impl_base *) list)->vtable
685 ->get_at (list, position);
688 GL_LIST_INLINE const void *
689 gl_list_get_first (gl_list_t list)
691 return gl_list_get_at (list, 0);
694 GL_LIST_INLINE const void *
695 gl_list_get_last (gl_list_t list)
697 return gl_list_get_at (list, gl_list_size (list) - 1);
700 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
701 gl_list_nx_set_at (gl_list_t list, size_t position, const void *elt)
703 return ((const struct gl_list_impl_base *) list)->vtable
704 ->nx_set_at (list, position, elt);
707 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
708 gl_list_nx_set_first (gl_list_t list, const void *elt)
710 return gl_list_nx_set_at (list, 0, elt);
713 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
714 gl_list_nx_set_last (gl_list_t list, const void *elt)
716 return gl_list_nx_set_at (list, gl_list_size (list) - 1, elt);
719 GL_LIST_INLINE gl_list_node_t
720 gl_list_search (gl_list_t list, const void *elt)
722 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
723 return ((const struct gl_list_impl_base *) list)->vtable
724 ->search_from_to (list, 0, size, elt);
727 GL_LIST_INLINE gl_list_node_t
728 gl_list_search_from (gl_list_t list, size_t start_index, const void *elt)
730 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
731 return ((const struct gl_list_impl_base *) list)->vtable
732 ->search_from_to (list, start_index, size, elt);
735 GL_LIST_INLINE gl_list_node_t
736 gl_list_search_from_to (gl_list_t list, size_t start_index, size_t end_index,
737 const void *elt)
739 return ((const struct gl_list_impl_base *) list)->vtable
740 ->search_from_to (list, start_index, end_index, elt);
743 GL_LIST_INLINE size_t
744 gl_list_indexof (gl_list_t list, const void *elt)
746 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
747 return ((const struct gl_list_impl_base *) list)->vtable
748 ->indexof_from_to (list, 0, size, elt);
751 GL_LIST_INLINE size_t
752 gl_list_indexof_from (gl_list_t list, size_t start_index, const void *elt)
754 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
755 return ((const struct gl_list_impl_base *) list)->vtable
756 ->indexof_from_to (list, start_index, size, elt);
759 GL_LIST_INLINE size_t
760 gl_list_indexof_from_to (gl_list_t list, size_t start_index, size_t end_index,
761 const void *elt)
763 return ((const struct gl_list_impl_base *) list)->vtable
764 ->indexof_from_to (list, start_index, end_index, elt);
767 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
768 gl_list_nx_add_first (gl_list_t list, const void *elt)
770 return ((const struct gl_list_impl_base *) list)->vtable
771 ->nx_add_first (list, elt);
774 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
775 gl_list_nx_add_last (gl_list_t list, const void *elt)
777 return ((const struct gl_list_impl_base *) list)->vtable
778 ->nx_add_last (list, elt);
781 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
782 gl_list_nx_add_before (gl_list_t list, gl_list_node_t node, const void *elt)
784 return ((const struct gl_list_impl_base *) list)->vtable
785 ->nx_add_before (list, node, elt);
788 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
789 gl_list_nx_add_after (gl_list_t list, gl_list_node_t node, const void *elt)
791 return ((const struct gl_list_impl_base *) list)->vtable
792 ->nx_add_after (list, node, elt);
795 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
796 gl_list_nx_add_at (gl_list_t list, size_t position, const void *elt)
798 return ((const struct gl_list_impl_base *) list)->vtable
799 ->nx_add_at (list, position, elt);
802 GL_LIST_INLINE bool
803 gl_list_remove_node (gl_list_t list, gl_list_node_t node)
805 return ((const struct gl_list_impl_base *) list)->vtable
806 ->remove_node (list, node);
809 GL_LIST_INLINE bool
810 gl_list_remove_at (gl_list_t list, size_t position)
812 return ((const struct gl_list_impl_base *) list)->vtable
813 ->remove_at (list, position);
816 GL_LIST_INLINE bool
817 gl_list_remove_first (gl_list_t list)
819 size_t size = gl_list_size (list);
820 if (size > 0)
821 return gl_list_remove_at (list, 0);
822 else
823 return false;
826 GL_LIST_INLINE bool
827 gl_list_remove_last (gl_list_t list)
829 size_t size = gl_list_size (list);
830 if (size > 0)
831 return gl_list_remove_at (list, size - 1);
832 else
833 return false;
836 GL_LIST_INLINE bool
837 gl_list_remove (gl_list_t list, const void *elt)
839 return ((const struct gl_list_impl_base *) list)->vtable
840 ->remove_elt (list, elt);
843 GL_LIST_INLINE void
844 gl_list_free (gl_list_t list)
846 ((const struct gl_list_impl_base *) list)->vtable->list_free (list);
849 GL_LIST_INLINE gl_list_iterator_t
850 gl_list_iterator (gl_list_t list)
852 return ((const struct gl_list_impl_base *) list)->vtable
853 ->iterator (list);
856 GL_LIST_INLINE gl_list_iterator_t
857 gl_list_iterator_from_to (gl_list_t list, size_t start_index, size_t end_index)
859 return ((const struct gl_list_impl_base *) list)->vtable
860 ->iterator_from_to (list, start_index, end_index);
863 GL_LIST_INLINE bool
864 gl_list_iterator_next (gl_list_iterator_t *iterator,
865 const void **eltp, gl_list_node_t *nodep)
867 return iterator->vtable->iterator_next (iterator, eltp, nodep);
870 GL_LIST_INLINE void
871 gl_list_iterator_free (gl_list_iterator_t *iterator)
873 iterator->vtable->iterator_free (iterator);
876 GL_LIST_INLINE gl_list_node_t
877 gl_sortedlist_search (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
879 return ((const struct gl_list_impl_base *) list)->vtable
880 ->sortedlist_search (list, compar, elt);
883 GL_LIST_INLINE gl_list_node_t
884 gl_sortedlist_search_from_to (gl_list_t list, gl_listelement_compar_fn compar, size_t start_index, size_t end_index, const void *elt)
886 return ((const struct gl_list_impl_base *) list)->vtable
887 ->sortedlist_search_from_to (list, compar, start_index, end_index,
888 elt);
891 GL_LIST_INLINE size_t
892 gl_sortedlist_indexof (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
894 return ((const struct gl_list_impl_base *) list)->vtable
895 ->sortedlist_indexof (list, compar, elt);
898 GL_LIST_INLINE size_t
899 gl_sortedlist_indexof_from_to (gl_list_t list, gl_listelement_compar_fn compar, size_t start_index, size_t end_index, const void *elt)
901 return ((const struct gl_list_impl_base *) list)->vtable
902 ->sortedlist_indexof_from_to (list, compar, start_index, end_index,
903 elt);
906 _GL_ATTRIBUTE_NODISCARD GL_LIST_INLINE gl_list_node_t
907 gl_sortedlist_nx_add (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
909 return ((const struct gl_list_impl_base *) list)->vtable
910 ->sortedlist_nx_add (list, compar, elt);
913 GL_LIST_INLINE bool
914 gl_sortedlist_remove (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
916 return ((const struct gl_list_impl_base *) list)->vtable
917 ->sortedlist_remove (list, compar, elt);
920 #ifdef __cplusplus
922 #endif
924 _GL_INLINE_HEADER_END
926 #endif /* _GL_LIST_H */