[llvm-commits] [llvm] r121935 - /llvm/trunk/include/llvm/ADT/IntervalMap.h
Jakob Stoklund Olesen
stoklund at 2pi.dk
Wed Dec 15 17:18:29 PST 2010
Author: stoklund
Date: Wed Dec 15 19:18:29 2010
New Revision: 121935
URL: http://llvm.org/viewvc/llvm-project?rev=121935&view=rev
Log:
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.
Modified:
llvm/trunk/include/llvm/ADT/IntervalMap.h
Modified: llvm/trunk/include/llvm/ADT/IntervalMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntervalMap.h?rev=121935&r1=121934&r2=121935&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/IntervalMap.h (original)
+++ llvm/trunk/include/llvm/ADT/IntervalMap.h Wed Dec 15 19:18:29 2010
@@ -940,6 +940,7 @@
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 @@
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
More information about the llvm-commits
mailing list