Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.