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