xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/ArrayRef.h (revision 8aac90f18aef7c9eea906c3ff9a001ca7b94f375)
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/SmallVector.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/Support/Compiler.h"
16 #include <algorithm>
17 #include <array>
18 #include <cassert>
19 #include <cstddef>
20 #include <initializer_list>
21 #include <iterator>
22 #include <memory>
23 #include <type_traits>
24 #include <vector>
25 
26 namespace llvm {
27   template<typename T> class [[nodiscard]] MutableArrayRef;
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_GSL_POINTER [[nodiscard]] ArrayRef {
42   public:
43     using value_type = T;
44     using pointer = value_type *;
45     using const_pointer = const value_type *;
46     using reference = value_type &;
47     using const_reference = const value_type &;
48     using iterator = const_pointer;
49     using const_iterator = const_pointer;
50     using reverse_iterator = std::reverse_iterator<iterator>;
51     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
52     using size_type = size_t;
53     using difference_type = ptrdiff_t;
54 
55   private:
56     /// The start of the array, in an external buffer.
57     const T *Data = nullptr;
58 
59     /// The number of elements.
60     size_type Length = 0;
61 
62   public:
63     /// @name Constructors
64     /// @{
65 
66     /// Construct an empty ArrayRef.
67     /*implicit*/ ArrayRef() = default;
68 
69     /// Construct an empty ArrayRef from std::nullopt.
70     /*implicit*/ ArrayRef(std::nullopt_t) {}
71 
72     /// Construct an ArrayRef from a single element.
73     /*implicit*/ ArrayRef(const T &OneElt)
74       : Data(&OneElt), Length(1) {}
75 
76     /// Construct an ArrayRef from a pointer and length.
77     constexpr /*implicit*/ ArrayRef(const T *data, size_t length)
78         : Data(data), Length(length) {}
79 
80     /// Construct an ArrayRef from a range.
81     constexpr ArrayRef(const T *begin, const T *end)
82         : Data(begin), Length(end - begin) {
83       assert(begin <= end);
84     }
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     constexpr /*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                  * = nullptr)
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> MutableArrayRef<T> copy(Allocator &A) {
181       T *Buff = A.template Allocate<T>(Length);
182       std::uninitialized_copy(begin(), end(), Buff);
183       return MutableArrayRef<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 [[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 std::nullopt.
325     /*implicit*/ MutableArrayRef(std::nullopt_t) : 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 Deduction guides
472   /// @{
473   /// Deduction guide to construct an ArrayRef from a single element.
474   template <typename T> ArrayRef(const T &OneElt) -> ArrayRef<T>;
475 
476   /// Deduction guide to construct an ArrayRef from a pointer and length
477   template <typename T> ArrayRef(const T *data, size_t length) -> ArrayRef<T>;
478 
479   /// Deduction guide to construct an ArrayRef from a range
480   template <typename T> ArrayRef(const T *data, const T *end) -> ArrayRef<T>;
481 
482   /// Deduction guide to construct an ArrayRef from a SmallVector
483   template <typename T> ArrayRef(const SmallVectorImpl<T> &Vec) -> ArrayRef<T>;
484 
485   /// Deduction guide to construct an ArrayRef from a SmallVector
486   template <typename T, unsigned N>
487   ArrayRef(const SmallVector<T, N> &Vec) -> ArrayRef<T>;
488 
489   /// Deduction guide to construct an ArrayRef from a std::vector
490   template <typename T> ArrayRef(const std::vector<T> &Vec) -> ArrayRef<T>;
491 
492   /// Deduction guide to construct an ArrayRef from a std::array
493   template <typename T, std::size_t N>
494   ArrayRef(const std::array<T, N> &Vec) -> ArrayRef<T>;
495 
496   /// Deduction guide to construct an ArrayRef from an ArrayRef (const)
497   template <typename T> ArrayRef(const ArrayRef<T> &Vec) -> ArrayRef<T>;
498 
499   /// Deduction guide to construct an ArrayRef from an ArrayRef
500   template <typename T> ArrayRef(ArrayRef<T> &Vec) -> ArrayRef<T>;
501 
502   /// Deduction guide to construct an ArrayRef from a C array.
503   template <typename T, size_t N> ArrayRef(const T (&Arr)[N]) -> ArrayRef<T>;
504 
505   /// @}
506 
507   /// @name ArrayRef Convenience constructors
508   /// @{
509   /// Construct an ArrayRef from a single element.
510   template <typename T>
511   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
512   ArrayRef<T> makeArrayRef(const T &OneElt) {
513     return OneElt;
514   }
515 
516   /// Construct an ArrayRef from a pointer and length.
517   template <typename T>
518   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
519   ArrayRef<T> makeArrayRef(const T *data, size_t length) {
520     return ArrayRef<T>(data, length);
521   }
522 
523   /// Construct an ArrayRef from a range.
524   template <typename T>
525   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
526   ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
527     return ArrayRef<T>(begin, end);
528   }
529 
530   /// Construct an ArrayRef from a SmallVector.
531   template <typename T>
532   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
533   ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
534     return Vec;
535   }
536 
537   /// Construct an ArrayRef from a SmallVector.
538   template <typename T, unsigned N>
539   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
540   ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
541     return Vec;
542   }
543 
544   /// Construct an ArrayRef from a std::vector.
545   template <typename T>
546   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
547   ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
548     return Vec;
549   }
550 
551   /// Construct an ArrayRef from a std::array.
552   template <typename T, std::size_t N>
553   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
554   ArrayRef<T> makeArrayRef(const std::array<T, N> &Arr) {
555     return Arr;
556   }
557 
558   /// Construct an ArrayRef from an ArrayRef (no-op) (const)
559   template <typename T>
560   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
561   ArrayRef<T> makeArrayRef(const ArrayRef<T> &Vec) {
562     return Vec;
563   }
564 
565   /// Construct an ArrayRef from an ArrayRef (no-op)
566   template <typename T>
567   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
568   ArrayRef<T> &makeArrayRef(ArrayRef<T> &Vec) {
569     return Vec;
570   }
571 
572   /// Construct an ArrayRef from a C array.
573   template <typename T, size_t N>
574   LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
575   ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
576     return ArrayRef<T>(Arr);
577   }
578 
579   /// @name MutableArrayRef Deduction guides
580   /// @{
581   /// Deduction guide to construct a `MutableArrayRef` from a single element
582   template <class T> MutableArrayRef(T &OneElt) -> MutableArrayRef<T>;
583 
584   /// Deduction guide to construct a `MutableArrayRef` from a pointer and
585   /// length.
586   template <class T>
587   MutableArrayRef(T *data, size_t length) -> MutableArrayRef<T>;
588 
589   /// Deduction guide to construct a `MutableArrayRef` from a `SmallVector`.
590   template <class T>
591   MutableArrayRef(SmallVectorImpl<T> &Vec) -> MutableArrayRef<T>;
592 
593   template <class T, unsigned N>
594   MutableArrayRef(SmallVector<T, N> &Vec) -> MutableArrayRef<T>;
595 
596   /// Deduction guide to construct a `MutableArrayRef` from a `std::vector`.
597   template <class T> MutableArrayRef(std::vector<T> &Vec) -> MutableArrayRef<T>;
598 
599   /// Deduction guide to construct a `MutableArrayRef` from a `std::array`.
600   template <class T, std::size_t N>
601   MutableArrayRef(std::array<T, N> &Vec) -> MutableArrayRef<T>;
602 
603   /// Deduction guide to construct a `MutableArrayRef` from a C array.
604   template <typename T, size_t N>
605   MutableArrayRef(T (&Arr)[N]) -> MutableArrayRef<T>;
606 
607   /// @}
608 
609   /// Construct a MutableArrayRef from a single element.
610   template <typename T>
611   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
612   MutableArrayRef<T> makeMutableArrayRef(T &OneElt) {
613     return OneElt;
614   }
615 
616   /// Construct a MutableArrayRef from a pointer and length.
617   template <typename T>
618   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
619   MutableArrayRef<T> makeMutableArrayRef(T *data, size_t length) {
620     return MutableArrayRef<T>(data, length);
621   }
622 
623   /// Construct a MutableArrayRef from a SmallVector.
624   template <typename T>
625   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
626   MutableArrayRef<T> makeMutableArrayRef(SmallVectorImpl<T> &Vec) {
627     return Vec;
628   }
629 
630   /// Construct a MutableArrayRef from a SmallVector.
631   template <typename T, unsigned N>
632   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
633   MutableArrayRef<T> makeMutableArrayRef(SmallVector<T, N> &Vec) {
634     return Vec;
635   }
636 
637   /// Construct a MutableArrayRef from a std::vector.
638   template <typename T>
639   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
640   MutableArrayRef<T> makeMutableArrayRef(std::vector<T> &Vec) {
641     return Vec;
642   }
643 
644   /// Construct a MutableArrayRef from a std::array.
645   template <typename T, std::size_t N>
646   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
647   MutableArrayRef<T> makeMutableArrayRef(std::array<T, N> &Arr) {
648     return Arr;
649   }
650 
651   /// Construct a MutableArrayRef from a MutableArrayRef (no-op) (const)
652   template <typename T>
653   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
654   MutableArrayRef<T> makeMutableArrayRef(const MutableArrayRef<T> &Vec) {
655     return Vec;
656   }
657 
658   /// Construct a MutableArrayRef from a C array.
659   template <typename T, size_t N>
660   LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
661   MutableArrayRef<T> makeMutableArrayRef(T (&Arr)[N]) {
662     return MutableArrayRef<T>(Arr);
663   }
664 
665   /// @}
666   /// @name ArrayRef Comparison Operators
667   /// @{
668 
669   template<typename T>
670   inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
671     return LHS.equals(RHS);
672   }
673 
674   template <typename T>
675   inline bool operator==(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
676     return ArrayRef<T>(LHS).equals(RHS);
677   }
678 
679   template <typename T>
680   inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
681     return !(LHS == RHS);
682   }
683 
684   template <typename T>
685   inline bool operator!=(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
686     return !(LHS == RHS);
687   }
688 
689   /// @}
690 
691   template <typename T> hash_code hash_value(ArrayRef<T> S) {
692     return hash_combine_range(S.begin(), S.end());
693   }
694 
695   // Provide DenseMapInfo for ArrayRefs.
696   template <typename T> struct DenseMapInfo<ArrayRef<T>, void> {
697     static inline ArrayRef<T> getEmptyKey() {
698       return ArrayRef<T>(
699           reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)), size_t(0));
700     }
701 
702     static inline ArrayRef<T> getTombstoneKey() {
703       return ArrayRef<T>(
704           reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)), size_t(0));
705     }
706 
707     static unsigned getHashValue(ArrayRef<T> Val) {
708       assert(Val.data() != getEmptyKey().data() &&
709              "Cannot hash the empty key!");
710       assert(Val.data() != getTombstoneKey().data() &&
711              "Cannot hash the tombstone key!");
712       return (unsigned)(hash_value(Val));
713     }
714 
715     static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
716       if (RHS.data() == getEmptyKey().data())
717         return LHS.data() == getEmptyKey().data();
718       if (RHS.data() == getTombstoneKey().data())
719         return LHS.data() == getTombstoneKey().data();
720       return LHS == RHS;
721     }
722   };
723 
724 } // end namespace llvm
725 
726 #endif // LLVM_ADT_ARRAYREF_H
727