Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:02

0001 //===- ArrayRef.h - Array Reference Wrapper ---------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_ADT_ARRAYREF_H
0010 #define LLVM_ADT_ARRAYREF_H
0011 
0012 #include "llvm/ADT/Hashing.h"
0013 #include "llvm/ADT/SmallVector.h"
0014 #include "llvm/ADT/STLExtras.h"
0015 #include "llvm/Support/Compiler.h"
0016 #include <algorithm>
0017 #include <array>
0018 #include <cassert>
0019 #include <cstddef>
0020 #include <initializer_list>
0021 #include <iterator>
0022 #include <memory>
0023 #include <type_traits>
0024 #include <vector>
0025 
0026 namespace llvm {
0027   template<typename T> class [[nodiscard]] MutableArrayRef;
0028 
0029   /// ArrayRef - Represent a constant reference to an array (0 or more elements
0030   /// consecutively in memory), i.e. a start pointer and a length.  It allows
0031   /// various APIs to take consecutive elements easily and conveniently.
0032   ///
0033   /// This class does not own the underlying data, it is expected to be used in
0034   /// situations where the data resides in some other buffer, whose lifetime
0035   /// extends past that of the ArrayRef. For this reason, it is not in general
0036   /// safe to store an ArrayRef.
0037   ///
0038   /// This is intended to be trivially copyable, so it should be passed by
0039   /// value.
0040   template<typename T>
0041   class LLVM_GSL_POINTER [[nodiscard]] ArrayRef {
0042   public:
0043     using value_type = T;
0044     using pointer = value_type *;
0045     using const_pointer = const value_type *;
0046     using reference = value_type &;
0047     using const_reference = const value_type &;
0048     using iterator = const_pointer;
0049     using const_iterator = const_pointer;
0050     using reverse_iterator = std::reverse_iterator<iterator>;
0051     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0052     using size_type = size_t;
0053     using difference_type = ptrdiff_t;
0054 
0055   private:
0056     /// The start of the array, in an external buffer.
0057     const T *Data = nullptr;
0058 
0059     /// The number of elements.
0060     size_type Length = 0;
0061 
0062   public:
0063     /// @name Constructors
0064     /// @{
0065 
0066     /// Construct an empty ArrayRef.
0067     /*implicit*/ ArrayRef() = default;
0068 
0069     /// Construct an empty ArrayRef from std::nullopt.
0070     /*implicit*/ ArrayRef(std::nullopt_t) {}
0071 
0072     /// Construct an ArrayRef from a single element.
0073     /*implicit*/ ArrayRef(const T &OneElt LLVM_LIFETIME_BOUND)
0074         : Data(&OneElt), Length(1) {}
0075 
0076     /// Construct an ArrayRef from a pointer and length.
0077     constexpr /*implicit*/ ArrayRef(const T *data LLVM_LIFETIME_BOUND,
0078                                     size_t length)
0079         : Data(data), Length(length) {}
0080 
0081     /// Construct an ArrayRef from a range.
0082     constexpr ArrayRef(const T *begin LLVM_LIFETIME_BOUND, const T *end)
0083         : Data(begin), Length(end - begin) {
0084       assert(begin <= end);
0085     }
0086 
0087     /// Construct an ArrayRef from a SmallVector. This is templated in order to
0088     /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
0089     /// copy-construct an ArrayRef.
0090     template<typename U>
0091     /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
0092       : Data(Vec.data()), Length(Vec.size()) {
0093     }
0094 
0095     /// Construct an ArrayRef from a std::vector.
0096     template<typename A>
0097     /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
0098       : Data(Vec.data()), Length(Vec.size()) {}
0099 
0100     /// Construct an ArrayRef from a std::array
0101     template <size_t N>
0102     /*implicit*/ constexpr ArrayRef(const std::array<T, N> &Arr)
0103         : Data(Arr.data()), Length(N) {}
0104 
0105     /// Construct an ArrayRef from a C array.
0106     template <size_t N>
0107     /*implicit*/ constexpr ArrayRef(const T (&Arr LLVM_LIFETIME_BOUND)[N])
0108         : Data(Arr), Length(N) {}
0109 
0110     /// Construct an ArrayRef from a std::initializer_list.
0111 #if LLVM_GNUC_PREREQ(9, 0, 0)
0112 // Disable gcc's warning in this constructor as it generates an enormous amount
0113 // of messages. Anyone using ArrayRef should already be aware of the fact that
0114 // it does not do lifetime extension.
0115 #pragma GCC diagnostic push
0116 #pragma GCC diagnostic ignored "-Winit-list-lifetime"
0117 #endif
0118     constexpr /*implicit*/ ArrayRef(
0119         std::initializer_list<T> Vec LLVM_LIFETIME_BOUND)
0120         : Data(Vec.begin() == Vec.end() ? (T *)nullptr : Vec.begin()),
0121           Length(Vec.size()) {}
0122 #if LLVM_GNUC_PREREQ(9, 0, 0)
0123 #pragma GCC diagnostic pop
0124 #endif
0125 
0126     /// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to
0127     /// ensure that only ArrayRefs of pointers can be converted.
0128     template <typename U>
0129     ArrayRef(const ArrayRef<U *> &A,
0130              std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
0131                  * = nullptr)
0132         : Data(A.data()), Length(A.size()) {}
0133 
0134     /// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is
0135     /// templated in order to avoid instantiating SmallVectorTemplateCommon<T>
0136     /// whenever we copy-construct an ArrayRef.
0137     template <typename U, typename DummyT>
0138     /*implicit*/ ArrayRef(
0139         const SmallVectorTemplateCommon<U *, DummyT> &Vec,
0140         std::enable_if_t<std::is_convertible<U *const *, T const *>::value> * =
0141             nullptr)
0142         : Data(Vec.data()), Length(Vec.size()) {}
0143 
0144     /// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE
0145     /// to ensure that only vectors of pointers can be converted.
0146     template <typename U, typename A>
0147     ArrayRef(const std::vector<U *, A> &Vec,
0148              std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
0149                  * = nullptr)
0150         : Data(Vec.data()), Length(Vec.size()) {}
0151 
0152     /// @}
0153     /// @name Simple Operations
0154     /// @{
0155 
0156     iterator begin() const { return Data; }
0157     iterator end() const { return Data + Length; }
0158 
0159     reverse_iterator rbegin() const { return reverse_iterator(end()); }
0160     reverse_iterator rend() const { return reverse_iterator(begin()); }
0161 
0162     /// empty - Check if the array is empty.
0163     bool empty() const { return Length == 0; }
0164 
0165     const T *data() const { return Data; }
0166 
0167     /// size - Get the array size.
0168     size_t size() const { return Length; }
0169 
0170     /// front - Get the first element.
0171     const T &front() const {
0172       assert(!empty());
0173       return Data[0];
0174     }
0175 
0176     /// back - Get the last element.
0177     const T &back() const {
0178       assert(!empty());
0179       return Data[Length-1];
0180     }
0181 
0182     // copy - Allocate copy in Allocator and return ArrayRef<T> to it.
0183     template <typename Allocator> MutableArrayRef<T> copy(Allocator &A) {
0184       T *Buff = A.template Allocate<T>(Length);
0185       std::uninitialized_copy(begin(), end(), Buff);
0186       return MutableArrayRef<T>(Buff, Length);
0187     }
0188 
0189     /// equals - Check for element-wise equality.
0190     bool equals(ArrayRef RHS) const {
0191       if (Length != RHS.Length)
0192         return false;
0193       return std::equal(begin(), end(), RHS.begin());
0194     }
0195 
0196     /// slice(n, m) - Chop off the first N elements of the array, and keep M
0197     /// elements in the array.
0198     ArrayRef<T> slice(size_t N, size_t M) const {
0199       assert(N+M <= size() && "Invalid specifier");
0200       return ArrayRef<T>(data()+N, M);
0201     }
0202 
0203     /// slice(n) - Chop off the first N elements of the array.
0204     ArrayRef<T> slice(size_t N) const { return drop_front(N); }
0205 
0206     /// Drop the first \p N elements of the array.
0207     ArrayRef<T> drop_front(size_t N = 1) const {
0208       assert(size() >= N && "Dropping more elements than exist");
0209       return slice(N, size() - N);
0210     }
0211 
0212     /// Drop the last \p N elements of the array.
0213     ArrayRef<T> drop_back(size_t N = 1) const {
0214       assert(size() >= N && "Dropping more elements than exist");
0215       return slice(0, size() - N);
0216     }
0217 
0218     /// Return a copy of *this with the first N elements satisfying the
0219     /// given predicate removed.
0220     template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred) const {
0221       return ArrayRef<T>(find_if_not(*this, Pred), end());
0222     }
0223 
0224     /// Return a copy of *this with the first N elements not satisfying
0225     /// the given predicate removed.
0226     template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred) const {
0227       return ArrayRef<T>(find_if(*this, Pred), end());
0228     }
0229 
0230     /// Return a copy of *this with only the first \p N elements.
0231     ArrayRef<T> take_front(size_t N = 1) const {
0232       if (N >= size())
0233         return *this;
0234       return drop_back(size() - N);
0235     }
0236 
0237     /// Return a copy of *this with only the last \p N elements.
0238     ArrayRef<T> take_back(size_t N = 1) const {
0239       if (N >= size())
0240         return *this;
0241       return drop_front(size() - N);
0242     }
0243 
0244     /// Return the first N elements of this Array that satisfy the given
0245     /// predicate.
0246     template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred) const {
0247       return ArrayRef<T>(begin(), find_if_not(*this, Pred));
0248     }
0249 
0250     /// Return the first N elements of this Array that don't satisfy the
0251     /// given predicate.
0252     template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred) const {
0253       return ArrayRef<T>(begin(), find_if(*this, Pred));
0254     }
0255 
0256     /// @}
0257     /// @name Operator Overloads
0258     /// @{
0259     const T &operator[](size_t Index) const {
0260       assert(Index < Length && "Invalid index!");
0261       return Data[Index];
0262     }
0263 
0264     /// Disallow accidental assignment from a temporary.
0265     ///
0266     /// The declaration here is extra complicated so that "arrayRef = {}"
0267     /// continues to select the move assignment operator.
0268     template <typename U>
0269     std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
0270     operator=(U &&Temporary) = delete;
0271 
0272     /// Disallow accidental assignment from a temporary.
0273     ///
0274     /// The declaration here is extra complicated so that "arrayRef = {}"
0275     /// continues to select the move assignment operator.
0276     template <typename U>
0277     std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
0278     operator=(std::initializer_list<U>) = delete;
0279 
0280     /// @}
0281     /// @name Expensive Operations
0282     /// @{
0283     std::vector<T> vec() const {
0284       return std::vector<T>(Data, Data+Length);
0285     }
0286 
0287     /// @}
0288     /// @name Conversion operators
0289     /// @{
0290     operator std::vector<T>() const {
0291       return std::vector<T>(Data, Data+Length);
0292     }
0293 
0294     /// @}
0295   };
0296 
0297   /// MutableArrayRef - Represent a mutable reference to an array (0 or more
0298   /// elements consecutively in memory), i.e. a start pointer and a length.  It
0299   /// allows various APIs to take and modify consecutive elements easily and
0300   /// conveniently.
0301   ///
0302   /// This class does not own the underlying data, it is expected to be used in
0303   /// situations where the data resides in some other buffer, whose lifetime
0304   /// extends past that of the MutableArrayRef. For this reason, it is not in
0305   /// general safe to store a MutableArrayRef.
0306   ///
0307   /// This is intended to be trivially copyable, so it should be passed by
0308   /// value.
0309   template<typename T>
0310   class [[nodiscard]] MutableArrayRef : public ArrayRef<T> {
0311   public:
0312     using value_type = T;
0313     using pointer = value_type *;
0314     using const_pointer = const value_type *;
0315     using reference = value_type &;
0316     using const_reference = const value_type &;
0317     using iterator = pointer;
0318     using const_iterator = const_pointer;
0319     using reverse_iterator = std::reverse_iterator<iterator>;
0320     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0321     using size_type = size_t;
0322     using difference_type = ptrdiff_t;
0323 
0324     /// Construct an empty MutableArrayRef.
0325     /*implicit*/ MutableArrayRef() = default;
0326 
0327     /// Construct an empty MutableArrayRef from std::nullopt.
0328     /*implicit*/ MutableArrayRef(std::nullopt_t) : ArrayRef<T>() {}
0329 
0330     /// Construct a MutableArrayRef from a single element.
0331     /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
0332 
0333     /// Construct a MutableArrayRef from a pointer and length.
0334     /*implicit*/ MutableArrayRef(T *data, size_t length)
0335       : ArrayRef<T>(data, length) {}
0336 
0337     /// Construct a MutableArrayRef from a range.
0338     MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
0339 
0340     /// Construct a MutableArrayRef from a SmallVector.
0341     /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
0342     : ArrayRef<T>(Vec) {}
0343 
0344     /// Construct a MutableArrayRef from a std::vector.
0345     /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
0346     : ArrayRef<T>(Vec) {}
0347 
0348     /// Construct a MutableArrayRef from a std::array
0349     template <size_t N>
0350     /*implicit*/ constexpr MutableArrayRef(std::array<T, N> &Arr)
0351         : ArrayRef<T>(Arr) {}
0352 
0353     /// Construct a MutableArrayRef from a C array.
0354     template <size_t N>
0355     /*implicit*/ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {}
0356 
0357     T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
0358 
0359     iterator begin() const { return data(); }
0360     iterator end() const { return data() + this->size(); }
0361 
0362     reverse_iterator rbegin() const { return reverse_iterator(end()); }
0363     reverse_iterator rend() const { return reverse_iterator(begin()); }
0364 
0365     /// front - Get the first element.
0366     T &front() const {
0367       assert(!this->empty());
0368       return data()[0];
0369     }
0370 
0371     /// back - Get the last element.
0372     T &back() const {
0373       assert(!this->empty());
0374       return data()[this->size()-1];
0375     }
0376 
0377     /// slice(n, m) - Chop off the first N elements of the array, and keep M
0378     /// elements in the array.
0379     MutableArrayRef<T> slice(size_t N, size_t M) const {
0380       assert(N + M <= this->size() && "Invalid specifier");
0381       return MutableArrayRef<T>(this->data() + N, M);
0382     }
0383 
0384     /// slice(n) - Chop off the first N elements of the array.
0385     MutableArrayRef<T> slice(size_t N) const {
0386       return slice(N, this->size() - N);
0387     }
0388 
0389     /// Drop the first \p N elements of the array.
0390     MutableArrayRef<T> drop_front(size_t N = 1) const {
0391       assert(this->size() >= N && "Dropping more elements than exist");
0392       return slice(N, this->size() - N);
0393     }
0394 
0395     MutableArrayRef<T> drop_back(size_t N = 1) const {
0396       assert(this->size() >= N && "Dropping more elements than exist");
0397       return slice(0, this->size() - N);
0398     }
0399 
0400     /// Return a copy of *this with the first N elements satisfying the
0401     /// given predicate removed.
0402     template <class PredicateT>
0403     MutableArrayRef<T> drop_while(PredicateT Pred) const {
0404       return MutableArrayRef<T>(find_if_not(*this, Pred), end());
0405     }
0406 
0407     /// Return a copy of *this with the first N elements not satisfying
0408     /// the given predicate removed.
0409     template <class PredicateT>
0410     MutableArrayRef<T> drop_until(PredicateT Pred) const {
0411       return MutableArrayRef<T>(find_if(*this, Pred), end());
0412     }
0413 
0414     /// Return a copy of *this with only the first \p N elements.
0415     MutableArrayRef<T> take_front(size_t N = 1) const {
0416       if (N >= this->size())
0417         return *this;
0418       return drop_back(this->size() - N);
0419     }
0420 
0421     /// Return a copy of *this with only the last \p N elements.
0422     MutableArrayRef<T> take_back(size_t N = 1) const {
0423       if (N >= this->size())
0424         return *this;
0425       return drop_front(this->size() - N);
0426     }
0427 
0428     /// Return the first N elements of this Array that satisfy the given
0429     /// predicate.
0430     template <class PredicateT>
0431     MutableArrayRef<T> take_while(PredicateT Pred) const {
0432       return MutableArrayRef<T>(begin(), find_if_not(*this, Pred));
0433     }
0434 
0435     /// Return the first N elements of this Array that don't satisfy the
0436     /// given predicate.
0437     template <class PredicateT>
0438     MutableArrayRef<T> take_until(PredicateT Pred) const {
0439       return MutableArrayRef<T>(begin(), find_if(*this, Pred));
0440     }
0441 
0442     /// @}
0443     /// @name Operator Overloads
0444     /// @{
0445     T &operator[](size_t Index) const {
0446       assert(Index < this->size() && "Invalid index!");
0447       return data()[Index];
0448     }
0449   };
0450 
0451   /// This is a MutableArrayRef that owns its array.
0452   template <typename T> class OwningArrayRef : public MutableArrayRef<T> {
0453   public:
0454     OwningArrayRef() = default;
0455     OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {}
0456 
0457     OwningArrayRef(ArrayRef<T> Data)
0458         : MutableArrayRef<T>(new T[Data.size()], Data.size()) {
0459       std::copy(Data.begin(), Data.end(), this->begin());
0460     }
0461 
0462     OwningArrayRef(OwningArrayRef &&Other) { *this = std::move(Other); }
0463 
0464     OwningArrayRef &operator=(OwningArrayRef &&Other) {
0465       delete[] this->data();
0466       this->MutableArrayRef<T>::operator=(Other);
0467       Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>());
0468       return *this;
0469     }
0470 
0471     ~OwningArrayRef() { delete[] this->data(); }
0472   };
0473 
0474   /// @name ArrayRef Deduction guides
0475   /// @{
0476   /// Deduction guide to construct an ArrayRef from a single element.
0477   template <typename T> ArrayRef(const T &OneElt) -> ArrayRef<T>;
0478 
0479   /// Deduction guide to construct an ArrayRef from a pointer and length
0480   template <typename T> ArrayRef(const T *data, size_t length) -> ArrayRef<T>;
0481 
0482   /// Deduction guide to construct an ArrayRef from a range
0483   template <typename T> ArrayRef(const T *data, const T *end) -> ArrayRef<T>;
0484 
0485   /// Deduction guide to construct an ArrayRef from a SmallVector
0486   template <typename T> ArrayRef(const SmallVectorImpl<T> &Vec) -> ArrayRef<T>;
0487 
0488   /// Deduction guide to construct an ArrayRef from a SmallVector
0489   template <typename T, unsigned N>
0490   ArrayRef(const SmallVector<T, N> &Vec) -> ArrayRef<T>;
0491 
0492   /// Deduction guide to construct an ArrayRef from a std::vector
0493   template <typename T> ArrayRef(const std::vector<T> &Vec) -> ArrayRef<T>;
0494 
0495   /// Deduction guide to construct an ArrayRef from a std::array
0496   template <typename T, std::size_t N>
0497   ArrayRef(const std::array<T, N> &Vec) -> ArrayRef<T>;
0498 
0499   /// Deduction guide to construct an ArrayRef from an ArrayRef (const)
0500   template <typename T> ArrayRef(const ArrayRef<T> &Vec) -> ArrayRef<T>;
0501 
0502   /// Deduction guide to construct an ArrayRef from an ArrayRef
0503   template <typename T> ArrayRef(ArrayRef<T> &Vec) -> ArrayRef<T>;
0504 
0505   /// Deduction guide to construct an ArrayRef from a C array.
0506   template <typename T, size_t N> ArrayRef(const T (&Arr)[N]) -> ArrayRef<T>;
0507 
0508   /// @}
0509 
0510   /// @name MutableArrayRef Deduction guides
0511   /// @{
0512   /// Deduction guide to construct a `MutableArrayRef` from a single element
0513   template <class T> MutableArrayRef(T &OneElt) -> MutableArrayRef<T>;
0514 
0515   /// Deduction guide to construct a `MutableArrayRef` from a pointer and
0516   /// length.
0517   template <class T>
0518   MutableArrayRef(T *data, size_t length) -> MutableArrayRef<T>;
0519 
0520   /// Deduction guide to construct a `MutableArrayRef` from a `SmallVector`.
0521   template <class T>
0522   MutableArrayRef(SmallVectorImpl<T> &Vec) -> MutableArrayRef<T>;
0523 
0524   template <class T, unsigned N>
0525   MutableArrayRef(SmallVector<T, N> &Vec) -> MutableArrayRef<T>;
0526 
0527   /// Deduction guide to construct a `MutableArrayRef` from a `std::vector`.
0528   template <class T> MutableArrayRef(std::vector<T> &Vec) -> MutableArrayRef<T>;
0529 
0530   /// Deduction guide to construct a `MutableArrayRef` from a `std::array`.
0531   template <class T, std::size_t N>
0532   MutableArrayRef(std::array<T, N> &Vec) -> MutableArrayRef<T>;
0533 
0534   /// Deduction guide to construct a `MutableArrayRef` from a C array.
0535   template <typename T, size_t N>
0536   MutableArrayRef(T (&Arr)[N]) -> MutableArrayRef<T>;
0537 
0538   /// @}
0539   /// @name ArrayRef Comparison Operators
0540   /// @{
0541 
0542   template<typename T>
0543   inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
0544     return LHS.equals(RHS);
0545   }
0546 
0547   template <typename T>
0548   inline bool operator==(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
0549     return ArrayRef<T>(LHS).equals(RHS);
0550   }
0551 
0552   template <typename T>
0553   inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
0554     return !(LHS == RHS);
0555   }
0556 
0557   template <typename T>
0558   inline bool operator!=(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
0559     return !(LHS == RHS);
0560   }
0561 
0562   /// @}
0563 
0564   template <typename T> hash_code hash_value(ArrayRef<T> S) {
0565     return hash_combine_range(S.begin(), S.end());
0566   }
0567 
0568   // Provide DenseMapInfo for ArrayRefs.
0569   template <typename T> struct DenseMapInfo<ArrayRef<T>, void> {
0570     static inline ArrayRef<T> getEmptyKey() {
0571       return ArrayRef<T>(
0572           reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)), size_t(0));
0573     }
0574 
0575     static inline ArrayRef<T> getTombstoneKey() {
0576       return ArrayRef<T>(
0577           reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)), size_t(0));
0578     }
0579 
0580     static unsigned getHashValue(ArrayRef<T> Val) {
0581       assert(Val.data() != getEmptyKey().data() &&
0582              "Cannot hash the empty key!");
0583       assert(Val.data() != getTombstoneKey().data() &&
0584              "Cannot hash the tombstone key!");
0585       return (unsigned)(hash_value(Val));
0586     }
0587 
0588     static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
0589       if (RHS.data() == getEmptyKey().data())
0590         return LHS.data() == getEmptyKey().data();
0591       if (RHS.data() == getTombstoneKey().data())
0592         return LHS.data() == getTombstoneKey().data();
0593       return LHS == RHS;
0594     }
0595   };
0596 
0597 } // end namespace llvm
0598 
0599 #endif // LLVM_ADT_ARRAYREF_H