diff --git a/src/internal_modules/roc_core/list.h b/src/internal_modules/roc_core/list.h index 7cd4b5817..d13ed780c 100644 --- a/src/internal_modules/roc_core/list.h +++ b/src/internal_modules/roc_core/list.h @@ -149,7 +149,7 @@ class List : public NonCopyable<> { if (size_ == 0) { insert_(element, NULL); } else { - insert_(element, container_of_(head_.next)); + insert_(element, head_.next); } } @@ -205,7 +205,26 @@ class List : public NonCopyable<> { //! @p element should not be member of any list. //! @p before should be member of this list or NULL. void insert_before(T& element, T& before) { - insert_(element, &before); + insert_(element, before.list_node_data()); + } + + //! Insert element into list. + //! + //! @remarks + //! - inserts @p element after @p after + //! - acquires ownership of @p element + //! + //! @pre + //! @p element should not be member of any list. + //! @p after should be member of this list. + void insert_after(T& element, T& after) { + ListNode::ListNodeData* data_after = after.list_node_data(); + + if (data_after->next == &head_) { + insert_(element, NULL); + } else { + insert_(element, data_after->next); + } } //! Remove element from list. @@ -242,13 +261,11 @@ class List : public NonCopyable<> { } } - void insert_(T& element, T* before) { + void insert_(T& element, ListNode::ListNodeData* data_before) { ListNode::ListNodeData* data_new = element.list_node_data(); check_is_member_(data_new, NULL); - ListNode::ListNodeData* data_before; - if (before != NULL) { - data_before = before->list_node_data(); + if (data_before != NULL) { check_is_member_(data_before, this); } else { data_before = &head_; diff --git a/src/tests/roc_core/test_list_operations.cpp b/src/tests/roc_core/test_list_operations.cpp index dd9bd8bdc..194911bf8 100644 --- a/src/tests/roc_core/test_list_operations.cpp +++ b/src/tests/roc_core/test_list_operations.cpp @@ -167,7 +167,7 @@ TEST(list_operations, push_front_many) { CHECK(!list.is_empty()); } -TEST(list_operations, insert_front) { +TEST(list_operations, insert_before_front) { list.push_back(objects[0]); list.insert_before(objects[1], *list.front()); @@ -178,7 +178,7 @@ TEST(list_operations, insert_front) { CHECK(!list.is_empty()); } -TEST(list_operations, insert_middle) { +TEST(list_operations, insert_before_middle) { list.push_back(objects[0]); list.push_back(objects[1]); @@ -193,6 +193,32 @@ TEST(list_operations, insert_middle) { POINTERS_EQUAL(&objects[2], list.nextof(*list.front())); } +TEST(list_operations, insert_after_back) { + list.push_back(objects[0]); + list.insert_after(objects[1], *list.back()); + + POINTERS_EQUAL(&objects[0], list.front()); + POINTERS_EQUAL(&objects[1], list.back()); + + LONGS_EQUAL(2, list.size()); + CHECK(!list.is_empty()); +} + +TEST(list_operations, insert_after_middle) { + list.push_back(objects[0]); + list.push_back(objects[1]); + + list.insert_after(objects[2], objects[0]); + + POINTERS_EQUAL(&objects[0], list.front()); + POINTERS_EQUAL(&objects[1], list.back()); + + LONGS_EQUAL(3, list.size()); + CHECK(!list.is_empty()); + + POINTERS_EQUAL(&objects[2], list.nextof(*list.front())); +} + TEST(list_operations, remove_front) { for (size_t i = 0; i < NumObjects; ++i) { list.push_back(objects[i]);