LLVM API Documentation
00001 //===--- ArrayRef.h - Array Reference Wrapper -------------------*- 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_ARRAYREF_H 00011 #define LLVM_ADT_ARRAYREF_H 00012 00013 #include "llvm/ADT/None.h" 00014 #include "llvm/ADT/STLExtras.h" 00015 #include "llvm/ADT/SmallVector.h" 00016 #include <vector> 00017 00018 namespace llvm { 00019 00020 /// ArrayRef - Represent a constant reference to an array (0 or more elements 00021 /// consecutively in memory), i.e. a start pointer and a length. It allows 00022 /// various APIs to take consecutive elements easily and conveniently. 00023 /// 00024 /// This class does not own the underlying data, it is expected to be used in 00025 /// situations where the data resides in some other buffer, whose lifetime 00026 /// extends past that of the ArrayRef. For this reason, it is not in general 00027 /// safe to store an ArrayRef. 00028 /// 00029 /// This is intended to be trivially copyable, so it should be passed by 00030 /// value. 00031 template<typename T> 00032 class ArrayRef { 00033 public: 00034 typedef const T *iterator; 00035 typedef const T *const_iterator; 00036 typedef size_t size_type; 00037 00038 typedef std::reverse_iterator<iterator> reverse_iterator; 00039 00040 private: 00041 /// The start of the array, in an external buffer. 00042 const T *Data; 00043 00044 /// The number of elements. 00045 size_type Length; 00046 00047 /// \brief A dummy "optional" type that is only created by implicit 00048 /// conversion from a reference to T. 00049 /// 00050 /// This type must *only* be used in a function argument or as a copy of 00051 /// a function argument, as otherwise it will hold a pointer to a temporary 00052 /// past that temporaries' lifetime. 00053 struct TRefOrNothing { 00054 const T *TPtr; 00055 00056 TRefOrNothing() : TPtr(nullptr) {} 00057 TRefOrNothing(const T &TRef) : TPtr(&TRef) {} 00058 }; 00059 00060 public: 00061 /// @name Constructors 00062 /// @{ 00063 00064 /// Construct an empty ArrayRef. 00065 /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {} 00066 00067 /// Construct an empty ArrayRef from None. 00068 /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {} 00069 00070 /// Construct an ArrayRef from a single element. 00071 /*implicit*/ ArrayRef(const T &OneElt) 00072 : Data(&OneElt), Length(1) {} 00073 00074 /// Construct an ArrayRef from a pointer and length. 00075 /*implicit*/ ArrayRef(const T *data, size_t length) 00076 : Data(data), Length(length) {} 00077 00078 /// Construct an ArrayRef from a range. 00079 ArrayRef(const T *begin, const T *end) 00080 : Data(begin), Length(end - begin) {} 00081 00082 /// Construct an ArrayRef from a SmallVector. This is templated in order to 00083 /// avoid instantiating SmallVectorTemplateCommon<T> whenever we 00084 /// copy-construct an ArrayRef. 00085 template<typename U> 00086 /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec) 00087 : Data(Vec.data()), Length(Vec.size()) { 00088 } 00089 00090 /// Construct an ArrayRef from a std::vector. 00091 template<typename A> 00092 /*implicit*/ ArrayRef(const std::vector<T, A> &Vec) 00093 : Data(Vec.data()), Length(Vec.size()) {} 00094 00095 /// Construct an ArrayRef from a C array. 00096 template <size_t N> 00097 /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N]) 00098 : Data(Arr), Length(N) {} 00099 00100 #if LLVM_HAS_INITIALIZER_LISTS 00101 /// Construct an ArrayRef from a std::initializer_list. 00102 /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec) 00103 : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()), 00104 Length(Vec.size()) {} 00105 #endif 00106 00107 /// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to 00108 /// ensure that only ArrayRefs of pointers can be converted. 00109 template <typename U> 00110 ArrayRef(const ArrayRef<U *> &A, 00111 typename std::enable_if< 00112 std::is_convertible<U *const *, T const *>::value>::type* = 0) 00113 : Data(A.data()), Length(A.size()) {} 00114 00115 /// @} 00116 /// @name Simple Operations 00117 /// @{ 00118 00119 iterator begin() const { return Data; } 00120 iterator end() const { return Data + Length; } 00121 00122 reverse_iterator rbegin() const { return reverse_iterator(end()); } 00123 reverse_iterator rend() const { return reverse_iterator(begin()); } 00124 00125 /// empty - Check if the array is empty. 00126 bool empty() const { return Length == 0; } 00127 00128 const T *data() const { return Data; } 00129 00130 /// size - Get the array size. 00131 size_t size() const { return Length; } 00132 00133 /// front - Get the first element. 00134 const T &front() const { 00135 assert(!empty()); 00136 return Data[0]; 00137 } 00138 00139 /// back - Get the last element. 00140 const T &back() const { 00141 assert(!empty()); 00142 return Data[Length-1]; 00143 } 00144 00145 // copy - Allocate copy in Allocator and return ArrayRef<T> to it. 00146 template <typename Allocator> ArrayRef<T> copy(Allocator &A) { 00147 T *Buff = A.template Allocate<T>(Length); 00148 std::copy(begin(), end(), Buff); 00149 return ArrayRef<T>(Buff, Length); 00150 } 00151 00152 /// equals - Check for element-wise equality. 00153 bool equals(ArrayRef RHS) const { 00154 if (Length != RHS.Length) 00155 return false; 00156 // Don't use std::equal(), since it asserts in MSVC on nullptr iterators. 00157 for (auto L = begin(), LE = end(), R = RHS.begin(); L != LE; ++L, ++R) 00158 // Match std::equal() in using == (instead of !=) to minimize API 00159 // requirements of ArrayRef'ed types. 00160 if (!(*L == *R)) 00161 return false; 00162 return true; 00163 } 00164 00165 /// slice(n) - Chop off the first N elements of the array. 00166 ArrayRef<T> slice(unsigned N) const { 00167 assert(N <= size() && "Invalid specifier"); 00168 return ArrayRef<T>(data()+N, size()-N); 00169 } 00170 00171 /// slice(n, m) - Chop off the first N elements of the array, and keep M 00172 /// elements in the array. 00173 ArrayRef<T> slice(unsigned N, unsigned M) const { 00174 assert(N+M <= size() && "Invalid specifier"); 00175 return ArrayRef<T>(data()+N, M); 00176 } 00177 00178 // \brief Drop the last \p N elements of the array. 00179 ArrayRef<T> drop_back(unsigned N = 1) const { 00180 assert(size() >= N && "Dropping more elements than exist"); 00181 return slice(0, size() - N); 00182 } 00183 00184 /// @} 00185 /// @name Operator Overloads 00186 /// @{ 00187 const T &operator[](size_t Index) const { 00188 assert(Index < Length && "Invalid index!"); 00189 return Data[Index]; 00190 } 00191 00192 /// @} 00193 /// @name Expensive Operations 00194 /// @{ 00195 std::vector<T> vec() const { 00196 return std::vector<T>(Data, Data+Length); 00197 } 00198 00199 /// @} 00200 /// @name Conversion operators 00201 /// @{ 00202 operator std::vector<T>() const { 00203 return std::vector<T>(Data, Data+Length); 00204 } 00205 00206 /// @} 00207 /// @{ 00208 /// @name Convenience methods 00209 00210 /// @brief Predicate for testing that the array equals the exact sequence of 00211 /// arguments. 00212 /// 00213 /// Will return false if the size is not equal to the exact number of 00214 /// arguments given or if the array elements don't equal the argument 00215 /// elements in order. Currently supports up to 16 arguments, but can 00216 /// easily be extended. 00217 bool equals(TRefOrNothing Arg0 = TRefOrNothing(), 00218 TRefOrNothing Arg1 = TRefOrNothing(), 00219 TRefOrNothing Arg2 = TRefOrNothing(), 00220 TRefOrNothing Arg3 = TRefOrNothing(), 00221 TRefOrNothing Arg4 = TRefOrNothing(), 00222 TRefOrNothing Arg5 = TRefOrNothing(), 00223 TRefOrNothing Arg6 = TRefOrNothing(), 00224 TRefOrNothing Arg7 = TRefOrNothing(), 00225 TRefOrNothing Arg8 = TRefOrNothing(), 00226 TRefOrNothing Arg9 = TRefOrNothing(), 00227 TRefOrNothing Arg10 = TRefOrNothing(), 00228 TRefOrNothing Arg11 = TRefOrNothing(), 00229 TRefOrNothing Arg12 = TRefOrNothing(), 00230 TRefOrNothing Arg13 = TRefOrNothing(), 00231 TRefOrNothing Arg14 = TRefOrNothing(), 00232 TRefOrNothing Arg15 = TRefOrNothing()) { 00233 TRefOrNothing Args[] = {Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, 00234 Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, 00235 Arg12, Arg13, Arg14, Arg15}; 00236 if (size() > array_lengthof(Args)) 00237 return false; 00238 00239 for (unsigned i = 0, e = size(); i != e; ++i) 00240 if (Args[i].TPtr == nullptr || (*this)[i] != *Args[i].TPtr) 00241 return false; 00242 00243 // Either the size is exactly as many args, or the next arg must be null. 00244 return size() == array_lengthof(Args) || Args[size()].TPtr == nullptr; 00245 } 00246 00247 /// @} 00248 }; 00249 00250 /// MutableArrayRef - Represent a mutable reference to an array (0 or more 00251 /// elements consecutively in memory), i.e. a start pointer and a length. It 00252 /// allows various APIs to take and modify consecutive elements easily and 00253 /// conveniently. 00254 /// 00255 /// This class does not own the underlying data, it is expected to be used in 00256 /// situations where the data resides in some other buffer, whose lifetime 00257 /// extends past that of the MutableArrayRef. For this reason, it is not in 00258 /// general safe to store a MutableArrayRef. 00259 /// 00260 /// This is intended to be trivially copyable, so it should be passed by 00261 /// value. 00262 template<typename T> 00263 class MutableArrayRef : public ArrayRef<T> { 00264 public: 00265 typedef T *iterator; 00266 00267 typedef std::reverse_iterator<iterator> reverse_iterator; 00268 00269 /// Construct an empty MutableArrayRef. 00270 /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} 00271 00272 /// Construct an empty MutableArrayRef from None. 00273 /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {} 00274 00275 /// Construct an MutableArrayRef from a single element. 00276 /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} 00277 00278 /// Construct an MutableArrayRef from a pointer and length. 00279 /*implicit*/ MutableArrayRef(T *data, size_t length) 00280 : ArrayRef<T>(data, length) {} 00281 00282 /// Construct an MutableArrayRef from a range. 00283 MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {} 00284 00285 /// Construct an MutableArrayRef from a SmallVector. 00286 /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec) 00287 : ArrayRef<T>(Vec) {} 00288 00289 /// Construct a MutableArrayRef from a std::vector. 00290 /*implicit*/ MutableArrayRef(std::vector<T> &Vec) 00291 : ArrayRef<T>(Vec) {} 00292 00293 /// Construct an MutableArrayRef from a C array. 00294 template <size_t N> 00295 /*implicit*/ LLVM_CONSTEXPR MutableArrayRef(T (&Arr)[N]) 00296 : ArrayRef<T>(Arr) {} 00297 00298 T *data() const { return const_cast<T*>(ArrayRef<T>::data()); } 00299 00300 iterator begin() const { return data(); } 00301 iterator end() const { return data() + this->size(); } 00302 00303 reverse_iterator rbegin() const { return reverse_iterator(end()); } 00304 reverse_iterator rend() const { return reverse_iterator(begin()); } 00305 00306 /// front - Get the first element. 00307 T &front() const { 00308 assert(!this->empty()); 00309 return data()[0]; 00310 } 00311 00312 /// back - Get the last element. 00313 T &back() const { 00314 assert(!this->empty()); 00315 return data()[this->size()-1]; 00316 } 00317 00318 /// slice(n) - Chop off the first N elements of the array. 00319 MutableArrayRef<T> slice(unsigned N) const { 00320 assert(N <= this->size() && "Invalid specifier"); 00321 return MutableArrayRef<T>(data()+N, this->size()-N); 00322 } 00323 00324 /// slice(n, m) - Chop off the first N elements of the array, and keep M 00325 /// elements in the array. 00326 MutableArrayRef<T> slice(unsigned N, unsigned M) const { 00327 assert(N+M <= this->size() && "Invalid specifier"); 00328 return MutableArrayRef<T>(data()+N, M); 00329 } 00330 00331 /// @} 00332 /// @name Operator Overloads 00333 /// @{ 00334 T &operator[](size_t Index) const { 00335 assert(Index < this->size() && "Invalid index!"); 00336 return data()[Index]; 00337 } 00338 }; 00339 00340 /// @name ArrayRef Convenience constructors 00341 /// @{ 00342 00343 /// Construct an ArrayRef from a single element. 00344 template<typename T> 00345 ArrayRef<T> makeArrayRef(const T &OneElt) { 00346 return OneElt; 00347 } 00348 00349 /// Construct an ArrayRef from a pointer and length. 00350 template<typename T> 00351 ArrayRef<T> makeArrayRef(const T *data, size_t length) { 00352 return ArrayRef<T>(data, length); 00353 } 00354 00355 /// Construct an ArrayRef from a range. 00356 template<typename T> 00357 ArrayRef<T> makeArrayRef(const T *begin, const T *end) { 00358 return ArrayRef<T>(begin, end); 00359 } 00360 00361 /// Construct an ArrayRef from a SmallVector. 00362 template <typename T> 00363 ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) { 00364 return Vec; 00365 } 00366 00367 /// Construct an ArrayRef from a SmallVector. 00368 template <typename T, unsigned N> 00369 ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) { 00370 return Vec; 00371 } 00372 00373 /// Construct an ArrayRef from a std::vector. 00374 template<typename T> 00375 ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) { 00376 return Vec; 00377 } 00378 00379 /// Construct an ArrayRef from a C array. 00380 template<typename T, size_t N> 00381 ArrayRef<T> makeArrayRef(const T (&Arr)[N]) { 00382 return ArrayRef<T>(Arr); 00383 } 00384 00385 /// @} 00386 /// @name ArrayRef Comparison Operators 00387 /// @{ 00388 00389 template<typename T> 00390 inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) { 00391 return LHS.equals(RHS); 00392 } 00393 00394 template<typename T> 00395 inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) { 00396 return !(LHS == RHS); 00397 } 00398 00399 /// @} 00400 00401 // ArrayRefs can be treated like a POD type. 00402 template <typename T> struct isPodLike; 00403 template <typename T> struct isPodLike<ArrayRef<T> > { 00404 static const bool value = true; 00405 }; 00406 } 00407 00408 #endif