changed to using a tail node in const_list

This commit is contained in:
cyborg1811m 2024-01-31 16:00:22 +01:00
parent c6e1c93b67
commit 398735ee3a
1 changed files with 91 additions and 52 deletions

View File

@ -25,9 +25,11 @@ namespace cc {
constexpr explicit _const_list_iterator_base(N *curr) noexcept : _curr(curr) {}
constexpr _const_list_iterator_base(const _const_list_iterator_base& other) noexcept : _curr(other._curr) {}
constexpr virtual const N& operator*() const { return *_curr; }
constexpr virtual const N& operator*() const noexcept { return *_curr; }
constexpr virtual const N* operator->() const noexcept { return _curr; }
constexpr virtual N* node() const { return _curr; }
constexpr virtual _const_list_iterator_base &operator++() noexcept = 0;
constexpr virtual _const_list_iterator_base &operator--() noexcept = 0;
constexpr virtual _const_list_iterator_base &operator++(int) & noexcept = 0;
@ -61,6 +63,8 @@ namespace cc {
constexpr explicit _const_const_list_iterator(N *curr) : _Base(curr) {}
constexpr _const_const_list_iterator(const _Base& other) noexcept : _Base(other) {}
constexpr const N* node() noexcept override { return _Base::node(); }
constexpr _const_const_list_iterator &operator++() noexcept override { _Base::_curr == _Base::_curr->_next; return *this; }
constexpr _const_const_list_iterator &operator--() noexcept override { _Base::_curr == _Base::_curr->_prev; return *this; }
constexpr _const_const_list_iterator operator++(int) & noexcept override { auto tmp = *this; _Base::_curr == _Base::_curr->_next; return tmp; }
@ -89,8 +93,8 @@ namespace cc {
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
private:
Node *_start = nullptr;
Node *_end = nullptr;
const_list_node<Node> _tail;
std::size_t _size = 0;
public:
@ -135,12 +139,8 @@ namespace cc {
void clear() noexcept;
constexpr iterator insert(const_iterator pos, const value_type& value);
constexpr iterator insert(const_iterator pos, value_type&& value);
constexpr iterator insert(const_iterator pos, size_type count, const value_type& value);
template<std::input_iterator InputIt>
constexpr iterator insert(const_iterator pos, InputIt first, InputIt last);
constexpr iterator insert(const_iterator pos, std::initializer_list<value_type> values);
constexpr iterator insert(const_iterator pos, value_type& value);
constexpr iterator insert(const_iterator pos, std::initializer_list<std::reference_wrapper<value_type>> values);
template<typename ...Args>
constexpr iterator emplace(const_iterator pos, Args&&... args);
@ -207,21 +207,24 @@ namespace cc {
}
private:
const_list_node *_prev = nullptr;
const_list_node *_next = nullptr;
const_list_node *_prev = this;
const_list_node *_next = this;
const_list<D> *_owner = nullptr;
void (*_delete_cb)() = nullptr;
public:
constexpr const_list_node() noexcept { asserts(); }
constexpr const_list_node(const const_list_node& other) noexcept;
constexpr const_list_node(const_list_node&& other) noexcept;
virtual constexpr ~const_list_node();
protected:
constexpr void on_delete(void (*cb)());
constexpr void on_delete(void (*cb)()) noexcept;
private:
void _remove();
constexpr void push_before(const_list_node *node) noexcept;
constexpr void unlink() noexcept;
friend class const_list<D>;
friend class _const_list_iterator_base<D>;
@ -262,36 +265,27 @@ namespace cc {
template<typename Node>
constexpr const_list<Node>::const_list(const_list &&other) noexcept
: _start(other._start), _end(other._end), _size(other._size)
: _tail(std::move(other._tail)),
_size(other._size)
{
asserts();
for (auto node : other) {
node._owner = this;
}
other._size = 0;
other._start = nullptr;
other._end = nullptr;
}
template<typename Node>
constexpr const_list<Node>::const_list(std::initializer_list<std::reference_wrapper<value_type>> init) noexcept
: _start(std::addressof(init.begin()->get())),
_end(std::addressof(std::prev(init.end())->get())),
: _tail(),
_size(init.size())
{
asserts();
auto prev = init.begin();
prev->get()._owner = this;
for (auto it = std::next(init.begin()); it != init.end(); ++it) {
prev->get()._next = std::addressof(it->get());
it->get()._prev = std::addressof(prev->get());
it->get()._owner = this;
prev = it;
auto prev = &_tail;
for (auto& it = init.rbegin(); it != init.rend(); ++it) {
prev->push_before(it->get());
prev = it->get();
}
}
@ -304,13 +298,12 @@ namespace cc {
template<typename Node>
constexpr const_list<Node> &const_list<Node>::operator=(const_list &&other) noexcept
{
for (auto node : other) {
for (auto& node : other) {
node._owner = this;
}
other._size = 0;
other._start = nullptr;
other._end = nullptr;
_tail = std::move(other._tail);
_size = other._size;
return *this;
}
@ -325,52 +318,98 @@ namespace cc {
template<typename Node>
constexpr void const_list<Node>::assign(std::initializer_list<std::reference_wrapper<value_type>> init) noexcept
{
auto prev = init.begin();
prev->get()._owner = this;
clear();
for (auto it = std::next(init.begin()); it != init.end(); ++it) {
prev->get()._next = std::addressof(it->get());
it->get()._prev = std::addressof(prev->get());
it->get()._owner = this;
prev = it;
}
}
template<typename Node>
void const_list<Node>::clear() noexcept
{
for (auto node : *this) {
node._remove();
node.unlink();
}
}
template<typename Node>
constexpr const_list<Node>::iterator const_list<Node>::insert(const_iterator pos, value_type &value)
{
pos->push_before(value);
++_size;
return --pos;
}
template<typename Node>
constexpr const_list<Node>::iterator const_list<Node>::insert(const_list::const_iterator pos,
std::initializer_list<std::reference_wrapper<value_type>> values)
{
auto prev = pos.node();
for (auto& it = values.rbegin(); it != values.rend(); ++it) {
prev->push_before(it->get());
prev = it->get();
}
_size += values.size();
return iterator(prev);
}
template<typename D>
constexpr const_list_node<D>::const_list_node(const const_list_node &other) noexcept
: _delete_cb(other._delete_cb)
{}
template<typename D>
constexpr const_list_node<D>::const_list_node(const_list_node &&other) noexcept
: _prev(other._prev),
_next(other._next),
_delete_cb(other._delete_cb)
{
_prev->_next = this;
_next->_prev = this;
}
template<typename D>
constexpr const_list_node<D>::~const_list_node()
{
if (_delete_cb)
(*_delete_cb)();
_owner->remove(*this);
_delete_cb();
unlink();
}
template<typename D>
constexpr void const_list_node<D>::on_delete(void (*cb)())
constexpr void const_list_node<D>::on_delete(void (*cb)()) noexcept
{
_delete_cb = cb;
}
template<typename D>
void const_list_node<D>::_remove()
constexpr void const_list_node<D>::unlink() noexcept
{
if (_delete_cb)
(*_delete_cb)();
_delete_cb();
_prev->_next = _next;
_next->_prev = _prev;
_next = this;
_prev = this;
_prev = nullptr;
_next = nullptr;
_owner = nullptr;
}
template<typename D>
constexpr void const_list_node<D>::push_before(const_list_node *node) noexcept
{
node->_prev = _prev;
node->_next = this;
_prev->next = node;
_prev = node;
}
} // cc
#endif //UDIFF_CONST_LIST_H_