diff --git a/include/const_list.h b/include/const_list.h index 9dace87..6cd5f17 100644 --- a/include/const_list.h +++ b/include/const_list.h @@ -159,19 +159,19 @@ namespace cc { constexpr void splice(const_iterator pos, const_list& other, const_iterator first, const_iterator last); constexpr void splice(const_iterator pos, const_list&& other, const_iterator first, const_iterator last); - constexpr size_type remove(const value_type& value); + constexpr size_type remove(const value_type& value) noexcept; template - size_type remove_if(UnaryPredicate p); + constexpr size_type remove_if(UnaryPredicate p); - void reverse() noexcept; + constexpr void reverse() noexcept; - size_type unique(); + constexpr size_type unique(); template constexpr size_type unique(BinaryPredicate p); constexpr void sort(); template - void sort(Compare comp); + constexpr void sort(Compare comp); }; @@ -617,6 +617,111 @@ namespace cc { _size += dist; } + template + constexpr const_list::size_type const_list::remove(const value_type &value) noexcept + { + // value has to be unique anyway + if (value._owner == this) { + const_cast(value).unlink(); + --_size; + + return 1; + } + + return 0; + } + + template + template + constexpr const_list::size_type const_list::remove_if(UnaryPredicate p) + { + auto tail = end(); + size_type nr = 0; + + for (auto it = begin(); it != tail; ++it) { + if (p(*it)) { + it = erase(it); + ++nr; + --_size; + } + } + + return nr; + } + + template + constexpr void const_list::reverse() noexcept + { + auto tail = end(); + + for (auto it = begin(); it != tail; --it) { + std::swap(it._node->_prev, it._node->_next); + } + std::swap(_tail._prev, _tail._next); + } + + template + constexpr const_list::size_type const_list::unique() + { + return unique([](const value_type& n1, const value_type& n2) { return n1 == n2; }); + } + + template + template + constexpr const_list::size_type const_list::unique(BinaryPredicate p) + { + auto it = begin(); + auto last = end(); + + if (it == last) return 0; + + const_list to_remove; + auto next = it; + while (++next != last) { + if (p(*it, *next)) { + to_remove.splice(to_remove.begin(), *this, next); + } else { + it = next; + } + next = it; + } + + return to_remove.size(); + } + + template + constexpr void const_list::sort() + { + sort([](const value_type& n1, const value_type& n2) { return n1 < n2; }); + } + + template + template + constexpr void const_list::sort(Compare comp) + { + auto last = end(); + auto it = begin(); + + const_list sorted; + auto sorted_end = sorted.end(); + + while (it != last) { + auto sorted_it = sorted.begin(); + while (sorted_it != sorted_end) { + if (comp(*it, *sorted_it)) { + break; + } else { + ++sorted_it; + } + } + auto sp_it = it; + ++it; + sorted.splice(sorted_it, *this, sp_it); + } + + *this = std::move(sorted); + } + template constexpr const_list_node::const_list_node(const const_list_node &other) noexcept : _delete_cb(other._delete_cb)