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