util/IntrusiveList: add method splice()
This commit is contained in:
parent
b78d6c9dd7
commit
84fd401d21
@ -526,4 +526,40 @@ public:
|
|||||||
|
|
||||||
++counter;
|
++counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the given range of items of the given list to this one
|
||||||
|
* before the given position.
|
||||||
|
*/
|
||||||
|
void splice(iterator position, IntrusiveList &from,
|
||||||
|
iterator _begin, iterator _end, size_type n) noexcept {
|
||||||
|
if (_begin == _end)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto &next_node = ToNode(*position);
|
||||||
|
auto &prev_node = ToNode(*std::prev(position));
|
||||||
|
|
||||||
|
auto &first_node = ToNode(*_begin);
|
||||||
|
auto &before_first_node = ToNode(*std::prev(_begin));
|
||||||
|
auto &last_node = ToNode(*std::prev(_end));
|
||||||
|
auto &after_last_node = ToNode(*_end);
|
||||||
|
|
||||||
|
/* remove from the other list */
|
||||||
|
IntrusiveListNode::Connect(before_first_node, after_last_node);
|
||||||
|
from.counter -= n;
|
||||||
|
|
||||||
|
/* insert into this list */
|
||||||
|
IntrusiveListNode::Connect(prev_node, first_node);
|
||||||
|
IntrusiveListNode::Connect(last_node, next_node);
|
||||||
|
counter += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move all items of the given list to this one before the
|
||||||
|
* given position.
|
||||||
|
*/
|
||||||
|
void splice(iterator position, IntrusiveList &from) noexcept {
|
||||||
|
spice(position, from, from.begin(), from.end(),
|
||||||
|
constant_time_size ? size() : 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020-2021 Max Kellermann <max.kellermann@gmail.com>
|
* Copyright 2020-2022 Max Kellermann <max.kellermann@gmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* author: Max Kellermann <mk@cm4all.com>
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
@ -89,6 +89,60 @@ TEST(IntrusiveList, Basic)
|
|||||||
ASSERT_EQ(i, list.begin());
|
ASSERT_EQ(i, list.begin());
|
||||||
--i;
|
--i;
|
||||||
ASSERT_EQ(i, list.end());
|
ASSERT_EQ(i, list.end());
|
||||||
|
|
||||||
|
IntrusiveList<Item> other_list;
|
||||||
|
Item d, e, f, g;
|
||||||
|
other_list.push_back(d);
|
||||||
|
other_list.push_back(e);
|
||||||
|
other_list.push_back(f);
|
||||||
|
other_list.push_back(g);
|
||||||
|
|
||||||
|
list.splice(std::next(list.begin()), other_list,
|
||||||
|
other_list.iterator_to(e),
|
||||||
|
other_list.iterator_to(g), 2);
|
||||||
|
|
||||||
|
i = other_list.begin();
|
||||||
|
ASSERT_EQ(&*i, &d);
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(&*i, &g);
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(i, other_list.end());
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(&*i, &d);
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(i, other_list.end());
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(&*i, &g);
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(&*i, &d);
|
||||||
|
ASSERT_EQ(i, other_list.begin());
|
||||||
|
|
||||||
|
i = list.begin();
|
||||||
|
ASSERT_EQ(&*i, &a);
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(&*i, &e);
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(&*i, &f);
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(&*i, &c);
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(i, list.end());
|
||||||
|
++i;
|
||||||
|
ASSERT_EQ(&*i, &a);
|
||||||
|
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(i, list.end());
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(&*i, &c);
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(&*i, &f);
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(&*i, &e);
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(&*i, &a);
|
||||||
|
ASSERT_EQ(i, list.begin());
|
||||||
|
--i;
|
||||||
|
ASSERT_EQ(i, list.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(IntrusiveList, SafeLink)
|
TEST(IntrusiveList, SafeLink)
|
||||||
|
Loading…
Reference in New Issue
Block a user