Reduce alignment of SmallVector<T> to the required amount, rather than forcing 16...
[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   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.
48     /*implicit*/ ArrayRef() : Data(0), Length(0) {}
49
50     /// Construct an ArrayRef from a single element.
51     /*implicit*/ ArrayRef(const T &OneElt)
52       : Data(&OneElt), Length(1) {}
53
54     /// Construct an ArrayRef from a pointer and length.
55     /*implicit*/ ArrayRef(const T *data, size_t length)
56       : Data(data), Length(length) {}
57
58     /// Construct an ArrayRef from a range.
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>
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>
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>
77     /*implicit*/ ArrayRef(const T (&Arr)[N])
78       : Data(Arr), Length(N) {}
79
80     /// @}
81     /// @name Simple Operations
82     /// @{
83
84     iterator begin() const { return Data; }
85     iterator end() const { return Data + Length; }
86
87     /// empty - Check if the array is empty.
88     bool empty() const { return Length == 0; }
89
90     const T *data() const { return Data; }
91
92     /// size - Get the array size.
93     size_t size() const { return Length; }
94
95     /// front - Get the first element.
96     const T &front() const {
97       assert(!empty());
98       return Data[0];
99     }
100
101     /// back - Get the last element.
102     const T &back() const {
103       assert(!empty());
104       return Data[Length-1];
105     }
106
107     /// equals - Check for element-wise equality.
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.
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.
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     /// @{
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.
173     /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
174     
175     /// Construct an MutableArrayRef from a single element.
176     /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
177     
178     /// Construct an MutableArrayRef from a pointer and length.
179     /*implicit*/ MutableArrayRef(T *data, size_t length)
180       : ArrayRef<T>(data, length) {}
181     
182     /// Construct an MutableArrayRef from a range.
183     MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
184     
185     /// Construct an MutableArrayRef from a SmallVector.
186     /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
187     : ArrayRef<T>(Vec) {}
188     
189     /// Construct a MutableArrayRef from a std::vector.
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>
195     /*implicit*/ MutableArrayRef(T (&Arr)[N])
196       : ArrayRef<T>(Arr) {}
197     
198     T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
199
200     iterator begin() const { return data(); }
201     iterator end() const { return data() + this->size(); }
202     
203     /// front - Get the first element.
204     T &front() const {
205       assert(!this->empty());
206       return data()[0];
207     }
208     
209     /// back - Get the last element.
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.
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.
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>
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>
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>
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>
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>
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>
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>
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