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