Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 23 additions & 32 deletions llvm/include/llvm/ADT/DenseMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1184,10 +1184,14 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
using iterator_category = std::forward_iterator_tag;

private:
pointer Ptr = nullptr;
pointer End = nullptr;
using BucketItTy =
std::conditional_t<shouldReverseIterate<KeyT>(),
std::reverse_iterator<pointer>, pointer>;

DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch)
BucketItTy Ptr = {};
BucketItTy End = {};

DenseMapIterator(BucketItTy Pos, BucketItTy E, const DebugEpochBase &Epoch)
: DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
assert(isHandleInSync() && "invalid construction!");
}
Expand All @@ -1201,29 +1205,24 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
// empty buckets.
if (IsEmpty)
return makeEnd(Buckets, Epoch);
if (shouldReverseIterate<KeyT>()) {
DenseMapIterator Iter(Buckets.end(), Buckets.begin(), Epoch);
Iter.RetreatPastEmptyBuckets();
return Iter;
}
DenseMapIterator Iter(Buckets.begin(), Buckets.end(), Epoch);
auto R = maybeReverse(Buckets);
DenseMapIterator Iter(R.begin(), R.end(), Epoch);
Iter.AdvancePastEmptyBuckets();
return Iter;
}

static DenseMapIterator makeEnd(iterator_range<pointer> Buckets,
const DebugEpochBase &Epoch) {
if (shouldReverseIterate<KeyT>())
return DenseMapIterator(Buckets.begin(), Buckets.begin(), Epoch);
return DenseMapIterator(Buckets.end(), Buckets.end(), Epoch);
auto R = maybeReverse(Buckets);
return DenseMapIterator(R.end(), R.end(), Epoch);
}

static DenseMapIterator makeIterator(pointer P,
iterator_range<pointer> Buckets,
const DebugEpochBase &Epoch) {
if (shouldReverseIterate<KeyT>())
return DenseMapIterator(P + 1, Buckets.begin(), Epoch);
return DenseMapIterator(P, Buckets.end(), Epoch);
auto R = maybeReverse(Buckets);
constexpr int Offset = shouldReverseIterate<KeyT>() ? 1 : 0;
return DenseMapIterator(BucketItTy(P + Offset), R.end(), Epoch);
}

// Converting ctor from non-const iterators to const iterators. SFINAE'd out
Expand All @@ -1238,16 +1237,16 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
reference operator*() const {
assert(isHandleInSync() && "invalid iterator access!");
assert(Ptr != End && "dereferencing end() iterator");
if (shouldReverseIterate<KeyT>())
return Ptr[-1];
return *Ptr;
}
pointer operator->() const { return &operator*(); }

friend bool operator==(const DenseMapIterator &LHS,
const DenseMapIterator &RHS) {
assert((!LHS.Ptr || LHS.isHandleInSync()) && "handle not in sync!");
assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
assert((!LHS.getEpochAddress() || LHS.isHandleInSync()) &&
"handle not in sync!");
assert((!RHS.getEpochAddress() || RHS.isHandleInSync()) &&
"handle not in sync!");
assert(LHS.getEpochAddress() == RHS.getEpochAddress() &&
"comparing incomparable iterators!");
return LHS.Ptr == RHS.Ptr;
Expand All @@ -1261,11 +1260,6 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
inline DenseMapIterator &operator++() { // Preincrement
assert(isHandleInSync() && "invalid iterator access!");
assert(Ptr != End && "incrementing end() iterator");
if (shouldReverseIterate<KeyT>()) {
--Ptr;
RetreatPastEmptyBuckets();
return *this;
}
++Ptr;
AdvancePastEmptyBuckets();
return *this;
Expand All @@ -1288,14 +1282,11 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
++Ptr;
}

void RetreatPastEmptyBuckets() {
assert(Ptr >= End);
const KeyT Empty = KeyInfoT::getEmptyKey();
const KeyT Tombstone = KeyInfoT::getTombstoneKey();

while (Ptr != End && (KeyInfoT::isEqual(Ptr[-1].getFirst(), Empty) ||
KeyInfoT::isEqual(Ptr[-1].getFirst(), Tombstone)))
--Ptr;
static auto maybeReverse(iterator_range<pointer> Range) {
if constexpr (shouldReverseIterate<KeyT>())
return reverse(Range);
else
return Range;
}
};

Expand Down