diff --git a/include/const_list.h b/include/const_list.h index 5b8b8c5..25a48f3 100644 --- a/include/const_list.h +++ b/include/const_list.h @@ -491,6 +491,120 @@ namespace cc { other._size = 0; } + template + constexpr void const_list::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 + constexpr void const_list::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 + constexpr void + const_list::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 + constexpr void + const_list::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 + constexpr void + const_list::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 + constexpr void + const_list::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 constexpr const_list_node::const_list_node(const const_list_node &other) noexcept : _delete_cb(other._delete_cb)