stdio: Don't break attribute 'scanf' on clang.
[gnulib.git] / lib / gl_list.h
blob53d6e5da617fa9ea10e56284aee78a82ac68fb6c
1 /* Abstract sequential list data type. -*- coding: utf-8 -*-
2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program 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 General Public License for more details.
15 You should have received a copy of the GNU 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 #include <stdbool.h>
22 #include <stddef.h>
24 #ifndef _GL_INLINE_HEADER_BEGIN
25 #error "Please include config.h first."
26 #endif
27 _GL_INLINE_HEADER_BEGIN
28 #ifndef GL_LIST_INLINE
29 # define GL_LIST_INLINE _GL_INLINE
30 #endif
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
37 /* gl_list is an abstract list data type. It can contain any number of
38 objects ('void *' or 'const void *' pointers) in any given order.
39 Duplicates are allowed, but can optionally be forbidden.
41 There are several implementations of this list datatype, optimized for
42 different operations or for memory. You can start using the simplest list
43 implementation, GL_ARRAY_LIST, and switch to a different implementation
44 later, when you realize which operations are performed the most frequently.
45 The API of the different implementations is exactly the same; when
46 switching to a different implementation, you only have to change the
47 gl_list_create call.
49 The implementations are:
50 GL_ARRAY_LIST a growable array
51 GL_CARRAY_LIST a growable circular array
52 GL_LINKED_LIST a linked list
53 GL_AVLTREE_LIST a binary tree (AVL tree)
54 GL_RBTREE_LIST a binary tree (red-black tree)
55 GL_LINKEDHASH_LIST a hash table with a linked list
56 GL_AVLTREEHASH_LIST a hash table with a binary tree (AVL tree)
57 GL_RBTREEHASH_LIST a hash table with a binary tree (red-black tree)
59 The memory consumption is asymptotically the same: O(1) for every object
60 in the list. When looking more closely at the average memory consumed
61 for an object, GL_ARRAY_LIST is the most compact representation, and
62 GL_LINKEDHASH_LIST and GL_TREEHASH_LIST need more memory.
64 The guaranteed average performance of the operations is, for a list of
65 n elements:
67 Operation ARRAY LINKED TREE LINKEDHASH TREEHASH
68 CARRAY with|without with|without
69 duplicates duplicates
71 gl_list_size O(1) O(1) O(1) O(1) O(1)
72 gl_list_node_value O(1) O(1) O(1) O(1) O(1)
73 gl_list_node_set_value O(1) O(1) O(1) O(1) O((log n)²)/O(1)
74 gl_list_next_node O(1) O(1) O(log n) O(1) O(log n)
75 gl_list_previous_node O(1) O(1) O(log n) O(1) O(log n)
76 gl_list_get_at O(1) O(n) O(log n) O(n) O(log n)
77 gl_list_get_first O(1) O(1) O(log n) O(1) O(log n)
78 gl_list_get_last O(1) O(1) O(log n) O(1) O(log n)
79 gl_list_set_at O(1) O(n) O(log n) O(n) O((log n)²)/O(log n)
80 gl_list_set_first O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
81 gl_list_set_last O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
82 gl_list_search O(n) O(n) O(n) O(n)/O(1) O(log n)/O(1)
83 gl_list_search_from O(n) O(n) O(n) O(n)/O(1) O((log n)²)/O(log n)
84 gl_list_search_from_to O(n) O(n) O(n) O(n)/O(1) O((log n)²)/O(log n)
85 gl_list_indexof O(n) O(n) O(n) O(n) O(log n)
86 gl_list_indexof_from O(n) O(n) O(n) O(n) O((log n)²)/O(log n)
87 gl_list_indexof_from_to O(n) O(n) O(n) O(n) O((log n)²)/O(log n)
88 gl_list_add_first O(n)/O(1) O(1) O(log n) O(1) O((log n)²)/O(log n)
89 gl_list_add_last O(1) O(1) O(log n) O(1) O((log n)²)/O(log n)
90 gl_list_add_before O(n) O(1) O(log n) O(1) O((log n)²)/O(log n)
91 gl_list_add_after O(n) O(1) O(log n) O(1) O((log n)²)/O(log n)
92 gl_list_add_at O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
93 gl_list_remove_node O(n) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
94 gl_list_remove_at O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
95 gl_list_remove_first O(n)/O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
96 gl_list_remove_last O(1) O(1) O(log n) O(n)/O(1) O((log n)²)/O(log n)
97 gl_list_remove O(n) O(n) O(n) O(n)/O(1) O((log n)²)/O(log n)
98 gl_list_iterator O(1) O(1) O(log n) O(1) O(log n)
99 gl_list_iterator_from_to O(1) O(n) O(log n) O(n) O(log n)
100 gl_list_iterator_next O(1) O(1) O(log n) O(1) O(log n)
101 gl_sortedlist_search O(log n) O(n) O(log n) O(n) O(log n)
102 gl_sortedlist_search_from O(log n) O(n) O(log n) O(n) O(log n)
103 gl_sortedlist_indexof O(log n) O(n) O(log n) O(n) O(log n)
104 gl_sortedlist_indexof_fro O(log n) O(n) O(log n) O(n) O(log n)
105 gl_sortedlist_add O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
106 gl_sortedlist_remove O(n) O(n) O(log n) O(n) O((log n)²)/O(log n)
109 /* -------------------------- gl_list_t Data Type -------------------------- */
111 /* Type of function used to compare two elements.
112 NULL denotes pointer comparison. */
113 typedef bool (*gl_listelement_equals_fn) (const void *elt1, const void *elt2);
115 /* Type of function used to compute a hash code.
116 NULL denotes a function that depends only on the pointer itself. */
117 typedef size_t (*gl_listelement_hashcode_fn) (const void *elt);
119 /* Type of function used to dispose an element once it's removed from a list.
120 NULL denotes a no-op. */
121 typedef void (*gl_listelement_dispose_fn) (const void *elt);
123 struct gl_list_impl;
124 /* Type representing an entire list. */
125 typedef struct gl_list_impl * gl_list_t;
127 struct gl_list_node_impl;
128 /* Type representing the position of an element in the list, in a way that
129 is more adapted to the list implementation than a plain index.
130 Note: It is invalidated by insertions and removals! */
131 typedef struct gl_list_node_impl * gl_list_node_t;
133 struct gl_list_implementation;
134 /* Type representing a list datatype implementation. */
135 typedef const struct gl_list_implementation * gl_list_implementation_t;
137 #if 0 /* Unless otherwise specified, these are defined inline below. */
139 /* Creates an empty list.
140 IMPLEMENTATION is one of GL_ARRAY_LIST, GL_CARRAY_LIST, GL_LINKED_LIST,
141 GL_AVLTREE_LIST, GL_RBTREE_LIST, GL_LINKEDHASH_LIST, GL_AVLTREEHASH_LIST,
142 GL_RBTREEHASH_LIST.
143 EQUALS_FN is an element comparison function or NULL.
144 HASHCODE_FN is an element hash code function or NULL.
145 DISPOSE_FN is an element disposal function or NULL.
146 ALLOW_DUPLICATES is false if duplicate elements shall not be allowed in
147 the list. The implementation may verify this at runtime. */
148 /* declared in gl_xlist.h */
149 extern gl_list_t gl_list_create_empty (gl_list_implementation_t implementation,
150 gl_listelement_equals_fn equals_fn,
151 gl_listelement_hashcode_fn hashcode_fn,
152 gl_listelement_dispose_fn dispose_fn,
153 bool allow_duplicates);
154 /* Likewise. Returns NULL upon out-of-memory. */
155 extern gl_list_t gl_list_nx_create_empty (gl_list_implementation_t implementation,
156 gl_listelement_equals_fn equals_fn,
157 gl_listelement_hashcode_fn hashcode_fn,
158 gl_listelement_dispose_fn dispose_fn,
159 bool allow_duplicates);
161 /* Creates a list with given contents.
162 IMPLEMENTATION is one of GL_ARRAY_LIST, GL_CARRAY_LIST, GL_LINKED_LIST,
163 GL_AVLTREE_LIST, GL_RBTREE_LIST, GL_LINKEDHASH_LIST, GL_AVLTREEHASH_LIST,
164 GL_RBTREEHASH_LIST.
165 EQUALS_FN is an element comparison function or NULL.
166 HASHCODE_FN is an element hash code function or NULL.
167 DISPOSE_FN is an element disposal function or NULL.
168 ALLOW_DUPLICATES is false if duplicate elements shall not be allowed in
169 the list. The implementation may verify this at runtime.
170 COUNT is the number of initial elements.
171 CONTENTS[0..COUNT-1] is the initial contents. */
172 /* declared in gl_xlist.h */
173 extern gl_list_t gl_list_create (gl_list_implementation_t implementation,
174 gl_listelement_equals_fn equals_fn,
175 gl_listelement_hashcode_fn hashcode_fn,
176 gl_listelement_dispose_fn dispose_fn,
177 bool allow_duplicates,
178 size_t count, const void **contents);
179 /* Likewise. Returns NULL upon out-of-memory. */
180 extern gl_list_t gl_list_nx_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);
187 /* Returns the current number of elements in a list. */
188 extern size_t gl_list_size (gl_list_t list);
190 /* Returns the element value represented by a list node. */
191 extern const void * gl_list_node_value (gl_list_t list, gl_list_node_t node);
193 /* Replaces the element value represented by a list node. */
194 /* declared in gl_xlist.h */
195 extern void gl_list_node_set_value (gl_list_t list, gl_list_node_t node,
196 const void *elt);
197 /* Likewise. Returns 0 upon success, -1 upon out-of-memory. */
198 extern int gl_list_node_nx_set_value (gl_list_t list, gl_list_node_t node,
199 const void *elt)
200 _GL_ATTRIBUTE_NODISCARD;
202 /* Returns the node immediately after the given node in the list, or NULL
203 if the given node is the last (rightmost) one in the list. */
204 extern gl_list_node_t gl_list_next_node (gl_list_t list, gl_list_node_t node);
206 /* Returns the node immediately before the given node in the list, or NULL
207 if the given node is the first (leftmost) one in the list. */
208 extern gl_list_node_t gl_list_previous_node (gl_list_t list, gl_list_node_t node);
210 /* Returns the element at a given position in the list.
211 POSITION must be >= 0 and < gl_list_size (list). */
212 extern const void * gl_list_get_at (gl_list_t list, size_t position);
214 /* Returns the element at the first position in the list.
215 The list must be non-empty. */
216 extern const void * gl_list_get_first (gl_list_t list);
218 /* Returns the element at the last position in the list.
219 The list must be non-empty. */
220 extern const void * gl_list_get_last (gl_list_t list);
222 /* Replaces the element at a given position in the list.
223 POSITION must be >= 0 and < gl_list_size (list).
224 Returns its node. */
225 /* declared in gl_xlist.h */
226 extern gl_list_node_t gl_list_set_at (gl_list_t list, size_t position,
227 const void *elt);
228 /* Likewise. Returns NULL upon out-of-memory. */
229 extern gl_list_node_t gl_list_nx_set_at (gl_list_t list, size_t position,
230 const void *elt)
231 _GL_ATTRIBUTE_NODISCARD;
233 /* Replaces the element at the first position in the list.
234 Returns its node.
235 The list must be non-empty. */
236 /* declared in gl_xlist.h */
237 extern gl_list_node_t gl_list_set_first (gl_list_t list, const void *elt);
238 /* Likewise. Returns NULL upon out-of-memory. */
239 extern gl_list_node_t gl_list_nx_set_first (gl_list_t list, const void *elt)
240 _GL_ATTRIBUTE_NODISCARD;
242 /* Replaces the element at the last position in the list.
243 Returns its node.
244 The list must be non-empty. */
245 /* declared in gl_xlist.h */
246 extern gl_list_node_t gl_list_set_last (gl_list_t list, const void *elt);
247 /* Likewise. Returns NULL upon out-of-memory. */
248 extern gl_list_node_t gl_list_nx_set_last (gl_list_t list, const void *elt)
249 _GL_ATTRIBUTE_NODISCARD;
251 /* Searches whether an element is already in the list.
252 Returns its node if found, or NULL if not present in the list. */
253 extern gl_list_node_t gl_list_search (gl_list_t list, const void *elt);
255 /* Searches whether an element is already in the list,
256 at a position >= START_INDEX.
257 Returns its node if found, or NULL if not present in the list. */
258 extern gl_list_node_t gl_list_search_from (gl_list_t list, size_t start_index,
259 const void *elt);
261 /* Searches whether an element is already in the list,
262 at a position >= START_INDEX and < END_INDEX.
263 Returns its node if found, or NULL if not present in the list. */
264 extern gl_list_node_t gl_list_search_from_to (gl_list_t list,
265 size_t start_index,
266 size_t end_index,
267 const void *elt);
269 /* Searches whether an element is already in the list.
270 Returns its position if found, or (size_t)(-1) if not present in the list. */
271 extern size_t gl_list_indexof (gl_list_t list, const void *elt);
273 /* Searches whether an element is already in the list,
274 at a position >= START_INDEX.
275 Returns its position if found, or (size_t)(-1) if not present in the list. */
276 extern size_t gl_list_indexof_from (gl_list_t list, size_t start_index,
277 const void *elt);
279 /* Searches whether an element is already in the list,
280 at a position >= START_INDEX and < END_INDEX.
281 Returns its position if found, or (size_t)(-1) if not present in the list. */
282 extern size_t gl_list_indexof_from_to (gl_list_t list,
283 size_t start_index, size_t end_index,
284 const void *elt);
286 /* Adds an element as the first element of the list.
287 Returns its node. */
288 /* declared in gl_xlist.h */
289 extern gl_list_node_t gl_list_add_first (gl_list_t list, const void *elt);
290 /* Likewise. Returns NULL upon out-of-memory. */
291 extern gl_list_node_t gl_list_nx_add_first (gl_list_t list, const void *elt)
292 _GL_ATTRIBUTE_NODISCARD;
294 /* Adds an element as the last element of the list.
295 Returns its node. */
296 /* declared in gl_xlist.h */
297 extern gl_list_node_t gl_list_add_last (gl_list_t list, const void *elt);
298 /* Likewise. Returns NULL upon out-of-memory. */
299 extern gl_list_node_t gl_list_nx_add_last (gl_list_t list, const void *elt)
300 _GL_ATTRIBUTE_NODISCARD;
302 /* Adds an element before a given element node of the list.
303 Returns its node. */
304 /* declared in gl_xlist.h */
305 extern gl_list_node_t gl_list_add_before (gl_list_t list, gl_list_node_t node,
306 const void *elt);
307 /* Likewise. Returns NULL upon out-of-memory. */
308 extern gl_list_node_t gl_list_nx_add_before (gl_list_t list,
309 gl_list_node_t node,
310 const void *elt)
311 _GL_ATTRIBUTE_NODISCARD;
313 /* Adds an element after a given element node of the list.
314 Returns its node. */
315 /* declared in gl_xlist.h */
316 extern gl_list_node_t gl_list_add_after (gl_list_t list, gl_list_node_t node,
317 const void *elt);
318 /* Likewise. Returns NULL upon out-of-memory. */
319 extern gl_list_node_t gl_list_nx_add_after (gl_list_t list, gl_list_node_t node,
320 const void *elt)
321 _GL_ATTRIBUTE_NODISCARD;
323 /* Adds an element at a given position in the list.
324 POSITION must be >= 0 and <= gl_list_size (list). */
325 /* declared in gl_xlist.h */
326 extern gl_list_node_t gl_list_add_at (gl_list_t list, size_t position,
327 const void *elt);
328 /* Likewise. Returns NULL upon out-of-memory. */
329 extern gl_list_node_t gl_list_nx_add_at (gl_list_t list, size_t position,
330 const void *elt)
331 _GL_ATTRIBUTE_NODISCARD;
333 /* Removes an element from the list.
334 Returns true. */
335 extern bool gl_list_remove_node (gl_list_t list, gl_list_node_t node);
337 /* Removes an element at a given position from the list.
338 POSITION must be >= 0 and < gl_list_size (list).
339 Returns true. */
340 extern bool gl_list_remove_at (gl_list_t list, size_t position);
342 /* Removes the element at the first position from the list.
343 Returns true if it was found and removed, or false if the list was empty. */
344 extern bool gl_list_remove_first (gl_list_t list);
346 /* Removes the element at the last position from the list.
347 Returns true if it was found and removed, or false if the list was empty. */
348 extern bool gl_list_remove_last (gl_list_t list);
350 /* Searches and removes an element from the list.
351 Returns true if it was found and removed. */
352 extern bool gl_list_remove (gl_list_t list, const void *elt);
354 /* Frees an entire list.
355 (But this call does not free the elements of the list. It only invokes
356 the DISPOSE_FN on each of the elements of the list, and only if the list
357 is not a sublist.) */
358 extern void gl_list_free (gl_list_t list);
360 #endif /* End of inline and gl_xlist.h-defined functions. */
362 /* --------------------- gl_list_iterator_t Data Type --------------------- */
364 /* Functions for iterating through a list. */
366 /* Type of an iterator that traverses a list.
367 This is a fixed-size struct, so that creation of an iterator doesn't need
368 memory allocation on the heap. */
369 typedef struct
371 /* For fast dispatch of gl_list_iterator_next. */
372 const struct gl_list_implementation *vtable;
373 /* For detecting whether the last returned element was removed. */
374 gl_list_t list;
375 size_t count;
376 /* Other, implementation-private fields. */
377 void *p; void *q;
378 size_t i; size_t j;
379 } gl_list_iterator_t;
381 #if 0 /* These are defined inline below. */
383 /* Creates an iterator traversing a list.
384 The list contents must not be modified while the iterator is in use,
385 except for replacing or removing the last returned element. */
386 extern gl_list_iterator_t gl_list_iterator (gl_list_t list);
388 /* Creates an iterator traversing the element with indices i,
389 start_index <= i < end_index, of a list.
390 The list contents must not be modified while the iterator is in use,
391 except for replacing or removing the last returned element. */
392 extern gl_list_iterator_t gl_list_iterator_from_to (gl_list_t list,
393 size_t start_index,
394 size_t end_index);
396 /* If there is a next element, stores the next element in *ELTP, stores its
397 node in *NODEP if NODEP is non-NULL, advances the iterator and returns true.
398 Otherwise, returns false. */
399 extern bool gl_list_iterator_next (gl_list_iterator_t *iterator,
400 const void **eltp, gl_list_node_t *nodep);
402 /* Frees an iterator. */
403 extern void gl_list_iterator_free (gl_list_iterator_t *iterator);
405 #endif /* End of inline functions. */
407 /* ---------------------- Sorted gl_list_t Data Type ---------------------- */
409 /* The following functions are for lists without duplicates where the
410 order is given by a sort criterion. */
412 /* Type of function used to compare two elements. Same as for qsort().
413 NULL denotes pointer comparison. */
414 typedef int (*gl_listelement_compar_fn) (const void *elt1, const void *elt2);
416 #if 0 /* Unless otherwise specified, these are defined inline below. */
418 /* Searches whether an element is already in the list.
419 The list is assumed to be sorted with COMPAR.
420 Returns its node if found, or NULL if not present in the list.
421 If the list contains several copies of ELT, the node of the leftmost one is
422 returned. */
423 extern gl_list_node_t gl_sortedlist_search (gl_list_t list,
424 gl_listelement_compar_fn compar,
425 const void *elt);
427 /* Searches whether an element is already in the list.
428 The list is assumed to be sorted with COMPAR.
429 Only list elements with indices >= START_INDEX and < END_INDEX are
430 considered; the implementation uses these bounds to minimize the number
431 of COMPAR invocations.
432 Returns its node if found, or NULL if not present in the list.
433 If the list contains several copies of ELT, the node of the leftmost one is
434 returned. */
435 extern gl_list_node_t gl_sortedlist_search_from_to (gl_list_t list,
436 gl_listelement_compar_fn compar,
437 size_t start_index,
438 size_t end_index,
439 const void *elt);
441 /* Searches whether an element is already in the list.
442 The list is assumed to be sorted with COMPAR.
443 Returns its position if found, or (size_t)(-1) if not present in the list.
444 If the list contains several copies of ELT, the position of the leftmost one
445 is returned. */
446 extern size_t gl_sortedlist_indexof (gl_list_t list,
447 gl_listelement_compar_fn compar,
448 const void *elt);
450 /* Searches whether an element is already in the list.
451 The list is assumed to be sorted with COMPAR.
452 Only list elements with indices >= START_INDEX and < END_INDEX are
453 considered; the implementation uses these bounds to minimize the number
454 of COMPAR invocations.
455 Returns its position if found, or (size_t)(-1) if not present in the list.
456 If the list contains several copies of ELT, the position of the leftmost one
457 is returned. */
458 extern size_t gl_sortedlist_indexof_from_to (gl_list_t list,
459 gl_listelement_compar_fn compar,
460 size_t start_index,
461 size_t end_index,
462 const void *elt);
464 /* Adds an element at the appropriate position in the list.
465 The list is assumed to be sorted with COMPAR.
466 Returns its node. */
467 /* declared in gl_xlist.h */
468 extern gl_list_node_t gl_sortedlist_add (gl_list_t list,
469 gl_listelement_compar_fn compar,
470 const void *elt);
471 /* Likewise. Returns NULL upon out-of-memory. */
472 extern gl_list_node_t gl_sortedlist_nx_add (gl_list_t list,
473 gl_listelement_compar_fn compar,
474 const void *elt)
475 _GL_ATTRIBUTE_NODISCARD;
477 /* Searches and removes an element from the list.
478 The list is assumed to be sorted with COMPAR.
479 Returns true if it was found and removed.
480 If the list contains several copies of ELT, only the leftmost one is
481 removed. */
482 extern bool gl_sortedlist_remove (gl_list_t list,
483 gl_listelement_compar_fn compar,
484 const void *elt);
486 #endif /* End of inline and gl_xlist.h-defined functions. */
488 /* ------------------------ Implementation Details ------------------------ */
490 struct gl_list_implementation
492 /* gl_list_t functions. */
493 gl_list_t (*nx_create_empty) (gl_list_implementation_t implementation,
494 gl_listelement_equals_fn equals_fn,
495 gl_listelement_hashcode_fn hashcode_fn,
496 gl_listelement_dispose_fn dispose_fn,
497 bool allow_duplicates);
498 gl_list_t (*nx_create) (gl_list_implementation_t implementation,
499 gl_listelement_equals_fn equals_fn,
500 gl_listelement_hashcode_fn hashcode_fn,
501 gl_listelement_dispose_fn dispose_fn,
502 bool allow_duplicates,
503 size_t count, const void **contents);
504 size_t (*size) (gl_list_t list);
505 const void * (*node_value) (gl_list_t list, gl_list_node_t node);
506 int (*node_nx_set_value) (gl_list_t list, gl_list_node_t node,
507 const void *elt);
508 gl_list_node_t (*next_node) (gl_list_t list, gl_list_node_t node);
509 gl_list_node_t (*previous_node) (gl_list_t list, gl_list_node_t node);
510 const void * (*get_at) (gl_list_t list, size_t position);
511 gl_list_node_t (*nx_set_at) (gl_list_t list, size_t position,
512 const void *elt);
513 gl_list_node_t (*search_from_to) (gl_list_t list, size_t start_index,
514 size_t end_index, const void *elt);
515 size_t (*indexof_from_to) (gl_list_t list, size_t start_index,
516 size_t end_index, const void *elt);
517 gl_list_node_t (*nx_add_first) (gl_list_t list, const void *elt);
518 gl_list_node_t (*nx_add_last) (gl_list_t list, const void *elt);
519 gl_list_node_t (*nx_add_before) (gl_list_t list, gl_list_node_t node,
520 const void *elt);
521 gl_list_node_t (*nx_add_after) (gl_list_t list, gl_list_node_t node,
522 const void *elt);
523 gl_list_node_t (*nx_add_at) (gl_list_t list, size_t position,
524 const void *elt);
525 bool (*remove_node) (gl_list_t list, gl_list_node_t node);
526 bool (*remove_at) (gl_list_t list, size_t position);
527 bool (*remove_elt) (gl_list_t list, const void *elt);
528 void (*list_free) (gl_list_t list);
529 /* gl_list_iterator_t functions. */
530 gl_list_iterator_t (*iterator) (gl_list_t list);
531 gl_list_iterator_t (*iterator_from_to) (gl_list_t list,
532 size_t start_index,
533 size_t end_index);
534 bool (*iterator_next) (gl_list_iterator_t *iterator,
535 const void **eltp, gl_list_node_t *nodep);
536 void (*iterator_free) (gl_list_iterator_t *iterator);
537 /* Sorted gl_list_t functions. */
538 gl_list_node_t (*sortedlist_search) (gl_list_t list,
539 gl_listelement_compar_fn compar,
540 const void *elt);
541 gl_list_node_t (*sortedlist_search_from_to) (gl_list_t list,
542 gl_listelement_compar_fn compar,
543 size_t start_index,
544 size_t end_index,
545 const void *elt);
546 size_t (*sortedlist_indexof) (gl_list_t list,
547 gl_listelement_compar_fn compar,
548 const void *elt);
549 size_t (*sortedlist_indexof_from_to) (gl_list_t list,
550 gl_listelement_compar_fn compar,
551 size_t start_index, size_t end_index,
552 const void *elt);
553 gl_list_node_t (*sortedlist_nx_add) (gl_list_t list,
554 gl_listelement_compar_fn compar,
555 const void *elt);
556 bool (*sortedlist_remove) (gl_list_t list,
557 gl_listelement_compar_fn compar,
558 const void *elt);
561 struct gl_list_impl_base
563 const struct gl_list_implementation *vtable;
564 gl_listelement_equals_fn equals_fn;
565 gl_listelement_hashcode_fn hashcode_fn;
566 gl_listelement_dispose_fn dispose_fn;
567 bool allow_duplicates;
570 /* Define all functions of this file as accesses to the
571 struct gl_list_implementation. */
573 GL_LIST_INLINE gl_list_t
574 gl_list_nx_create_empty (gl_list_implementation_t implementation,
575 gl_listelement_equals_fn equals_fn,
576 gl_listelement_hashcode_fn hashcode_fn,
577 gl_listelement_dispose_fn dispose_fn,
578 bool allow_duplicates)
580 return implementation->nx_create_empty (implementation, equals_fn,
581 hashcode_fn, dispose_fn,
582 allow_duplicates);
585 GL_LIST_INLINE gl_list_t
586 gl_list_nx_create (gl_list_implementation_t implementation,
587 gl_listelement_equals_fn equals_fn,
588 gl_listelement_hashcode_fn hashcode_fn,
589 gl_listelement_dispose_fn dispose_fn,
590 bool allow_duplicates,
591 size_t count, const void **contents)
593 return implementation->nx_create (implementation, equals_fn, hashcode_fn,
594 dispose_fn, allow_duplicates, count,
595 contents);
598 GL_LIST_INLINE size_t
599 gl_list_size (gl_list_t list)
601 return ((const struct gl_list_impl_base *) list)->vtable
602 ->size (list);
605 GL_LIST_INLINE const void *
606 gl_list_node_value (gl_list_t list, gl_list_node_t node)
608 return ((const struct gl_list_impl_base *) list)->vtable
609 ->node_value (list, node);
612 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD int
613 gl_list_node_nx_set_value (gl_list_t list, gl_list_node_t node,
614 const void *elt)
616 return ((const struct gl_list_impl_base *) list)->vtable
617 ->node_nx_set_value (list, node, elt);
620 GL_LIST_INLINE gl_list_node_t
621 gl_list_next_node (gl_list_t list, gl_list_node_t node)
623 return ((const struct gl_list_impl_base *) list)->vtable
624 ->next_node (list, node);
627 GL_LIST_INLINE gl_list_node_t
628 gl_list_previous_node (gl_list_t list, gl_list_node_t node)
630 return ((const struct gl_list_impl_base *) list)->vtable
631 ->previous_node (list, node);
634 GL_LIST_INLINE const void *
635 gl_list_get_at (gl_list_t list, size_t position)
637 return ((const struct gl_list_impl_base *) list)->vtable
638 ->get_at (list, position);
641 GL_LIST_INLINE const void *
642 gl_list_get_first (gl_list_t list)
644 return gl_list_get_at (list, 0);
647 GL_LIST_INLINE const void *
648 gl_list_get_last (gl_list_t list)
650 return gl_list_get_at (list, gl_list_size (list) - 1);
653 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
654 gl_list_nx_set_at (gl_list_t list, size_t position, const void *elt)
656 return ((const struct gl_list_impl_base *) list)->vtable
657 ->nx_set_at (list, position, elt);
660 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
661 gl_list_nx_set_first (gl_list_t list, const void *elt)
663 return gl_list_nx_set_at (list, 0, elt);
666 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
667 gl_list_nx_set_last (gl_list_t list, const void *elt)
669 return gl_list_nx_set_at (list, gl_list_size (list) - 1, elt);
672 GL_LIST_INLINE gl_list_node_t
673 gl_list_search (gl_list_t list, const void *elt)
675 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
676 return ((const struct gl_list_impl_base *) list)->vtable
677 ->search_from_to (list, 0, size, elt);
680 GL_LIST_INLINE gl_list_node_t
681 gl_list_search_from (gl_list_t list, size_t start_index, const void *elt)
683 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
684 return ((const struct gl_list_impl_base *) list)->vtable
685 ->search_from_to (list, start_index, size, elt);
688 GL_LIST_INLINE gl_list_node_t
689 gl_list_search_from_to (gl_list_t list, size_t start_index, size_t end_index,
690 const void *elt)
692 return ((const struct gl_list_impl_base *) list)->vtable
693 ->search_from_to (list, start_index, end_index, elt);
696 GL_LIST_INLINE size_t
697 gl_list_indexof (gl_list_t list, const void *elt)
699 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
700 return ((const struct gl_list_impl_base *) list)->vtable
701 ->indexof_from_to (list, 0, size, elt);
704 GL_LIST_INLINE size_t
705 gl_list_indexof_from (gl_list_t list, size_t start_index, const void *elt)
707 size_t size = ((const struct gl_list_impl_base *) list)->vtable->size (list);
708 return ((const struct gl_list_impl_base *) list)->vtable
709 ->indexof_from_to (list, start_index, size, elt);
712 GL_LIST_INLINE size_t
713 gl_list_indexof_from_to (gl_list_t list, size_t start_index, size_t end_index,
714 const void *elt)
716 return ((const struct gl_list_impl_base *) list)->vtable
717 ->indexof_from_to (list, start_index, end_index, elt);
720 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
721 gl_list_nx_add_first (gl_list_t list, const void *elt)
723 return ((const struct gl_list_impl_base *) list)->vtable
724 ->nx_add_first (list, elt);
727 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
728 gl_list_nx_add_last (gl_list_t list, const void *elt)
730 return ((const struct gl_list_impl_base *) list)->vtable
731 ->nx_add_last (list, elt);
734 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
735 gl_list_nx_add_before (gl_list_t list, gl_list_node_t node, const void *elt)
737 return ((const struct gl_list_impl_base *) list)->vtable
738 ->nx_add_before (list, node, elt);
741 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
742 gl_list_nx_add_after (gl_list_t list, gl_list_node_t node, const void *elt)
744 return ((const struct gl_list_impl_base *) list)->vtable
745 ->nx_add_after (list, node, elt);
748 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
749 gl_list_nx_add_at (gl_list_t list, size_t position, const void *elt)
751 return ((const struct gl_list_impl_base *) list)->vtable
752 ->nx_add_at (list, position, elt);
755 GL_LIST_INLINE bool
756 gl_list_remove_node (gl_list_t list, gl_list_node_t node)
758 return ((const struct gl_list_impl_base *) list)->vtable
759 ->remove_node (list, node);
762 GL_LIST_INLINE bool
763 gl_list_remove_at (gl_list_t list, size_t position)
765 return ((const struct gl_list_impl_base *) list)->vtable
766 ->remove_at (list, position);
769 GL_LIST_INLINE bool
770 gl_list_remove_first (gl_list_t list)
772 size_t size = gl_list_size (list);
773 if (size > 0)
774 return gl_list_remove_at (list, 0);
775 else
776 return false;
779 GL_LIST_INLINE bool
780 gl_list_remove_last (gl_list_t list)
782 size_t size = gl_list_size (list);
783 if (size > 0)
784 return gl_list_remove_at (list, size - 1);
785 else
786 return false;
789 GL_LIST_INLINE bool
790 gl_list_remove (gl_list_t list, const void *elt)
792 return ((const struct gl_list_impl_base *) list)->vtable
793 ->remove_elt (list, elt);
796 GL_LIST_INLINE void
797 gl_list_free (gl_list_t list)
799 ((const struct gl_list_impl_base *) list)->vtable->list_free (list);
802 GL_LIST_INLINE gl_list_iterator_t
803 gl_list_iterator (gl_list_t list)
805 return ((const struct gl_list_impl_base *) list)->vtable
806 ->iterator (list);
809 GL_LIST_INLINE gl_list_iterator_t
810 gl_list_iterator_from_to (gl_list_t list, size_t start_index, size_t end_index)
812 return ((const struct gl_list_impl_base *) list)->vtable
813 ->iterator_from_to (list, start_index, end_index);
816 GL_LIST_INLINE bool
817 gl_list_iterator_next (gl_list_iterator_t *iterator,
818 const void **eltp, gl_list_node_t *nodep)
820 return iterator->vtable->iterator_next (iterator, eltp, nodep);
823 GL_LIST_INLINE void
824 gl_list_iterator_free (gl_list_iterator_t *iterator)
826 iterator->vtable->iterator_free (iterator);
829 GL_LIST_INLINE gl_list_node_t
830 gl_sortedlist_search (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
832 return ((const struct gl_list_impl_base *) list)->vtable
833 ->sortedlist_search (list, compar, elt);
836 GL_LIST_INLINE gl_list_node_t
837 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)
839 return ((const struct gl_list_impl_base *) list)->vtable
840 ->sortedlist_search_from_to (list, compar, start_index, end_index,
841 elt);
844 GL_LIST_INLINE size_t
845 gl_sortedlist_indexof (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
847 return ((const struct gl_list_impl_base *) list)->vtable
848 ->sortedlist_indexof (list, compar, elt);
851 GL_LIST_INLINE size_t
852 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)
854 return ((const struct gl_list_impl_base *) list)->vtable
855 ->sortedlist_indexof_from_to (list, compar, start_index, end_index,
856 elt);
859 GL_LIST_INLINE _GL_ATTRIBUTE_NODISCARD gl_list_node_t
860 gl_sortedlist_nx_add (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
862 return ((const struct gl_list_impl_base *) list)->vtable
863 ->sortedlist_nx_add (list, compar, elt);
866 GL_LIST_INLINE bool
867 gl_sortedlist_remove (gl_list_t list, gl_listelement_compar_fn compar, const void *elt)
869 return ((const struct gl_list_impl_base *) list)->vtable
870 ->sortedlist_remove (list, compar, elt);
873 #ifdef __cplusplus
875 #endif
877 _GL_INLINE_HEADER_END
879 #endif /* _GL_LIST_H */