mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Add IntervalMapOverlaps - An iterator for overlapping intervals in two
IntervalMaps. The IntervalMaps can have different template parameters, but the KeyT and Traits types must be the same. Tests are forthcoming. llvm-svn: 121935
This commit is contained in:
parent
c22ad4d7ae
commit
ae68a4eb6d
@ -940,6 +940,7 @@ class IntervalMap {
|
||||
|
||||
public:
|
||||
typedef typename Sizer::Allocator Allocator;
|
||||
typedef Traits KeyTraits;
|
||||
|
||||
private:
|
||||
// The root data is either a RootLeaf or a RootBranchData instance.
|
||||
@ -2006,6 +2007,96 @@ iterator::overflow(unsigned Level) {
|
||||
return SplitRoot;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//--- IntervalMapOverlaps ----//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two
|
||||
/// IntervalMaps. The maps may be different, but the KeyT and Traits types
|
||||
/// should be the same.
|
||||
///
|
||||
/// Typical uses:
|
||||
///
|
||||
/// 1. Test for overlap:
|
||||
/// bool overlap = IntervalMapOverlaps(a, b).valid();
|
||||
///
|
||||
/// 2. Enumerate overlaps:
|
||||
/// for (IntervalMapOverlaps I(a, b); I.valid() ; ++I) { ... }
|
||||
///
|
||||
template <typename MapA, typename MapB>
|
||||
class IntervalMapOverlaps {
|
||||
typedef typename MapA::KeyTraits Traits;
|
||||
typename MapA::const_iterator posA;
|
||||
typename MapB::const_iterator posB;
|
||||
|
||||
/// advance - Move posA and posB forward until reaching an overlap, or until
|
||||
/// either meets end.
|
||||
/// Don't move the iterators if they are already overlapping.
|
||||
void advance() {
|
||||
for (;;) {
|
||||
// Make a.end > b.start.
|
||||
posA.advanceTo(posB.start());
|
||||
if (!posA.valid() || !Traits::stopLess(posB.end(), posA.start()))
|
||||
return;
|
||||
// Make b.end > a.start.
|
||||
posB.advanceTo(posA.start());
|
||||
if (!posB.valid() || !Traits::stopLess(posA.end(), posB.start()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/// IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
|
||||
IntervalMapOverlaps(const MapA &a, const MapB &b)
|
||||
: posA(b.empty() ? a.end() : a.find(b.start())),
|
||||
posB(posA.valid() ? b.find(posA.start()) : b.end()) {
|
||||
if (valid())
|
||||
advance();
|
||||
}
|
||||
|
||||
/// valid - Return true if iterator is at an overlap.
|
||||
bool valid() const {
|
||||
return posA.valid() && posB.valid();
|
||||
}
|
||||
|
||||
/// a - access the left hand side in the overlap.
|
||||
const typename MapA::const_iterator &a() const { return posA; }
|
||||
|
||||
/// b - access the right hand side in the overlap.
|
||||
const typename MapB::const_iterator &b() const { return posB; }
|
||||
|
||||
/// skipA - Move to the next overlap that doesn't involve a().
|
||||
void skipA() {
|
||||
++posA;
|
||||
if (!posA.valid() || !Traits::stopLess(posB.end(), posA.start()))
|
||||
return;
|
||||
// Second half-loop of advance().
|
||||
posB.advanceTo(posA.start());
|
||||
if (!posB.valid() || !Traits::stopLess(posA.end(), posB.start()))
|
||||
return ;
|
||||
advance();
|
||||
}
|
||||
|
||||
/// skipB - Move to the next overlap that doesn't involve b().
|
||||
void skipB() {
|
||||
++posB;
|
||||
if (!posB.valid() || !Traits::stopLess(posA.end(), posB.start()))
|
||||
return;
|
||||
advance();
|
||||
}
|
||||
|
||||
/// Preincrement - Move to the next overlap.
|
||||
IntervalMapOverlaps &operator++() {
|
||||
// Bump the iterator that ends first. The other one may have more overlaps.
|
||||
if (Traits::startLess(posB.end(), posA.end()))
|
||||
skipB();
|
||||
else
|
||||
skipA();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user