changed const_list_iterator design and implementation
This commit is contained in:
parent
4df86f81c5
commit
c60cfaf8e8
|
|
@ -18,66 +18,46 @@ namespace cc {
|
|||
template<typename Node>
|
||||
class const_list;
|
||||
|
||||
template<typename N>
|
||||
class _const_list_iterator_base {
|
||||
protected:
|
||||
const_list_node<N> *_curr = nullptr;
|
||||
template<typename N, bool _const>
|
||||
class _const_list_iterator {
|
||||
|
||||
public:
|
||||
constexpr _const_list_iterator_base() noexcept = default;
|
||||
constexpr explicit _const_list_iterator_base(const_list_node<N> *curr) noexcept : _curr(curr) {}
|
||||
constexpr _const_list_iterator_base(const _const_list_iterator_base& other) noexcept : _curr(other._curr) {}
|
||||
using node_N = const_list_node<N>;
|
||||
using const_node_N = const const_list_node<N>;
|
||||
|
||||
constexpr virtual const N& operator*() const noexcept { return *dynamic_cast<N*>(_curr); }
|
||||
constexpr virtual const N* operator->() const noexcept { return dynamic_cast<N*>(_curr); }
|
||||
using node_base_type = std::conditional<_const, const_node_N, node_N>::type;
|
||||
using node_type = std::conditional<_const, const N, N>::type;
|
||||
|
||||
constexpr const_list_node<N>* node() const { return _curr; }
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = node_type;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
|
||||
constexpr virtual _const_list_iterator_base &operator++() noexcept { return *this; };
|
||||
constexpr virtual _const_list_iterator_base &operator--() noexcept { return *this; };
|
||||
node_base_type* _node = nullptr;
|
||||
|
||||
constexpr bool operator==(const _const_list_iterator_base &other) const { return _curr == other._curr; }
|
||||
constexpr _const_list_iterator() noexcept = default;
|
||||
constexpr explicit _const_list_iterator(node_base_type *node) noexcept : _node(node) {}
|
||||
|
||||
protected:
|
||||
template<bool _other_const, std::enable_if_t<_const || (_other_const == _const), bool> = true>
|
||||
constexpr _const_list_iterator(const _const_list_iterator<N, _other_const>& other) noexcept
|
||||
: _node(other._node) {}
|
||||
|
||||
friend class const_list<N>;
|
||||
};
|
||||
constexpr node_type& operator*() const noexcept { return *dynamic_cast<node_type*>(_node); }
|
||||
constexpr node_type* operator->() const noexcept { return dynamic_cast<node_type*>(_node); }
|
||||
|
||||
template<typename N>
|
||||
class _const_list_iterator : public _const_list_iterator_base<N> {
|
||||
using _Base = _const_list_iterator_base<N>;
|
||||
public:
|
||||
constexpr _const_list_iterator() noexcept : _Base() {}
|
||||
constexpr explicit _const_list_iterator(const_list_node<N> *curr) noexcept : _Base(curr) {}
|
||||
constexpr _const_list_iterator(const _Base& other) noexcept : _Base(other) {}
|
||||
constexpr _const_list_iterator &operator++() noexcept { _node = _node->_next; return *this; }
|
||||
constexpr _const_list_iterator &operator--() noexcept { _node = _node->_prev; return *this; }
|
||||
constexpr _const_list_iterator operator++(int) noexcept { auto tmp = *this; _node = _node->_next; return tmp; }
|
||||
constexpr _const_list_iterator operator--(int) noexcept { auto tmp = *this; _node = _node->_prev; return tmp; }
|
||||
|
||||
constexpr N& operator*() const noexcept override { return *dynamic_cast<N*>(_Base::_curr); }
|
||||
constexpr N* operator->() const noexcept override { return dynamic_cast<N*>(_Base::_curr); }
|
||||
|
||||
constexpr _const_list_iterator &operator++() noexcept override { _Base::_curr = _Base::_curr->_next; return *this; }
|
||||
constexpr _const_list_iterator &operator--() noexcept override { _Base::_curr = _Base::_curr->_prev; return *this; }
|
||||
constexpr _const_list_iterator operator++(int) noexcept { auto tmp = *this; _Base::_curr = _Base::_curr->_next; return tmp; }
|
||||
constexpr _const_list_iterator operator--(int) noexcept { auto tmp = *this; _Base::_curr = _Base::_curr->_prev; return tmp; }
|
||||
|
||||
};
|
||||
|
||||
template<typename N>
|
||||
class _const_const_list_iterator : public _const_list_iterator_base<N> {
|
||||
using _Base = _const_list_iterator_base<N>;
|
||||
public:
|
||||
constexpr _const_const_list_iterator() : _Base() {}
|
||||
constexpr explicit _const_const_list_iterator(const const_list_node<N> *curr) : _Base(const_cast<const_list_node<N>*>(curr)) {} // @TODO: change code to remove const_cast
|
||||
constexpr _const_const_list_iterator(const _Base& other) noexcept : _Base(other) {}
|
||||
|
||||
constexpr const N* node() noexcept { 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 { auto tmp = *this; _Base::_curr = _Base::_curr->_next; return tmp; }
|
||||
constexpr _const_const_list_iterator operator--(int) noexcept { auto tmp = *this; _Base::_curr = _Base::_curr->_prev; return tmp; }
|
||||
template<bool _const_other>
|
||||
[[nodiscard]] constexpr bool operator==(const _const_list_iterator<N, _const_other> &other) const { return _node == other._node; }
|
||||
|
||||
private:
|
||||
constexpr _const_list_iterator<N> _const_cast() noexcept { return _const_list_iterator<N>(_Base::_curr); }
|
||||
constexpr _const_list_iterator<N, false> _const_cast() const noexcept
|
||||
requires (_const)
|
||||
{ return _const_list_iterator<N, false>(const_cast<node_N*>(_node)); }
|
||||
|
||||
friend class const_list<N>;
|
||||
};
|
||||
|
|
@ -98,8 +78,8 @@ namespace cc {
|
|||
using const_reference = const value_type&;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
using iterator = _const_list_iterator<Node>;
|
||||
using const_iterator = _const_const_list_iterator<Node>;
|
||||
using iterator = _const_list_iterator<Node, false>;
|
||||
using const_iterator = _const_list_iterator<Node, true>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
|
|
@ -238,10 +218,9 @@ namespace cc {
|
|||
constexpr void push_before(const_list_node *node) noexcept;
|
||||
constexpr void unlink() noexcept;
|
||||
|
||||
template<typename N, bool c>
|
||||
friend class _const_list_iterator;
|
||||
friend class const_list<D>;
|
||||
friend class _const_list_iterator_base<D>;
|
||||
friend class _const_list_iterator<D>;
|
||||
friend class _const_const_list_iterator<D>;
|
||||
};
|
||||
|
||||
template<typename N1, typename N2>
|
||||
|
|
@ -365,7 +344,7 @@ namespace cc {
|
|||
|
||||
for (auto& value : values) {
|
||||
// it's operator-> may fail as it could be the tail node
|
||||
it.node()->push_before(std::addressof(value.get()));
|
||||
it._node->push_before(std::addressof(value.get()));
|
||||
value.get()._owner = this;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue