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