1 //===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_ADT_ARRAYREF_H 11 #define LLVM_ADT_ARRAYREF_H 12 13 #include "llvm/ADT/SmallVector.h" 14 #include <vector> 15 16 namespace llvm { 17 18 /// ArrayRef - Represent a constant reference to an array (0 or more elements 19 /// consecutively in memory), i.e. a start pointer and a length. It allows 20 /// various APIs to take consecutive elements easily and conveniently. 21 /// 22 /// This class does not own the underlying data, it is expected to be used in 23 /// situations where the data resides in some other buffer, whose lifetime 24 /// extends past that of the ArrayRef. For this reason, it is not in general 25 /// safe to store an ArrayRef. 26 /// 27 /// This is intended to be trivially copyable, so it should be passed by 28 /// value. 29 template<typename T> 30 class ArrayRef { 31 public: 32 typedef const T *iterator; 33 typedef const T *const_iterator; 34 typedef size_t size_type; 35 36 private: 37 /// The start of the array, in an external buffer. 38 const T *Data; 39 40 /// The number of elements. 41 size_type Length; 42 43 public: 44 /// @name Constructors 45 /// @{ 46 47 /// Construct an empty ArrayRef. ArrayRef()48 /*implicit*/ ArrayRef() : Data(0), Length(0) {} 49 50 /// Construct an ArrayRef from a single element. ArrayRef(const T & OneElt)51 /*implicit*/ ArrayRef(const T &OneElt) 52 : Data(&OneElt), Length(1) {} 53 54 /// Construct an ArrayRef from a pointer and length. ArrayRef(const T * data,size_t length)55 /*implicit*/ ArrayRef(const T *data, size_t length) 56 : Data(data), Length(length) {} 57 58 /// Construct an ArrayRef from a range. ArrayRef(const T * begin,const T * end)59 ArrayRef(const T *begin, const T *end) 60 : Data(begin), Length(end - begin) {} 61 62 /// Construct an ArrayRef from a SmallVector. This is templated in order to 63 /// avoid instantiating SmallVectorTemplateCommon<T> whenever we 64 /// copy-construct an ArrayRef. 65 template<typename U> ArrayRef(const SmallVectorTemplateCommon<T,U> & Vec)66 /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec) 67 : Data(Vec.data()), Length(Vec.size()) { 68 } 69 70 /// Construct an ArrayRef from a std::vector. 71 template<typename A> ArrayRef(const std::vector<T,A> & Vec)72 /*implicit*/ ArrayRef(const std::vector<T, A> &Vec) 73 : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {} 74 75 /// Construct an ArrayRef from a C array. 76 template <size_t N> ArrayRef(const T (& Arr)[N])77 /*implicit*/ ArrayRef(const T (&Arr)[N]) 78 : Data(Arr), Length(N) {} 79 80 /// @} 81 /// @name Simple Operations 82 /// @{ 83 begin()84 iterator begin() const { return Data; } end()85 iterator end() const { return Data + Length; } 86 87 /// empty - Check if the array is empty. empty()88 bool empty() const { return Length == 0; } 89 data()90 const T *data() const { return Data; } 91 92 /// size - Get the array size. size()93 size_t size() const { return Length; } 94 95 /// front - Get the first element. front()96 const T &front() const { 97 assert(!empty()); 98 return Data[0]; 99 } 100 101 /// back - Get the last element. back()102 const T &back() const { 103 assert(!empty()); 104 return Data[Length-1]; 105 } 106 107 /// equals - Check for element-wise equality. equals(ArrayRef RHS)108 bool equals(ArrayRef RHS) const { 109 if (Length != RHS.Length) 110 return false; 111 for (size_type i = 0; i != Length; i++) 112 if (Data[i] != RHS.Data[i]) 113 return false; 114 return true; 115 } 116 117 /// slice(n) - Chop off the first N elements of the array. slice(unsigned N)118 ArrayRef<T> slice(unsigned N) const { 119 assert(N <= size() && "Invalid specifier"); 120 return ArrayRef<T>(data()+N, size()-N); 121 } 122 123 /// slice(n, m) - Chop off the first N elements of the array, and keep M 124 /// elements in the array. slice(unsigned N,unsigned M)125 ArrayRef<T> slice(unsigned N, unsigned M) const { 126 assert(N+M <= size() && "Invalid specifier"); 127 return ArrayRef<T>(data()+N, M); 128 } 129 130 /// @} 131 /// @name Operator Overloads 132 /// @{ 133 const T &operator[](size_t Index) const { 134 assert(Index < Length && "Invalid index!"); 135 return Data[Index]; 136 } 137 138 /// @} 139 /// @name Expensive Operations 140 /// @{ vec()141 std::vector<T> vec() const { 142 return std::vector<T>(Data, Data+Length); 143 } 144 145 /// @} 146 /// @name Conversion operators 147 /// @{ 148 operator std::vector<T>() const { 149 return std::vector<T>(Data, Data+Length); 150 } 151 152 /// @} 153 }; 154 155 /// MutableArrayRef - Represent a mutable reference to an array (0 or more 156 /// elements consecutively in memory), i.e. a start pointer and a length. It 157 /// allows various APIs to take and modify consecutive elements easily and 158 /// conveniently. 159 /// 160 /// This class does not own the underlying data, it is expected to be used in 161 /// situations where the data resides in some other buffer, whose lifetime 162 /// extends past that of the MutableArrayRef. For this reason, it is not in 163 /// general safe to store a MutableArrayRef. 164 /// 165 /// This is intended to be trivially copyable, so it should be passed by 166 /// value. 167 template<typename T> 168 class MutableArrayRef : public ArrayRef<T> { 169 public: 170 typedef T *iterator; 171 172 /// Construct an empty ArrayRef. MutableArrayRef()173 /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} 174 175 /// Construct an MutableArrayRef from a single element. MutableArrayRef(T & OneElt)176 /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} 177 178 /// Construct an MutableArrayRef from a pointer and length. MutableArrayRef(T * data,size_t length)179 /*implicit*/ MutableArrayRef(T *data, size_t length) 180 : ArrayRef<T>(data, length) {} 181 182 /// Construct an MutableArrayRef from a range. MutableArrayRef(T * begin,T * end)183 MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {} 184 185 /// Construct an MutableArrayRef from a SmallVector. MutableArrayRef(SmallVectorImpl<T> & Vec)186 /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec) 187 : ArrayRef<T>(Vec) {} 188 189 /// Construct a MutableArrayRef from a std::vector. MutableArrayRef(std::vector<T> & Vec)190 /*implicit*/ MutableArrayRef(std::vector<T> &Vec) 191 : ArrayRef<T>(Vec) {} 192 193 /// Construct an MutableArrayRef from a C array. 194 template <size_t N> MutableArrayRef(T (& Arr)[N])195 /*implicit*/ MutableArrayRef(T (&Arr)[N]) 196 : ArrayRef<T>(Arr) {} 197 data()198 T *data() const { return const_cast<T*>(ArrayRef<T>::data()); } 199 begin()200 iterator begin() const { return data(); } end()201 iterator end() const { return data() + this->size(); } 202 203 /// front - Get the first element. front()204 T &front() const { 205 assert(!this->empty()); 206 return data()[0]; 207 } 208 209 /// back - Get the last element. back()210 T &back() const { 211 assert(!this->empty()); 212 return data()[this->size()-1]; 213 } 214 215 /// slice(n) - Chop off the first N elements of the array. slice(unsigned N)216 MutableArrayRef<T> slice(unsigned N) const { 217 assert(N <= this->size() && "Invalid specifier"); 218 return MutableArrayRef<T>(data()+N, this->size()-N); 219 } 220 221 /// slice(n, m) - Chop off the first N elements of the array, and keep M 222 /// elements in the array. slice(unsigned N,unsigned M)223 MutableArrayRef<T> slice(unsigned N, unsigned M) const { 224 assert(N+M <= this->size() && "Invalid specifier"); 225 return MutableArrayRef<T>(data()+N, M); 226 } 227 228 /// @} 229 /// @name Operator Overloads 230 /// @{ 231 T &operator[](size_t Index) const { 232 assert(Index < this->size() && "Invalid index!"); 233 return data()[Index]; 234 } 235 }; 236 237 /// @name ArrayRef Convenience constructors 238 /// @{ 239 240 /// Construct an ArrayRef from a single element. 241 template<typename T> makeArrayRef(const T & OneElt)242 ArrayRef<T> makeArrayRef(const T &OneElt) { 243 return OneElt; 244 } 245 246 /// Construct an ArrayRef from a pointer and length. 247 template<typename T> makeArrayRef(const T * data,size_t length)248 ArrayRef<T> makeArrayRef(const T *data, size_t length) { 249 return ArrayRef<T>(data, length); 250 } 251 252 /// Construct an ArrayRef from a range. 253 template<typename T> makeArrayRef(const T * begin,const T * end)254 ArrayRef<T> makeArrayRef(const T *begin, const T *end) { 255 return ArrayRef<T>(begin, end); 256 } 257 258 /// Construct an ArrayRef from a SmallVector. 259 template <typename T> makeArrayRef(const SmallVectorImpl<T> & Vec)260 ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) { 261 return Vec; 262 } 263 264 /// Construct an ArrayRef from a SmallVector. 265 template <typename T, unsigned N> makeArrayRef(const SmallVector<T,N> & Vec)266 ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) { 267 return Vec; 268 } 269 270 /// Construct an ArrayRef from a std::vector. 271 template<typename T> makeArrayRef(const std::vector<T> & Vec)272 ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) { 273 return Vec; 274 } 275 276 /// Construct an ArrayRef from a C array. 277 template<typename T, size_t N> makeArrayRef(const T (& Arr)[N])278 ArrayRef<T> makeArrayRef(const T (&Arr)[N]) { 279 return ArrayRef<T>(Arr); 280 } 281 282 /// @} 283 /// @name ArrayRef Comparison Operators 284 /// @{ 285 286 template<typename T> 287 inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) { 288 return LHS.equals(RHS); 289 } 290 291 template<typename T> 292 inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) { 293 return !(LHS == RHS); 294 } 295 296 /// @} 297 298 // ArrayRefs can be treated like a POD type. 299 template <typename T> struct isPodLike; 300 template <typename T> struct isPodLike<ArrayRef<T> > { 301 static const bool value = true; 302 }; 303 } 304 305 #endif 306