xref: /aosp_15_r20/external/pytorch/c10/util/ArrayRef.h (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker //===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
2*da0073e9SAndroid Build Coastguard Worker //
3*da0073e9SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*da0073e9SAndroid Build Coastguard Worker //
5*da0073e9SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*da0073e9SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*da0073e9SAndroid Build Coastguard Worker //
8*da0073e9SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*da0073e9SAndroid Build Coastguard Worker 
10*da0073e9SAndroid Build Coastguard Worker // ATen: modified from llvm::ArrayRef.
11*da0073e9SAndroid Build Coastguard Worker // removed llvm-specific functionality
12*da0073e9SAndroid Build Coastguard Worker // removed some implicit const -> non-const conversions that rely on
13*da0073e9SAndroid Build Coastguard Worker // complicated std::enable_if meta-programming
14*da0073e9SAndroid Build Coastguard Worker // removed a bunch of slice variants for simplicity...
15*da0073e9SAndroid Build Coastguard Worker 
16*da0073e9SAndroid Build Coastguard Worker #pragma once
17*da0073e9SAndroid Build Coastguard Worker 
18*da0073e9SAndroid Build Coastguard Worker #include <c10/macros/Macros.h>
19*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Deprecated.h>
20*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Exception.h>
21*da0073e9SAndroid Build Coastguard Worker #include <c10/util/SmallVector.h>
22*da0073e9SAndroid Build Coastguard Worker 
23*da0073e9SAndroid Build Coastguard Worker #include <array>
24*da0073e9SAndroid Build Coastguard Worker #include <cstddef>
25*da0073e9SAndroid Build Coastguard Worker #include <cstdint>
26*da0073e9SAndroid Build Coastguard Worker #include <initializer_list>
27*da0073e9SAndroid Build Coastguard Worker #include <iterator>
28*da0073e9SAndroid Build Coastguard Worker #include <ostream>
29*da0073e9SAndroid Build Coastguard Worker #include <type_traits>
30*da0073e9SAndroid Build Coastguard Worker #include <vector>
31*da0073e9SAndroid Build Coastguard Worker 
32*da0073e9SAndroid Build Coastguard Worker namespace c10 {
33*da0073e9SAndroid Build Coastguard Worker /// ArrayRef - Represent a constant reference to an array (0 or more elements
34*da0073e9SAndroid Build Coastguard Worker /// consecutively in memory), i.e. a start pointer and a length.  It allows
35*da0073e9SAndroid Build Coastguard Worker /// various APIs to take consecutive elements easily and conveniently.
36*da0073e9SAndroid Build Coastguard Worker ///
37*da0073e9SAndroid Build Coastguard Worker /// This class does not own the underlying data, it is expected to be used in
38*da0073e9SAndroid Build Coastguard Worker /// situations where the data resides in some other buffer, whose lifetime
39*da0073e9SAndroid Build Coastguard Worker /// extends past that of the ArrayRef. For this reason, it is not in general
40*da0073e9SAndroid Build Coastguard Worker /// safe to store an ArrayRef.
41*da0073e9SAndroid Build Coastguard Worker ///
42*da0073e9SAndroid Build Coastguard Worker /// This is intended to be trivially copyable, so it should be passed by
43*da0073e9SAndroid Build Coastguard Worker /// value.
44*da0073e9SAndroid Build Coastguard Worker template <typename T>
45*da0073e9SAndroid Build Coastguard Worker class ArrayRef final {
46*da0073e9SAndroid Build Coastguard Worker  public:
47*da0073e9SAndroid Build Coastguard Worker   using iterator = const T*;
48*da0073e9SAndroid Build Coastguard Worker   using const_iterator = const T*;
49*da0073e9SAndroid Build Coastguard Worker   using size_type = size_t;
50*da0073e9SAndroid Build Coastguard Worker   using value_type = T;
51*da0073e9SAndroid Build Coastguard Worker 
52*da0073e9SAndroid Build Coastguard Worker   using reverse_iterator = std::reverse_iterator<iterator>;
53*da0073e9SAndroid Build Coastguard Worker 
54*da0073e9SAndroid Build Coastguard Worker  private:
55*da0073e9SAndroid Build Coastguard Worker   /// The start of the array, in an external buffer.
56*da0073e9SAndroid Build Coastguard Worker   const T* Data;
57*da0073e9SAndroid Build Coastguard Worker 
58*da0073e9SAndroid Build Coastguard Worker   /// The number of elements.
59*da0073e9SAndroid Build Coastguard Worker   size_type Length;
60*da0073e9SAndroid Build Coastguard Worker 
debugCheckNullptrInvariant()61*da0073e9SAndroid Build Coastguard Worker   void debugCheckNullptrInvariant() {
62*da0073e9SAndroid Build Coastguard Worker     TORCH_INTERNAL_ASSERT_DEBUG_ONLY(
63*da0073e9SAndroid Build Coastguard Worker         Data != nullptr || Length == 0,
64*da0073e9SAndroid Build Coastguard Worker         "created ArrayRef with nullptr and non-zero length! std::optional relies on this being illegal");
65*da0073e9SAndroid Build Coastguard Worker   }
66*da0073e9SAndroid Build Coastguard Worker 
67*da0073e9SAndroid Build Coastguard Worker  public:
68*da0073e9SAndroid Build Coastguard Worker   /// @name Constructors
69*da0073e9SAndroid Build Coastguard Worker   /// @{
70*da0073e9SAndroid Build Coastguard Worker 
71*da0073e9SAndroid Build Coastguard Worker   /// Construct an empty ArrayRef.
ArrayRef()72*da0073e9SAndroid Build Coastguard Worker   /* implicit */ constexpr ArrayRef() : Data(nullptr), Length(0) {}
73*da0073e9SAndroid Build Coastguard Worker 
74*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a single element.
75*da0073e9SAndroid Build Coastguard Worker   // TODO Make this explicit
ArrayRef(const T & OneElt)76*da0073e9SAndroid Build Coastguard Worker   constexpr ArrayRef(const T& OneElt) : Data(&OneElt), Length(1) {}
77*da0073e9SAndroid Build Coastguard Worker 
78*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a pointer and length.
ArrayRef(const T * data,size_t length)79*da0073e9SAndroid Build Coastguard Worker   C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA ArrayRef(const T* data, size_t length)
80*da0073e9SAndroid Build Coastguard Worker       : Data(data), Length(length) {
81*da0073e9SAndroid Build Coastguard Worker     debugCheckNullptrInvariant();
82*da0073e9SAndroid Build Coastguard Worker   }
83*da0073e9SAndroid Build Coastguard Worker 
84*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a range.
ArrayRef(const T * begin,const T * end)85*da0073e9SAndroid Build Coastguard Worker   C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA ArrayRef(const T* begin, const T* end)
86*da0073e9SAndroid Build Coastguard Worker       : Data(begin), Length(end - begin) {
87*da0073e9SAndroid Build Coastguard Worker     debugCheckNullptrInvariant();
88*da0073e9SAndroid Build Coastguard Worker   }
89*da0073e9SAndroid Build Coastguard Worker 
90*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a SmallVector. This is templated in order to
91*da0073e9SAndroid Build Coastguard Worker   /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
92*da0073e9SAndroid Build Coastguard Worker   /// copy-construct an ArrayRef.
93*da0073e9SAndroid Build Coastguard Worker   template <typename U>
ArrayRef(const SmallVectorTemplateCommon<T,U> & Vec)94*da0073e9SAndroid Build Coastguard Worker   /* implicit */ ArrayRef(const SmallVectorTemplateCommon<T, U>& Vec)
95*da0073e9SAndroid Build Coastguard Worker       : Data(Vec.data()), Length(Vec.size()) {
96*da0073e9SAndroid Build Coastguard Worker     debugCheckNullptrInvariant();
97*da0073e9SAndroid Build Coastguard Worker   }
98*da0073e9SAndroid Build Coastguard Worker 
99*da0073e9SAndroid Build Coastguard Worker   template <
100*da0073e9SAndroid Build Coastguard Worker       typename Container,
101*da0073e9SAndroid Build Coastguard Worker       typename = std::enable_if_t<std::is_same_v<
102*da0073e9SAndroid Build Coastguard Worker           std::remove_const_t<decltype(std::declval<Container>().data())>,
103*da0073e9SAndroid Build Coastguard Worker           T*>>>
ArrayRef(const Container & container)104*da0073e9SAndroid Build Coastguard Worker   /* implicit */ ArrayRef(const Container& container)
105*da0073e9SAndroid Build Coastguard Worker       : Data(container.data()), Length(container.size()) {
106*da0073e9SAndroid Build Coastguard Worker     debugCheckNullptrInvariant();
107*da0073e9SAndroid Build Coastguard Worker   }
108*da0073e9SAndroid Build Coastguard Worker 
109*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a std::vector.
110*da0073e9SAndroid Build Coastguard Worker   // The enable_if stuff here makes sure that this isn't used for
111*da0073e9SAndroid Build Coastguard Worker   // std::vector<bool>, because ArrayRef can't work on a std::vector<bool>
112*da0073e9SAndroid Build Coastguard Worker   // bitfield.
113*da0073e9SAndroid Build Coastguard Worker   template <typename A>
ArrayRef(const std::vector<T,A> & Vec)114*da0073e9SAndroid Build Coastguard Worker   /* implicit */ ArrayRef(const std::vector<T, A>& Vec)
115*da0073e9SAndroid Build Coastguard Worker       : Data(Vec.data()), Length(Vec.size()) {
116*da0073e9SAndroid Build Coastguard Worker     static_assert(
117*da0073e9SAndroid Build Coastguard Worker         !std::is_same<T, bool>::value,
118*da0073e9SAndroid Build Coastguard Worker         "ArrayRef<bool> cannot be constructed from a std::vector<bool> bitfield.");
119*da0073e9SAndroid Build Coastguard Worker   }
120*da0073e9SAndroid Build Coastguard Worker 
121*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a std::array
122*da0073e9SAndroid Build Coastguard Worker   template <size_t N>
ArrayRef(const std::array<T,N> & Arr)123*da0073e9SAndroid Build Coastguard Worker   /* implicit */ constexpr ArrayRef(const std::array<T, N>& Arr)
124*da0073e9SAndroid Build Coastguard Worker       : Data(Arr.data()), Length(N) {}
125*da0073e9SAndroid Build Coastguard Worker 
126*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a C array.
127*da0073e9SAndroid Build Coastguard Worker   template <size_t N>
128*da0073e9SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(*c-arrays*)
ArrayRef(const T (& Arr)[N])129*da0073e9SAndroid Build Coastguard Worker   /* implicit */ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {}
130*da0073e9SAndroid Build Coastguard Worker 
131*da0073e9SAndroid Build Coastguard Worker   /// Construct an ArrayRef from a std::initializer_list.
ArrayRef(const std::initializer_list<T> & Vec)132*da0073e9SAndroid Build Coastguard Worker   /* implicit */ constexpr ArrayRef(const std::initializer_list<T>& Vec)
133*da0073e9SAndroid Build Coastguard Worker       : Data(
134*da0073e9SAndroid Build Coastguard Worker             std::begin(Vec) == std::end(Vec) ? static_cast<T*>(nullptr)
135*da0073e9SAndroid Build Coastguard Worker                                              : std::begin(Vec)),
136*da0073e9SAndroid Build Coastguard Worker         Length(Vec.size()) {}
137*da0073e9SAndroid Build Coastguard Worker 
138*da0073e9SAndroid Build Coastguard Worker   /// @}
139*da0073e9SAndroid Build Coastguard Worker   /// @name Simple Operations
140*da0073e9SAndroid Build Coastguard Worker   /// @{
141*da0073e9SAndroid Build Coastguard Worker 
begin()142*da0073e9SAndroid Build Coastguard Worker   constexpr iterator begin() const {
143*da0073e9SAndroid Build Coastguard Worker     return Data;
144*da0073e9SAndroid Build Coastguard Worker   }
end()145*da0073e9SAndroid Build Coastguard Worker   constexpr iterator end() const {
146*da0073e9SAndroid Build Coastguard Worker     return Data + Length;
147*da0073e9SAndroid Build Coastguard Worker   }
148*da0073e9SAndroid Build Coastguard Worker 
149*da0073e9SAndroid Build Coastguard Worker   // These are actually the same as iterator, since ArrayRef only
150*da0073e9SAndroid Build Coastguard Worker   // gives you const iterators.
cbegin()151*da0073e9SAndroid Build Coastguard Worker   constexpr const_iterator cbegin() const {
152*da0073e9SAndroid Build Coastguard Worker     return Data;
153*da0073e9SAndroid Build Coastguard Worker   }
cend()154*da0073e9SAndroid Build Coastguard Worker   constexpr const_iterator cend() const {
155*da0073e9SAndroid Build Coastguard Worker     return Data + Length;
156*da0073e9SAndroid Build Coastguard Worker   }
157*da0073e9SAndroid Build Coastguard Worker 
rbegin()158*da0073e9SAndroid Build Coastguard Worker   constexpr reverse_iterator rbegin() const {
159*da0073e9SAndroid Build Coastguard Worker     return reverse_iterator(end());
160*da0073e9SAndroid Build Coastguard Worker   }
rend()161*da0073e9SAndroid Build Coastguard Worker   constexpr reverse_iterator rend() const {
162*da0073e9SAndroid Build Coastguard Worker     return reverse_iterator(begin());
163*da0073e9SAndroid Build Coastguard Worker   }
164*da0073e9SAndroid Build Coastguard Worker 
165*da0073e9SAndroid Build Coastguard Worker   /// empty - Check if the array is empty.
empty()166*da0073e9SAndroid Build Coastguard Worker   constexpr bool empty() const {
167*da0073e9SAndroid Build Coastguard Worker     return Length == 0;
168*da0073e9SAndroid Build Coastguard Worker   }
169*da0073e9SAndroid Build Coastguard Worker 
data()170*da0073e9SAndroid Build Coastguard Worker   constexpr const T* data() const {
171*da0073e9SAndroid Build Coastguard Worker     return Data;
172*da0073e9SAndroid Build Coastguard Worker   }
173*da0073e9SAndroid Build Coastguard Worker 
174*da0073e9SAndroid Build Coastguard Worker   /// size - Get the array size.
size()175*da0073e9SAndroid Build Coastguard Worker   constexpr size_t size() const {
176*da0073e9SAndroid Build Coastguard Worker     return Length;
177*da0073e9SAndroid Build Coastguard Worker   }
178*da0073e9SAndroid Build Coastguard Worker 
179*da0073e9SAndroid Build Coastguard Worker   /// front - Get the first element.
front()180*da0073e9SAndroid Build Coastguard Worker   C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA const T& front() const {
181*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK(
182*da0073e9SAndroid Build Coastguard Worker         !empty(), "ArrayRef: attempted to access front() of empty list");
183*da0073e9SAndroid Build Coastguard Worker     return Data[0];
184*da0073e9SAndroid Build Coastguard Worker   }
185*da0073e9SAndroid Build Coastguard Worker 
186*da0073e9SAndroid Build Coastguard Worker   /// back - Get the last element.
back()187*da0073e9SAndroid Build Coastguard Worker   C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA const T& back() const {
188*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK(!empty(), "ArrayRef: attempted to access back() of empty list");
189*da0073e9SAndroid Build Coastguard Worker     return Data[Length - 1];
190*da0073e9SAndroid Build Coastguard Worker   }
191*da0073e9SAndroid Build Coastguard Worker 
192*da0073e9SAndroid Build Coastguard Worker   /// equals - Check for element-wise equality.
equals(ArrayRef RHS)193*da0073e9SAndroid Build Coastguard Worker   constexpr bool equals(ArrayRef RHS) const {
194*da0073e9SAndroid Build Coastguard Worker     return Length == RHS.Length && std::equal(begin(), end(), RHS.begin());
195*da0073e9SAndroid Build Coastguard Worker   }
196*da0073e9SAndroid Build Coastguard Worker 
197*da0073e9SAndroid Build Coastguard Worker   /// slice(n, m) - Take M elements of the array starting at element N
slice(size_t N,size_t M)198*da0073e9SAndroid Build Coastguard Worker   C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA ArrayRef<T> slice(size_t N, size_t M)
199*da0073e9SAndroid Build Coastguard Worker       const {
200*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK(
201*da0073e9SAndroid Build Coastguard Worker         N + M <= size(),
202*da0073e9SAndroid Build Coastguard Worker         "ArrayRef: invalid slice, N = ",
203*da0073e9SAndroid Build Coastguard Worker         N,
204*da0073e9SAndroid Build Coastguard Worker         "; M = ",
205*da0073e9SAndroid Build Coastguard Worker         M,
206*da0073e9SAndroid Build Coastguard Worker         "; size = ",
207*da0073e9SAndroid Build Coastguard Worker         size());
208*da0073e9SAndroid Build Coastguard Worker     return ArrayRef<T>(data() + N, M);
209*da0073e9SAndroid Build Coastguard Worker   }
210*da0073e9SAndroid Build Coastguard Worker 
211*da0073e9SAndroid Build Coastguard Worker   /// slice(n) - Chop off the first N elements of the array.
slice(size_t N)212*da0073e9SAndroid Build Coastguard Worker   C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA ArrayRef<T> slice(size_t N) const {
213*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK(
214*da0073e9SAndroid Build Coastguard Worker         N <= size(), "ArrayRef: invalid slice, N = ", N, "; size = ", size());
215*da0073e9SAndroid Build Coastguard Worker     return slice(N, size() - N);
216*da0073e9SAndroid Build Coastguard Worker   }
217*da0073e9SAndroid Build Coastguard Worker 
218*da0073e9SAndroid Build Coastguard Worker   /// @}
219*da0073e9SAndroid Build Coastguard Worker   /// @name Operator Overloads
220*da0073e9SAndroid Build Coastguard Worker   /// @{
221*da0073e9SAndroid Build Coastguard Worker   constexpr const T& operator[](size_t Index) const {
222*da0073e9SAndroid Build Coastguard Worker     return Data[Index];
223*da0073e9SAndroid Build Coastguard Worker   }
224*da0073e9SAndroid Build Coastguard Worker 
225*da0073e9SAndroid Build Coastguard Worker   /// Vector compatibility
at(size_t Index)226*da0073e9SAndroid Build Coastguard Worker   C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA const T& at(size_t Index) const {
227*da0073e9SAndroid Build Coastguard Worker     TORCH_CHECK(
228*da0073e9SAndroid Build Coastguard Worker         Index < Length,
229*da0073e9SAndroid Build Coastguard Worker         "ArrayRef: invalid index Index = ",
230*da0073e9SAndroid Build Coastguard Worker         Index,
231*da0073e9SAndroid Build Coastguard Worker         "; Length = ",
232*da0073e9SAndroid Build Coastguard Worker         Length);
233*da0073e9SAndroid Build Coastguard Worker     return Data[Index];
234*da0073e9SAndroid Build Coastguard Worker   }
235*da0073e9SAndroid Build Coastguard Worker 
236*da0073e9SAndroid Build Coastguard Worker   /// Disallow accidental assignment from a temporary.
237*da0073e9SAndroid Build Coastguard Worker   ///
238*da0073e9SAndroid Build Coastguard Worker   /// The declaration here is extra complicated so that "arrayRef = {}"
239*da0073e9SAndroid Build Coastguard Worker   /// continues to select the move assignment operator.
240*da0073e9SAndroid Build Coastguard Worker   template <typename U>
241*da0073e9SAndroid Build Coastguard Worker   std::enable_if_t<std::is_same_v<U, T>, ArrayRef<T>>& operator=(
242*da0073e9SAndroid Build Coastguard Worker       // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
243*da0073e9SAndroid Build Coastguard Worker       U&& Temporary) = delete;
244*da0073e9SAndroid Build Coastguard Worker 
245*da0073e9SAndroid Build Coastguard Worker   /// Disallow accidental assignment from a temporary.
246*da0073e9SAndroid Build Coastguard Worker   ///
247*da0073e9SAndroid Build Coastguard Worker   /// The declaration here is extra complicated so that "arrayRef = {}"
248*da0073e9SAndroid Build Coastguard Worker   /// continues to select the move assignment operator.
249*da0073e9SAndroid Build Coastguard Worker   template <typename U>
250*da0073e9SAndroid Build Coastguard Worker   std::enable_if_t<std::is_same_v<U, T>, ArrayRef<T>>& operator=(
251*da0073e9SAndroid Build Coastguard Worker       std::initializer_list<U>) = delete;
252*da0073e9SAndroid Build Coastguard Worker 
253*da0073e9SAndroid Build Coastguard Worker   /// @}
254*da0073e9SAndroid Build Coastguard Worker   /// @name Expensive Operations
255*da0073e9SAndroid Build Coastguard Worker   /// @{
vec()256*da0073e9SAndroid Build Coastguard Worker   std::vector<T> vec() const {
257*da0073e9SAndroid Build Coastguard Worker     return std::vector<T>(Data, Data + Length);
258*da0073e9SAndroid Build Coastguard Worker   }
259*da0073e9SAndroid Build Coastguard Worker 
260*da0073e9SAndroid Build Coastguard Worker   /// @}
261*da0073e9SAndroid Build Coastguard Worker };
262*da0073e9SAndroid Build Coastguard Worker 
263*da0073e9SAndroid Build Coastguard Worker template <typename T>
264*da0073e9SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, ArrayRef<T> list) {
265*da0073e9SAndroid Build Coastguard Worker   int i = 0;
266*da0073e9SAndroid Build Coastguard Worker   out << "[";
267*da0073e9SAndroid Build Coastguard Worker   for (const auto& e : list) {
268*da0073e9SAndroid Build Coastguard Worker     if (i++ > 0)
269*da0073e9SAndroid Build Coastguard Worker       out << ", ";
270*da0073e9SAndroid Build Coastguard Worker     out << e;
271*da0073e9SAndroid Build Coastguard Worker   }
272*da0073e9SAndroid Build Coastguard Worker   out << "]";
273*da0073e9SAndroid Build Coastguard Worker   return out;
274*da0073e9SAndroid Build Coastguard Worker }
275*da0073e9SAndroid Build Coastguard Worker 
276*da0073e9SAndroid Build Coastguard Worker /// @name ArrayRef Convenience constructors
277*da0073e9SAndroid Build Coastguard Worker /// @{
278*da0073e9SAndroid Build Coastguard Worker 
279*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a single element.
280*da0073e9SAndroid Build Coastguard Worker template <typename T>
makeArrayRef(const T & OneElt)281*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const T& OneElt) {
282*da0073e9SAndroid Build Coastguard Worker   return OneElt;
283*da0073e9SAndroid Build Coastguard Worker }
284*da0073e9SAndroid Build Coastguard Worker 
285*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a pointer and length.
286*da0073e9SAndroid Build Coastguard Worker template <typename T>
makeArrayRef(const T * data,size_t length)287*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const T* data, size_t length) {
288*da0073e9SAndroid Build Coastguard Worker   return ArrayRef<T>(data, length);
289*da0073e9SAndroid Build Coastguard Worker }
290*da0073e9SAndroid Build Coastguard Worker 
291*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a range.
292*da0073e9SAndroid Build Coastguard Worker template <typename T>
makeArrayRef(const T * begin,const T * end)293*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const T* begin, const T* end) {
294*da0073e9SAndroid Build Coastguard Worker   return ArrayRef<T>(begin, end);
295*da0073e9SAndroid Build Coastguard Worker }
296*da0073e9SAndroid Build Coastguard Worker 
297*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a SmallVector.
298*da0073e9SAndroid Build Coastguard Worker template <typename T>
makeArrayRef(const SmallVectorImpl<T> & Vec)299*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const SmallVectorImpl<T>& Vec) {
300*da0073e9SAndroid Build Coastguard Worker   return Vec;
301*da0073e9SAndroid Build Coastguard Worker }
302*da0073e9SAndroid Build Coastguard Worker 
303*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a SmallVector.
304*da0073e9SAndroid Build Coastguard Worker template <typename T, unsigned N>
makeArrayRef(const SmallVector<T,N> & Vec)305*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const SmallVector<T, N>& Vec) {
306*da0073e9SAndroid Build Coastguard Worker   return Vec;
307*da0073e9SAndroid Build Coastguard Worker }
308*da0073e9SAndroid Build Coastguard Worker 
309*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a std::vector.
310*da0073e9SAndroid Build Coastguard Worker template <typename T>
makeArrayRef(const std::vector<T> & Vec)311*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const std::vector<T>& Vec) {
312*da0073e9SAndroid Build Coastguard Worker   return Vec;
313*da0073e9SAndroid Build Coastguard Worker }
314*da0073e9SAndroid Build Coastguard Worker 
315*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a std::array.
316*da0073e9SAndroid Build Coastguard Worker template <typename T, std::size_t N>
makeArrayRef(const std::array<T,N> & Arr)317*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const std::array<T, N>& Arr) {
318*da0073e9SAndroid Build Coastguard Worker   return Arr;
319*da0073e9SAndroid Build Coastguard Worker }
320*da0073e9SAndroid Build Coastguard Worker 
321*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from an ArrayRef (no-op) (const)
322*da0073e9SAndroid Build Coastguard Worker template <typename T>
makeArrayRef(const ArrayRef<T> & Vec)323*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const ArrayRef<T>& Vec) {
324*da0073e9SAndroid Build Coastguard Worker   return Vec;
325*da0073e9SAndroid Build Coastguard Worker }
326*da0073e9SAndroid Build Coastguard Worker 
327*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from an ArrayRef (no-op)
328*da0073e9SAndroid Build Coastguard Worker template <typename T>
makeArrayRef(ArrayRef<T> & Vec)329*da0073e9SAndroid Build Coastguard Worker ArrayRef<T>& makeArrayRef(ArrayRef<T>& Vec) {
330*da0073e9SAndroid Build Coastguard Worker   return Vec;
331*da0073e9SAndroid Build Coastguard Worker }
332*da0073e9SAndroid Build Coastguard Worker 
333*da0073e9SAndroid Build Coastguard Worker /// Construct an ArrayRef from a C array.
334*da0073e9SAndroid Build Coastguard Worker template <typename T, size_t N>
335*da0073e9SAndroid Build Coastguard Worker // NOLINTNEXTLINE(*c-arrays*)
makeArrayRef(const T (& Arr)[N])336*da0073e9SAndroid Build Coastguard Worker ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
337*da0073e9SAndroid Build Coastguard Worker   return ArrayRef<T>(Arr);
338*da0073e9SAndroid Build Coastguard Worker }
339*da0073e9SAndroid Build Coastguard Worker 
340*da0073e9SAndroid Build Coastguard Worker // WARNING: Template instantiation will NOT be willing to do an implicit
341*da0073e9SAndroid Build Coastguard Worker // conversions to get you to an c10::ArrayRef, which is why we need so
342*da0073e9SAndroid Build Coastguard Worker // many overloads.
343*da0073e9SAndroid Build Coastguard Worker 
344*da0073e9SAndroid Build Coastguard Worker template <typename T>
345*da0073e9SAndroid Build Coastguard Worker bool operator==(c10::ArrayRef<T> a1, c10::ArrayRef<T> a2) {
346*da0073e9SAndroid Build Coastguard Worker   return a1.equals(a2);
347*da0073e9SAndroid Build Coastguard Worker }
348*da0073e9SAndroid Build Coastguard Worker 
349*da0073e9SAndroid Build Coastguard Worker template <typename T>
350*da0073e9SAndroid Build Coastguard Worker bool operator!=(c10::ArrayRef<T> a1, c10::ArrayRef<T> a2) {
351*da0073e9SAndroid Build Coastguard Worker   return !a1.equals(a2);
352*da0073e9SAndroid Build Coastguard Worker }
353*da0073e9SAndroid Build Coastguard Worker 
354*da0073e9SAndroid Build Coastguard Worker template <typename T>
355*da0073e9SAndroid Build Coastguard Worker bool operator==(const std::vector<T>& a1, c10::ArrayRef<T> a2) {
356*da0073e9SAndroid Build Coastguard Worker   return c10::ArrayRef<T>(a1).equals(a2);
357*da0073e9SAndroid Build Coastguard Worker }
358*da0073e9SAndroid Build Coastguard Worker 
359*da0073e9SAndroid Build Coastguard Worker template <typename T>
360*da0073e9SAndroid Build Coastguard Worker bool operator!=(const std::vector<T>& a1, c10::ArrayRef<T> a2) {
361*da0073e9SAndroid Build Coastguard Worker   return !c10::ArrayRef<T>(a1).equals(a2);
362*da0073e9SAndroid Build Coastguard Worker }
363*da0073e9SAndroid Build Coastguard Worker 
364*da0073e9SAndroid Build Coastguard Worker template <typename T>
365*da0073e9SAndroid Build Coastguard Worker bool operator==(c10::ArrayRef<T> a1, const std::vector<T>& a2) {
366*da0073e9SAndroid Build Coastguard Worker   return a1.equals(c10::ArrayRef<T>(a2));
367*da0073e9SAndroid Build Coastguard Worker }
368*da0073e9SAndroid Build Coastguard Worker 
369*da0073e9SAndroid Build Coastguard Worker template <typename T>
370*da0073e9SAndroid Build Coastguard Worker bool operator!=(c10::ArrayRef<T> a1, const std::vector<T>& a2) {
371*da0073e9SAndroid Build Coastguard Worker   return !a1.equals(c10::ArrayRef<T>(a2));
372*da0073e9SAndroid Build Coastguard Worker }
373*da0073e9SAndroid Build Coastguard Worker 
374*da0073e9SAndroid Build Coastguard Worker using IntArrayRef = ArrayRef<int64_t>;
375*da0073e9SAndroid Build Coastguard Worker 
376*da0073e9SAndroid Build Coastguard Worker // This alias is deprecated because it doesn't make ownership
377*da0073e9SAndroid Build Coastguard Worker // semantics obvious.  Use IntArrayRef instead!
378*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_DEPRECATED_USING(IntList, ArrayRef<int64_t>)
379*da0073e9SAndroid Build Coastguard Worker 
380*da0073e9SAndroid Build Coastguard Worker } // namespace c10
381