1 //===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_ADT_ARRAYREF_H
11 #define LLVM_ADT_ARRAYREF_H
13 #include "llvm/ADT/None.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/Support/Allocator.h"
20 /// ArrayRef - Represent a constant reference to an array (0 or more elements
21 /// consecutively in memory), i.e. a start pointer and a length. It allows
22 /// various APIs to take consecutive elements easily and conveniently.
24 /// This class does not own the underlying data, it is expected to be used in
25 /// situations where the data resides in some other buffer, whose lifetime
26 /// extends past that of the ArrayRef. For this reason, it is not in general
27 /// safe to store an ArrayRef.
29 /// This is intended to be trivially copyable, so it should be passed by
34 typedef const T *iterator;
35 typedef const T *const_iterator;
36 typedef size_t size_type;
38 typedef std::reverse_iterator<iterator> reverse_iterator;
41 /// The start of the array, in an external buffer.
44 /// The number of elements.
48 /// @name Constructors
51 /// Construct an empty ArrayRef.
52 /*implicit*/ ArrayRef() : Data(0), Length(0) {}
54 /// Construct an empty ArrayRef from None.
55 /*implicit*/ ArrayRef(NoneType) : Data(0), Length(0) {}
57 /// Construct an ArrayRef from a single element.
58 /*implicit*/ ArrayRef(const T &OneElt)
59 : Data(&OneElt), Length(1) {}
61 /// Construct an ArrayRef from a pointer and length.
62 /*implicit*/ ArrayRef(const T *data, size_t length)
63 : Data(data), Length(length) {}
65 /// Construct an ArrayRef from a range.
66 ArrayRef(const T *begin, const T *end)
67 : Data(begin), Length(end - begin) {}
69 /// Construct an ArrayRef from a SmallVector. This is templated in order to
70 /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
71 /// copy-construct an ArrayRef.
73 /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
74 : Data(Vec.data()), Length(Vec.size()) {
77 /// Construct an ArrayRef from a std::vector.
79 /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
80 : Data(Vec.data()), Length(Vec.size()) {}
82 /// Construct an ArrayRef from a C array.
84 /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N])
85 : Data(Arr), Length(N) {}
87 #if LLVM_HAS_INITIALIZER_LISTS
88 /// Construct an ArrayRef from a std::initializer_list.
89 /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
90 : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()),
95 /// @name Simple Operations
98 iterator begin() const { return Data; }
99 iterator end() const { return Data + Length; }
101 reverse_iterator rbegin() const { return reverse_iterator(end()); }
102 reverse_iterator rend() const { return reverse_iterator(begin()); }
104 /// empty - Check if the array is empty.
105 bool empty() const { return Length == 0; }
107 const T *data() const { return Data; }
109 /// size - Get the array size.
110 size_t size() const { return Length; }
112 /// front - Get the first element.
113 const T &front() const {
118 /// back - Get the last element.
119 const T &back() const {
121 return Data[Length-1];
124 // copy - Allocate copy in BumpPtrAllocator and return ArrayRef<T> to it.
125 ArrayRef<T> copy(BumpPtrAllocator &Allocator) {
126 T *Buff = Allocator.Allocate<T>(Length);
127 std::copy(begin(), end(), Buff);
128 return ArrayRef<T>(Buff, Length);
131 /// equals - Check for element-wise equality.
132 bool equals(ArrayRef RHS) const {
133 if (Length != RHS.Length)
135 for (size_type i = 0; i != Length; i++)
136 if (Data[i] != RHS.Data[i])
141 /// slice(n) - Chop off the first N elements of the array.
142 ArrayRef<T> slice(unsigned N) const {
143 assert(N <= size() && "Invalid specifier");
144 return ArrayRef<T>(data()+N, size()-N);
147 /// slice(n, m) - Chop off the first N elements of the array, and keep M
148 /// elements in the array.
149 ArrayRef<T> slice(unsigned N, unsigned M) const {
150 assert(N+M <= size() && "Invalid specifier");
151 return ArrayRef<T>(data()+N, M);
155 /// @name Operator Overloads
157 const T &operator[](size_t Index) const {
158 assert(Index < Length && "Invalid index!");
163 /// @name Expensive Operations
165 std::vector<T> vec() const {
166 return std::vector<T>(Data, Data+Length);
170 /// @name Conversion operators
172 operator std::vector<T>() const {
173 return std::vector<T>(Data, Data+Length);
179 /// MutableArrayRef - Represent a mutable reference to an array (0 or more
180 /// elements consecutively in memory), i.e. a start pointer and a length. It
181 /// allows various APIs to take and modify consecutive elements easily and
184 /// This class does not own the underlying data, it is expected to be used in
185 /// situations where the data resides in some other buffer, whose lifetime
186 /// extends past that of the MutableArrayRef. For this reason, it is not in
187 /// general safe to store a MutableArrayRef.
189 /// This is intended to be trivially copyable, so it should be passed by
192 class MutableArrayRef : public ArrayRef<T> {
196 typedef std::reverse_iterator<iterator> reverse_iterator;
198 /// Construct an empty MutableArrayRef.
199 /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
201 /// Construct an empty MutableArrayRef from None.
202 /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}
204 /// Construct an MutableArrayRef from a single element.
205 /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
207 /// Construct an MutableArrayRef from a pointer and length.
208 /*implicit*/ MutableArrayRef(T *data, size_t length)
209 : ArrayRef<T>(data, length) {}
211 /// Construct an MutableArrayRef from a range.
212 MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
214 /// Construct an MutableArrayRef from a SmallVector.
215 /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
216 : ArrayRef<T>(Vec) {}
218 /// Construct a MutableArrayRef from a std::vector.
219 /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
220 : ArrayRef<T>(Vec) {}
222 /// Construct an MutableArrayRef from a C array.
224 /*implicit*/ MutableArrayRef(T (&Arr)[N])
225 : ArrayRef<T>(Arr) {}
227 T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
229 iterator begin() const { return data(); }
230 iterator end() const { return data() + this->size(); }
232 reverse_iterator rbegin() const { return reverse_iterator(end()); }
233 reverse_iterator rend() const { return reverse_iterator(begin()); }
235 /// front - Get the first element.
237 assert(!this->empty());
241 /// back - Get the last element.
243 assert(!this->empty());
244 return data()[this->size()-1];
247 /// slice(n) - Chop off the first N elements of the array.
248 MutableArrayRef<T> slice(unsigned N) const {
249 assert(N <= this->size() && "Invalid specifier");
250 return MutableArrayRef<T>(data()+N, this->size()-N);
253 /// slice(n, m) - Chop off the first N elements of the array, and keep M
254 /// elements in the array.
255 MutableArrayRef<T> slice(unsigned N, unsigned M) const {
256 assert(N+M <= this->size() && "Invalid specifier");
257 return MutableArrayRef<T>(data()+N, M);
261 /// @name Operator Overloads
263 T &operator[](size_t Index) const {
264 assert(Index < this->size() && "Invalid index!");
265 return data()[Index];
269 /// @name ArrayRef Convenience constructors
272 /// Construct an ArrayRef from a single element.
274 ArrayRef<T> makeArrayRef(const T &OneElt) {
278 /// Construct an ArrayRef from a pointer and length.
280 ArrayRef<T> makeArrayRef(const T *data, size_t length) {
281 return ArrayRef<T>(data, length);
284 /// Construct an ArrayRef from a range.
286 ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
287 return ArrayRef<T>(begin, end);
290 /// Construct an ArrayRef from a SmallVector.
291 template <typename T>
292 ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
296 /// Construct an ArrayRef from a SmallVector.
297 template <typename T, unsigned N>
298 ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
302 /// Construct an ArrayRef from a std::vector.
304 ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
308 /// Construct an ArrayRef from a C array.
309 template<typename T, size_t N>
310 ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
311 return ArrayRef<T>(Arr);
315 /// @name ArrayRef Comparison Operators
319 inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
320 return LHS.equals(RHS);
324 inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
325 return !(LHS == RHS);
330 // ArrayRefs can be treated like a POD type.
331 template <typename T> struct isPodLike;
332 template <typename T> struct isPodLike<ArrayRef<T> > {
333 static const bool value = true;