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