Commit c633cc3a authored by Kei Nakashima's avatar Kei Nakashima Committed by Commit Bot

Added Unlink, erase, pop_back and pop_front to VectorBackedLinkedList

Implemented Unlink, erase, pop_back and pop_front.
The first one unlink the given node from prev/next nodes.
|erase| removes the node with the given iterator from the used list and
prepends it to the free list as a free node.
At this time, its value is set to be empty.

Change-Id: Ic8a64c89f429037ef5628c25d89a58ce16081e8c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2094481
Commit-Queue: Kei Nakashima <keinakashima@google.com>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748169}
parent 4810306f
...@@ -129,6 +129,17 @@ class VectorBackedLinkedList { ...@@ -129,6 +129,17 @@ class VectorBackedLinkedList {
// is executed by just updating indices of related nodes. // is executed by just updating indices of related nodes.
void MoveTo(const_iterator target, const_iterator new_position); void MoveTo(const_iterator target, const_iterator new_position);
iterator erase(const_iterator);
void pop_front() {
DCHECK(!empty());
erase(cbegin());
}
void pop_back() {
DCHECK(!empty());
erase(--cend());
}
private: private:
bool IsFreeListEmpty() const { return free_head_index_ == anchor_index_; } bool IsFreeListEmpty() const { return free_head_index_ == anchor_index_; }
...@@ -424,6 +435,24 @@ void VectorBackedLinkedList<T>::MoveTo(const_iterator target, ...@@ -424,6 +435,24 @@ void VectorBackedLinkedList<T>::MoveTo(const_iterator target,
target_node.next_index_ = new_position_index; target_node.next_index_ = new_position_index;
} }
template <typename T>
typename VectorBackedLinkedList<T>::iterator VectorBackedLinkedList<T>::erase(
const_iterator position) {
DCHECK(position != end());
wtf_size_t position_index = position.GetIndex();
Node& node = nodes_[position_index];
wtf_size_t next_index = node.next_index_;
Unlink(node);
node.value_ = HashTraits<T>::EmptyValue();
node.next_index_ = free_head_index_;
free_head_index_ = position_index;
size_--;
return iterator(next_index, this);
}
template <typename T> template <typename T>
void VectorBackedLinkedList<T>::Unlink(const Node& node) { void VectorBackedLinkedList<T>::Unlink(const Node& node) {
wtf_size_t prev_index = node.prev_index_; wtf_size_t prev_index = node.prev_index_;
......
...@@ -110,6 +110,89 @@ TEST(VectorBackedLinkedList, MoveTo) { ...@@ -110,6 +110,89 @@ TEST(VectorBackedLinkedList, MoveTo) {
EXPECT_EQ(*it, 2); EXPECT_EQ(*it, 2);
} }
TEST(VectorBackedLinkedList, Erase) {
using List = VectorBackedLinkedList<int>;
List list;
List::iterator it = list.insert(list.end(), 1);
EXPECT_EQ(*it, 1);
list.push_back(2);
list.push_back(3);
list.push_back(4);
list.push_back(5);
EXPECT_EQ(list.size(), 5u);
List::iterator target = list.begin();
++target;
it = list.erase(target); // list = {1, 3, 4, 5}
EXPECT_EQ(*it, 3);
EXPECT_EQ(list.size(), 4u);
it = list.erase(++it); // list = {1, 3, 5}
EXPECT_EQ(*it, 5);
EXPECT_EQ(list.size(), 3u);
it = list.erase(list.begin()); // list = {3, 5}
EXPECT_EQ(*it, 3);
EXPECT_EQ(list.size(), 2u);
it = list.begin();
EXPECT_EQ(*it, 3);
++it;
EXPECT_EQ(*it, 5);
++it;
EXPECT_TRUE(it == list.end());
}
TEST(VectorBackedLinkedList, PopFront) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
int i = 1;
for (auto element : list) {
EXPECT_EQ(element, i);
i++;
}
list.pop_front();
EXPECT_EQ(list.front(), 2);
EXPECT_EQ(list.back(), 3);
EXPECT_EQ(list.size(), 2u);
list.pop_front();
EXPECT_EQ(list.front(), 3);
EXPECT_EQ(list.back(), 3);
EXPECT_EQ(list.size(), 1u);
list.pop_front();
EXPECT_TRUE(list.empty());
}
TEST(VectorBackedLinkedList, PopBack) {
using List = VectorBackedLinkedList<int>;
List list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.pop_back();
EXPECT_EQ(list.front(), 1);
EXPECT_EQ(list.back(), 2);
EXPECT_EQ(list.size(), 2u);
list.pop_back();
EXPECT_EQ(list.front(), 1);
EXPECT_EQ(list.back(), 1);
EXPECT_EQ(list.size(), 1u);
list.pop_back();
EXPECT_TRUE(list.empty());
}
TEST(VectorBackedLinkedList, Iterator) { TEST(VectorBackedLinkedList, Iterator) {
using List = VectorBackedLinkedList<int>; using List = VectorBackedLinkedList<int>;
List list; List list;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment