Skip to content

Commit 93942f5

Browse files
[ADT] Merge ConstIterator and Iterator of DenseSet into one class (NFC) (llvm#155068)
This patch merges ConstIterator and Iterator of DenseSet into DenseSetIterator, a single template class with a boolean value to control its const behavior. template <bool IsConst> class DenseSetIterator { ... }; using iterator = DenseSetIterator<false>; using const_iterator = DenseSetIterator<true>; Note that DenseMapIterator also uses the same boolean trick.
1 parent b147644 commit 93942f5

File tree

1 file changed

+42
-69
lines changed

1 file changed

+42
-69
lines changed

llvm/include/llvm/ADT/DenseSet.h

Lines changed: 42 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -104,95 +104,68 @@ class DenseSetImpl {
104104

105105
void swap(DenseSetImpl &RHS) { TheMap.swap(RHS.TheMap); }
106106

107-
// Iterators.
108-
109-
class ConstIterator;
110-
111-
class Iterator {
112-
typename MapTy::iterator I;
107+
private:
108+
template <bool IsConst> class DenseSetIterator {
113109
friend class DenseSetImpl;
114-
friend class ConstIterator;
115-
116-
public:
117-
using difference_type = typename MapTy::iterator::difference_type;
118-
using value_type = ValueT;
119-
using pointer = value_type *;
120-
using reference = value_type &;
121-
using iterator_category = std::forward_iterator_tag;
122110

123-
Iterator() = default;
124-
Iterator(const typename MapTy::iterator &i) : I(i) {}
125-
126-
ValueT &operator*() { return I->getFirst(); }
127-
const ValueT &operator*() const { return I->getFirst(); }
128-
ValueT *operator->() { return &I->getFirst(); }
129-
const ValueT *operator->() const { return &I->getFirst(); }
130-
131-
Iterator &operator++() {
132-
++I;
133-
return *this;
134-
}
135-
Iterator operator++(int) {
136-
auto T = *this;
137-
++I;
138-
return T;
139-
}
140-
friend bool operator==(const Iterator &X, const Iterator &Y) {
141-
return X.I == Y.I;
142-
}
143-
friend bool operator!=(const Iterator &X, const Iterator &Y) {
144-
return X.I != Y.I;
145-
}
146-
};
111+
using MapIteratorT =
112+
std::conditional_t<IsConst, typename MapTy::const_iterator,
113+
typename MapTy::iterator>;
147114

148-
class ConstIterator {
149-
typename MapTy::const_iterator I;
150-
friend class DenseSetImpl;
151-
friend class Iterator;
115+
MapIteratorT I;
152116

153117
public:
154-
using difference_type = typename MapTy::const_iterator::difference_type;
155-
using value_type = ValueT;
156-
using pointer = const value_type *;
157-
using reference = const value_type &;
118+
using difference_type = typename MapIteratorT::difference_type;
158119
using iterator_category = std::forward_iterator_tag;
120+
using value_type = ValueT;
121+
using pointer =
122+
std::conditional_t<IsConst, const value_type *, value_type *>;
123+
using reference =
124+
std::conditional_t<IsConst, const value_type &, value_type &>;
159125

160-
ConstIterator() = default;
161-
ConstIterator(const Iterator &B) : I(B.I) {}
162-
ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
126+
DenseSetIterator() = default;
127+
DenseSetIterator(MapIteratorT I) : I(I) {}
163128

164-
const ValueT &operator*() const { return I->getFirst(); }
165-
const ValueT *operator->() const { return &I->getFirst(); }
129+
// Allow conversion from iterator to const_iterator.
130+
template <bool C = IsConst, typename = std::enable_if_t<C>>
131+
DenseSetIterator(const DenseSetIterator<false> &Other) : I(Other.I) {}
166132

167-
ConstIterator &operator++() {
133+
reference operator*() const { return I->getFirst(); }
134+
pointer operator->() const { return &I->getFirst(); }
135+
136+
DenseSetIterator &operator++() {
168137
++I;
169138
return *this;
170139
}
171-
ConstIterator operator++(int) {
140+
DenseSetIterator operator++(int) {
172141
auto T = *this;
173142
++I;
174143
return T;
175144
}
176-
friend bool operator==(const ConstIterator &X, const ConstIterator &Y) {
177-
return X.I == Y.I;
145+
146+
friend bool operator==(const DenseSetIterator &LHS,
147+
const DenseSetIterator &RHS) {
148+
return LHS.I == RHS.I;
178149
}
179-
friend bool operator!=(const ConstIterator &X, const ConstIterator &Y) {
180-
return X.I != Y.I;
150+
friend bool operator!=(const DenseSetIterator &LHS,
151+
const DenseSetIterator &RHS) {
152+
return LHS.I != RHS.I;
181153
}
182154
};
183155

184-
using iterator = Iterator;
185-
using const_iterator = ConstIterator;
156+
public:
157+
using iterator = DenseSetIterator<false>;
158+
using const_iterator = DenseSetIterator<true>;
186159

187-
iterator begin() { return Iterator(TheMap.begin()); }
188-
iterator end() { return Iterator(TheMap.end()); }
160+
iterator begin() { return iterator(TheMap.begin()); }
161+
iterator end() { return iterator(TheMap.end()); }
189162

190-
const_iterator begin() const { return ConstIterator(TheMap.begin()); }
191-
const_iterator end() const { return ConstIterator(TheMap.end()); }
163+
const_iterator begin() const { return const_iterator(TheMap.begin()); }
164+
const_iterator end() const { return const_iterator(TheMap.end()); }
192165

193-
iterator find(const_arg_type_t<ValueT> V) { return Iterator(TheMap.find(V)); }
166+
iterator find(const_arg_type_t<ValueT> V) { return iterator(TheMap.find(V)); }
194167
const_iterator find(const_arg_type_t<ValueT> V) const {
195-
return ConstIterator(TheMap.find(V));
168+
return const_iterator(TheMap.find(V));
196169
}
197170

198171
/// Check if the set contains the given element.
@@ -206,15 +179,15 @@ class DenseSetImpl {
206179
/// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key type
207180
/// used.
208181
template <class LookupKeyT> iterator find_as(const LookupKeyT &Val) {
209-
return Iterator(TheMap.find_as(Val));
182+
return iterator(TheMap.find_as(Val));
210183
}
211184
template <class LookupKeyT>
212185
const_iterator find_as(const LookupKeyT &Val) const {
213-
return ConstIterator(TheMap.find_as(Val));
186+
return const_iterator(TheMap.find_as(Val));
214187
}
215188

216-
void erase(Iterator I) { return TheMap.erase(I.I); }
217-
void erase(ConstIterator CI) { return TheMap.erase(CI.I); }
189+
void erase(iterator I) { return TheMap.erase(I.I); }
190+
void erase(const_iterator CI) { return TheMap.erase(CI.I); }
218191

219192
std::pair<iterator, bool> insert(const ValueT &V) {
220193
detail::DenseSetEmpty Empty;

0 commit comments

Comments
 (0)