10 #ifndef WPIUTIL_WPI_ITERATOR_H 11 #define WPIUTIL_WPI_ITERATOR_H 17 #include <type_traits> 65 template <
typename DerivedT,
typename IteratorCategoryT,
typename T,
66 typename DifferenceTypeT = std::ptrdiff_t,
typename PointerT = T *,
67 typename ReferenceT = T &>
69 :
public std::iterator<IteratorCategoryT, T, DifferenceTypeT, PointerT,
73 IsRandomAccess = std::is_base_of<std::random_access_iterator_tag,
74 IteratorCategoryT>::value,
75 IsBidirectional = std::is_base_of<std::bidirectional_iterator_tag,
76 IteratorCategoryT>::value,
92 operator ReferenceT()
const {
return *I; }
96 DerivedT operator+(DifferenceTypeT n)
const {
97 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
98 "Must pass the derived type to this template!");
101 "The '+' operator is only defined for random access iterators.");
102 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
106 friend DerivedT operator+(DifferenceTypeT n,
const DerivedT &i) {
109 "The '+' operator is only defined for random access iterators.");
112 DerivedT operator-(DifferenceTypeT n)
const {
115 "The '-' operator is only defined for random access iterators.");
116 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
121 DerivedT &operator++() {
122 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
123 "Must pass the derived type to this template!");
124 return static_cast<DerivedT *
>(
this)->
operator+=(1);
126 DerivedT operator++(
int) {
127 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
128 ++*
static_cast<DerivedT *
>(
this);
131 DerivedT &operator--() {
134 "The decrement operator is only defined for bidirectional iterators.");
135 return static_cast<DerivedT *
>(
this)->
operator-=(1);
137 DerivedT operator--(
int) {
140 "The decrement operator is only defined for bidirectional iterators.");
141 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
142 --*
static_cast<DerivedT *
>(
this);
146 bool operator!=(
const DerivedT &RHS)
const {
147 return !
static_cast<const DerivedT *
>(
this)->
operator==(RHS);
150 bool operator>(
const DerivedT &RHS)
const {
153 "Relational operators are only defined for random access iterators.");
154 return !
static_cast<const DerivedT *
>(
this)->
operator<(RHS) &&
155 !
static_cast<const DerivedT *
>(
this)->
operator==(RHS);
157 bool operator<=(
const DerivedT &RHS)
const {
160 "Relational operators are only defined for random access iterators.");
161 return !
static_cast<const DerivedT *
>(
this)->
operator>(RHS);
163 bool operator>=(
const DerivedT &RHS)
const {
166 "Relational operators are only defined for random access iterators.");
167 return !
static_cast<const DerivedT *
>(
this)->
operator<(RHS);
170 PointerT operator->() {
return &
static_cast<DerivedT *
>(
this)->
operator*(); }
171 PointerT operator->()
const {
172 return &
static_cast<const DerivedT *
>(
this)->
operator*();
175 static_assert(IsRandomAccess,
176 "Subscripting is only defined for random access iterators.");
177 return ReferenceProxy(static_cast<DerivedT *>(
this)->
operator+(n));
180 static_assert(IsRandomAccess,
181 "Subscripting is only defined for random access iterators.");
182 return ReferenceProxy(static_cast<const DerivedT *>(
this)->
operator+(n));
192 typename DerivedT,
typename WrappedIteratorT,
193 typename IteratorCategoryT =
194 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
195 typename T =
typename std::iterator_traits<WrappedIteratorT>::value_type,
196 typename DifferenceTypeT =
197 typename std::iterator_traits<WrappedIteratorT>::difference_type,
198 typename PointerT =
typename std::conditional<
199 std::is_same<T,
typename std::iterator_traits<
200 WrappedIteratorT>::value_type>::value,
201 typename std::iterator_traits<WrappedIteratorT>::pointer, T *>::type,
202 typename ReferenceT =
typename std::conditional<
203 std::is_same<T,
typename std::iterator_traits<
204 WrappedIteratorT>::value_type>::value,
205 typename std::iterator_traits<WrappedIteratorT>::reference, T &>::type,
207 typename WrappedTraitsT = std::iterator_traits<WrappedIteratorT>>
210 DifferenceTypeT, PointerT, ReferenceT> {
211 using BaseT =
typename iterator_adaptor_base::iterator_facade_base;
219 static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
220 "Must pass the derived type to this template!");
223 const WrappedIteratorT &wrapped()
const {
return I; }
226 using difference_type = DifferenceTypeT;
228 DerivedT &operator+=(difference_type n) {
230 BaseT::IsRandomAccess,
231 "The '+=' operator is only defined for random access iterators.");
233 return *
static_cast<DerivedT *
>(
this);
235 DerivedT &operator-=(difference_type n) {
237 BaseT::IsRandomAccess,
238 "The '-=' operator is only defined for random access iterators.");
240 return *
static_cast<DerivedT *
>(
this);
242 using BaseT::operator-;
243 difference_type operator-(
const DerivedT &RHS)
const {
245 BaseT::IsRandomAccess,
246 "The '-' operator is only defined for random access iterators.");
252 using BaseT::operator++;
253 DerivedT &operator++() {
255 return *
static_cast<DerivedT *
>(
this);
257 using BaseT::operator--;
258 DerivedT &operator--() {
260 BaseT::IsBidirectional,
261 "The decrement operator is only defined for bidirectional iterators.");
263 return *
static_cast<DerivedT *
>(
this);
266 bool operator==(
const DerivedT &RHS)
const {
return I == RHS.I; }
267 bool operator<(
const DerivedT &RHS)
const {
269 BaseT::IsRandomAccess,
270 "Relational operators are only defined for random access iterators.");
274 ReferenceT operator*()
const {
return *I; }
286 template <
typename WrappedIteratorT,
287 typename T =
typename std::remove_reference<
288 decltype(**std::declval<WrappedIteratorT>())>::type>
291 pointee_iterator<WrappedIteratorT>, WrappedIteratorT,
292 typename std::iterator_traits<WrappedIteratorT>::iterator_category,
295 template <
typename U>
297 : pointee_iterator::iterator_adaptor_base(std::forward<U &&>(u)) {}
299 T &operator*()
const {
return **this->I; }
302 template <
typename RangeT,
typename WrappedIteratorT =
303 decltype(std::begin(std::declval<RangeT>()))>
305 make_pointee_range(RangeT &&Range) {
307 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
308 PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
311 template <
typename WrappedIteratorT,
312 typename T = decltype(&*std::declval<WrappedIteratorT>())>
315 WrappedIteratorT, T> {
322 : pointer_iterator::iterator_adaptor_base(std::move(u)) {}
324 T &operator*() {
return Ptr = &*this->I; }
325 const T &operator*()
const {
return Ptr = &*this->I; }
328 template <
typename RangeT,
typename WrappedIteratorT =
329 decltype(std::begin(std::declval<RangeT>()))>
331 make_pointer_range(RangeT &&Range) {
333 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
334 PointerIteratorT(std::end(std::forward<RangeT>(Range))));
339 #endif // LLVM_ADT_ITERATOR_H This provides a very simple, boring adaptor for a begin and end iterator into a range type...
bool operator<(json::const_reference lhs, json::const_reference rhs) noexcept
Definition: json.cpp:986
namespace to hold default to_json function
Definition: json_binary_writer.cpp:39
CRTP base class for adapting an iterator to a different type.
Definition: iterator.h:208
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:68
A range adaptor for a pair of iterators.
Definition: iterator_range.h:32
An iterator type that allows iterating over the pointees via some other iterator. ...
Definition: iterator.h:289
Definition: iterator.h:313
A proxy object for computing a reference via indirecting a copy of an iterator.
Definition: iterator.h:84
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:54
bool operator==(json::const_reference lhs, json::const_reference rhs) noexcept
Definition: json.cpp:921