const_list: implemented splice

This commit is contained in:
cyborg1811m 2024-02-08 19:45:59 +01:00
parent 5cda16f846
commit 03a694431c
1 changed files with 114 additions and 0 deletions

View File

@ -491,6 +491,120 @@ namespace cc {
other._size = 0;
}
template<typename Node>
constexpr void const_list<Node>::splice(const_list::const_iterator pos, const_list &other)
{
if (other._size == 0) return;
for (auto& value : other) {
value._owner = this;
}
pos->_prev->_next = other._tail->_next;
pos->_prev = other._tail->_prev;
_size += other._size;
other._tail->_prev = &other._tail;
other._tail->_next = &other._tail;
other._size = 0;
}
template<typename Node>
constexpr void const_list<Node>::splice(const_list::const_iterator pos, const_list &&other)
{
if (other._size == 0) return;
for (auto& value : other) {
value._owner = this;
}
pos->_prev->_next = other._tail->_next;
pos->_prev = other._tail->_prev;
_size += other._size;
other._tail->_prev = &other._tail;
other._tail->_next = &other._tail;
}
template<typename Node>
constexpr void
const_list<Node>::splice(const_list::const_iterator pos, const_list &other, const_list::const_iterator it)
{
// if it does point into other, then it has to have a size
pos._const_cast()->push_before(it._const_cast()._node);
++_size;
--other._size;
}
template<typename Node>
constexpr void
const_list<Node>::splice(const_list::const_iterator pos, const_list &&other, const_list::const_iterator it)
{
pos._const_cast()->push_before(it._const_cast()._node);
++_size;
}
template<typename Node>
constexpr void
const_list<Node>::splice(const_list::const_iterator pos, const_list &other, const_list::const_iterator first,
const_list::const_iterator last)
{
auto p = pos._const_cast();
auto f = first._const_cast();
auto l = last._const_cast();
std::size_t dist = 0;
for (auto it = f; it != l; ++it) {
it._node->_owner = this;
++dist;
}
// we cannot use operator->, since it returns nullptr if it is a tail node
auto first_prev = f._node->_prev;
p._node->_prev->_next = f._node;
f._node->_prev->_next = l._node;
f._node->_prev = p._node->_prev;
p._node->_prev = l._node->_prev;
l._node->_prev->_next = p._node;
l._node->_prev = first_prev;
_size += dist;
other._size -= dist;
}
template<typename Node>
constexpr void
const_list<Node>::splice(const_list::const_iterator pos, const_list &&other, const_list::const_iterator first,
const_list::const_iterator last)
{
auto f = first._const_cast();
auto l = last._const_cast();
std::size_t dist = 0;
for (auto it = f; it != l; ++it) {
it->_owner = this;
++dist;
}
auto first_prev = first->_prev;
pos->_prev->_next = f._node;
f->_prev->_next = l._node;
f->_prev = pos->_prev;
pos->_prev = l->_prev;
l->_prev->_next = pos._node;
l->_prev = first_prev;
_size += dist;
}
template<typename D>
constexpr const_list_node<D>::const_list_node(const const_list_node &other) noexcept
: _delete_cb(other._delete_cb)