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 ptrdiff_t offset = holder->link[avl_type2index(dir)].offset;
108 return offset == (ptrdiff_t)-1 ? NULL : (
void *)avl + offset;
112 shavlh_set_link(
struct shavl *
const avl,
struct shavlh *lhs,
113 int dir,
struct shavlh *rhs)
115 ptrdiff_t offset = rhs ? (
void *)rhs - (
void *)avl : (ptrdiff_t)-1;
116 lhs->link[avl_type2index(dir)].offset = offset;
120 struct shavlh *shavl_end(
const struct shavl *
const avl,
int dir)
122 ptrdiff_t offset = avl->end[avl_type2index(dir)].offset;
123 return offset == (ptrdiff_t)-1 ? NULL : (
void *)avl + offset;
127 shavl_set_end(
struct shavl *
const avl,
int dir,
struct shavlh *holder)
129 ptrdiff_t offset = holder ? (
void *)holder - (
void *)avl : (ptrdiff_t)-1;
130 avl->end[avl_type2index(dir)].offset = offset;
133 #define shavl_count(avl) ((avl)->count) 134 #define shavl_height(avl) ((avl)->height) 135 #define shavl_anchor(avl) (&(avl)->anchor) 137 #define shavlh_up(avl, holder) \ 138 shavlh_link((avl), (holder), AVL_UP) 139 #define shavlh_left(avl, holder) \ 140 shavlh_link((avl), (holder), AVL_LEFT) 141 #define shavlh_right(avl, holder) \ 142 shavlh_link((avl), (holder), AVL_RIGHT) 144 #define shavlh_thr_tst(avl, holder, side) \ 145 (shavlh_link(avl, holder, side) == NULL) 146 #define shavlh_child(avl, holder, side) \ 147 (shavlh_link((avl),(holder),(side))) 148 #define shavlh_has_child(avl, holder, side) \ 149 (!shavlh_thr_tst(avl, holder, side)) 151 #define shavl_top(avl) (shavlh_right(avl, shavl_anchor(avl))) 152 #define shavl_head(avl) (shavl_end((avl), AVL_LEFT)) 153 #define shavl_tail(avl) (shavl_end((avl), AVL_RIGHT)) 159 #define DECLARE_SHAVL_SEARCH(__search_fn, __cmp) \ 160 struct shavlh *__search_fn(const struct shavl *const avl, \ 161 const struct shavlh *const node, \ 162 int *const pdelta, int dir) \ 164 int delta = AVL_RIGHT; \ 165 struct shavlh *holder = shavl_top(avl), *next; \ 167 if (holder == NULL) \ 171 delta = __cmp(node, holder); \ 179 if (!(delta ?: dir)) \ 181 next = shavlh_child(avl, holder, delta ?: dir); \ 194 #define avlh_link(avl, holder, dir) ((holder)->link[avl_type2index(dir)].ptr) 196 #define avl_end(avl, dir) ((avl)->end[avl_type2index(dir)].ptr) 199 avlh_set_link(
struct avl *
const avl,
struct avlh *lhs,
int dir,
struct avlh *rhs)
201 avlh_link(avl, lhs, dir) = rhs;
205 avl_set_end(
struct avl *
const avl,
int dir,
struct avlh *holder)
207 avl_end(avl, dir) = holder;
210 #define avl_count(avl) ((avl)->count) 211 #define avl_height(avl) ((avl)->height) 212 #define avl_anchor(avl) (&(avl)->anchor) 214 #define avlh_up(avl, holder) avlh_link((avl), (holder), AVL_UP) 215 #define avlh_left(avl, holder) avlh_link((avl), (holder), AVL_LEFT) 216 #define avlh_right(avl, holder) avlh_link((avl), (holder), AVL_RIGHT) 218 #define avlh_thr_tst(avl, holder, side) (avlh_link(avl, holder, side) == NULL) 219 #define avlh_child(avl, holder, side) (avlh_link((avl),(holder),(side))) 220 #define avlh_has_child(avl, holder, side) (!avlh_thr_tst(avl, holder, side)) 222 #define avl_top(avl) (avlh_right(avl, avl_anchor(avl))) 223 #define avl_head(avl) (avl_end((avl), AVL_LEFT)) 224 #define avl_tail(avl) (avl_end((avl), AVL_RIGHT)) 230 #define DECLARE_AVL_SEARCH(__search_fn, __cmp) \ 231 struct avlh *__search_fn(const struct avl *const avl, \ 232 const struct avlh *const node, \ 233 int *const pdelta, int dir) \ 235 int delta = AVL_RIGHT; \ 236 struct avlh *holder = avl_top(avl), *next; \ 238 if (holder == NULL) \ 242 delta = __cmp(node, holder); \ 250 if (!(delta ?: dir)) \ 252 next = avlh_child(avl, holder, delta ?: dir); \ 268 #define avl_sign(v) \ 270 typeof(v) _v = (v); \ 271 ((_v) > 0) - ((_v) < 0); \ 277 #define avl_cmp_sign(l, r) \ 279 typeof(l) _l = (l); \ 280 typeof(r) _r = (r); \ 281 (_l > _r) - (_l < _r); \ 284 static inline struct __AVL_T(avlh) *
285 __AVL(search_inner)(
const struct __AVL_T(avl) *
const avl,
286 const struct __AVL_T(avlh) *n,
int *delta,
287 const struct __AVL_T(avl_searchops) *ops)
289 return ops->search(avl, n, delta, 0);
293 struct __AVL_T(avlh) *__AVL(gettop)(
const struct __AVL_T(avl) *
const avl)
295 return __AVL(top)(avl);
299 struct __AVL_T(avlh) *__AVL(gethead)(
const struct __AVL_T(avl) *
const avl)
301 return __AVL(head)(avl);
305 struct __AVL_T(avlh) *__AVL(gettail)(
const struct __AVL_T(avl) *
const avl)
307 return __AVL(tail)(avl);
311 unsigned int __AVL(getcount)(
const struct __AVL_T(avl) *
const avl)
313 return __AVL(count)(avl);
316 struct __AVL_T(avlh) *__AVL(inorder)(
const struct __AVL_T(avl) *
const avl,
317 struct __AVL_T(avlh) *holder,
320 struct __AVL_T(avlh) *__AVL(postorder)(
const struct __AVL_T(avl) *
const avl,
321 struct __AVL_T(avlh) *
const holder,
324 struct __AVL_T(avlh) *__AVL(preorder)(
const struct __AVL_T(avl) *
const avl,
325 struct __AVL_T(avlh) *holder,
328 static inline struct __AVL_T(avlh) *
329 __AVL(next)(
const struct __AVL_T(avl) *
const avl,
330 struct __AVL_T(avlh) *
const holder)
332 return __AVL(inorder)(avl, holder, AVL_RIGHT);
335 static inline struct __AVL_T(avlh) *
336 __AVL(prev)(
const struct __AVL_T(avl) *
const avl,
337 struct __AVL_T(avlh) *
const holder)
339 return __AVL(inorder)(avl, holder, AVL_LEFT);
342 static inline struct __AVL_T(avlh) *
343 __AVL(postorder_next)(
const struct __AVL_T(avl) *
const avl,
344 struct __AVL_T(avlh) *
const holder)
346 return __AVL(postorder)(avl, holder, AVL_RIGHT);
349 static inline struct __AVL_T(avlh) *
350 __AVL(postorder_prev)(
const struct __AVL_T(avl) *
const avl,
351 struct __AVL_T(avlh) *
const holder)
353 return __AVL(postorder)(avl, holder, AVL_LEFT);
356 static inline struct __AVL_T(avlh) *
357 __AVL(preorder_next)(
const struct __AVL_T(avl) *
const avl,
358 struct __AVL_T(avlh) *
const holder)
360 return __AVL(preorder)(avl, holder, AVL_RIGHT);
363 static inline struct __AVL_T(avlh) *
364 __AVL(preorder_prev)(
const struct __AVL_T(avl) *
const avl,
365 struct __AVL_T(avlh) *
const holder)
367 return __AVL(preorder)(avl, holder, AVL_LEFT);
370 static inline void __AVLH(init)(
struct __AVL_T(avlh) *
const holder)
376 static inline struct __AVL_T(avlh) *
377 __AVL(search)(
const struct __AVL_T(avl) *
const avl,
378 const struct __AVL_T(avlh) *node,
379 const struct __AVL_T(avl_searchops) *ops)
381 struct __AVL_T(avlh) *holder;
384 holder = __AVL(search_inner)(avl, node, &delta, ops);
391 static inline struct __AVL_T(avlh) *
392 __AVL(search_nearest)(
const struct __AVL_T(avl) *
const avl,
393 const struct __AVL_T(avlh) *node,
int dir,
394 const struct __AVL_T(avl_searchops) *ops)
396 struct __AVL_T(avlh) *holder;
399 holder = __AVL(search_inner)(avl, node, &delta, ops);
400 if (!holder || delta != dir)
403 return __AVL(inorder)(avl, holder, dir);
406 static inline struct __AVL_T(avlh) *
407 __AVL(search_le)(
const struct __AVL_T(avl) *
const avl,
408 const struct __AVL_T(avlh) *node,
409 const struct __AVL_T(avl_searchops) *ops)
411 return __AVL(search_nearest)(avl, node, AVL_LEFT, ops);
414 static inline struct __AVL_T(avlh) *
415 __AVL(search_ge)(
const struct __AVL_T(avl) *
const avl,
416 const struct __AVL_T(avlh) *node,
417 const struct __AVL_T(avl_searchops) *ops)
419 return __AVL(search_nearest)(avl, node, AVL_RIGHT, ops);
422 static inline struct __AVL_T(avlh) *
423 __AVL(search_multi)(
const struct __AVL_T(avl) *
const avl,
424 const struct __AVL_T(avlh) *node,
int dir,
425 const struct __AVL_T(avl_searchops) *ops)
427 struct __AVL_T(avlh) *holder;
430 holder = ops->search(avl, node, &delta, dir);
437 return __AVL(inorder)(avl, holder, -dir);
440 static inline struct __AVL_T(avlh) *
441 __AVL(search_first)(
const struct __AVL_T(avl) *
const avl,
442 const struct __AVL_T(avlh) *node,
443 const struct __AVL_T(avl_searchops) *ops)
445 return __AVL(search_multi)(avl, node, AVL_LEFT, ops);
448 static inline struct __AVL_T(avlh) *
449 __AVL(search_last)(
const struct __AVL_T(avl) *
const avl,
450 const struct __AVL_T(avlh) *node,
451 const struct __AVL_T(avl_searchops) *ops)
453 return __AVL(search_multi)(avl, node, AVL_RIGHT, ops);
460 void __AVL(init)(
struct __AVL_T(avl) *
const avl);
462 void __AVL(destroy)(
struct __AVL_T(avl) *
const avl);
464 int __AVL(insert)(
struct __AVL_T(avl) *
const avl,
465 struct __AVL_T(avlh) *
const holder,
466 const struct __AVL_T(avl_searchops) *ops);
468 int __AVL(insert_front)(
struct __AVL_T(avl) *avl,
469 struct __AVL_T(avlh) *holder,
470 const struct __AVL_T(avl_searchops) *ops);
472 int __AVL(insert_back)(
struct __AVL_T(avl) *avl,
473 struct __AVL_T(avlh) *holder,
474 const struct __AVL_T(avl_searchops) *ops);
476 int __AVL(insert_at)(
struct __AVL_T(avl) *
const avl,
477 struct __AVL_T(avlh) *parent,
int dir,
478 struct __AVL_T(avlh) *child);
480 int __AVL(prepend)(
struct __AVL_T(avl) *
const avl,
481 struct __AVL_T(avlh) *
const holder,
482 const struct __AVL_T(avl_searchops) *ops);
484 int __AVL(append)(
struct __AVL_T(avl) *
const avl,
485 struct __AVL_T(avlh) *
const holder,
486 const struct __AVL_T(avl_searchops) *ops);
488 int __AVL(
delete)(
struct __AVL_T(avl) *
const avl,
489 struct __AVL_T(avlh) *node);
491 int __AVL(replace)(
struct __AVL_T(avl) *avl,
492 struct __AVL_T(avlh) *oldh,
493 struct __AVL_T(avlh) *newh,
494 const struct __AVL_T(avl_searchops) *ops);
496 struct __AVL_T(avlh) *__AVL(update)(
struct __AVL_T(avl) *
const avl,
497 struct __AVL_T(avlh) *
const holder,
498 const struct __AVL_T(avl_searchops) *ops);
500 struct __AVL_T(avlh) *__AVL(
set)(
struct __AVL_T(avl) *
const avl,
501 struct __AVL_T(avlh) *
const holder,
502 const struct __AVL_T(avl_searchops) *ops);
504 void __AVL(clear)(
struct __AVL_T(avl) *
const avl,
505 void (*destruct)(
struct __AVL_T(avlh) *));
507 int __AVL(check)(
const struct __AVL_T(avl) *avl,
508 const struct __AVL_T(avl_searchops) *ops);
510 void __AVL(dump)(FILE *file,
const struct __AVL_T(avl) *
const avl,
511 __AVL_T(avlh_prn_t) *prn,
unsigned int indent,