PR-URL: https://github.com/nodejs/node/pull/54536 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com>
153 lines
3.6 KiB
C++
153 lines
3.6 KiB
C++
// Copyright 2023 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "src/base/doubly-threaded-list.h"
|
|
|
|
#include "src/base/vector.h"
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
namespace v8::base {
|
|
|
|
class DoublyThreadedListTest : public TestWithPlatform {};
|
|
|
|
TEST_F(DoublyThreadedListTest, BasicTest) {
|
|
struct Elem {
|
|
int val;
|
|
bool operator==(const Elem& other) const {
|
|
return val == other.val && prev_ == other.prev_ && next_ == other.next_;
|
|
}
|
|
|
|
Elem** prev_;
|
|
Elem* next_;
|
|
|
|
// Defining getters required by the default DoublyThreadedListTraits.
|
|
Elem*** prev() { return &prev_; }
|
|
Elem** next() { return &next_; }
|
|
};
|
|
|
|
DoublyThreadedList<Elem*> list;
|
|
Elem e1{1, nullptr, nullptr};
|
|
Elem e2{1, nullptr, nullptr};
|
|
Elem e3{1, nullptr, nullptr};
|
|
Elem e4{1, nullptr, nullptr};
|
|
|
|
list.PushFront(&e1);
|
|
EXPECT_EQ(**(list.begin()), e1);
|
|
|
|
list.PushFront(&e2);
|
|
list.PushFront(&e3);
|
|
list.PushFront(&e4);
|
|
EXPECT_EQ(**(list.begin()), e4);
|
|
EXPECT_EQ(*e4.next_, e3);
|
|
EXPECT_EQ(*e3.next_, e2);
|
|
EXPECT_EQ(*e2.next_, e1);
|
|
EXPECT_EQ(e1.next_, nullptr);
|
|
EXPECT_EQ(*e1.prev_, &e1);
|
|
EXPECT_EQ(*e2.prev_, &e2);
|
|
EXPECT_EQ(*e3.prev_, &e3);
|
|
EXPECT_EQ(*e4.prev_, &e4);
|
|
|
|
// Removing front
|
|
list.Remove(&e4);
|
|
EXPECT_EQ(**(list.begin()), e3);
|
|
EXPECT_EQ(*e3.prev_, &e3);
|
|
EXPECT_EQ(e4.next_, nullptr);
|
|
EXPECT_EQ(e4.prev_, nullptr);
|
|
|
|
// Removing middle
|
|
list.Remove(&e2);
|
|
EXPECT_EQ(*e3.next_, e1);
|
|
EXPECT_EQ(e2.prev_, nullptr);
|
|
EXPECT_EQ(e2.next_, nullptr);
|
|
EXPECT_EQ(e1.prev_, &e3.next_);
|
|
EXPECT_EQ(*e1.prev_, &e1);
|
|
|
|
// Removing back
|
|
list.Remove(&e1);
|
|
EXPECT_EQ(e3.next_, nullptr);
|
|
EXPECT_EQ(e1.prev_, nullptr);
|
|
EXPECT_EQ(e1.next_, nullptr);
|
|
EXPECT_EQ(**(list.begin()), e3);
|
|
|
|
// Removing only item
|
|
list.Remove(&e3);
|
|
EXPECT_EQ(e3.prev_, nullptr);
|
|
EXPECT_EQ(e3.next_, nullptr);
|
|
EXPECT_TRUE(list.empty());
|
|
}
|
|
|
|
TEST_F(DoublyThreadedListTest, IteratorTest) {
|
|
struct Elem {
|
|
int val;
|
|
bool operator==(const Elem& other) const {
|
|
return val == other.val && prev_ == other.prev_ && next_ == other.next_;
|
|
}
|
|
|
|
Elem** prev_;
|
|
Elem* next_;
|
|
|
|
// Defining getters required by the default DoublyThreadedListTraits.
|
|
Elem*** prev() { return &prev_; }
|
|
Elem** next() { return &next_; }
|
|
};
|
|
|
|
DoublyThreadedList<Elem*> list;
|
|
Elem e1{1, nullptr, nullptr};
|
|
Elem e2{1, nullptr, nullptr};
|
|
Elem e3{1, nullptr, nullptr};
|
|
Elem e4{1, nullptr, nullptr};
|
|
|
|
list.PushFront(&e1);
|
|
list.PushFront(&e2);
|
|
list.PushFront(&e3);
|
|
list.PushFront(&e4);
|
|
|
|
int count = 0;
|
|
for (Elem* e : list) {
|
|
USE(e);
|
|
count++;
|
|
}
|
|
EXPECT_EQ(count, 4);
|
|
|
|
// Iterating and checking that all items are where they should be
|
|
auto it = list.begin();
|
|
EXPECT_EQ(**it, e4);
|
|
++it;
|
|
EXPECT_EQ(**it, e3);
|
|
++it;
|
|
EXPECT_EQ(**it, e2);
|
|
++it;
|
|
EXPECT_EQ(**it, e1);
|
|
++it;
|
|
EXPECT_FALSE(it != list.end());
|
|
|
|
// Removing with the iterator
|
|
it = list.begin();
|
|
EXPECT_EQ(**it, e4);
|
|
it = list.RemoveAt(it);
|
|
EXPECT_EQ(**it, e3);
|
|
++it;
|
|
EXPECT_EQ(**it, e2);
|
|
it = list.RemoveAt(it);
|
|
EXPECT_EQ(**it, e1);
|
|
EXPECT_EQ(*e3.next_, e1);
|
|
it = list.RemoveAt(it);
|
|
EXPECT_FALSE(it != list.end());
|
|
EXPECT_EQ(e3.next_, nullptr);
|
|
it = list.begin();
|
|
it = list.RemoveAt(it);
|
|
|
|
EXPECT_TRUE(list.empty());
|
|
EXPECT_EQ(e1.next_, nullptr);
|
|
EXPECT_EQ(e2.next_, nullptr);
|
|
EXPECT_EQ(e3.next_, nullptr);
|
|
EXPECT_EQ(e4.next_, nullptr);
|
|
EXPECT_EQ(e1.prev_, nullptr);
|
|
EXPECT_EQ(e2.prev_, nullptr);
|
|
EXPECT_EQ(e3.prev_, nullptr);
|
|
EXPECT_EQ(e4.prev_, nullptr);
|
|
}
|
|
|
|
} // namespace v8::base
|