changed to using a tail node in const_list
This commit is contained in:
parent
c6e1c93b67
commit
398735ee3a
|
|
@ -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_
|
||||
|
|
|
|||
Loading…
Reference in New Issue