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/Hashing.h" |
14 | #include "llvm/ADT/None.h" |
15 | #include "llvm/ADT/STLExtras.h" |
16 | #include "llvm/ADT/SmallVector.h" |
17 | #include <array> |
18 | #include <vector> |
19 | |
20 | namespace llvm { |
21 | /// ArrayRef - Represent a constant reference to an array (0 or more elements |
22 | /// consecutively in memory), i.e. a start pointer and a length. It allows |
23 | /// various APIs to take consecutive elements easily and conveniently. |
24 | /// |
25 | /// This class does not own the underlying data, it is expected to be used in |
26 | /// situations where the data resides in some other buffer, whose lifetime |
27 | /// extends past that of the ArrayRef. For this reason, it is not in general |
28 | /// safe to store an ArrayRef. |
29 | /// |
30 | /// This is intended to be trivially copyable, so it should be passed by |
31 | /// value. |
32 | template<typename T> |
33 | class LLVM_NODISCARD ArrayRef { |
34 | public: |
35 | typedef const T *iterator; |
36 | typedef const T *const_iterator; |
37 | typedef size_t size_type; |
38 | |
39 | typedef std::reverse_iterator<iterator> reverse_iterator; |
40 | |
41 | private: |
42 | /// The start of the array, in an external buffer. |
43 | const T *Data; |
44 | |
45 | /// The number of elements. |
46 | size_type Length; |
47 | |
48 | public: |
49 | /// @name Constructors |
50 | /// @{ |
51 | |
52 | /// Construct an empty ArrayRef. |
53 | /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {} |
54 | |
55 | /// Construct an empty ArrayRef from None. |
56 | /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {} |
57 | |
58 | /// Construct an ArrayRef from a single element. |
59 | /*implicit*/ ArrayRef(const T &OneElt) |
60 | : Data(&OneElt), Length(1) {} |
61 | |
62 | /// Construct an ArrayRef from a pointer and length. |
63 | /*implicit*/ ArrayRef(const T *data, size_t length) |
64 | : Data(data), Length(length) {} |
65 | |
66 | /// Construct an ArrayRef from a range. |
67 | ArrayRef(const T *begin, const T *end) |
68 | : Data(begin), Length(end - begin) {} |
69 | |
70 | /// Construct an ArrayRef from a SmallVector. This is templated in order to |
71 | /// avoid instantiating SmallVectorTemplateCommon<T> whenever we |
72 | /// copy-construct an ArrayRef. |
73 | template<typename U> |
74 | /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec) |
75 | : Data(Vec.data()), Length(Vec.size()) { |
76 | } |
77 | |
78 | /// Construct an ArrayRef from a std::vector. |
79 | template<typename A> |
80 | /*implicit*/ ArrayRef(const std::vector<T, A> &Vec) |
81 | : Data(Vec.data()), Length(Vec.size()) {} |
82 | |
83 | /// Construct an ArrayRef from a std::array |
84 | template <size_t N> |
85 | /*implicit*/ constexpr ArrayRef(const std::array<T, N> &Arr) |
86 | : Data(Arr.data()), Length(N) {} |
87 | |
88 | /// Construct an ArrayRef from a C array. |
89 | template <size_t N> |
90 | /*implicit*/ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {} |
91 | |
92 | /// Construct an ArrayRef from a std::initializer_list. |
93 | /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec) |
94 | : Data(Vec.begin() == Vec.end() ? (T*)nullptr : Vec.begin()), |
95 | Length(Vec.size()) {} |
96 | |
97 | /// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to |
98 | /// ensure that only ArrayRefs of pointers can be converted. |
99 | template <typename U> |
100 | ArrayRef( |
101 | const ArrayRef<U *> &A, |
102 | typename std::enable_if< |
103 | std::is_convertible<U *const *, T const *>::value>::type * = nullptr) |
104 | : Data(A.data()), Length(A.size()) {} |
105 | |
106 | /// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is |
107 | /// templated in order to avoid instantiating SmallVectorTemplateCommon<T> |
108 | /// whenever we copy-construct an ArrayRef. |
109 | template<typename U, typename DummyT> |
110 | /*implicit*/ ArrayRef( |
111 | const SmallVectorTemplateCommon<U *, DummyT> &Vec, |
112 | typename std::enable_if< |
113 | std::is_convertible<U *const *, T const *>::value>::type * = nullptr) |
114 | : Data(Vec.data()), Length(Vec.size()) { |
115 | } |
116 | |
117 | /// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE |
118 | /// to ensure that only vectors of pointers can be converted. |
119 | template<typename U, typename A> |
120 | ArrayRef(const std::vector<U *, A> &Vec, |
121 | typename std::enable_if< |
122 | std::is_convertible<U *const *, T const *>::value>::type* = 0) |
123 | : Data(Vec.data()), Length(Vec.size()) {} |
124 | |
125 | /// @} |
126 | /// @name Simple Operations |
127 | /// @{ |
128 | |
129 | iterator begin() const { return Data; } |
130 | iterator end() const { return Data + Length; } |
131 | |
132 | reverse_iterator rbegin() const { return reverse_iterator(end()); } |
133 | reverse_iterator rend() const { return reverse_iterator(begin()); } |
134 | |
135 | /// empty - Check if the array is empty. |
136 | bool empty() const { return Length == 0; } |
137 | |
138 | const T *data() const { return Data; } |
139 | |
140 | /// size - Get the array size. |
141 | size_t size() const { return Length; } |
142 | |
143 | /// front - Get the first element. |
144 | const T &front() const { |
145 | assert(!empty()); |
146 | return Data[0]; |
147 | } |
148 | |
149 | /// back - Get the last element. |
150 | const T &back() const { |
151 | assert(!empty()); |
152 | return Data[Length-1]; |
153 | } |
154 | |
155 | // copy - Allocate copy in Allocator and return ArrayRef<T> to it. |
156 | template <typename Allocator> ArrayRef<T> copy(Allocator &A) { |
157 | T *Buff = A.template Allocate<T>(Length); |
158 | std::uninitialized_copy(begin(), end(), Buff); |
159 | return ArrayRef<T>(Buff, Length); |
160 | } |
161 | |
162 | /// equals - Check for element-wise equality. |
163 | bool equals(ArrayRef RHS) const { |
164 | if (Length != RHS.Length) |
165 | return false; |
166 | return std::equal(begin(), end(), RHS.begin()); |
167 | } |
168 | |
169 | /// slice(n, m) - Chop off the first N elements of the array, and keep M |
170 | /// elements in the array. |
171 | ArrayRef<T> slice(size_t N, size_t M) const { |
172 | assert(N+M <= size() && "Invalid specifier" ); |
173 | return ArrayRef<T>(data()+N, M); |
174 | } |
175 | |
176 | /// slice(n) - Chop off the first N elements of the array. |
177 | ArrayRef<T> slice(size_t N) const { return slice(N, size() - N); } |
178 | |
179 | /// \brief Drop the first \p N elements of the array. |
180 | ArrayRef<T> drop_front(size_t N = 1) const { |
181 | assert(size() >= N && "Dropping more elements than exist" ); |
182 | return slice(N, size() - N); |
183 | } |
184 | |
185 | /// \brief Drop the last \p N elements of the array. |
186 | ArrayRef<T> drop_back(size_t N = 1) const { |
187 | assert(size() >= N && "Dropping more elements than exist" ); |
188 | return slice(0, size() - N); |
189 | } |
190 | |
191 | /// \brief Return a copy of *this with the first N elements satisfying the |
192 | /// given predicate removed. |
193 | template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred) const { |
194 | return ArrayRef<T>(find_if_not(*this, Pred), end()); |
195 | } |
196 | |
197 | /// \brief Return a copy of *this with the first N elements not satisfying |
198 | /// the given predicate removed. |
199 | template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred) const { |
200 | return ArrayRef<T>(find_if(*this, Pred), end()); |
201 | } |
202 | |
203 | /// \brief Return a copy of *this with only the first \p N elements. |
204 | ArrayRef<T> take_front(size_t N = 1) const { |
205 | if (N >= size()) |
206 | return *this; |
207 | return drop_back(size() - N); |
208 | } |
209 | |
210 | /// \brief Return a copy of *this with only the last \p N elements. |
211 | ArrayRef<T> take_back(size_t N = 1) const { |
212 | if (N >= size()) |
213 | return *this; |
214 | return drop_front(size() - N); |
215 | } |
216 | |
217 | /// \brief Return the first N elements of this Array that satisfy the given |
218 | /// predicate. |
219 | template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred) const { |
220 | return ArrayRef<T>(begin(), find_if_not(*this, Pred)); |
221 | } |
222 | |
223 | /// \brief Return the first N elements of this Array that don't satisfy the |
224 | /// given predicate. |
225 | template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred) const { |
226 | return ArrayRef<T>(begin(), find_if(*this, Pred)); |
227 | } |
228 | |
229 | /// @} |
230 | /// @name Operator Overloads |
231 | /// @{ |
232 | const T &operator[](size_t Index) const { |
233 | assert(Index < Length && "Invalid index!" ); |
234 | return Data[Index]; |
235 | } |
236 | |
237 | /// Disallow accidental assignment from a temporary. |
238 | /// |
239 | /// The declaration here is extra complicated so that "arrayRef = {}" |
240 | /// continues to select the move assignment operator. |
241 | template <typename U> |
242 | typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type & |
243 | operator=(U &&Temporary) = delete; |
244 | |
245 | /// Disallow accidental assignment from a temporary. |
246 | /// |
247 | /// The declaration here is extra complicated so that "arrayRef = {}" |
248 | /// continues to select the move assignment operator. |
249 | template <typename U> |
250 | typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type & |
251 | operator=(std::initializer_list<U>) = delete; |
252 | |
253 | /// @} |
254 | /// @name Expensive Operations |
255 | /// @{ |
256 | std::vector<T> vec() const { |
257 | return std::vector<T>(Data, Data+Length); |
258 | } |
259 | |
260 | /// @} |
261 | /// @name Conversion operators |
262 | /// @{ |
263 | operator std::vector<T>() const { |
264 | return std::vector<T>(Data, Data+Length); |
265 | } |
266 | |
267 | /// @} |
268 | }; |
269 | |
270 | /// MutableArrayRef - Represent a mutable reference to an array (0 or more |
271 | /// elements consecutively in memory), i.e. a start pointer and a length. It |
272 | /// allows various APIs to take and modify consecutive elements easily and |
273 | /// conveniently. |
274 | /// |
275 | /// This class does not own the underlying data, it is expected to be used in |
276 | /// situations where the data resides in some other buffer, whose lifetime |
277 | /// extends past that of the MutableArrayRef. For this reason, it is not in |
278 | /// general safe to store a MutableArrayRef. |
279 | /// |
280 | /// This is intended to be trivially copyable, so it should be passed by |
281 | /// value. |
282 | template<typename T> |
283 | class LLVM_NODISCARD MutableArrayRef : public ArrayRef<T> { |
284 | public: |
285 | typedef T *iterator; |
286 | |
287 | typedef std::reverse_iterator<iterator> reverse_iterator; |
288 | |
289 | /// Construct an empty MutableArrayRef. |
290 | /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} |
291 | |
292 | /// Construct an empty MutableArrayRef from None. |
293 | /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {} |
294 | |
295 | /// Construct an MutableArrayRef from a single element. |
296 | /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} |
297 | |
298 | /// Construct an MutableArrayRef from a pointer and length. |
299 | /*implicit*/ MutableArrayRef(T *data, size_t length) |
300 | : ArrayRef<T>(data, length) {} |
301 | |
302 | /// Construct an MutableArrayRef from a range. |
303 | MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {} |
304 | |
305 | /// Construct an MutableArrayRef from a SmallVector. |
306 | /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec) |
307 | : ArrayRef<T>(Vec) {} |
308 | |
309 | /// Construct a MutableArrayRef from a std::vector. |
310 | /*implicit*/ MutableArrayRef(std::vector<T> &Vec) |
311 | : ArrayRef<T>(Vec) {} |
312 | |
313 | /// Construct an ArrayRef from a std::array |
314 | template <size_t N> |
315 | /*implicit*/ constexpr MutableArrayRef(std::array<T, N> &Arr) |
316 | : ArrayRef<T>(Arr) {} |
317 | |
318 | /// Construct an MutableArrayRef from a C array. |
319 | template <size_t N> |
320 | /*implicit*/ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {} |
321 | |
322 | T *data() const { return const_cast<T*>(ArrayRef<T>::data()); } |
323 | |
324 | iterator begin() const { return data(); } |
325 | iterator end() const { return data() + this->size(); } |
326 | |
327 | reverse_iterator rbegin() const { return reverse_iterator(end()); } |
328 | reverse_iterator rend() const { return reverse_iterator(begin()); } |
329 | |
330 | /// front - Get the first element. |
331 | T &front() const { |
332 | assert(!this->empty()); |
333 | return data()[0]; |
334 | } |
335 | |
336 | /// back - Get the last element. |
337 | T &back() const { |
338 | assert(!this->empty()); |
339 | return data()[this->size()-1]; |
340 | } |
341 | |
342 | /// slice(n, m) - Chop off the first N elements of the array, and keep M |
343 | /// elements in the array. |
344 | MutableArrayRef<T> slice(size_t N, size_t M) const { |
345 | assert(N + M <= this->size() && "Invalid specifier" ); |
346 | return MutableArrayRef<T>(this->data() + N, M); |
347 | } |
348 | |
349 | /// slice(n) - Chop off the first N elements of the array. |
350 | MutableArrayRef<T> slice(size_t N) const { |
351 | return slice(N, this->size() - N); |
352 | } |
353 | |
354 | /// \brief Drop the first \p N elements of the array. |
355 | MutableArrayRef<T> drop_front(size_t N = 1) const { |
356 | assert(this->size() >= N && "Dropping more elements than exist" ); |
357 | return slice(N, this->size() - N); |
358 | } |
359 | |
360 | MutableArrayRef<T> drop_back(size_t N = 1) const { |
361 | assert(this->size() >= N && "Dropping more elements than exist" ); |
362 | return slice(0, this->size() - N); |
363 | } |
364 | |
365 | /// \brief Return a copy of *this with the first N elements satisfying the |
366 | /// given predicate removed. |
367 | template <class PredicateT> |
368 | MutableArrayRef<T> drop_while(PredicateT Pred) const { |
369 | return MutableArrayRef<T>(find_if_not(*this, Pred), end()); |
370 | } |
371 | |
372 | /// \brief Return a copy of *this with the first N elements not satisfying |
373 | /// the given predicate removed. |
374 | template <class PredicateT> |
375 | MutableArrayRef<T> drop_until(PredicateT Pred) const { |
376 | return MutableArrayRef<T>(find_if(*this, Pred), end()); |
377 | } |
378 | |
379 | /// \brief Return a copy of *this with only the first \p N elements. |
380 | MutableArrayRef<T> take_front(size_t N = 1) const { |
381 | if (N >= this->size()) |
382 | return *this; |
383 | return drop_back(this->size() - N); |
384 | } |
385 | |
386 | /// \brief Return a copy of *this with only the last \p N elements. |
387 | MutableArrayRef<T> take_back(size_t N = 1) const { |
388 | if (N >= this->size()) |
389 | return *this; |
390 | return drop_front(this->size() - N); |
391 | } |
392 | |
393 | /// \brief Return the first N elements of this Array that satisfy the given |
394 | /// predicate. |
395 | template <class PredicateT> |
396 | MutableArrayRef<T> take_while(PredicateT Pred) const { |
397 | return MutableArrayRef<T>(begin(), find_if_not(*this, Pred)); |
398 | } |
399 | |
400 | /// \brief Return the first N elements of this Array that don't satisfy the |
401 | /// given predicate. |
402 | template <class PredicateT> |
403 | MutableArrayRef<T> take_until(PredicateT Pred) const { |
404 | return MutableArrayRef<T>(begin(), find_if(*this, Pred)); |
405 | } |
406 | |
407 | /// @} |
408 | /// @name Operator Overloads |
409 | /// @{ |
410 | T &operator[](size_t Index) const { |
411 | assert(Index < this->size() && "Invalid index!" ); |
412 | return data()[Index]; |
413 | } |
414 | }; |
415 | |
416 | /// This is a MutableArrayRef that owns its array. |
417 | template <typename T> class OwningArrayRef : public MutableArrayRef<T> { |
418 | public: |
419 | OwningArrayRef() {} |
420 | OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {} |
421 | OwningArrayRef(ArrayRef<T> Data) |
422 | : MutableArrayRef<T>(new T[Data.size()], Data.size()) { |
423 | std::copy(Data.begin(), Data.end(), this->begin()); |
424 | } |
425 | OwningArrayRef(OwningArrayRef &&Other) { *this = Other; } |
426 | OwningArrayRef &operator=(OwningArrayRef &&Other) { |
427 | delete[] this->data(); |
428 | this->MutableArrayRef<T>::operator=(Other); |
429 | Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>()); |
430 | return *this; |
431 | } |
432 | ~OwningArrayRef() { delete[] this->data(); } |
433 | }; |
434 | |
435 | /// @name ArrayRef Convenience constructors |
436 | /// @{ |
437 | |
438 | /// Construct an ArrayRef from a single element. |
439 | template<typename T> |
440 | ArrayRef<T> makeArrayRef(const T &OneElt) { |
441 | return OneElt; |
442 | } |
443 | |
444 | /// Construct an ArrayRef from a pointer and length. |
445 | template<typename T> |
446 | ArrayRef<T> makeArrayRef(const T *data, size_t length) { |
447 | return ArrayRef<T>(data, length); |
448 | } |
449 | |
450 | /// Construct an ArrayRef from a range. |
451 | template<typename T> |
452 | ArrayRef<T> makeArrayRef(const T *begin, const T *end) { |
453 | return ArrayRef<T>(begin, end); |
454 | } |
455 | |
456 | /// Construct an ArrayRef from a SmallVector. |
457 | template <typename T> |
458 | ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) { |
459 | return Vec; |
460 | } |
461 | |
462 | /// Construct an ArrayRef from a SmallVector. |
463 | template <typename T, unsigned N> |
464 | ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) { |
465 | return Vec; |
466 | } |
467 | |
468 | /// Construct an ArrayRef from a std::vector. |
469 | template<typename T> |
470 | ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) { |
471 | return Vec; |
472 | } |
473 | |
474 | /// Construct an ArrayRef from an ArrayRef (no-op) (const) |
475 | template <typename T> ArrayRef<T> makeArrayRef(const ArrayRef<T> &Vec) { |
476 | return Vec; |
477 | } |
478 | |
479 | /// Construct an ArrayRef from an ArrayRef (no-op) |
480 | template <typename T> ArrayRef<T> &makeArrayRef(ArrayRef<T> &Vec) { |
481 | return Vec; |
482 | } |
483 | |
484 | /// Construct an ArrayRef from a C array. |
485 | template<typename T, size_t N> |
486 | ArrayRef<T> makeArrayRef(const T (&Arr)[N]) { |
487 | return ArrayRef<T>(Arr); |
488 | } |
489 | |
490 | /// @} |
491 | /// @name ArrayRef Comparison Operators |
492 | /// @{ |
493 | |
494 | template<typename T> |
495 | inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) { |
496 | return LHS.equals(RHS); |
497 | } |
498 | |
499 | template<typename T> |
500 | inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) { |
501 | return !(LHS == RHS); |
502 | } |
503 | |
504 | /// @} |
505 | |
506 | // ArrayRefs can be treated like a POD type. |
507 | template <typename T> struct isPodLike; |
508 | template <typename T> struct isPodLike<ArrayRef<T> > { |
509 | static const bool value = true; |
510 | }; |
511 | |
512 | template <typename T> hash_code hash_value(ArrayRef<T> S) { |
513 | return hash_combine_range(S.begin(), S.end()); |
514 | } |
515 | } // end namespace llvm |
516 | |
517 | #endif // LLVM_ADT_ARRAYREF_H |
518 | |