[ADT] Simplify DenseMapIterator with std::reverse_iterator (NFC) (#157389)
DenseMapIterator has two tasks:
- iterate the buckets in the requested direction
- skip the empty and tombstone buckets
These tasks are intertwined in the current implementation.
This patch cleans up DenseMapIterator by separating the two tasks.
Specifically, we introduce a private middleman iterator type called
BucketItTy. This is the same as the pointer-based iterator in the
forward direction, but it becomes std::reverse_iterator<pointer>
otherwise. Now, the user-facing iterator iterates over BucketItTy
while skipping the empty and tombstone buckets. This way,
AdvancePastEmptyBuckets always calls BucketItTy::operator++. If the
reverse iteration is requested, the underlying raw pointer gets
decremented, but that logic is hidden behind
std::reverse_iterator<pointer>::operator++.
As a result, we can remove RetreatPastEmptyBuckets and a couple of
calls to shouldReverseIterate.
Here is a data point. A couple of months ago, we were calling
shouldReverseIterate from 18 places in DenseMap.h. That's down to 5.
This patch reduces it further down to 3.