mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:07:45 +00:00
AK+Tests: Add IntrusiveList<T,...>::insert_before(..) method
The insert_before method on AK::InlineLinkedList is used, so in order to achieve feature parity, we need to implement it for AK::IntrusiveList as well.
This commit is contained in:
parent
4586668fc3
commit
b7f8343f87
2 changed files with 49 additions and 0 deletions
|
@ -54,6 +54,7 @@ public:
|
||||||
[[nodiscard]] size_t size_slow() const;
|
[[nodiscard]] size_t size_slow() const;
|
||||||
void append(T& n);
|
void append(T& n);
|
||||||
void prepend(T& n);
|
void prepend(T& n);
|
||||||
|
void insert_before(T&, T&);
|
||||||
void remove(T& n);
|
void remove(T& n);
|
||||||
[[nodiscard]] bool contains(const T&) const;
|
[[nodiscard]] bool contains(const T&) const;
|
||||||
[[nodiscard]] Container first() const;
|
[[nodiscard]] Container first() const;
|
||||||
|
@ -264,6 +265,28 @@ inline void IntrusiveList<T, Container, member>::prepend(T& n)
|
||||||
m_storage.m_last = &nnode;
|
m_storage.m_last = &nnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
|
inline void IntrusiveList<T, Container, member>::insert_before(T& bn, T& n)
|
||||||
|
{
|
||||||
|
remove(n);
|
||||||
|
|
||||||
|
auto& new_node = n.*member;
|
||||||
|
auto& before_node = bn.*member;
|
||||||
|
new_node.m_storage = &m_storage;
|
||||||
|
new_node.m_next = &before_node;
|
||||||
|
new_node.m_prev = before_node.m_prev;
|
||||||
|
if (before_node.m_prev)
|
||||||
|
before_node.m_prev->m_next = &new_node;
|
||||||
|
before_node.m_prev = &new_node;
|
||||||
|
|
||||||
|
if (m_storage.m_first == &before_node) {
|
||||||
|
m_storage.m_first = &new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (!RemoveReference<decltype(new_node)>::IsRaw)
|
||||||
|
new_node.m_self.reference = &n;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
inline void IntrusiveList<T, Container, member>::remove(T& n)
|
inline void IntrusiveList<T, Container, member>::remove(T& n)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,32 @@ TEST_CASE(insert)
|
||||||
delete list.take_last();
|
delete list.take_last();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(insert_before)
|
||||||
|
{
|
||||||
|
IntrusiveTestList list;
|
||||||
|
auto two = new IntrusiveTestItem();
|
||||||
|
list.append(*two);
|
||||||
|
auto zero = new IntrusiveTestItem();
|
||||||
|
list.append(*zero);
|
||||||
|
auto one = new IntrusiveTestItem();
|
||||||
|
list.insert_before(*zero, *one);
|
||||||
|
|
||||||
|
EXPECT_EQ(list.first(), two);
|
||||||
|
EXPECT_EQ(list.last(), zero);
|
||||||
|
EXPECT(list.contains(*zero));
|
||||||
|
EXPECT(list.contains(*one));
|
||||||
|
EXPECT(list.contains(*two));
|
||||||
|
|
||||||
|
EXPECT(zero->m_list_node.is_in_list());
|
||||||
|
EXPECT(one->m_list_node.is_in_list());
|
||||||
|
EXPECT(two->m_list_node.is_in_list());
|
||||||
|
EXPECT_EQ(list.size_slow(), 3u);
|
||||||
|
|
||||||
|
while (auto elem = list.take_first()) {
|
||||||
|
delete elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(enumeration)
|
TEST_CASE(enumeration)
|
||||||
{
|
{
|
||||||
constexpr size_t expected_size = 10;
|
constexpr size_t expected_size = 10;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue