Proper encapsulation of the color attribute.
This commit is contained in:
1 parent
c08504863c
commit
4c21c504e5
1 file changed
+21
-18
+21
-18
@@ -98,6 +98,8 @@
|
|||||||
#define RBTREEI_IS_RED(x) ((x)->color == RBTREE_RED)
|
#define RBTREEI_IS_RED(x) ((x)->color == RBTREE_RED)
|
||||||
#define RBTREEI_IS_BLACK(x) ((x)->color == RBTREE_BLACK)
|
#define RBTREEI_IS_BLACK(x) ((x)->color == RBTREE_BLACK)
|
||||||
#define RBTREEI_COPY_COLOR(x,y) ((x)->color = (y)->color)
|
#define RBTREEI_COPY_COLOR(x,y) ((x)->color = (y)->color)
|
||||||
|
#define RBTREEI_GET_COLOR(x) ((x)->color + 0)
|
||||||
|
#define RBTREEI_SET_COLOR(x, c) ((x)->color = (c))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RBTREE_BLACK = 0, RBTREE_RED
|
RBTREE_BLACK = 0, RBTREE_RED
|
||||||
@@ -656,16 +658,17 @@ typedef enum {
|
|||||||
return tree->size == 0; \
|
return tree->size == 0; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline rbtreei_color_e \
|
/* Take care of the case n == NULL too */ \
|
||||||
M_C(name, _int_get_color)(const node_t *n) \
|
static inline bool \
|
||||||
|
M_C(name, _int_is_black)(const node_t *n) \
|
||||||
{ \
|
{ \
|
||||||
return (n == NULL) ? RBTREE_BLACK : n->color; \
|
return (n == NULL) ? true : RBTREEI_IS_BLACK(n); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void \
|
static inline void \
|
||||||
M_C(name, _int_set_color)(node_t *n, rbtreei_color_e c) \
|
M_C(name, _int_set_black)(node_t *n) \
|
||||||
{ \
|
{ \
|
||||||
if (n != NULL) n->color = c; \
|
if (n != NULL) RBTREEI_SET_BLACK(n); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline node_t * \
|
static inline node_t * \
|
||||||
@@ -727,7 +730,7 @@ typedef enum {
|
|||||||
unsigned int cpt_n = cpt; \
|
unsigned int cpt_n = cpt; \
|
||||||
node_t *v = n; /* the replacement node */ \
|
node_t *v = n; /* the replacement node */ \
|
||||||
node_t *u; /* the deleted node */ \
|
node_t *u; /* the deleted node */ \
|
||||||
rbtreei_color_e v_color = v->color; \
|
rbtreei_color_e v_color = RBTREEI_GET_COLOR(v); \
|
||||||
/* Classical removal of a node from a binary tree */ \
|
/* Classical removal of a node from a binary tree */ \
|
||||||
if (v->child[0] != NULL && v->child[1] != NULL) { \
|
if (v->child[0] != NULL && v->child[1] != NULL) { \
|
||||||
/* node has 2 child. */ \
|
/* node has 2 child. */ \
|
||||||
@@ -758,8 +761,8 @@ typedef enum {
|
|||||||
tab[cpt_n-1]->child[which[cpt_n-1]] = v; \
|
tab[cpt_n-1]->child[which[cpt_n-1]] = v; \
|
||||||
v->child[0] = n->child[0]; \
|
v->child[0] = n->child[0]; \
|
||||||
v->child[1] = n->child[1]; \
|
v->child[1] = n->child[1]; \
|
||||||
v_color = v->color; \
|
v_color = RBTREEI_GET_COLOR(v); \
|
||||||
v->color = n->color; \
|
RBTREEI_COPY_COLOR(v, n); \
|
||||||
tab[cpt_n] = v; \
|
tab[cpt_n] = v; \
|
||||||
/* For the algorithm, 'u' is now the deleted node */ \
|
/* For the algorithm, 'u' is now the deleted node */ \
|
||||||
} else { \
|
} else { \
|
||||||
@@ -774,7 +777,7 @@ typedef enum {
|
|||||||
\
|
\
|
||||||
/* Rebalance from child to root */ \
|
/* Rebalance from child to root */ \
|
||||||
if (v_color == RBTREE_BLACK \
|
if (v_color == RBTREE_BLACK \
|
||||||
&& M_C(name, _int_get_color)(u) == RBTREE_BLACK) { \
|
&& M_C(name, _int_is_black)(u)) { \
|
||||||
/* tab[0] is NULL, tab[1] is root, u is double black */ \
|
/* tab[0] is NULL, tab[1] is root, u is double black */ \
|
||||||
node_t *p = u, *s; \
|
node_t *p = u, *s; \
|
||||||
while (cpt >= 2) { \
|
while (cpt >= 2) { \
|
||||||
@@ -783,7 +786,7 @@ typedef enum {
|
|||||||
assert (p != NULL && u == p->child[nbChild]); \
|
assert (p != NULL && u == p->child[nbChild]); \
|
||||||
s = p->child[!nbChild]; \
|
s = p->child[!nbChild]; \
|
||||||
/* if sibling is red, perform a rotation to move sibling up */ \
|
/* if sibling is red, perform a rotation to move sibling up */ \
|
||||||
if (M_C(name, _int_get_color)(s) == RBTREE_RED) { \
|
if (!M_C(name, _int_is_black)(s)) { \
|
||||||
p = M_C(name, _int_rotate) (p, tab[cpt-1], !nbChild); \
|
p = M_C(name, _int_rotate) (p, tab[cpt-1], !nbChild); \
|
||||||
RBTREEI_SET_BLACK(p); /* was sibling */ \
|
RBTREEI_SET_BLACK(p); /* was sibling */ \
|
||||||
tab[cpt] = p; \
|
tab[cpt] = p; \
|
||||||
@@ -792,14 +795,14 @@ typedef enum {
|
|||||||
assert (p != NULL); \
|
assert (p != NULL); \
|
||||||
RBTREEI_SET_RED(p); \
|
RBTREEI_SET_RED(p); \
|
||||||
s = p->child[!nbChild]; \
|
s = p->child[!nbChild]; \
|
||||||
assert (M_C(name, _int_get_color)(s) == RBTREE_BLACK); \
|
assert (M_C(name, _int_is_black)(s)); \
|
||||||
} \
|
} \
|
||||||
assert (p != NULL && u == p->child[nbChild]); \
|
assert (p != NULL && u == p->child[nbChild]); \
|
||||||
/* if both childreen of s are black */ \
|
/* if both childreen of s are black */ \
|
||||||
/* perform recoloring and recur on parent if black */ \
|
/* perform recoloring and recur on parent if black */ \
|
||||||
if (s != NULL \
|
if (s != NULL \
|
||||||
&& M_C(name, _int_get_color)(s->child[0])== RBTREE_BLACK \
|
&& M_C(name, _int_is_black)(s->child[0]) \
|
||||||
&& M_C(name, _int_get_color)(s->child[1])== RBTREE_BLACK) { \
|
&& M_C(name, _int_is_black)(s->child[1])) { \
|
||||||
assert(M_C(name, _int_depth)(s->child[0]) == M_C(name, _int_depth)(s->child[1])); \
|
assert(M_C(name, _int_depth)(s->child[0]) == M_C(name, _int_depth)(s->child[1])); \
|
||||||
RBTREEI_SET_RED(s); \
|
RBTREEI_SET_RED(s); \
|
||||||
if (RBTREEI_IS_RED(p)) { \
|
if (RBTREEI_IS_RED(p)) { \
|
||||||
@@ -813,8 +816,8 @@ typedef enum {
|
|||||||
assert (s != NULL); \
|
assert (s != NULL); \
|
||||||
/* at least one child of 's' is red */ \
|
/* at least one child of 's' is red */ \
|
||||||
/* perform rotation(s) */ \
|
/* perform rotation(s) */ \
|
||||||
bool childIsRight = M_C(name, _int_get_color)(s->child[1])== RBTREE_RED; \
|
bool childIsRight = !M_C(name, _int_is_black)(s->child[1]); \
|
||||||
rbtreei_color_e p_color = p->color; \
|
rbtreei_color_e p_color = RBTREEI_GET_COLOR (p); \
|
||||||
if (childIsRight != nbChild) { \
|
if (childIsRight != nbChild) { \
|
||||||
/* left-left or right-right case */ \
|
/* left-left or right-right case */ \
|
||||||
p = M_C(name, _int_rotate) (p, tab[cpt-1], childIsRight); \
|
p = M_C(name, _int_rotate) (p, tab[cpt-1], childIsRight); \
|
||||||
@@ -822,7 +825,7 @@ typedef enum {
|
|||||||
s = M_C(name, _int_rotate) (s, p, childIsRight); \
|
s = M_C(name, _int_rotate) (s, p, childIsRight); \
|
||||||
p = M_C(name, _int_rotate) (p, tab[cpt-1], !nbChild); \
|
p = M_C(name, _int_rotate) (p, tab[cpt-1], !nbChild); \
|
||||||
} \
|
} \
|
||||||
p->color = p_color; \
|
RBTREEI_SET_COLOR(p, p_color); \
|
||||||
assert(p->child[0] != NULL && p->child[1] != NULL); \
|
assert(p->child[0] != NULL && p->child[1] != NULL); \
|
||||||
RBTREEI_SET_BLACK(p->child[0]); \
|
RBTREEI_SET_BLACK(p->child[0]); \
|
||||||
RBTREEI_SET_BLACK(p->child[1]); \
|
RBTREEI_SET_BLACK(p->child[1]); \
|
||||||
@@ -832,11 +835,11 @@ typedef enum {
|
|||||||
} \
|
} \
|
||||||
} /* while */ \
|
} /* while */ \
|
||||||
if (cpt == 1 /* root has been reached? */ ) { \
|
if (cpt == 1 /* root has been reached? */ ) { \
|
||||||
M_C(name, _int_set_color)(p, RBTREE_BLACK); \
|
M_C(name, _int_set_black)(p); \
|
||||||
assert (tree->node == p); \
|
assert (tree->node == p); \
|
||||||
} \
|
} \
|
||||||
} else { \
|
} else { \
|
||||||
M_C(name, _int_set_color)(u, RBTREE_BLACK); \
|
M_C(name, _int_set_black)(u); \
|
||||||
} \
|
} \
|
||||||
assert (tree->node == NULL || RBTREEI_IS_BLACK(tree->node)); \
|
assert (tree->node == NULL || RBTREEI_IS_BLACK(tree->node)); \
|
||||||
/* delete it */ \
|
/* delete it */ \
|
||||||
|
|||||||
Reference in new issue
Block a user