Static Value-Flow Analysis
iterator.h
Go to the documentation of this file.
1 //===- iterator.h - Utilities for using and defining iterators --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef UTIL_ITERATOR_H
10 #define UTIL_ITERATOR_H
11 
12 #include "Util/iterator_range.h"
13 #include <cstddef>
14 #include <iterator>
15 #include <type_traits>
16 #include <utility>
17 
18 namespace SVF
19 {
20 
64 template <typename DerivedT, typename IteratorCategoryT, typename T,
65  typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T *,
66  typename ReferenceT = T &>
68 {
69 public:
70  using iterator_category = IteratorCategoryT;
71  using value_type = T;
72  using difference_type = DifferenceTypeT;
73  using pointer = PointerT;
74  using reference = ReferenceT;
75 
76 protected:
77  enum
78  {
79  IsRandomAccess = std::is_base_of<std::random_access_iterator_tag,
80  IteratorCategoryT>::value,
81  IsBidirectional = std::is_base_of<std::bidirectional_iterator_tag,
82  IteratorCategoryT>::value,
83  };
84 
91  {
93 
94  DerivedT I;
95 
96  ReferenceProxy(DerivedT I) : I(std::move(I)) {}
97 
98  public:
99  operator ReferenceT() const
100  {
101  return *I;
102  }
103  };
104 
105 public:
106  DerivedT operator+(DifferenceTypeT n) const
107  {
108  static_assert(std::is_base_of<iter_facade_base, DerivedT>::value,
109  "Must pass the derived type to this template!");
110  static_assert(
112  "The '+' operator is only defined for random access iterators.");
113  DerivedT tmp = *static_cast<const DerivedT *>(this);
114  tmp += n;
115  return tmp;
116  }
117  friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
118  {
119  static_assert(
121  "The '+' operator is only defined for random access iterators.");
122  return i + n;
123  }
124  DerivedT operator-(DifferenceTypeT n) const
125  {
126  static_assert(
128  "The '-' operator is only defined for random access iterators.");
129  DerivedT tmp = *static_cast<const DerivedT *>(this);
130  tmp -= n;
131  return tmp;
132  }
133 
134  DerivedT &operator++()
135  {
136  static_assert(std::is_base_of<iter_facade_base, DerivedT>::value,
137  "Must pass the derived type to this template!");
138  return static_cast<DerivedT *>(this)->operator+=(1);
139  }
140  DerivedT operator++(int)
141  {
142  DerivedT tmp = *static_cast<DerivedT *>(this);
143  ++*static_cast<DerivedT *>(this);
144  return tmp;
145  }
146  DerivedT &operator--()
147  {
148  static_assert(
150  "The decrement operator is only defined for bidirectional iterators.");
151  return static_cast<DerivedT *>(this)->operator-=(1);
152  }
153  DerivedT operator--(int)
154  {
155  static_assert(
157  "The decrement operator is only defined for bidirectional iterators.");
158  DerivedT tmp = *static_cast<DerivedT *>(this);
159  --*static_cast<DerivedT *>(this);
160  return tmp;
161  }
162 
163 #ifndef __cpp_impl_three_way_comparison
164  bool operator!=(const DerivedT &RHS) const
165  {
166  return !(static_cast<const DerivedT &>(*this) == RHS);
167  }
168 #endif
169 
170  bool operator>(const DerivedT &RHS) const
171  {
172  static_assert(
174  "Relational operators are only defined for random access iterators.");
175  return !(static_cast<const DerivedT &>(*this) < RHS) &&
176  !(static_cast<const DerivedT &>(*this) == RHS);
177  }
178  bool operator<=(const DerivedT &RHS) const
179  {
180  static_assert(
182  "Relational operators are only defined for random access iterators.");
183  return !(static_cast<const DerivedT &>(*this) > RHS);
184  }
185  bool operator>=(const DerivedT &RHS) const
186  {
187  static_assert(
189  "Relational operators are only defined for random access iterators.");
190  return !(static_cast<const DerivedT &>(*this) < RHS);
191  }
192 
193  PointerT operator->()
194  {
195  return &static_cast<DerivedT *>(this)->operator*();
196  }
197  PointerT operator->() const
198  {
199  return &static_cast<const DerivedT *>(this)->operator*();
200  }
201  ReferenceProxy operator[](DifferenceTypeT n)
202  {
203  static_assert(IsRandomAccess,
204  "Subscripting is only defined for random access iterators.");
205  return ReferenceProxy(static_cast<DerivedT *>(this)->operator+(n));
206  }
207  ReferenceProxy operator[](DifferenceTypeT n) const
208  {
209  static_assert(IsRandomAccess,
210  "Subscripting is only defined for random access iterators.");
211  return ReferenceProxy(static_cast<const DerivedT *>(this)->operator+(n));
212  }
213 };
214 
220 template <
221  typename DerivedT, typename WrappedIteratorT,
222  typename IteratorCategoryT =
223  typename std::iterator_traits<WrappedIteratorT>::iterator_category,
224  typename T = typename std::iterator_traits<WrappedIteratorT>::value_type,
225  typename DifferenceTypeT =
226  typename std::iterator_traits<WrappedIteratorT>::difference_type,
227  typename PointerT = std::conditional_t<
228  std::is_same<T, typename std::iterator_traits<
229  WrappedIteratorT>::value_type>::value,
230  typename std::iterator_traits<WrappedIteratorT>::pointer, T *>,
231  typename ReferenceT = std::conditional_t<
232  std::is_same<T, typename std::iterator_traits<
233  WrappedIteratorT>::value_type>::value,
234  typename std::iterator_traits<WrappedIteratorT>::reference, T &>>
236  : public iter_facade_base<DerivedT, IteratorCategoryT, T,
237  DifferenceTypeT, PointerT, ReferenceT>
238 {
239  using BaseT = typename iter_adaptor_base::iter_facade_base;
240 
241 protected:
242  WrappedIteratorT I;
243 
244  iter_adaptor_base() = default;
245 
246  explicit iter_adaptor_base(WrappedIteratorT u) : I(std::move(u))
247  {
248  static_assert(std::is_base_of<iter_adaptor_base, DerivedT>::value,
249  "Must pass the derived type to this template!");
250  }
251 
252  const WrappedIteratorT &wrapped() const
253  {
254  return I;
255  }
256 
257 public:
258  using difference_type = DifferenceTypeT;
259 
261  {
262  static_assert(
263  BaseT::IsRandomAccess,
264  "The '+=' operator is only defined for random access iterators.");
265  I += n;
266  return *static_cast<DerivedT *>(this);
267  }
269  {
270  static_assert(
271  BaseT::IsRandomAccess,
272  "The '-=' operator is only defined for random access iterators.");
273  I -= n;
274  return *static_cast<DerivedT *>(this);
275  }
276  using BaseT::operator-;
277  difference_type operator-(const DerivedT &RHS) const
278  {
279  static_assert(
280  BaseT::IsRandomAccess,
281  "The '-' operator is only defined for random access iterators.");
282  return I - RHS.I;
283  }
284 
285  // We have to explicitly provide ++ and -- rather than letting the facade
286  // forward to += because WrappedIteratorT might not support +=.
287  using BaseT::operator++;
288  DerivedT &operator++()
289  {
290  ++I;
291  return *static_cast<DerivedT *>(this);
292  }
293  using BaseT::operator--;
294  DerivedT &operator--()
295  {
296  static_assert(
297  BaseT::IsBidirectional,
298  "The decrement operator is only defined for bidirectional iterators.");
299  --I;
300  return *static_cast<DerivedT *>(this);
301  }
302 
303  friend bool operator==(const iter_adaptor_base &LHS,
304  const iter_adaptor_base &RHS)
305  {
306  return LHS.I == RHS.I;
307  }
308  friend bool operator<(const iter_adaptor_base &LHS,
309  const iter_adaptor_base &RHS)
310  {
311  static_assert(
312  BaseT::IsRandomAccess,
313  "Relational operators are only defined for random access iterators.");
314  return LHS.I < RHS.I;
315  }
316 
317  ReferenceT operator*() const
318  {
319  return *I;
320  }
321 };
322 
332 template <typename WrappedIteratorT,
333  typename T = std::remove_reference_t<decltype(
334  **std::declval<WrappedIteratorT>())>>
337  pointee_iter<WrappedIteratorT, T>, WrappedIteratorT,
338  typename std::iterator_traits<WrappedIteratorT>::iterator_category,
339  T>
340 {
341  pointee_iter() = default;
342  template <typename U>
344  : pointee_iter::iter_adaptor_base(std::forward<U &&>(u)) {}
345 
346  T &operator*() const
347  {
348  return **this->I;
349  }
350 };
351 
352 template <typename RangeT, typename WrappedIteratorT =
353  decltype(std::begin(std::declval<RangeT>()))>
354 iter_range<pointee_iter<WrappedIteratorT>>
355  make_pointee_range(RangeT &&Range)
356 {
357  using PointeeIteratorT = pointee_iter<WrappedIteratorT>;
358  return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(Range))),
359  PointeeIteratorT(std::end(std::forward<RangeT>(Range))));
360 }
361 
362 template <typename WrappedIteratorT,
363  typename T = decltype(&*std::declval<WrappedIteratorT>())>
365  : public iter_adaptor_base<
366  pointer_iterator<WrappedIteratorT, T>, WrappedIteratorT,
367  typename std::iterator_traits<WrappedIteratorT>::iterator_category,
368  T>
369 {
370  mutable T Ptr;
371 
372 public:
373  pointer_iterator() = default;
374 
375  explicit pointer_iterator(WrappedIteratorT u)
377 
379  {
380  return Ptr = &*this->I;
381  }
382  const T &operator*() const
383  {
384  return Ptr = &*this->I;
385  }
386 };
387 
388 template <typename RangeT, typename WrappedIteratorT =
389  decltype(std::begin(std::declval<RangeT>()))>
390 iter_range<pointer_iterator<WrappedIteratorT>>
391  make_pointer_range(RangeT &&Range)
392 {
393  using PointerIteratorT = pointer_iterator<WrappedIteratorT>;
394  return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(Range))),
395  PointerIteratorT(std::end(std::forward<RangeT>(Range))));
396 }
397 
398 template <typename WrappedIteratorT,
399  typename T1 = std::remove_reference_t<decltype(
400  **std::declval<WrappedIteratorT>())>,
401  typename T2 = std::add_pointer_t<T1>>
404 
405 } // end namespace llvm
406 
407 #endif // LLVM_ADT_ITERATOR_H
cJSON * n
Definition: cJSON.cpp:2558
DerivedT & operator+=(difference_type n)
Definition: iterator.h:260
friend bool operator<(const iter_adaptor_base &LHS, const iter_adaptor_base &RHS)
Definition: iterator.h:308
friend bool operator==(const iter_adaptor_base &LHS, const iter_adaptor_base &RHS)
Definition: iterator.h:303
DifferenceTypeT difference_type
Definition: iterator.h:258
DerivedT & operator--()
Definition: iterator.h:294
WrappedIteratorT I
Definition: iterator.h:242
DerivedT & operator-=(difference_type n)
Definition: iterator.h:268
DerivedT & operator++()
Definition: iterator.h:288
difference_type operator-(const DerivedT &RHS) const
Definition: iterator.h:277
iter_adaptor_base(WrappedIteratorT u)
Definition: iterator.h:246
ReferenceT operator*() const
Definition: iterator.h:317
const WrappedIteratorT & wrapped() const
Definition: iterator.h:252
typename iter_adaptor_base::iter_facade_base BaseT
Definition: iterator.h:239
IteratorCategoryT iterator_category
Definition: iterator.h:70
ReferenceProxy operator[](DifferenceTypeT n)
Definition: iterator.h:201
DerivedT operator++(int)
Definition: iterator.h:140
ReferenceT reference
Definition: iterator.h:74
DifferenceTypeT difference_type
Definition: iterator.h:72
bool operator>(const DerivedT &RHS) const
Definition: iterator.h:170
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
Definition: iterator.h:117
PointerT operator->()
Definition: iterator.h:193
bool operator!=(const DerivedT &RHS) const
Definition: iterator.h:164
DerivedT operator--(int)
Definition: iterator.h:153
PointerT operator->() const
Definition: iterator.h:197
DerivedT operator+(DifferenceTypeT n) const
Definition: iterator.h:106
DerivedT & operator++()
Definition: iterator.h:134
ReferenceProxy operator[](DifferenceTypeT n) const
Definition: iterator.h:207
bool operator>=(const DerivedT &RHS) const
Definition: iterator.h:185
bool operator<=(const DerivedT &RHS) const
Definition: iterator.h:178
DerivedT operator-(DifferenceTypeT n) const
Definition: iterator.h:124
DerivedT & operator--()
Definition: iterator.h:146
pointer_iterator(WrappedIteratorT u)
Definition: iterator.h:375
pointer_iterator()=default
const T & operator*() const
Definition: iterator.h:382
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447
for isBitcode
Definition: BasicTypes.h:68
iter_range< T > make_range(T x, T y)
iter_range< pointee_iter< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
Definition: iterator.h:355
iter_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition: iterator.h:391
T & operator*() const
Definition: iterator.h:346
pointee_iter(U &&u)
Definition: iterator.h:343
pointee_iter()=default