beta-0.89.2
[luatex.git] / source / texk / web2c / mplibdir / avl.h
blob9771c0952201108880e2c8447458db92b5fc290e
2 /*
3 pyavl -- HEADER FILE "avl.h"
4 Interface to manipulate "objects" of type 'avl_tree' and 'avl_iterator'
5 */
7 #ifndef __AVL__
8 #define __AVL__
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <stdlib.h>
14 #define avl_del mp_avl_del
15 #define avl_ins mp_avl_ins
16 #define avl_tree mp_avl_tree
17 #define avl_entry mp_avl_entry
18 #define avl_find mp_avl_find
19 #define avl_create mp_avl_create
20 #define avl_destroy mp_avl_destroy
22 typedef enum
23 { avl_false, avl_true } avl_bool_t;
25 #ifndef MPW_C
26 #include <inttypes.h>
27 typedef int8_t avl_code_t;
28 typedef int8_t avl_bal_t;
29 typedef uint32_t avl_size_t;
30 #else
31 #include <MacTypes.h>
32 typedef SInt8 avl_code_t;
33 typedef SInt8 avl_bal_t;
34 typedef UInt32 avl_size_t;
35 #endif
37 typedef int (*avl_compare_func) (void *param, const void *lhs,
38 const void *rhs);
39 typedef void *(*avl_item_copy_func) (const void *item);
40 typedef void *(*avl_item_dispose_func) (void *item);
41 typedef void (*avl_item_func) (const void *item, void *param);
42 typedef void *(*avl_alloc_func) (size_t);
43 typedef void (*avl_dealloc_func) (void *);
45 #ifdef AVL_FOR_PYTHON
46 #undef AVL_CMPERR
47 #undef AVL_NULLCHECKS
48 #define AVL_CMPERR 1
49 #define AVL_NULLCHECKS 1
50 #else
51 #ifndef AVL_CMPERR
52 #define AVL_CMPERR 0
53 #endif
54 #ifndef AVL_NULLCHECKS
55 #define AVL_NULLCHECKS 0
56 #endif
57 #endif
59 #if AVL_CMPERR != 0
60 extern avl_code_t avl_errcmp_occurred(void *);
61 #endif
63 /* At minimum, shallow copy */
65 const void *avl_default_item_copy(const void *);
66 void *avl_default_item_dispose(void *);
68 #define AVL_STACK_CAPACITY 32 /* for avl_split() function */
70 typedef enum
72 AVL_ITERATOR_INI_PRE,
73 AVL_ITERATOR_INI_POST,
74 AVL_ITERATOR_INI_INTREE
75 } avl_ini_t;
77 typedef struct avl_tree_ *avl_tree;
78 typedef struct avl_iterator_ *avl_iterator;
80 typedef struct avl_itersource_ avl_itersource_struct, *avl_itersource;
82 struct avl_itersource_
84 void *p;
85 /* return nonzero on error */
86 avl_code_t(*f) (avl_itersource from, void **to);
89 typedef struct
91 avl_compare_func compare;
92 avl_item_copy_func copy;
93 avl_item_dispose_func dispose;
94 avl_alloc_func alloc;
95 avl_dealloc_func dealloc;
96 } avl_config_struct, *avl_config;
98 /* -------------------------------------------------------------------------------------------------/
99 Public Functions
100 ---------------------------------------------------------------------------------------------------*/
103 --- CREATE ---
104 Return a new tree and set its config.
105 Return NULL on allocation failure.
106 * 'alloc' defaults to malloc from stdlib
107 * 'dealloc' defaults to free from stdlib
108 * 'param' user param/refcon
111 avl_tree avl_create(avl_compare_func compare,
112 avl_item_copy_func copy,
113 avl_item_dispose_func dispose,
114 avl_alloc_func alloc,
115 avl_dealloc_func dealloc, void *param);
118 --- RESET ---
119 Empty tree 't' as in 'avl_empty()' and modify its config.
122 void
123 avl_reset(avl_tree t,
124 avl_compare_func compare,
125 avl_item_copy_func copy,
126 avl_item_dispose_func dispose,
127 avl_alloc_func alloc, avl_dealloc_func dealloc);
130 --- EMPTY ---
131 Empty tree 't', calling its dispose_func for each item in 't'.
132 The config is untouched.
135 void avl_empty(avl_tree t);
138 --- DESTROY ---
139 Empty tree 't' and free the handle.
142 void avl_destroy(avl_tree t);
145 --- DUPLICATE (COPY) ---
146 Return a copy of tree 't', using its copy_func for each item in 't'.
147 Upon failure to allocate room for some item, return NULL.
150 avl_tree avl_dup(avl_tree t, void *param);
153 --- EMPTYNESS ---
154 Return 'avl_true' iff tree 't' is empty (i.e. the handle is NULL or 't' contains no item).
157 avl_bool_t avl_isempty(avl_tree t);
160 --- SIZE ---
161 Return number of items contained in tree 't'.
164 avl_size_t avl_size(avl_tree t);
167 --- FIRST (MINIMUM) ---
168 Return first item in in-order traversal of 't'.
169 Return NULL if 't' is empty.
172 void *avl_first(avl_tree t);
175 --- LAST (MAXIMUM) ---
176 Return last item in in-order traversal of 't'.
177 Return NULL if 't' is empty.
180 void *avl_last(avl_tree t);
183 --- FIND MATCHING ITEM ---
184 Find item matching 'item' parameter in tree 't'.
185 Return NULL if it's not found.
186 If there are multiple matches, the first one that is encountered
187 during the search is returned; it may not be the one with lowest rank.
190 void *avl_find(const void *item, avl_tree t);
193 --- INDEX (RANK) OF ITEM ---
194 Return smallest index 'i' s.t. 't[i]' matches 'item',
195 or zero if 'item' is not found.
198 avl_size_t avl_index(const void *item, avl_tree t);
201 --- SPAN ITEMS ---
202 Return integers 'i,j' s.t. 't[i,j]'
203 i smallest index s.t. t[i] >= lo_item, or t->count+1 and
204 j greatest one s.t. t[j] <= hi_item, or 0.
205 If 'hi_item' is less than 'lo_item' those are swapped.
206 Return codes:
207 0 success
208 -1 error: tree had no root
209 -2 error: compare failed
212 avl_code_t
213 avl_span(const void *lo_item,
214 const void *hi_item,
215 avl_tree t, avl_size_t * lo_idx, avl_size_t * hi_idx);
218 --- FIND AT LEAST ---
219 Return smallest item in 't' that is GEQ 'item', or NULL.
222 void *avl_find_atleast(const void *item, avl_tree t);
225 --- FIND AT MOST ---
226 Return largest item in 't' that is LEQ 'item', or NULL.
229 void *avl_find_atmost(const void *item, avl_tree t);
232 --- FIND BY INDEX (RANK) ---
233 Find item in 't' by index, that is return 't[idx]'.
234 If 'idx' is not in '[1,avl_size(t)]' then return NULL.
235 If a compare failed then return NULL.
238 void *avl_find_index(avl_size_t idx, avl_tree t);
241 --- INSERTION ---
242 Insert 'item' in tree 't' with regard to its compare_func.
243 Say 'avl_ins(item,t,avl_true)' to insert 'item' in 't'
244 even if it is there already.
245 If 'item' is a duplicate and 'allow_duplicates' is avl_false,
246 nothing is done.
247 Return codes:
248 -1 error: allocation of new node failed
249 -2 error: compare failed, tree unchanged
250 0 nothing was done, no error
251 +1 operation successful
252 +2 the same and height(t) increased by one.
255 avl_code_t avl_ins(void *item, avl_tree t, avl_bool_t allow_duplicates);
258 --- DELETION ---
259 Remove 'item' from tree 't', calling its dispose_func.
260 To make a backup of 'item' involving its copy_func,
261 say 't(item,backup)' where 'backup' is some pointer to pointer to item.
262 Otherwise set it to NULL.
263 Return codes:
264 0 item not found
265 -2 error: compare failed, tree unchanged
266 +1 operation successful
267 +2 the same and height(t) decreased by one.
270 avl_code_t avl_del(void *item, avl_tree t, void **backup);
273 --- DELETE FIRST ---
274 Remove first item in in-order traversal from tree 't'.
275 Note that only one item is removed.
276 Return +1 or +2 as above.
279 avl_code_t avl_del_first(avl_tree t, void **backup);
282 --- DELETE LAST ---
283 Remove last item in in-order traversal from tree 't'.
284 Note that only one item is removed.
285 Return +1 or +2 as above.
288 avl_code_t avl_del_last(avl_tree t, void **backup);
291 --- INSERT IN FRONT OF INDEX ---
292 Insert 'item' in tree 't' so that afterwards,
293 't[idx]=item' except if 'idx<=0' or 'idx>size(t)+1'.
294 To append 'item' to 't' regardless of order,
295 say 'avl_ins_index(item,size+1,t)'.
298 avl_code_t avl_ins_index(void *item, avl_size_t idx, avl_tree t);
301 --- DELETE ITEM BY INDEX ---
302 Remove item of rank 'idx' from tree 't' and
303 return +1 or +2 as above except if 'idx' is not in
304 '[1,avl_size(t)]' in which case return 0.
307 avl_code_t avl_del_index(avl_size_t idx, avl_tree t, void **backup);
310 --- IN-PLACE CONCATENATION ---
311 Pre-condition: 't0' and 't1' are valid avl_trees
312 Note that the code does not check whether the maximal item in 't0' is LEQ than
313 the minimal item in 't1'.
314 Post-condition: 't0' handles the concatenation of
315 't0' and 't1' which becomes empty (but its config is untouched).
318 void avl_cat(avl_tree t0, avl_tree t1);
321 --- SPLITTING ---
322 Pre-condition: 't0' and 't1' are existing handles.
323 Post-condition: items in 't0' all compare LEQ than 'item'
324 and items in 't1' all compare GEQ than 'item'.
325 This implementation removes one item.
326 Return codes:
327 0 item not found, no-op
328 -2 compare failed, tree unchanged
329 +1 success
332 avl_code_t avl_split(const void *item, avl_tree t, avl_tree t0, avl_tree t1);
335 --- IN-ORDER TRAVERSAL ---
336 Walk tree 't' in in-order, applying 'proc' at each node.
337 The 'param' pointer is passed to 'proc', like this:
338 '(*proc) (item_at_node,param)'.
341 void avl_walk(avl_tree t, avl_item_func proc, void *param);
344 --- SLICE ---
345 Create a _new tree_ from the slice 't[lo_idx,hi_idx)'
346 provided 'lo_idx <= hi_idx' and these indices
347 are both in range. If a new tree can't be created
348 or if some item can't be allocated, return NULL.
349 Otherwise if the indices are inconsistent return NULL.
352 avl_tree
353 avl_slice(avl_tree t, avl_size_t lo_idx, avl_size_t hi_idx, void *param);
355 /* ----------------------------------------------------------/
356 ITERATORS
358 An iterator assigned to a tree 't' is still usable after
359 any item is inserted into 't' and after any item
360 not located at this iterator's current position is
361 deleted. The 'avl_iterator_del()' function may be used
362 to remove the item at the iterator's current position.
363 ------------------------------------------------------------*/
366 --- ITERATOR --- SEEK
367 Find 'item' in this iterator's tree as in 'avl_find()'
368 and make it the current position.
371 void avl_iterator_seek(const void *item, avl_iterator iter);
374 --- ITERATOR --- COUNT
375 Return size of this iterator's tree
378 avl_size_t avl_iterator_count(avl_iterator iter);
381 --- ITERATOR --- SEEK BY INDEX
382 Set the current position of 'iter' to 't[idx]'
383 where 't' is the tree that is iterated over.
386 void avl_iterator_seek_index(avl_size_t idx, avl_iterator iter);
389 --- ITERATOR --- CURRENT POSITION
390 Return item at current position of 'iter'.
393 void *avl_iterator_cur(avl_iterator iter);
396 --- ITERATOR --- INDEX
397 Return rank of current item of 'iter' (as a result of computation)
398 except it returns 0 or size of tree plus one if 'iter' is a pre- or post- iterator.
401 avl_size_t avl_iterator_index(avl_iterator iter);
404 --- ITERATOR --- CREATE
405 Return a new cursor for tree 't'.
406 If allocation of an iterator struct is impossible, return NULL.
407 Say 'avl_iterator_new(t, ini)' with 'ini==AVL_ITERATOR_INI_PRE' or 'ini==AVL_ITERATOR_INI_POST'
408 or say 'avl_iterator_new(t, AVL_ITERATOR_INI_INTREE, item_pointer)'
409 to set the iterator's current position via 'avl_iterator_seek(item_pointer,the_iterator)'.
410 In the latter case, the iterator is flagged
411 as pre-iterator if the item is not found.
414 avl_iterator avl_iterator_new(avl_tree t, avl_ini_t ini, ...);
417 --- ITERATOR --- KILL
418 Cleanup: free the iterator struct.
421 void avl_iterator_kill(avl_iterator iter);
424 --- ITERATOR --- SUCCESSOR
425 Get next item pointer in iterator or NULL.
426 'iter' is flagged as post-iterator if it's in post-position.
429 void *avl_iterator_next(avl_iterator iter);
432 --- ITERATOR --- PREDECESSOR
433 Get next item pointer in iterator or NULL.
434 'iter' is flagged as pre-iterator if it's in pre-position.
437 void *avl_iterator_prev(avl_iterator iter);
440 --- ITERATOR --- DELETION
441 Remove item at current position of iterator 'iter' from its tree, if there is one.
442 Current position is set to next item or iterator is flagged as post-iterator.
445 avl_code_t avl_iterator_del(avl_iterator iter, void **backup);
448 --- VERIFICATION ---
449 Return avl_true iff 't' is a valid avl_tree.
450 Note that 'avl_verify(NULL)==avl_false'.
453 #ifdef HAVE_AVL_VERIFY
454 avl_bool_t avl_verify(avl_tree t);
455 #endif /* HAVE_AVL_VERIFY */
458 --- LOAD ---
459 More general version of avl_slice
462 avl_tree
463 avl_xload(avl_itersource src,
464 void **pres, avl_size_t len, avl_config conf, void *param);
466 #endif /* __AVL__ */