1//===- iterator.h - Utilities for using and defining iterators --*- C++ -*-===// 
  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 
  7//===----------------------------------------------------------------------===// 
  9#ifndef LLVM_ADT_ITERATOR_H 
  10#define LLVM_ADT_ITERATOR_H 
  20/// CRTP base class which implements the entire standard iterator facade 
  21/// in terms of a minimal subset of the interface. 
  23/// Use this when it is reasonable to implement most of the iterator 
  24/// functionality in terms of a core subset. If you need special behavior or 
  25/// there are performance implications for this, you may want to override the 
  26/// relevant members instead. 
  28/// Note, one abstraction that this does *not* provide is implementing 
  29/// subtraction in terms of addition by negating the difference. Negation isn't 
  30/// always information preserving, and I can see very reasonable iterator 
  31/// designs where this doesn't work well. It doesn't really force much added 
  32/// boilerplate anyways. 
  34/// Another abstraction that this doesn't provide is implementing increment in 
  35/// terms of addition of one. These aren't equivalent for all iterator 
  36/// categories, and respecting that adds a lot of complexity for little gain. 
  38/// Iterators are expected to have const rules analogous to pointers, with a 
  39/// single, const-qualified operator*() that returns ReferenceT. This matches 
  40/// the second and third pointers in the following example: 
  43/// { int *I = &Value; } // ReferenceT 'int&' 
  44/// { int *const I = &Value; } // ReferenceT 'int&'; const 
  45/// { const int *I = &Value; } // ReferenceT 'const int&' 
  46/// { const int *const I = &Value; } // ReferenceT 'const int&'; const 
  48/// If an iterator facade returns a handle to its own state, then T (and 
  49/// PointerT and ReferenceT) should usually be const-qualified. Otherwise, if 
  50/// clients are expected to modify the handle itself, the field can be declared 
  51/// mutable or use const_cast. 
  53/// Classes wishing to use `iterator_facade_base` should implement the following 
  57/// (All of the following methods) 
  58/// - DerivedT &operator=(const DerivedT &R); 
  59/// - bool operator==(const DerivedT &R) const; 
  60/// - T &operator*() const; 
  61/// - DerivedT &operator++(); 
  63/// Bidirectional Iterators: 
  64/// (All methods of forward iterators, plus the following) 
  65/// - DerivedT &operator--(); 
  67/// Random-access Iterators: 
  68/// (All methods of bidirectional iterators excluding the following) 
  69/// - DerivedT &operator++(); 
  70/// - DerivedT &operator--(); 
  71/// (and plus the following) 
  72/// - bool operator<(const DerivedT &RHS) const; 
  73/// - DifferenceTypeT operator-(const DerivedT &R) const; 
  74/// - DerivedT &operator+=(DifferenceTypeT N); 
  75/// - DerivedT &operator-=(DifferenceTypeT N); 
  77template <
typename DerivedT, 
typename IteratorCategoryT, 
typename T,
 
  78 typename DifferenceTypeT = std::ptrdiff_t, 
typename PointerT = 
T *,
 
  79 typename ReferenceT = 
T &>
 
  91 IteratorCategoryT>::value,
 
  93 IteratorCategoryT>::value,
 
  96 /// A proxy object for computing a reference via indirecting a copy of an 
  97 /// iterator. This is used in APIs which need to produce a reference via 
  98 /// indirection but for which the iterator object might be a temporary. The 
  99 /// proxy preserves the iterator internally and exposes the indirected 
  100 /// reference via a conversion operator. 
  101  class ReferenceProxy {
 
  102 friend iterator_facade_base;
 
  106 ReferenceProxy(DerivedT I) : 
I(std::move(I)) {}
 
  109  operator ReferenceT()
 const { 
return *I; }
 
 
  112 /// A proxy object for computing a pointer via indirecting a copy of a 
  113 /// reference. This is used in APIs which need to produce a pointer but for 
  114 /// which the reference might be a temporary. The proxy preserves the 
  115 /// reference internally and exposes the pointer via a arrow operator. 
  117 friend iterator_facade_base;
 
  121 template <
typename RefT>
 
  122 PointerProxy(RefT &&R) : R(std::forward<RefT>(R)) {}
 
 
  130 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
 
  131 "Must pass the derived type to this template!");
 
  134 "The '+' operator is only defined for random access iterators.");
 
  135 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
 
 
  139  friend DerivedT 
operator+(DifferenceTypeT n, 
const DerivedT &i) {
 
  142 "The '+' operator is only defined for random access iterators.");
 
 
  148 "The '-' operator is only defined for random access iterators.");
 
  149 DerivedT tmp = *
static_cast<const DerivedT *
>(
this);
 
 
  155 static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
 
  156 "Must pass the derived type to this template!");
 
  157 return static_cast<DerivedT *
>(
this)->
operator+=(1);
 
 
  160 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
 
  161 ++*
static_cast<DerivedT *
>(
this);
 
 
  167 "The decrement operator is only defined for bidirectional iterators.");
 
  168 return static_cast<DerivedT *
>(
this)->
operator-=(1);
 
 
  173 "The decrement operator is only defined for bidirectional iterators.");
 
  174 DerivedT tmp = *
static_cast<DerivedT *
>(
this);
 
  175 --*
