xref: /aosp_15_r20/external/executorch/runtime/core/span.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #pragma once
10 
11 #include <cstdint>
12 
13 #include <executorch/runtime/platform/assert.h>
14 
15 namespace executorch {
16 namespace runtime {
17 
18 /**
19  * Represent a reference to an array (0 or more elements
20  * consecutively in memory), i.e. a start pointer and a length.  It allows
21  * various APIs to take consecutive elements easily and conveniently.
22  *
23  * This class does not own the underlying data, it is expected to be used in
24  * situations where the data resides in some other buffer, whose lifetime
25  * extends past that of the Span.
26  *
27  * Span and ArrayRef are extrememly similar with the difference being ArrayRef
28  * views a list of constant elements and Span views a list of mutable elements.
29  * Clients should decide between the two based on if the list elements for their
30  * use case should be mutable.
31  *
32  * This is intended to be trivially copyable, so it should be passed by
33  * value.
34  */
35 template <typename T>
36 class Span final {
37  public:
38   using iterator = T*;
39   using size_type = size_t;
40 
41  public:
42   /// Construct an empty Span.
Span()43   /* implicit */ constexpr Span() noexcept : data_(nullptr), length_(0) {}
44 
45   /// Construct a Span from a pointer and length.
Span(T * data,size_t length)46   Span(T* data, size_t length) : data_(data), length_(length) {
47     ET_DCHECK(data_ != nullptr || length_ == 0);
48   }
49 
50   /// Construct a Span from a range.
Span(T * begin,T * end)51   Span(T* begin, T* end) : data_(begin), length_(end - begin) {}
52 
53   /// Construct a Span from a C array.
54   template <size_t N>
Span(T (& Arr)[N])55   /* implicit */ constexpr Span(T (&Arr)[N]) : data_(Arr), length_(N) {}
56 
57   /// @returns a pointer to the start of the underlying element buffer.
begin()58   iterator begin() const noexcept {
59     return data_;
60   }
61 
62   /// @returns a pointer to the end of the underlying element buffer.
end()63   iterator end() const noexcept {
64     return data_ + length_;
65   }
66 
67   /// @retval a boolean indicating if the Span is empty.
empty()68   constexpr bool empty() const noexcept {
69     return length_ == 0;
70   }
71 
72   /// @returns a pointer to the start of the underlying element buffer.
data()73   constexpr T* data() const noexcept {
74     return data_;
75   }
76 
77   /// @returns the number of elements in the Span.
size()78   constexpr size_t size() const noexcept {
79     return length_;
80   }
81 
82   /// Unchecked index into the array according to the argument index.
83   /// @returns a reference to the element at the specified index.
84   T& operator[](size_t index) const {
85     return data_[index];
86   }
87 
88  private:
89   /// The start of the array, in an external buffer.
90   T* data_;
91 
92   /// The number of elements.
93   size_type length_;
94 };
95 
96 } // namespace runtime
97 } // namespace executorch
98 
99 namespace torch {
100 namespace executor {
101 // TODO(T197294990): Remove these deprecated aliases once all users have moved
102 // to the new `::executorch` namespaces.
103 using ::executorch::runtime::Span;
104 } // namespace executor
105 } // namespace torch
106