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