mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-14 17:34:41 +00:00
ADT: Add MapVector::remove_if
Add a `MapVector::remove_if()` that erases items in bulk in linear time, as opposed to quadratic time for repeated calls to `MapVector::erase()`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213090 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4b0a7f3946
commit
c12ce2b661
@ -1441,8 +1441,10 @@ order, making it an easy (but somewhat expensive) solution for non-deterministic
|
||||
iteration over maps of pointers.
|
||||
|
||||
It is implemented by mapping from key to an index in a vector of key,value
|
||||
pairs. This provides fast lookup and iteration, but has two main drawbacks: The
|
||||
key is stored twice and removing elements takes linear time.
|
||||
pairs. This provides fast lookup and iteration, but has two main drawbacks:
|
||||
the key is stored twice and removing elements takes linear time. If it is
|
||||
necessary to remove elements, it's best to remove them in bulk using
|
||||
``remove_if()``.
|
||||
|
||||
.. _dss_inteqclasses:
|
||||
|
||||
|
@ -146,8 +146,36 @@ public:
|
||||
}
|
||||
return Next;
|
||||
}
|
||||
|
||||
/// \brief Remove the elements that match the predicate.
|
||||
///
|
||||
/// Erase all elements that match \c Pred in a single pass. Takes linear
|
||||
/// time.
|
||||
template <class Predicate> void remove_if(Predicate Pred);
|
||||
};
|
||||
|
||||
template <typename KeyT, typename ValueT, typename MapType, typename VectorType>
|
||||
template <class Function>
|
||||
void MapVector<KeyT, ValueT, MapType, VectorType>::remove_if(Function Pred) {
|
||||
auto O = Vector.begin();
|
||||
for (auto I = O, E = Vector.end(); I != E; ++I) {
|
||||
if (Pred(*I)) {
|
||||
// Erase from the map.
|
||||
Map.erase(I->first);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (I != O) {
|
||||
// Move the value and update the index in the map.
|
||||
*O = std::move(*I);
|
||||
Map[O->first] = O - Vector.begin();
|
||||
}
|
||||
++O;
|
||||
}
|
||||
// Erase trailing entries in the vector.
|
||||
Vector.erase(O, Vector.end());
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -68,3 +68,24 @@ TEST(MapVectorTest, erase) {
|
||||
ASSERT_EQ(MV[3], 4);
|
||||
ASSERT_EQ(MV[5], 6);
|
||||
}
|
||||
|
||||
TEST(MapVectorTest, remove_if) {
|
||||
MapVector<int, int> MV;
|
||||
|
||||
MV.insert(std::make_pair(1, 11));
|
||||
MV.insert(std::make_pair(2, 12));
|
||||
MV.insert(std::make_pair(3, 13));
|
||||
MV.insert(std::make_pair(4, 14));
|
||||
MV.insert(std::make_pair(5, 15));
|
||||
MV.insert(std::make_pair(6, 16));
|
||||
ASSERT_EQ(MV.size(), 6u);
|
||||
|
||||
MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
|
||||
ASSERT_EQ(MV.size(), 3u);
|
||||
ASSERT_EQ(MV.find(1), MV.end());
|
||||
ASSERT_EQ(MV.find(3), MV.end());
|
||||
ASSERT_EQ(MV.find(5), MV.end());
|
||||
ASSERT_EQ(MV[2], 12);
|
||||
ASSERT_EQ(MV[4], 14);
|
||||
ASSERT_EQ(MV[6], 16);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user