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 class APInt; 18 19 /// ArrayRef - Represent a constant reference to an array (0 or more elements 20 /// consecutively in memory), i.e. a start pointer and a length. It allows 21 /// various APIs to take consecutive elements easily and conveniently. 22 /// 23 /// This class does not own the underlying data, it is expected to be used in 24 /// situations where the data resides in some other buffer, whose lifetime 25 /// extends past that of the ArrayRef. For this reason, it is not in general 26 /// safe to store an ArrayRef. 27 /// 28 /// This is intended to be trivially copyable, so it should be passed by 29 /// value. 30 template<typename T> 31 class ArrayRef { 32 public: 33 typedef const T *iterator; 34 typedef const T *const_iterator; 35 typedef size_t size_type; 36 37 private: 38 /// The start of the array, in an external buffer. 39 const T *Data; 40 41 /// The number of elements. 42 size_type Length; 43 44 public: 45 /// @name Constructors 46 /// @{ 47 48 /// Construct an empty ArrayRef. ArrayRef()49 /*implicit*/ ArrayRef() : Data(0), Length(0) {} 50 51 /// Construct an ArrayRef from a single element. ArrayRef(const T & OneElt)52 /*implicit*/ ArrayRef(const T &OneElt) 53 : Data(&OneElt), Length(1) {} 54 55 /// Construct an ArrayRef from a pointer and length. ArrayRef(const T * data,size_t length)56 /*implicit*/ ArrayRef(const T *data, size_t length) 57 : Data(data), Length(length) {} 58 59 /// Construct an ArrayRef from a range. ArrayRef(const T * begin,const T * end)60 ArrayRef(const T *begin, const T *end) 61 : Data(begin), Length(end - begin) {} 62 63 /// Construct an ArrayRef from a SmallVector. ArrayRef(const SmallVectorImpl<T> & Vec)64 /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec) 65 : Data(Vec.data()), Length(Vec.size()) {} 66 67 /// Construct an ArrayRef from a std::vector. ArrayRef(const std::vector<T> & Vec)68 /*implicit*/ ArrayRef(const std::vector<T> &Vec) 69 : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {} 70 71 /// Construct an ArrayRef from a C array. 72 template <size_t N> ArrayRef(const T (& Arr)[N])73 /*implicit*/ ArrayRef(const T (&Arr)[N]) 74 : Data(Arr), Length(N) {} 75 76 /// @} 77 /// @name Simple Operations 78 /// @{ 79 begin()80 iterator begin() const { return Data; } end()81 iterator end() const { return Data + Length; } 82 83 /// empty - Check if the array is empty. empty()84 bool empty() const { return Length == 0; } 85 data()86 const T *data() const { return Data; } 87 88 /// size - Get the array size. size()89 size_t size() const { return Length; } 90 91 /// front - Get the first element. front()92 const T &front() const { 93 assert(!empty()); 94 return Data[0]; 95 } 96 97 /// back - Get the last element. back()98 const T &back() const { 99 assert(!empty()); 100 return Data[Length-1]; 101 } 102 103 /// equals - Check for element-wise equality. equals(ArrayRef RHS)104 bool equals(ArrayRef RHS) const { 105 if (Length != RHS.Length) 106 return false; 107 for (size_type i = 0; i != Length; i++) 108 if (Data[i] != RHS.Data[i]) 109 return false; 110 return true; 111 } 112 113 /// slice(n) - Chop off the first N elements of the array. slice(unsigned N)114 ArrayRef<T> slice(unsigned N) { 115 assert(N <= size() && "Invalid specifier"); 116 return ArrayRef<T>(data()+N, size()-N); 117 } 118 119 /// slice(n, m) - Chop off the first N elements of the array, and keep M 120 /// elements in the array. slice(unsigned N,unsigned M)121 ArrayRef<T> slice(unsigned N, unsigned M) { 122 assert(N+M <= size() && "Invalid specifier"); 123 return ArrayRef<T>(data()+N, M); 124 } 125 126 /// @} 127 /// @name Operator Overloads 128 /// @{ 129 const T &operator[](size_t Index) const { 130 assert(Index < Length && "Invalid index!"); 131 return Data[Index]; 132 } 133 134 /// @} 135 /// @name Expensive Operations 136 /// @{ vec()137 std::vector<T> vec() const { 138 return std::vector<T>(Data, Data+Length); 139 } 140 141 /// @} 142 /// @name Conversion operators 143 /// @{ 144 operator std::vector<T>() const { 145 return std::vector<T>(Data, Data+Length); 146 } 147 148 /// @} 149 }; 150 151 /// @name ArrayRef Convenience constructors 152 /// @{ 153 154 /// Construct an ArrayRef from a single element. 155 template<typename T> makeArrayRef(const T & OneElt)156 ArrayRef<T> makeArrayRef(const T &OneElt) { 157 return OneElt; 158 } 159 160 /// Construct an ArrayRef from a pointer and length. 161 template<typename T> makeArrayRef(const T * data,size_t length)162 ArrayRef<T> makeArrayRef(const T *data, size_t length) { 163 return ArrayRef<T>(data, length); 164 } 165 166 /// Construct an ArrayRef from a range. 167 template<typename T> makeArrayRef(const T * begin,const T * end)168 ArrayRef<T> makeArrayRef(const T *begin, const T *end) { 169 return ArrayRef<T>(begin, end); 170 } 171 172 /// Construct an ArrayRef from a SmallVector. 173 template <typename T> makeArrayRef(const SmallVectorImpl<T> & Vec)174 ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) { 175 return Vec; 176 } 177 178 /// Construct an ArrayRef from a SmallVector. 179 template <typename T, unsigned N> makeArrayRef(const SmallVector<T,N> & Vec)180 ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) { 181 return Vec; 182 } 183 184 /// Construct an ArrayRef from a std::vector. 185 template<typename T> makeArrayRef(const std::vector<T> & Vec)186 ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) { 187 return Vec; 188 } 189 190 /// Construct an ArrayRef from a C array. 191 template<typename T, size_t N> makeArrayRef(const T (& Arr)[N])192 ArrayRef<T> makeArrayRef(const T (&Arr)[N]) { 193 return ArrayRef<T>(Arr); 194 } 195 196 /// @} 197 /// @name ArrayRef Comparison Operators 198 /// @{ 199 200 template<typename T> 201 inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) { 202 return LHS.equals(RHS); 203 } 204 205 template<typename T> 206 inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) { 207 return !(LHS == RHS); 208 } 209 210 /// @} 211 212 // ArrayRefs can be treated like a POD type. 213 template <typename T> struct isPodLike; 214 template <typename T> struct isPodLike<ArrayRef<T> > { 215 static const bool value = true; 216 }; 217 } 218 219 #endif 220