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