10 #ifndef LLVM_ADT_ITERATOR_H
11 #define LLVM_ADT_ITERATOR_H
15 #include <type_traits>
62 template <
typename DerivedT,
typename IteratorCategoryT,
typename T,
63 typename DifferenceTypeT = std::ptrdiff_t,
typename PointerT =
T *,
64 typename ReferenceT =
T &>
66 :
public std::iterator<IteratorCategoryT, T, DifferenceTypeT, PointerT,
71 std::is_base_of<std::random_access_iterator_tag, IteratorCategoryT>::value,
73 std::is_base_of<std::bidirectional_iterator_tag, IteratorCategoryT>::value,
89 operator ReferenceT()
const {
return *I; }
96 "The '+' operator is only defined for random access iterators.");
97 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
101 friend DerivedT
operator+(DifferenceTypeT n,
const DerivedT &
i) {
104 "The '+' operator is only defined for random access iterators.");
110 "The '-' operator is only defined for random access iterators.");
111 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
117 return static_cast<DerivedT *
>(
this)->
operator+=(1);
120 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
121 ++*
static_cast<DerivedT *
>(
this);
127 "The decrement operator is only defined for bidirectional iterators.");
128 return static_cast<DerivedT *
>(
this)->
operator-=(1);
133 "The decrement operator is only defined for bidirectional iterators.");
134 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
135 --*
static_cast<DerivedT *
>(
this);
140 return !
static_cast<const DerivedT *
>(
this)->
operator==(RHS);
146 "Relational operators are only defined for random access iterators.");
147 return !
static_cast<const DerivedT *
>(
this)->
operator<(RHS) &&
148 !
static_cast<const DerivedT *
>(
this)->
operator==(RHS);
153 "Relational operators are only defined for random access iterators.");
154 return !
static_cast<const DerivedT *
>(
this)->
operator>(RHS);
159 "Relational operators are only defined for random access iterators.");
160 return !
static_cast<const DerivedT *
>(
this)->
operator<(RHS);
164 return &
static_cast<const DerivedT *
>(
this)->
operator*();
168 "Subscripting is only defined for random access iterators.");
169 return ReferenceProxy(static_cast<const DerivedT *>(
this)->
operator+(n));
179 typename DerivedT,
typename WrappedIteratorT,
180 typename IteratorCategoryT =
181 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
182 typename T =
typename std::iterator_traits<WrappedIteratorT>::value_type,
183 typename DifferenceTypeT =
184 typename std::iterator_traits<WrappedIteratorT>::difference_type,
185 typename PointerT =
typename std::conditional<
186 std::is_same<
T,
typename std::iterator_traits<
187 WrappedIteratorT>::value_type>::value,
188 typename std::iterator_traits<WrappedIteratorT>::pointer,
T *>::type,
189 typename ReferenceT =
typename std::conditional<
190 std::is_same<
T,
typename std::iterator_traits<
191 WrappedIteratorT>::value_type>::value,
192 typename std::iterator_traits<WrappedIteratorT>::reference,
T &>::type,
194 typename WrappedTraitsT = std::iterator_traits<WrappedIteratorT>>
197 DifferenceTypeT, PointerT, ReferenceT> {
198 typedef typename iterator_adaptor_base::iterator_facade_base BaseT;
207 const WrappedIteratorT &
wrapped()
const {
return I; }
214 BaseT::IsRandomAccess,
215 "The '+=' operator is only defined for random access iterators.");
217 return *
static_cast<DerivedT *
>(
this);
221 BaseT::IsRandomAccess,
222 "The '-=' operator is only defined for random access iterators.");
224 return *
static_cast<DerivedT *
>(
this);
226 using BaseT::operator-;
229 BaseT::IsRandomAccess,
230 "The '-' operator is only defined for random access iterators.");
236 using BaseT::operator++;
239 return *
static_cast<DerivedT *
>(
this);
241 using BaseT::operator--;
244 BaseT::IsBidirectional,
245 "The decrement operator is only defined for bidirectional iterators.");
247 return *
static_cast<DerivedT *
>(
this);
253 BaseT::IsRandomAccess,
254 "Relational operators are only defined for random access iterators.");
270 template <
typename WrappedIteratorT,
271 typename T =
typename std::remove_reference<
272 decltype(**std::declval<WrappedIteratorT>())>::type>
275 pointee_iterator<WrappedIteratorT>, WrappedIteratorT,
276 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
279 template <
typename U>
286 template <
typename WrappedIteratorT,
287 typename T = decltype(&*std::declval<WrappedIteratorT>())>
290 WrappedIteratorT, T> {
305 #endif // LLVM_ADT_ITERATOR_H
DifferenceTypeT difference_type
iterator_adaptor_base(WrappedIteratorT u)
difference_type operator-(const DerivedT &RHS) const
bool operator>(const DerivedT &RHS) const
bool operator>=(const DerivedT &RHS) const
const T & operator*() const
A proxy object for computing a reference via indirecting a copy of an iterator.
DerivedT operator-(DifferenceTypeT n) const
DerivedT operator+(DifferenceTypeT n) const
iterator_adaptor_base()=default
bool operator==(const DerivedT &RHS) const
bool operator<=(const DerivedT &RHS) const
DerivedT & operator+=(difference_type n)
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
bool operator!=(const DerivedT &RHS) const
ReferenceT operator*() const
pointer_iterator()=default
CRTP base class for adapting an iterator to a different type.
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
An iterator type that allows iterating over the pointees via some other iterator. ...
pointer_iterator(WrappedIteratorT u)
pointee_iterator()=default
const WrappedIteratorT & wrapped() const
DerivedT & operator-=(difference_type n)
PointerT operator->() const
ReferenceProxy operator[](DifferenceTypeT n) const
bool operator<(const DerivedT &RHS) const