Skip to content

Commit

Permalink
linked-list reverse iteration (#343)
Browse files Browse the repository at this point in the history
  • Loading branch information
graebm authored May 9, 2019
1 parent 534c7f2 commit f0a8edf
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
24 changes: 24 additions & 0 deletions include/aws/common/linked_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,37 @@ AWS_STATIC_IMPL const struct aws_linked_list_node *aws_linked_list_end(const str
return &list->tail;
}

/**
* Returns a pointer for the last element in the list.
* Used to begin iterating the list in reverse. Ex:
* for (i = aws_linked_list_rbegin(list); i != aws_linked_list_rend(list); i = aws_linked_list_prev(i)) {...}
*/
AWS_STATIC_IMPL struct aws_linked_list_node *aws_linked_list_rbegin(const struct aws_linked_list *list) {
return list->tail.prev;
}

/**
* Returns the pointer to one before the first element in the list.
* Used to end iterating the list in reverse.
*/
AWS_STATIC_IMPL const struct aws_linked_list_node *aws_linked_list_rend(const struct aws_linked_list *list) {
return &list->head;
}

/**
* Returns the next element in the list.
*/
AWS_STATIC_IMPL struct aws_linked_list_node *aws_linked_list_next(const struct aws_linked_list_node *node) {
return node->next;
}

/**
* Returns the previous element in the list.
*/
AWS_STATIC_IMPL struct aws_linked_list_node *aws_linked_list_prev(const struct aws_linked_list_node *node) {
return node->prev;
}

/**
* Inserts to_add immediately after after.
*/
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ add_test_case(priority_queue_remove_interior_sift_down_test)
add_test_case(linked_list_push_back_pop_front)
add_test_case(linked_list_push_front_pop_back)
add_test_case(linked_list_iteration)
add_test_case(linked_list_reverse_iteration)
add_test_case(linked_list_swap_contents)

add_test_case(hex_encoding_test_case_empty_test)
Expand Down
39 changes: 39 additions & 0 deletions tests/linked_list_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ static int s_test_linked_list_iteration(struct aws_allocator *allocator, void *c
aws_linked_list_init(&list);

ASSERT_TRUE(aws_linked_list_empty(&list));
ASSERT_PTR_EQUALS(aws_linked_list_begin(&list), aws_linked_list_end(&list));

struct int_value first = (struct int_value){.value = 1};
struct int_value second = (struct int_value){.value = 2};
Expand All @@ -127,6 +128,7 @@ static int s_test_linked_list_iteration(struct aws_allocator *allocator, void *c
aws_linked_list_push_back(&list, &fourth.node);

ASSERT_FALSE(aws_linked_list_empty(&list));
ASSERT_FALSE(aws_linked_list_begin(&list) == aws_linked_list_end(&list));

int count = 1;
for (struct aws_linked_list_node *iter = aws_linked_list_begin(&list); iter != aws_linked_list_end(&list);
Expand All @@ -140,6 +142,42 @@ static int s_test_linked_list_iteration(struct aws_allocator *allocator, void *c
return 0;
}

static int s_test_linked_list_reverse_iteration(struct aws_allocator *allocator, void *ctx) {
(void)allocator;
(void)ctx;

struct aws_linked_list list;

aws_linked_list_init(&list);

ASSERT_TRUE(aws_linked_list_empty(&list));
ASSERT_PTR_EQUALS(aws_linked_list_rbegin(&list), aws_linked_list_rend(&list));

struct int_value first = (struct int_value){.value = 1};
struct int_value second = (struct int_value){.value = 2};
struct int_value third = (struct int_value){.value = 3};
struct int_value fourth = (struct int_value){.value = 4};

aws_linked_list_push_back(&list, &first.node);
aws_linked_list_push_back(&list, &second.node);
aws_linked_list_push_back(&list, &third.node);
aws_linked_list_push_back(&list, &fourth.node);

ASSERT_FALSE(aws_linked_list_empty(&list));
ASSERT_FALSE(aws_linked_list_rbegin(&list) == aws_linked_list_rend(&list));

int count = 4;
for (struct aws_linked_list_node *iter = aws_linked_list_rbegin(&list); iter != aws_linked_list_rend(&list);
iter = aws_linked_list_prev(iter)) {

int item = AWS_CONTAINER_OF(iter, struct int_value, node)->value;
ASSERT_INT_EQUALS(count, item);
--count;
}

return 0;
}

static int s_test_linked_list_swap_contents(struct aws_allocator *allocator, void *ctx) {
(void)allocator;
(void)ctx;
Expand Down Expand Up @@ -232,4 +270,5 @@ static int s_test_linked_list_swap_contents(struct aws_allocator *allocator, voi
AWS_TEST_CASE(linked_list_push_back_pop_front, s_test_linked_list_order_push_back_pop_front)
AWS_TEST_CASE(linked_list_push_front_pop_back, s_test_linked_list_order_push_front_pop_back)
AWS_TEST_CASE(linked_list_iteration, s_test_linked_list_iteration)
AWS_TEST_CASE(linked_list_reverse_iteration, s_test_linked_list_reverse_iteration)
AWS_TEST_CASE(linked_list_swap_contents, s_test_linked_list_swap_contents)

0 comments on commit f0a8edf

Please sign in to comment.