static_cast<DerivedT *
>(
this);
 
 
  179#ifndef __cpp_impl_three_way_comparison 
  181 return !(
static_cast<const DerivedT &
>(*this) == 
RHS);
 
 
  188 "Relational operators are only defined for random access iterators.");
 
  189 return !(
static_cast<const DerivedT &
>(*this) < 
RHS) &&
 
  190 !(
static_cast<const DerivedT &
>(*
this) == 
RHS);
 
 
  195 "Relational operators are only defined for random access iterators.");
 
  196 return !(
static_cast<const DerivedT &
>(*this) > 
RHS);
 
 
  201 "Relational operators are only defined for random access iterators.");
 
  202 return !(
static_cast<const DerivedT &
>(*this) < 
RHS);
 
 
  206 return static_cast<const DerivedT *
>(
this)->
operator*();
 
 
  210 "Subscripting is only defined for random access iterators.");
 
  211 return static_cast<const DerivedT *
>(
this)->
operator+(n);
 
 
 
  215/// CRTP base class for adapting an iterator to a different type. 
  217/// This class can be used through CRTP to adapt one iterator into another. 
  218/// Typically this is done through providing in the derived class a custom \c 
  219/// operator* implementation. Other methods can be overridden as well. 
  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<
 
  230 typename std::iterator_traits<WrappedIteratorT>::pointer, 
T *>,
 
  231 typename ReferenceT = std::conditional_t<
 
  232 std::is_same<
T, 
typename std::iterator_traits<
 
  234 typename std::iterator_traits<WrappedIteratorT>::reference, 
T &>>
 
  237 DifferenceTypeT, PointerT, ReferenceT> {
 
  238 using BaseT = 
typename iterator_adaptor_base::iterator_facade_base;
 
  246 static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
 
  247 "Must pass the derived type to this template!");
 
 
  257 BaseT::IsRandomAccess,
 
  258 "The '+=' operator is only defined for random access iterators.");
 
  260 return *
static_cast<DerivedT *
>(
this);
 
 
  264 BaseT::IsRandomAccess,
 
  265 "The '-=' operator is only defined for random access iterators.");
 
  267 return *
static_cast<DerivedT *
>(
this);
 
 
  269 using BaseT::operator-;
 
  272 BaseT::IsRandomAccess,
 
  273 "The '-' operator is only defined for random access iterators.");
 
 
  277 // We have to explicitly provide ++ and -- rather than letting the facade 
  278 // forward to += because WrappedIteratorT might not support +=. 
  279 using BaseT::operator++;
 
  282 return *
static_cast<DerivedT *
>(
this);
 
 
  284 using BaseT::operator--;
 
  287 BaseT::IsBidirectional,
 
  288 "The decrement operator is only defined for bidirectional iterators.");
 
  290 return *
static_cast<DerivedT *
>(
this);
 
 
  300 BaseT::IsRandomAccess,
 
  301 "Relational operators are only defined for random access iterators.");
 
 
 
  308/// An iterator type that allows iterating over the pointees via some 
  311/// The typical usage of this is to expose a type that iterates over Ts, but 
  312/// which is implemented with some iterator over T*s: 
  315/// using iterator = pointee_iterator<SmallVectorImpl<T *>::iterator>; 
  318 typename T = std::remove_reference_t<
decltype(
 
  319 **std::declval<WrappedIteratorT>())>>
 
  326 template <
typename U>
 
 
  334 decltype(std::begin(std::declval<RangeT>()))>
 
  338 return make_range(PointeeIteratorT(std::begin(std::forward<RangeT>(
Range))),
 
  339 PointeeIteratorT(std::end(std::forward<RangeT>(
Range))));
 
 
  343 typename T = 
decltype(&*std::declval<WrappedIteratorT>())>
 
  361 decltype(std::begin(std::declval<RangeT>()))>
 
  365 return make_range(PointerIteratorT(std::begin(std::forward<RangeT>(
Range))),
 
  366 PointerIteratorT(std::end(std::forward<RangeT>(
Range))));
 
 
  370 typename T1 = std::remove_reference_t<
decltype(
 
  371 **std::declval<WrappedIteratorT>())>,
 
  372 typename T2 = std::add_pointer_t<T1>>
 
  376} 
// end namespace llvm 
  378#endif // LLVM_ADT_ITERATOR_H 
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
 
iterator_adaptor_base(WrappedIteratorT u)
 
const WrappedIteratorT & wrapped() const
 
DerivedT & operator+=(difference_type n)
 
iterator_adaptor_base()=default
 
difference_type operator-(const DerivedT &RHS) const
 
friend bool operator<(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
 
DerivedT & operator-=(difference_type n)
 
friend bool operator==(const iterator_adaptor_base &LHS, const iterator_adaptor_base &RHS)
 
ReferenceT operator*() const
 
typename std::iterator_traits< IteratorBase >::difference_type difference_type
 
PointerT operator->() const
 
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
 
PointerProxy operator->() const
 
IteratorCategoryT iterator_category
 
bool operator<=(const DerivedT &RHS) const
 
bool operator>=(const DerivedT &RHS) const
 
DerivedT operator-(DifferenceTypeT n) const
 
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
 
DifferenceTypeT difference_type
 
bool operator!=(const DerivedT &RHS) const
 
bool operator>(const DerivedT &RHS) const
 
DerivedT operator+(DifferenceTypeT n) const
 
ReferenceProxy operator[](DifferenceTypeT n) const
 
pointer_iterator(WrappedIteratorT u)
 
pointer_iterator()=default
 
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
 
This is an optimization pass for GlobalISel generic memory operations.
 
pointer_iterator< pointee_iterator< WrappedIteratorT, T1 >, T2 > raw_pointer_iterator
 
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
 
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
 
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
 
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
 
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
 
Implement std::hash so that hash_code can be used in STL containers.
 
An iterator type that allows iterating over the pointees via some other iterator.
 
pointee_iterator()=default