LLVM API Documentation
00001 //===- iterator.h - Utilities for using and defining iterators --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_ADT_ITERATOR_H 00011 #define LLVM_ADT_ITERATOR_H 00012 00013 #include <iterator> 00014 #include <cstddef> 00015 00016 namespace llvm { 00017 00018 /// \brief CRTP base class which implements the entire standard iterator facade 00019 /// in terms of a minimal subset of the interface. 00020 /// 00021 /// Use this when it is reasonable to implement most of the iterator 00022 /// functionality in terms of a core subset. If you need special behavior or 00023 /// there are performance implications for this, you may want to override the 00024 /// relevant members instead. 00025 /// 00026 /// Note, one abstraction that this does *not* provide is implementing 00027 /// subtraction in terms of addition by negating the difference. Negation isn't 00028 /// always information preserving, and I can see very reasonable iterator 00029 /// designs where this doesn't work well. It doesn't really force much added 00030 /// boilerplate anyways. 00031 /// 00032 /// Another abstraction that this doesn't provide is implementing increment in 00033 /// terms of addition of one. These aren't equivalent for all iterator 00034 /// categories, and respecting that adds a lot of complexity for little gain. 00035 template <typename DerivedT, typename IteratorCategoryT, typename T, 00036 typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T *, 00037 typename ReferenceT = T &> 00038 class iterator_facade_base 00039 : public std::iterator<IteratorCategoryT, T, DifferenceTypeT, PointerT, 00040 ReferenceT> { 00041 protected: 00042 enum { 00043 IsRandomAccess = 00044 std::is_base_of<std::random_access_iterator_tag, IteratorCategoryT>::value, 00045 IsBidirectional = 00046 std::is_base_of<std::bidirectional_iterator_tag, IteratorCategoryT>::value, 00047 }; 00048 00049 public: 00050 DerivedT operator+(DifferenceTypeT n) const { 00051 static_assert( 00052 IsRandomAccess, 00053 "The '+' operator is only defined for random access iterators."); 00054 DerivedT tmp = *static_cast<const DerivedT *>(this); 00055 tmp += n; 00056 return tmp; 00057 } 00058 friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i) { 00059 static_assert( 00060 IsRandomAccess, 00061 "The '+' operator is only defined for random access iterators."); 00062 return i + n; 00063 } 00064 DerivedT operator-(DifferenceTypeT n) const { 00065 static_assert( 00066 IsRandomAccess, 00067 "The '-' operator is only defined for random access iterators."); 00068 DerivedT tmp = *static_cast<const DerivedT *>(this); 00069 tmp -= n; 00070 return tmp; 00071 } 00072 00073 DerivedT &operator++() { 00074 return static_cast<DerivedT *>(this)->operator+=(1); 00075 } 00076 DerivedT operator++(int) { 00077 DerivedT tmp = *static_cast<DerivedT *>(this); 00078 ++*static_cast<DerivedT *>(this); 00079 return tmp; 00080 } 00081 DerivedT &operator--() { 00082 static_assert( 00083 IsBidirectional, 00084 "The decrement operator is only defined for bidirectional iterators."); 00085 return static_cast<DerivedT *>(this)->operator-=(1); 00086 } 00087 DerivedT operator--(int) { 00088 static_assert( 00089 IsBidirectional, 00090 "The decrement operator is only defined for bidirectional iterators."); 00091 DerivedT tmp = *static_cast<DerivedT *>(this); 00092 --*static_cast<DerivedT *>(this); 00093 return tmp; 00094 } 00095 00096 bool operator!=(const DerivedT &RHS) const { 00097 return !static_cast<const DerivedT *>(this)->operator==(RHS); 00098 } 00099 00100 bool operator>(const DerivedT &RHS) const { 00101 static_assert( 00102 IsRandomAccess, 00103 "Relational operators are only defined for random access iterators."); 00104 return !static_cast<const DerivedT *>(this)->operator<(RHS) && 00105 !static_cast<const DerivedT *>(this)->operator==(RHS); 00106 } 00107 bool operator<=(const DerivedT &RHS) const { 00108 static_assert( 00109 IsRandomAccess, 00110 "Relational operators are only defined for random access iterators."); 00111 return !static_cast<const DerivedT *>(this)->operator>(RHS); 00112 } 00113 bool operator>=(const DerivedT &RHS) const { 00114 static_assert( 00115 IsRandomAccess, 00116 "Relational operators are only defined for random access iterators."); 00117 return !static_cast<const DerivedT *>(this)->operator<(RHS); 00118 } 00119 00120 PointerT operator->() const { 00121 return &static_cast<const DerivedT *>(this)->operator*(); 00122 } 00123 ReferenceT operator[](DifferenceTypeT n) const { 00124 static_assert(IsRandomAccess, 00125 "Subscripting is only defined for random access iterators."); 00126 return *static_cast<const DerivedT *>(this)->operator+(n); 00127 } 00128 }; 00129 00130 /// \brief CRTP base class for adapting an iterator to a different type. 00131 /// 00132 /// This class can be used through CRTP to adapt one iterator into another. 00133 /// Typically this is done through providing in the derived class a custom \c 00134 /// operator* implementation. Other methods can be overridden as well. 00135 template < 00136 typename DerivedT, typename WrappedIteratorT, 00137 typename IteratorCategoryT = 00138 typename std::iterator_traits<WrappedIteratorT>::iterator_category, 00139 typename T = typename std::iterator_traits<WrappedIteratorT>::value_type, 00140 typename DifferenceTypeT = 00141 typename std::iterator_traits<WrappedIteratorT>::difference_type, 00142 typename PointerT = T *, typename ReferenceT = T &, 00143 // Don't provide these, they are mostly to act as aliases below. 00144 typename WrappedTraitsT = std::iterator_traits<WrappedIteratorT>> 00145 class iterator_adaptor_base 00146 : public iterator_facade_base<DerivedT, IteratorCategoryT, T, 00147 DifferenceTypeT, PointerT, ReferenceT> { 00148 typedef typename iterator_adaptor_base::iterator_facade_base BaseT; 00149 00150 protected: 00151 WrappedIteratorT I; 00152 00153 iterator_adaptor_base() {} 00154 00155 template <typename U> 00156 explicit iterator_adaptor_base( 00157 U &&u, 00158 typename std::enable_if< 00159 !std::is_base_of<typename std::remove_cv< 00160 typename std::remove_reference<U>::type>::type, 00161 DerivedT>::value, 00162 int>::type = 0) 00163 : I(std::forward<U &&>(u)) {} 00164 00165 public: 00166 typedef DifferenceTypeT difference_type; 00167 00168 DerivedT &operator+=(difference_type n) { 00169 static_assert( 00170 BaseT::IsRandomAccess, 00171 "The '+=' operator is only defined for random access iterators."); 00172 I += n; 00173 return *static_cast<DerivedT *>(this); 00174 } 00175 DerivedT &operator-=(difference_type n) { 00176 static_assert( 00177 BaseT::IsRandomAccess, 00178 "The '-=' operator is only defined for random access iterators."); 00179 I -= n; 00180 return *static_cast<DerivedT *>(this); 00181 } 00182 using BaseT::operator-; 00183 difference_type operator-(const DerivedT &RHS) const { 00184 static_assert( 00185 BaseT::IsRandomAccess, 00186 "The '-' operator is only defined for random access iterators."); 00187 return I - RHS.I; 00188 } 00189 00190 // We have to explicitly provide ++ and -- rather than letting the facade 00191 // forward to += because WrappedIteratorT might not support +=. 00192 using BaseT::operator++; 00193 DerivedT &operator++() { 00194 ++I; 00195 return *static_cast<DerivedT *>(this); 00196 } 00197 using BaseT::operator--; 00198 DerivedT &operator--() { 00199 static_assert( 00200 BaseT::IsBidirectional, 00201 "The decrement operator is only defined for bidirectional iterators."); 00202 --I; 00203 return *static_cast<DerivedT *>(this); 00204 } 00205 00206 bool operator==(const DerivedT &RHS) const { return I == RHS.I; } 00207 bool operator<(const DerivedT &RHS) const { 00208 static_assert( 00209 BaseT::IsRandomAccess, 00210 "Relational operators are only defined for random access iterators."); 00211 return I < RHS.I; 00212 } 00213 00214 ReferenceT operator*() const { return *I; } 00215 }; 00216 00217 /// \brief An iterator type that allows iterating over the pointees via some 00218 /// other iterator. 00219 /// 00220 /// The typical usage of this is to expose a type that iterates over Ts, but 00221 /// which is implemented with some iterator over T*s: 00222 /// 00223 /// \code 00224 /// typedef pointee_iterator<SmallVectorImpl<T *>::iterator> iterator; 00225 /// \endcode 00226 template <typename WrappedIteratorT, 00227 typename T = typename std::remove_reference< 00228 decltype(**std::declval<WrappedIteratorT>())>::type> 00229 struct pointee_iterator 00230 : iterator_adaptor_base< 00231 pointee_iterator<WrappedIteratorT>, WrappedIteratorT, 00232 typename std::iterator_traits<WrappedIteratorT>::iterator_category, 00233 T> { 00234 pointee_iterator() {} 00235 template <typename U> 00236 pointee_iterator(U &&u) 00237 : pointee_iterator::iterator_adaptor_base(std::forward<U &&>(u)) {} 00238 00239 T &operator*() const { return **this->I; } 00240 }; 00241 00242 } 00243 00244 #endif