diff --git a/include/const_list.h b/include/const_list.h index 4b3d736..f99ffdd 100644 --- a/include/const_list.h +++ b/include/const_list.h @@ -25,13 +25,13 @@ namespace cc { public: constexpr _const_list_iterator_base() noexcept = default; - constexpr explicit _const_list_iterator_base(N *curr) noexcept : _curr(curr) {} + constexpr explicit _const_list_iterator_base(const_list_node *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 noexcept { return *dynamic_cast(_curr); } constexpr virtual const N* operator->() const noexcept { return dynamic_cast(_curr); } - constexpr virtual const_list_node* node() const { return _curr; } + constexpr const_list_node* node() const { return _curr; } constexpr virtual _const_list_iterator_base &operator++() noexcept { return *this; }; constexpr virtual _const_list_iterator_base &operator--() noexcept { return *this; }; @@ -39,7 +39,6 @@ namespace cc { constexpr bool operator==(const _const_list_iterator_base &other) const { return _curr == other._curr; } protected: - constexpr _const_list_iterator_base(const_list_node *tail) : _curr(tail) {} friend class const_list; }; @@ -49,7 +48,7 @@ namespace cc { using _Base = _const_list_iterator_base; public: constexpr _const_list_iterator() noexcept : _Base() {} - constexpr explicit _const_list_iterator(N *curr) noexcept : _Base(curr) {} + constexpr explicit _const_list_iterator(const_list_node *curr) noexcept : _Base(curr) {} constexpr _const_list_iterator(const _Base& other) noexcept : _Base(other) {} constexpr N& operator*() const noexcept override { return *dynamic_cast(_Base::_curr); } @@ -67,15 +66,20 @@ namespace cc { using _Base = _const_list_iterator_base; public: constexpr _const_const_list_iterator() : _Base() {} - constexpr explicit _const_const_list_iterator(N *curr) : _Base(curr) {} + constexpr explicit _const_const_list_iterator(const const_list_node *curr) : _Base(const_cast*>(curr)) {} // @TODO: change code to remove const_cast constexpr _const_const_list_iterator(const _Base& other) noexcept : _Base(other) {} - constexpr const N* node() noexcept override { return _Base::node(); } + 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; } + + private: + constexpr _const_list_iterator _const_cast() noexcept { return _const_list_iterator(_Base::_curr); } + + friend class const_list; }; template @@ -142,6 +146,7 @@ namespace cc { [[nodiscard]] constexpr const_reverse_iterator crend() const noexcept { return std::reverse_iterator(begin()); }; [[nodiscard]] constexpr bool empty() const noexcept { return _size == 0; } + [[nodiscard]] constexpr size_type size() const noexcept { return _size; } [[nodiscard]] constexpr size_type max_size() const noexcept { return SIZE_MAX; } void clear() noexcept; @@ -149,9 +154,6 @@ namespace cc { constexpr iterator insert(const_iterator pos, value_type& value); constexpr iterator insert(const_iterator pos, std::initializer_list> values); - template - constexpr iterator emplace(const_iterator pos, Args&&... args); - constexpr iterator erase(const_iterator pos); constexpr iterator erase(const_iterator first, const_iterator last); @@ -329,11 +331,7 @@ namespace cc { { clear(); - for (auto& value : init) { - _tail.push_before(std::addressof(value.get())); - value.get()._owner = this; - } - _size += init.size(); + insert(begin(), init); } template @@ -351,25 +349,29 @@ namespace cc { template constexpr const_list::iterator const_list::insert(const_iterator pos, value_type &value) { - pos->push_before(value); + auto it = pos._const_cast(); + + it->push_before(value); ++_size; - return --pos; + return --it; } template constexpr const_list::iterator const_list::insert(const_list::const_iterator pos, std::initializer_list> values) { - auto prev = pos.node(); - for (auto& it = values.rbegin(); it != values.rend(); ++it) { - prev->push_before(it->get()); - prev = it->get(); + auto it = pos._const_cast(); + + for (auto& value : values) { + // it's operator-> may fail as it could be the tail node + it.node()->push_before(std::addressof(value.get())); + value.get()._owner = this; } _size += values.size(); - return iterator(prev); + return it; } template