Fix use of CompEnd predicate to be standards conforming

The existing CompEnd predicate does not define a strict weak order as required
by the C++03 standard; therefore, its use as a predicate to std::upper_bound
is invalid. For a discussion of this issue, see
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#270

This patch replaces the asymmetrical comparison with an iterator adaptor that
achieves the same effect while being strictly standard-conforming by ensuring
an apples-to-apples comparison.

llvm-svn: 127462
This commit is contained in:
John Wiegley 2011-03-11 08:54:34 +00:00
parent 6b7e3bc992
commit 8559f5914c
1 changed files with 111 additions and 9 deletions

View File

@ -30,24 +30,126 @@
#include <algorithm>
using namespace llvm;
// CompEnd - Compare LiveRange ends.
// SlotIndexIterator - adapt an iterator over LiveRanges to look
// like an iterator over SlotIndexes by accessing the .end member.
namespace {
struct CompEnd {
bool operator()(SlotIndex A, const LiveRange &B) const {
return A < B.end;
struct SlotIndexIterator
: std::iterator<std::random_access_iterator_tag, SlotIndex> {
SlotIndexIterator() {
}
bool operator()(const LiveRange &A, SlotIndex B) const {
return A.end < B;
explicit SlotIndexIterator(LiveInterval::iterator it)
: it(it) {
}
bool operator()(const LiveRange &A, const LiveRange &B) const {
return A.end < B.end;
SlotIndexIterator(const SlotIndexIterator & that)
: it(that.it) {
}
SlotIndexIterator & operator=(const SlotIndexIterator & that) {
it = that.it;
return *this;
}
SlotIndexIterator & operator++() {
++it;
return *this;
}
SlotIndexIterator operator++(int) {
SlotIndexIterator that(*this);
++*this;
return that;
}
SlotIndexIterator & operator--() {
--it;
return *this;
}
SlotIndexIterator operator--(int) {
SlotIndexIterator that(*this);
--*this;
return that;
}
SlotIndexIterator & operator+=(std::ptrdiff_t n) {
it += n;
return *this;
}
SlotIndexIterator & operator-=(std::ptrdiff_t n) {
it -= n;
return *this;
}
friend bool operator==(SlotIndexIterator lhs, SlotIndexIterator rhs) {
return lhs.it == rhs.it;
}
friend bool operator!=(SlotIndexIterator lhs, SlotIndexIterator rhs) {
return lhs.it != rhs.it;
}
friend bool operator<(SlotIndexIterator lhs, SlotIndexIterator rhs) {
return lhs.it < rhs.it;
}
friend bool operator<=(SlotIndexIterator lhs, SlotIndexIterator rhs) {
return lhs.it <= rhs.it;
}
friend bool operator>(SlotIndexIterator lhs, SlotIndexIterator rhs) {
return lhs.it > rhs.it;
}
friend bool operator>=(SlotIndexIterator lhs, SlotIndexIterator rhs) {
return lhs.it >= rhs.it;
}
friend SlotIndexIterator operator+(SlotIndexIterator that, std::ptrdiff_t n) {
return SlotIndexIterator(that.it + n);
}
friend SlotIndexIterator operator+(std::ptrdiff_t n, SlotIndexIterator that) {
return SlotIndexIterator(n + that.it);
}
friend SlotIndexIterator operator-(SlotIndexIterator that, std::ptrdiff_t n) {
return SlotIndexIterator(that.it - n);
}
friend std::ptrdiff_t operator-(SlotIndexIterator lhs, SlotIndexIterator rhs) {
return lhs.it - rhs.it;
}
reference operator*() const {
return it->end;
}
reference operator[](std::ptrdiff_t n) const {
return it[n].end;
}
pointer operator->() const {
return &it->end;
}
LiveInterval::iterator base() const {
return it;
}
private:
LiveInterval::iterator it;
};
}
LiveInterval::iterator LiveInterval::find(SlotIndex Pos) {
assert(Pos.isValid() && "Cannot search for an invalid index");
return std::upper_bound(begin(), end(), Pos, CompEnd());
return std::upper_bound(
SlotIndexIterator(begin()),
SlotIndexIterator(end()), Pos).base();
}
/// killedInRange - Return true if the interval has kills in [Start,End).