diff options
author | Nick Mathewson <nickm@torproject.org> | 2016-11-23 14:07:53 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-11-30 14:42:52 -0500 |
commit | 21c47c44109a9de373f40c454e653953ba21312e (patch) | |
tree | 59c0d7000483b9f1e71f170cd57a2ede38c99b5b /src | |
parent | bf64564e37c5fc01111bc476d1b93890b15a18bf (diff) | |
download | tor-21c47c44109a9de373f40c454e653953ba21312e.tar.gz tor-21c47c44109a9de373f40c454e653953ba21312e.zip |
Add a smartlist_remove_keeporder() function, with tests.
Diffstat (limited to 'src')
-rw-r--r-- | src/common/container.c | 18 | ||||
-rw-r--r-- | src/common/container.h | 1 | ||||
-rw-r--r-- | src/test/test_containers.c | 41 |
3 files changed, 60 insertions, 0 deletions
diff --git a/src/common/container.c b/src/common/container.c index ec59dccf62..1448ab403c 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -132,6 +132,24 @@ smartlist_remove(smartlist_t *sl, const void *element) } } +/** As <b>smartlist_remove</b>, but do not change the order of + * any elements not removed */ +void +smartlist_remove_keeporder(smartlist_t *sl, const void *element) +{ + int i, j, num_used_orig = sl->num_used; + if (element == NULL) + return; + + for (i=j=0; j < num_used_orig; ++j) { + if (sl->list[j] == element) { + --sl->num_used; + } else { + sl->list[i++] = sl->list[j]; + } + } +} + /** If <b>sl</b> is nonempty, remove and return the final element. Otherwise, * return NULL. */ void * diff --git a/src/common/container.h b/src/common/container.h index 71495b660a..00c3ca81ad 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -33,6 +33,7 @@ void smartlist_clear(smartlist_t *sl); void smartlist_add(smartlist_t *sl, void *element); void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2); void smartlist_remove(smartlist_t *sl, const void *element); +void smartlist_remove_keeporder(smartlist_t *sl, const void *element); void *smartlist_pop_last(smartlist_t *sl); void smartlist_reverse(smartlist_t *sl); void smartlist_string_remove(smartlist_t *sl, const char *element); diff --git a/src/test/test_containers.c b/src/test/test_containers.c index d7291a2ce2..41f3f873de 100644 --- a/src/test/test_containers.c +++ b/src/test/test_containers.c @@ -882,6 +882,46 @@ test_container_strmap(void *arg) tor_free(v105); } +static void +test_container_smartlist_remove(void *arg) +{ + (void) arg; + int array[5]; + smartlist_t *sl = smartlist_new(); + int i,j; + + for (j=0; j < 2; ++j) + for (i=0; i < 5; ++i) + smartlist_add(sl, &array[i]); + + smartlist_remove(sl, &array[0]); + smartlist_remove(sl, &array[3]); + smartlist_remove(sl, &array[4]); + tt_assert(! smartlist_contains(sl, &array[0])); + tt_assert(smartlist_contains(sl, &array[1])); + tt_assert(smartlist_contains(sl, &array[2])); + tt_assert(! smartlist_contains(sl, &array[3])); + tt_assert(! smartlist_contains(sl, &array[4])); + tt_int_op(smartlist_len(sl), OP_EQ, 4); + + smartlist_clear(sl); + for (j=0; j < 2; ++j) + for (i=0; i < 5; ++i) + smartlist_add(sl, &array[i]); + + smartlist_remove_keeporder(sl, &array[0]); + smartlist_remove_keeporder(sl, &array[3]); + smartlist_remove_keeporder(sl, &array[4]); + tt_int_op(smartlist_len(sl), OP_EQ, 4); + tt_ptr_op(smartlist_get(sl, 0), OP_EQ, &array[1]); + tt_ptr_op(smartlist_get(sl, 1), OP_EQ, &array[2]); + tt_ptr_op(smartlist_get(sl, 2), OP_EQ, &array[1]); + tt_ptr_op(smartlist_get(sl, 3), OP_EQ, &array[2]); + + done: + smartlist_free(sl); +} + /** Run unit tests for getting the median of a list. */ static void test_container_order_functions(void *arg) @@ -1239,6 +1279,7 @@ struct testcase_t container_tests[] = { CONTAINER_LEGACY(smartlist_digests), CONTAINER_LEGACY(smartlist_join), CONTAINER_LEGACY(smartlist_pos), + CONTAINER(smartlist_remove, 0), CONTAINER(smartlist_ints_eq, 0), CONTAINER_LEGACY(bitarray), CONTAINER_LEGACY(digestset), |