Update definition of returned iterator of _it_from of RB tree

from the greatest element of 'rbtree' lower of equal than 'data'
to the lowest element of the tree 'rbtree' greater or equal than 'data'

It is more logical and natural:
if you have a tree of elements between [2, 4], and you want
to iterate all elements from 0 to 10, the old definition doesn't allow
you to iterate easily over this subset.
This commit is contained in:
Patrick Pelissier committed 2021-07-16 22:46:44 +02:00
1 parent 7dc1a9dc0e
commit 85a363d325
3 files changed
+33 -21

No files matched your search

+1 -1
View File
@@ -2818,7 +2818,7 @@ Set the iterator 'it' to no element of 'rbtree'.
##### void name\_it\_from(name\_it\_t it, const name\_t rbtree, const type data)
Set the iterator 'it' to
the greatest element of 'rbtree' lower of equal than 'data'
the lowest element of the tree 'rbtree' greater or equal than 'data'
or an iterator to no element is there is none.
##### bool name\_end\_p(const name\_it\_t it)
+8 -4
View File
@@ -570,9 +570,9 @@ typedef enum {
M_RBTR33_CONTRACT (tree); \
M_ASSERT (it != NULL); \
unsigned int cpt = 0; \
int cmp = -1; \
int cmp = 1; \
node_t *n = tree->node; \
/* Find the greatest element lower or equal than data in the tree */ \
/* Find the lowest element greater or equal than data in the tree */ \
while (n != NULL) { \
M_ASSERT (cpt < M_RBTR33_MAX_STACK); \
it->which[cpt] = 0; \
@@ -584,9 +584,13 @@ typedef enum {
it->which[cpt-1] = (int8_t) child; \
n = n->child[child]; \
} \
/* If the lowest element is still greater than data, invalid iterator */ \
if (cmp > 0) cpt = 0; \
/* Save the iterator */ \
it->cpt = cpt; \
/* The iterator found may be strictly lower than data. \
In this case, go to the next element */ \
if (cmp < 0) { \
M_C(name, _next)(it); \
} \
} \
\
static inline bool \
+24 -16
View File
@@ -351,11 +351,6 @@ static void test_from(void)
assert(!rbtree_uint_it_while_p(it, 2));
rbtree_uint_it_from(it, tree, 2);
assert(rbtree_uint_end_p(it));
assert(rbtree_uint_it_until_p(it, 3));
assert(!rbtree_uint_it_while_p(it, 3));
rbtree_uint_it_from(it, tree, 4);
assert(!rbtree_uint_end_p(it));
assert(rbtree_uint_it_until_p(it, 3));
assert(rbtree_uint_it_while_p(it, 3));
@@ -364,6 +359,11 @@ static void test_from(void)
assert(rbtree_uint_it_until_p(it, 2));
assert(!rbtree_uint_it_while_p(it, 2));
rbtree_uint_it_from(it, tree, 4);
assert(rbtree_uint_end_p(it));
assert(rbtree_uint_it_until_p(it, 3));
assert(!rbtree_uint_it_while_p(it, 3));
// More elements
rbtree_uint_push(tree, 10);
rbtree_uint_push(tree, 5);
@@ -410,24 +410,32 @@ static void test_from(void)
}
assert(k == 2);
// No element is lower or equal than 0 ==> The set is empty
k = 0;
const unsigned int tab1[] = { 1, 3, 5};
for( rbtree_uint_it_from(it, tree, 0); rbtree_uint_it_while_p(it, 6); rbtree_uint_next(it)) {
assert (k < 3);
assert(tab0[k] == *rbtree_uint_cref(it));
k++;
}
assert(k == 0);
// The iteration starts from 3 which is lower or equal than 4.
k = 0;
for( rbtree_uint_it_from(it, tree, 4); rbtree_uint_it_while_p(it, 7); rbtree_uint_next(it)) {
assert (k < 3);
assert(tab0[k] == *rbtree_uint_cref(it));
assert(tab1[k] == *rbtree_uint_cref(it));
k++;
}
assert(k == 3);
k = 0;
const unsigned int tab2[] = { 5, 7};
for( rbtree_uint_it_from(it, tree, 4); rbtree_uint_it_while_p(it, 7); rbtree_uint_next(it)) {
assert (k < 2);
assert(tab2[k] == *rbtree_uint_cref(it));
k++;
}
assert(k == 2);
// From higher than all elements in the tree ==> no iterator.
k = 0;
for( rbtree_uint_it_from(it, tree, 11); rbtree_uint_it_while_p(it, 17); rbtree_uint_next(it)) {
assert (k < 2);
k++;
}
assert(k == 0);
rbtree_uint_clear(tree);
}