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