23 #if (!defined(_BOILERPLATE_AVL_INNER_H) && !defined(AVL_PSHARED)) || \ 24 (!defined(_BOILERPLATE_AVL_SHARED_INNER_H) && defined(AVL_PSHARED)) 26 #if !defined(_BOILERPLATE_AVL_H) && !defined(_BOILERPLATE_SHAVL_H) 27 #error "Do not include this file directly. Use <boilerplate/avl.h> or <boilerplate/shavl.h> instead." 34 #define __AVL(__decl) shavl_ ## __decl 35 #define __AVLH(__decl) shavlh_ ## __decl 36 #define __AVL_T(__type) sh ## __type 37 #define _BOILERPLATE_AVL_SHARED_INNER_H 39 #define __AVL(__decl) avl_ ## __decl 40 #define __AVLH(__decl) avlh_ ## __decl 41 #define __AVL_T(__type) __type 42 #define _BOILERPLATE_AVL_INNER_H 45 struct __AVL_T(avlh) {
46 #define AVLH_APP_BITS 28 47 unsigned int flags: AVLH_APP_BITS;
52 struct __AVL_T(avlh) *ptr;
65 typedef int __AVL_T(avlh_cmp_t)(
const struct __AVL_T(avlh) *
const,
66 const struct __AVL_T(avlh) *
const);
68 typedef struct __AVL_T(avlh) *
69 __AVL_T(avl_search_t)(
const struct __AVL_T(avl) *,
70 const struct __AVL_T(avlh) *,
int *, int);
72 typedef int __AVL_T(avlh_prn_t)(
char *, size_t,
73 const struct __AVL_T(avlh) *
const);
75 struct __AVL_T(avl_searchops) {
76 __AVL_T(avl_search_t) *search;
77 __AVL_T(avlh_cmp_t) *cmp;
81 struct __AVL_T(avlh) anchor;
84 struct __AVL_T(avlh) *ptr;
94 #define avl_opposite(type) (-(type)) 96 #define avl_type2index(type) ((type)+1) 98 #define AVL_THR_LEFT (1 << avl_type2index(AVL_LEFT)) 99 #define AVL_THR_RIGHT (1 << avl_type2index(AVL_RIGHT)) 103 static inline struct shavlh *
104 shavlh_link(
const struct shavl *
const avl,
105 const struct shavlh *
const holder,
unsigned int dir)
107 return (
void *)avl + holder->link[avl_type2index(dir)].offset;
111 shavlh_set_link(
struct shavl *
const avl,
struct shavlh *lhs,
112 int dir,
struct shavlh *rhs)
114 lhs->link[avl_type2index(dir)].offset = (
void *)rhs - (
void *)avl;
118 struct shavlh *shavl_end(
const struct shavl *
const avl,
int dir)
120 return (
void *)avl + avl->end[avl_type2index(dir)].offset;
124 shavl_set_end(
struct shavl *
const avl,
int dir,
struct shavlh *holder)
126 avl->end[avl_type2index(dir)].offset = (
void *)holder - (
void *)avl;
129 #define shavl_count(avl) ((avl)->count) 130 #define shavl_height(avl) ((avl)->height) 131 #define shavl_anchor(avl) (&(avl)->anchor) 133 #define shavlh_up(avl, holder) \ 134 shavlh_link((avl), (holder), AVL_UP) 135 #define shavlh_left(avl, holder) \ 136 shavlh_link((avl), (holder), AVL_LEFT) 137 #define shavlh_right(avl, holder) \ 138 shavlh_link((avl), (holder), AVL_RIGHT) 140 #define shavlh_thr_tst(avl, holder, side) \ 141 (shavlh_link(avl, holder, side) == NULL) 142 #define shavlh_child(avl, holder, side) \ 143 (shavlh_link((avl),(holder),(side))) 144 #define shavlh_has_child(avl, holder, side) \ 145 (!shavlh_thr_tst(avl, holder, side)) 147 #define shavl_top(avl) (shavlh_right(avl, shavl_anchor(avl))) 148 #define shavl_head(avl) (shavl_end((avl), AVL_LEFT)) 149 #define shavl_tail(avl) (shavl_end((avl), AVL_RIGHT)) 155 #define DECLARE_SHAVL_SEARCH(__search_fn, __cmp) \ 156 struct shavlh *__search_fn(const struct shavl *const avl, \ 157 const struct shavlh *const node, \ 158 int *const pdelta, int dir) \ 160 int delta = AVL_RIGHT; \ 161 struct shavlh *holder = shavl_top(avl), *next; \ 163 if (holder == NULL) \ 167 delta = __cmp(node, holder); \ 175 if (!(delta ?: dir)) \ 177 next = shavlh_child(avl, holder, delta ?: dir); \ 190 #define avlh_link(avl, holder, dir) ((holder)->link[avl_type2index(dir)].ptr) 192 #define avl_end(avl, dir) ((avl)->end[avl_type2index(dir)].ptr) 195 avlh_set_link(
struct avl *
const avl,
struct avlh *lhs,
int dir,
struct avlh *rhs)
197 avlh_link(avl, lhs, dir) = rhs;
201 avl_set_end(
struct avl *
const avl,
int dir,
struct avlh *holder)
203 avl_end(avl, dir) = holder;
206 #define avl_count(avl) ((avl)->count) 207 #define avl_height(avl) ((avl)->height) 208 #define avl_anchor(avl) (&(avl)->anchor) 210 #define avlh_up(avl, holder) avlh_link((avl), (holder), AVL_UP) 211 #define avlh_left(avl, holder) avlh_link((avl), (holder), AVL_LEFT) 212 #define avlh_right(avl, holder) avlh_link((avl), (holder), AVL_RIGHT) 214 #define avlh_thr_tst(avl, holder, side) (avlh_link(avl, holder, side) == NULL) 215 #define avlh_child(avl, holder, side) (avlh_link((avl),(holder),(side))) 216 #define avlh_has_child(avl, holder, side) (!avlh_thr_tst(avl, holder, side)) 218 #define avl_top(avl) (avlh_right(avl, avl_anchor(avl))) 219 #define avl_head(avl) (avl_end((avl), AVL_LEFT)) 220 #define avl_tail(avl) (avl_end((avl), AVL_RIGHT)) 226 #define DECLARE_AVL_SEARCH(__search_fn, __cmp) \ 227 struct avlh *__search_fn(const struct avl *const avl, \ 228 const struct avlh *const node, \ 229 int *const pdelta, int dir) \ 231 int delta = AVL_RIGHT; \ 232 struct avlh *holder = avl_top(avl), *next; \ 234 if (holder == NULL) \ 238 delta = __cmp(node, holder); \ 246 if (!(delta ?: dir)) \ 248 next = avlh_child(avl, holder, delta ?: dir); \ 264 #define avl_sign(v) \ 266 typeof(v) _v = (v); \ 267 ((_v) > 0) - ((_v) < 0); \ 273 #define avl_cmp_sign(l, r) \ 275 typeof(l) _l = (l); \ 276 typeof(r) _r = (r); \ 277 (_l > _r) - (_l < _r); \ 280 static inline struct __AVL_T(avlh) *
281 __AVL(search_inner)(
const struct __AVL_T(avl) *
const avl,
282 const struct __AVL_T(avlh) *n,
int *delta,
283 const struct __AVL_T(avl_searchops) *ops)
285 return ops->search(avl, n, delta, 0);
289 struct __AVL_T(avlh) *__AVL(gettop)(
const struct __AVL_T(avl) *
const avl)
291 return __AVL(top)(avl);
295 struct __AVL_T(avlh) *__AVL(gethead)(
const struct __AVL_T(avl) *
const avl)
297 return __AVL(head)(avl);
301 struct __AVL_T(avlh) *__AVL(gettail)(
const struct __AVL_T(avl) *
const avl)
303 return __AVL(tail)(avl);
307 unsigned int __AVL(getcount)(
const struct __AVL_T(avl) *
const avl)
309 return __AVL(count)(avl);
312 struct __AVL_T(avlh) *__AVL(inorder)(
const struct __AVL_T(avl) *
const avl,
313 struct __AVL_T(avlh) *holder,
316 struct __AVL_T(avlh) *__AVL(postorder)(
const struct __AVL_T(avl) *
const avl,
317 struct __AVL_T(avlh) *
const holder,
320 struct __AVL_T(avlh) *__AVL(preorder)(
const struct __AVL_T(avl) *
const avl,
321 struct __AVL_T(avlh) *holder,
324 static inline struct __AVL_T(avlh) *
325 __AVL(next)(
const struct __AVL_T(avl) *
const avl,
326 struct __AVL_T(avlh) *
const holder)
328 return __AVL(inorder)(avl, holder, AVL_RIGHT);
331 static inline struct __AVL_T(avlh) *
332 __AVL(prev)(
const struct __AVL_T(avl) *
const avl,
333 struct __AVL_T(avlh) *
const holder)
335 return __AVL(inorder)(avl, holder, AVL_LEFT);
338 static inline struct __AVL_T(avlh) *
339 __AVL(postorder_next)(
const struct __AVL_T(avl) *
const avl,
340 struct __AVL_T(avlh) *
const holder)
342 return __AVL(postorder)(avl, holder, AVL_RIGHT);
345 static inline struct __AVL_T(avlh) *
346 __AVL(postorder_prev)(
const struct __AVL_T(avl) *
const avl,
347 struct __AVL_T(avlh) *
const holder)
349 return __AVL(postorder)(avl, holder, AVL_LEFT);
352 static inline struct __AVL_T(avlh) *
353 __AVL(preorder_next)(
const struct __AVL_T(avl) *
const avl,
354 struct __AVL_T(avlh) *
const holder)
356 return __AVL(preorder)(avl, holder, AVL_RIGHT);
359 static inline struct __AVL_T(avlh) *
360 __AVL(preorder_prev)(
const struct __AVL_T(avl) *
const avl,
361 struct __AVL_T(avlh) *
const holder)
363 return __AVL(preorder)(avl, holder, AVL_LEFT);
366 static inline void __AVLH(init)(
struct __AVL_T(avlh) *
const holder)
372 static inline struct __AVL_T(avlh) *
373 __AVL(search)(
const struct __AVL_T(avl) *
const avl,
374 const struct __AVL_T(avlh) *node,
375 const struct __AVL_T(avl_searchops) *ops)
377 struct __AVL_T(avlh) *holder;
380 holder = __AVL(search_inner)(avl, node, &delta, ops);
387 static inline struct __AVL_T(avlh) *
388 __AVL(search_nearest)(
const struct __AVL_T(avl) *
const avl,
389 const struct __AVL_T(avlh) *node,
int dir,
390 const struct __AVL_T(avl_searchops) *ops)
392 struct __AVL_T(avlh) *holder;
395 holder = __AVL(search_inner)(avl, node, &delta, ops);
396 if (!holder || delta != dir)
399 return __AVL(inorder)(avl, holder, dir);
402 static inline struct __AVL_T(avlh) *
403 __AVL(search_le)(
const struct __AVL_T(avl) *
const avl,
404 const struct __AVL_T(avlh) *node,
405 const struct __AVL_T(avl_searchops) *ops)
407 return __AVL(search_nearest)(avl, node, AVL_LEFT, ops);
410 static inline struct __AVL_T(avlh) *
411 __AVL(search_ge)(
const struct __AVL_T(avl) *
const avl,
412 const struct __AVL_T(avlh) *node,
413 const struct __AVL_T(avl_searchops) *ops)
415 return __AVL(search_nearest)(avl, node, AVL_RIGHT, ops);
418 static inline struct __AVL_T(avlh) *
419 __AVL(search_multi)(
const struct __AVL_T(avl) *
const avl,
420 const struct __AVL_T(avlh) *node,
int dir,
421 const struct __AVL_T(avl_searchops) *ops)
423 struct __AVL_T(avlh) *holder;
426 holder = ops->search(avl, node, &delta, dir);
433 return __AVL(inorder)(avl, holder, -dir);
436 static inline struct __AVL_T(avlh) *
437 __AVL(search_first)(
const struct __AVL_T(avl) *
const avl,
438 const struct __AVL_T(avlh) *node,
439 const struct __AVL_T(avl_searchops) *ops)
441 return __AVL(search_multi)(avl, node, AVL_LEFT, ops);
444 static inline struct __AVL_T(avlh) *
445 __AVL(search_last)(
const struct __AVL_T(avl) *
const avl,
446 const struct __AVL_T(avlh) *node,
447 const struct __AVL_T(avl_searchops) *ops)
449 return __AVL(search_multi)(avl, node, AVL_RIGHT, ops);
456 void __AVL(init)(
struct __AVL_T(avl) *
const avl);
458 void __AVL(destroy)(
struct __AVL_T(avl) *
const avl);
460 int __AVL(insert)(
struct __AVL_T(avl) *
const avl,
461 struct __AVL_T(avlh) *
const holder,
462 const struct __AVL_T(avl_searchops) *ops);
464 int __AVL(insert_front)(
struct __AVL_T(avl) *avl,
465 struct __AVL_T(avlh) *holder,
466 const struct __AVL_T(avl_searchops) *ops);
468 int __AVL(insert_back)(
struct __AVL_T(avl) *avl,
469 struct __AVL_T(avlh) *holder,
470 const struct __AVL_T(avl_searchops) *ops);
472 int __AVL(insert_at)(
struct __AVL_T(avl) *
const avl,
473 struct __AVL_T(avlh) *parent,
int dir,
474 struct __AVL_T(avlh) *child);
476 int __AVL(prepend)(
struct __AVL_T(avl) *
const avl,
477 struct __AVL_T(avlh) *
const holder,
478 const struct __AVL_T(avl_searchops) *ops);
480 int __AVL(append)(
struct __AVL_T(avl) *
const avl,
481 struct __AVL_T(avlh) *
const holder,
482 const struct __AVL_T(avl_searchops) *ops);
484 int __AVL(
delete)(
struct __AVL_T(avl) *
const avl,
485 struct __AVL_T(avlh) *node);
487 int __AVL(replace)(
struct __AVL_T(avl) *avl,
488 struct __AVL_T(avlh) *oldh,
489 struct __AVL_T(avlh) *newh,
490 const struct __AVL_T(avl_searchops) *ops);
492 struct __AVL_T(avlh) *__AVL(update)(
struct __AVL_T(avl) *
const avl,
493 struct __AVL_T(avlh) *
const holder,
494 const struct __AVL_T(avl_searchops) *ops);
496 struct __AVL_T(avlh) *__AVL(
set)(
struct __AVL_T(avl) *
const avl,
497 struct __AVL_T(avlh) *
const holder,
498 const struct __AVL_T(avl_searchops) *ops);
500 void __AVL(clear)(
struct __AVL_T(avl) *
const avl,
501 void (*destruct)(
struct __AVL_T(avlh) *));
503 int __AVL(check)(
const struct __AVL_T(avl) *avl,
504 const struct __AVL_T(avl_searchops) *ops);
506 void __AVL(dump)(FILE *file,
const struct __AVL_T(avl) *
const avl,
507 __AVL_T(avlh_prn_t) *prn,
unsigned int indent,