diff --git a/README.md b/README.md index b8ec7033..1ab8fc95 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/m-rbtree.h b/m-rbtree.h index 33bc187f..d53dbabe 100644 --- a/m-rbtree.h +++ b/m-rbtree.h @@ -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 \ diff --git a/tests/test-mrbtree.c b/tests/test-mrbtree.c index c42e6592..94df559d 100644 --- a/tests/test-mrbtree.c +++ b/tests/test-mrbtree.c @@ -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); }