const_list: implemented remove, reverse, unique and sort

This commit is contained in:
cyborg1811m 2024-03-05 09:43:01 +01:00
parent 51d140274a
commit fcecffd3c7
1 changed files with 110 additions and 5 deletions

View File

@ -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 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<typename UnaryPredicate> template<typename UnaryPredicate>
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<typename BinaryPredicate> template<typename BinaryPredicate>
constexpr size_type unique(BinaryPredicate p); constexpr size_type unique(BinaryPredicate p);
constexpr void sort(); constexpr void sort();
template<typename Compare> template<typename Compare>
void sort(Compare comp); constexpr void sort(Compare comp);
}; };
@ -617,6 +617,111 @@ namespace cc {
_size += dist; _size += dist;
} }
template<typename Node>
constexpr const_list<Node>::size_type const_list<Node>::remove(const value_type &value) noexcept
{
// value has to be unique anyway
if (value._owner == this) {
const_cast<value_type&>(value).unlink();
--_size;
return 1;
}
return 0;
}
template<typename Node>
template<typename UnaryPredicate>
constexpr const_list<Node>::size_type const_list<Node>::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<typename Node>
constexpr void const_list<Node>::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<typename Node>
constexpr const_list<Node>::size_type const_list<Node>::unique()
{
return unique([](const value_type& n1, const value_type& n2) { return n1 == n2; });
}
template<typename Node>
template<typename BinaryPredicate>
constexpr const_list<Node>::size_type const_list<Node>::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<typename Node>
constexpr void const_list<Node>::sort()
{
sort([](const value_type& n1, const value_type& n2) { return n1 < n2; });
}
template<typename Node>
template<typename Compare>
constexpr void const_list<Node>::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<typename D> template<typename D>
constexpr const_list_node<D>::const_list_node(const const_list_node &other) noexcept constexpr const_list_node<D>::const_list_node(const const_list_node &other) noexcept
: _delete_cb(other._delete_cb) : _delete_cb(other._delete_cb)