const_list: implemented remove, reverse, unique and sort
This commit is contained in:
parent
51d140274a
commit
fcecffd3c7
|
|
@ -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<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>
|
||||
constexpr size_type unique(BinaryPredicate p);
|
||||
|
||||
constexpr void sort();
|
||||
template<typename Compare>
|
||||
void sort(Compare comp);
|
||||
constexpr void sort(Compare comp);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -617,6 +617,111 @@ namespace cc {
|
|||
_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>
|
||||
constexpr const_list_node<D>::const_list_node(const const_list_node &other) noexcept
|
||||
: _delete_cb(other._delete_cb)
|
||||
|
|
|
|||
Loading…
Reference in New Issue