/* Auto-Generated by RBGen version 0.1 on 2021-10-12T14:36:27Z */

#ifndef RBTREE_H
#define RBTREE_H

#include <stdbool.h>
#include <stddef.h>

/**
 * Red/Black tree node.  Nodes point to other nodes, so pointer math is
 * needed to reach the data paired with the node.
 */
typedef struct rbtree_node {
	struct rbtree_node *left, *right, *parent;
	size_t color: 1;
#if SIZE_MAX == 0xFFFF
	size_t count: 15;
#elif SIZE_MAX == 0xFFFFFFFF
	size_t count: 31;
#else
	size_t count: 63;
#endif
} rbtree_node_t;

typedef int (*rbtree_compare_fn)(void *ctx, void *a, void *b);

#define rbtree_node_is_in_tree(node) ((bool) (node)->count)

/* Initialize a tree */
extern void rbtree_init_tree( rbtree_node_t *root_sentinel, rbtree_node_t *leaf_sentinel );

/* Returns previous node in conceptual sorted list of nodes, or NULL */
extern rbtree_node_t *rbtree_node_prev( rbtree_node_t *node );

/* Returns next node in conceptual sorted list of nodes, or NULL */
extern rbtree_node_t *rbtree_node_next( rbtree_node_t *node );

/* Returns right-most child of this node, or NULL */
extern rbtree_node_t *rbtree_node_right_leaf( rbtree_node_t *node );

/* Returns left-most child of this node, or NULL */
extern rbtree_node_t *rbtree_node_left_leaf( rbtree_node_t *node );

/* Add a node to a tree */
extern bool rbtree_node_insert( rbtree_node_t *hint, rbtree_node_t *node, rbtree_compare_fn cmp_fn, void *ctx, int cmp_pointer_ofs );

extern rbtree_node_t * rbtree_find_nearest( rbtree_node_t *node, void *goal,
	int(*cmp_fn)(void *ctx, void *a, void *b), void *ctx, int cmp_pointer_ofs,
	int *cmp_result );

/* Find a node matching or close to 'goal'.  Pass NULL for answers that aren't needed.
 * Returns true for an exact match (cmp==0) and false for anything else.
 */
extern bool rbtree_find_all( rbtree_node_t *node, void *goal, rbtree_compare_fn cmp_fn, void *ctx, int cmp_pointer_ofs,
	rbtree_node_t **result_first, rbtree_node_t **result_last, size_t *result_count );

/* Returns index of a node within the tree, as if the tree were a sorted array.
 * In other words, returns the number of nodes with a key less than this node.
 */
extern size_t rbtree_node_index( rbtree_node_t *node );

/* Returns Nth child of a node, or NULL */
extern rbtree_node_t *rbtree_node_child_at_index( rbtree_node_t *node, size_t index );


/* Remove a node from the tree */
extern void rbtree_node_prune( rbtree_node_t *node );


/* Remove all nodes from the tree, and optionally run a function on each */
extern void rbtree_clear( rbtree_node_t *root_sentinel, void (*destructor)(void *obj, void *opaque), int obj_ofs, void *opaque );

/* Check tree for internal validity */
#define RBTREE_INVALID_ROOT     1
#define RBTREE_INVALID_SENTINEL 2
#define RBTREE_INVALID_NODE     4
#define RBTREE_INVALID_COUNT    8
#define RBTREE_INVALID_COLOR   16
#define RBTREE_INVALID_ORDER   32
extern int rbtree_check_structure( rbtree_node_t *node, rbtree_compare_fn cmp_fn, void *ctx, int cmp_pointer_ofs );


#endif /* RBTREE_H */
