Improved efficiency of CSequence::removeIf, but CCollection::removeIf must still use the old algorithm.

This commit is contained in:
Mathew Sutcliffe
2016-01-09 18:21:36 +00:00
parent 956d54ba32
commit 6ddce24f0c
3 changed files with 49 additions and 23 deletions

View File

@@ -338,6 +338,31 @@ namespace BlackMisc
*/
void remove(const CCollection &other) { *this = CCollection(*this).difference(other); }
/*!
* \brief Remove elements for which a given predicate returns true.
* \pre The collection must be initialized.
* \return The number of elements removed.
*/
template <class Predicate>
int removeIf(Predicate p)
{
int count = 0;
for (auto it = begin(); it != end();)
{
if (p(*it)) { it = erase(it); count++; }
else { ++it; }
}
return count;
}
//! \copydoc BlackMisc::CContainerBase::removeIf
template <class K0, class V0, class... KeysValues>
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
{
// using-declaration doesn't play nicely with injected template names
return CCollection::CContainerBase::removeIf(k0, v0, keysValues...);
}
/*!
* \brief Test for equality.
*/

View File

@@ -87,23 +87,6 @@ namespace BlackMisc
return other;
}
/*!
* \brief Remove elements for which a given predicate returns true.
* \pre The sequence must be initialized.
* \return The number of elements removed.
*/
template <class Predicate>
int removeIf(Predicate p)
{
int count = 0;
for (auto it = derived().begin(); it != derived().end();)
{
if (p(*it)) { it = derived().erase(it); count++; }
else { ++it; }
}
return count;
}
/*!
* \brief Remove elements matching some particular key/value pair(s).
* \param k0 A pointer to a member function of T.
@@ -114,7 +97,7 @@ namespace BlackMisc
template <class K0, class V0, class... KeysValues>
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
{
return removeIf(BlackMisc::Predicates::MemberEqual(k0, v0, keysValues...));
return derived().removeIf(BlackMisc::Predicates::MemberEqual(k0, v0, keysValues...));
}
public:

View File

@@ -387,6 +387,28 @@ namespace BlackMisc
return count;
}
/*!
* \brief Remove elements for which a given predicate returns true.
* \pre The sequence must be initialized.
* \return The number of elements removed.
*/
template <class Predicate>
int removeIf(Predicate p)
{
auto newEnd = std::remove_if(begin(), end(), p);
int count = std::distance(newEnd, end());
erase(newEnd, end());
return count;
}
//! \copydoc BlackMisc::CContainerBase::removeIf
template <class K0, class V0, class... KeysValues>
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
{
// using-declaration doesn't play nicely with injected template names
return CSequence::CContainerBase::removeIf(k0, v0, keysValues...);
}
/*!
* \brief Remove all elements if they are in other
* \pre The sequence must be initialized.
@@ -394,13 +416,9 @@ namespace BlackMisc
*/
int removeIfIn(const CSequence &other)
{
auto newEnd = std::remove_if(begin(), end(), [&other](const T &v) { return other.contains(v); });
int count = std::distance(newEnd, end());
erase(newEnd, end());
return count;
return removeIf([&other](const T &v) { return other.contains(v); });
}
/*!
* \brief Replace elements matching the given element with a replacement.
* \return The number of elements replaced.