| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #include <c10/util/C++17.h> |
| #include <c10/util/Deprecated.h> |
| #include <c10/util/Exception.h> |
| #include <c10/util/SmallVector.h> |
|
|
| #include <array> |
| #include <iterator> |
| #include <vector> |
|
|
| namespace c10 { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| template <typename T> |
| class ArrayRef final { |
| public: |
| using iterator = const T*; |
| using const_iterator = const T*; |
| using size_type = size_t; |
| using value_type = T; |
|
|
| using reverse_iterator = std::reverse_iterator<iterator>; |
|
|
| private: |
| |
| const T* Data; |
|
|
| |
| size_type Length; |
|
|
| void debugCheckNullptrInvariant() { |
| TORCH_INTERNAL_ASSERT_DEBUG_ONLY( |
| Data != nullptr || Length == 0, |
| "created ArrayRef with nullptr and non-zero length! c10::optional relies on this being illegal"); |
| } |
|
|
| public: |
| |
| |
|
|
| |
| constexpr ArrayRef() : Data(nullptr), Length(0) {} |
|
|
| |
| |
| constexpr ArrayRef(const T& OneElt) : Data(&OneElt), Length(1) {} |
|
|
| |
| C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA ArrayRef(const T* data, size_t length) |
| : Data(data), Length(length) { |
| debugCheckNullptrInvariant(); |
| } |
|
|
| |
| C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA ArrayRef(const T* begin, const T* end) |
| : Data(begin), Length(end - begin) { |
| debugCheckNullptrInvariant(); |
| } |
|
|
| |
| |
| |
| template <typename U> |
| ArrayRef(const SmallVectorTemplateCommon<T, U>& Vec) |
| : Data(Vec.data()), Length(Vec.size()) { |
| debugCheckNullptrInvariant(); |
| } |
|
|
| template < |
| typename Container, |
| typename = std::enable_if_t<std::is_same< |
| std::remove_const_t<decltype(std::declval<Container>().data())>, |
| T*>::value>> |
| ArrayRef(const Container& container) |
| : Data(container.data()), Length(container.size()) { |
| debugCheckNullptrInvariant(); |
| } |
|
|
| |
| |
| |
| |
| template <typename A> |
| ArrayRef(const std::vector<T, A>& Vec) |
| : Data(Vec.data()), Length(Vec.size()) { |
| static_assert( |
| !std::is_same<T, bool>::value, |
| "ArrayRef<bool> cannot be constructed from a std::vector<bool> bitfield."); |
| } |
|
|
| |
| template <size_t N> |
| constexpr ArrayRef(const std::array<T, N>& Arr) |
| : Data(Arr.data()), Length(N) {} |
|
|
| |
| template <size_t N> |
| constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {} |
|
|
| |
| constexpr ArrayRef(const std::initializer_list<T>& Vec) |
| : Data( |
| std::begin(Vec) == std::end(Vec) ? static_cast<T*>(nullptr) |
| : std::begin(Vec)), |
| Length(Vec.size()) {} |
|
|
| |
| |
| |
|
|
| constexpr iterator begin() const { |
| return Data; |
| } |
| constexpr iterator end() const { |
| return Data + Length; |
| } |
|
|
| |
| |
| constexpr const_iterator cbegin() const { |
| return Data; |
| } |
| constexpr const_iterator cend() const { |
| return Data + Length; |
| } |
|
|
| constexpr reverse_iterator rbegin() const { |
| return reverse_iterator(end()); |
| } |
| constexpr reverse_iterator rend() const { |
| return reverse_iterator(begin()); |
| } |
|
|
| |
| constexpr bool empty() const { |
| return Length == 0; |
| } |
|
|
| constexpr const T* data() const { |
| return Data; |
| } |
|
|
| |
| constexpr size_t size() const { |
| return Length; |
| } |
|
|
| |
| C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA const T& front() const { |
| TORCH_CHECK( |
| !empty(), "ArrayRef: attempted to access front() of empty list"); |
| return Data[0]; |
| } |
|
|
| |
| C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA const T& back() const { |
| TORCH_CHECK(!empty(), "ArrayRef: attempted to access back() of empty list"); |
| return Data[Length - 1]; |
| } |
|
|
| |
| constexpr bool equals(ArrayRef RHS) const { |
| return Length == RHS.Length && std::equal(begin(), end(), RHS.begin()); |
| } |
|
|
| |
| C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA ArrayRef<T> slice(size_t N, size_t M) |
| const { |
| TORCH_CHECK( |
| N + M <= size(), |
| "ArrayRef: invalid slice, N = ", |
| N, |
| "; M = ", |
| M, |
| "; size = ", |
| size()); |
| return ArrayRef<T>(data() + N, M); |
| } |
|
|
| |
| constexpr ArrayRef<T> slice(size_t N) const { |
| return slice(N, size() - N); |
| } |
|
|
| |
| |
| |
| constexpr const T& operator[](size_t Index) const { |
| return Data[Index]; |
| } |
|
|
| |
| C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA const T& at(size_t Index) const { |
| TORCH_CHECK( |
| Index < Length, |
| "ArrayRef: invalid index Index = ", |
| Index, |
| "; Length = ", |
| Length); |
| return Data[Index]; |
| } |
|
|
| |
| |
| |
| |
| template <typename U> |
| typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type& |
| operator=(U&& Temporary) = delete; |
|
|
| |
| |
| |
| |
| template <typename U> |
| typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type& |
| operator=(std::initializer_list<U>) = delete; |
|
|
| |
| |
| |
| std::vector<T> vec() const { |
| return std::vector<T>(Data, Data + Length); |
| } |
|
|
| |
| }; |
|
|
| template <typename T> |
| std::ostream& operator<<(std::ostream& out, ArrayRef<T> list) { |
| int i = 0; |
| out << "["; |
| for (auto e : list) { |
| if (i++ > 0) |
| out << ", "; |
| out << e; |
| } |
| out << "]"; |
| return out; |
| } |
|
|
| |
| |
|
|
| |
| template <typename T> |
| ArrayRef<T> makeArrayRef(const T& OneElt) { |
| return OneElt; |
| } |
|
|
| |
| template <typename T> |
| ArrayRef<T> makeArrayRef(const T* data, size_t length) { |
| return ArrayRef<T>(data, length); |
| } |
|
|
| |
| template <typename T> |
| ArrayRef<T> makeArrayRef(const T* begin, const T* end) { |
| return ArrayRef<T>(begin, end); |
| } |
|
|
| |
| template <typename T> |
| ArrayRef<T> makeArrayRef(const SmallVectorImpl<T>& Vec) { |
| return Vec; |
| } |
|
|
| |
| template <typename T, unsigned N> |
| ArrayRef<T> makeArrayRef(const SmallVector<T, N>& Vec) { |
| return Vec; |
| } |
|
|
| |
| template <typename T> |
| ArrayRef<T> makeArrayRef(const std::vector<T>& Vec) { |
| return Vec; |
| } |
|
|
| |
| template <typename T, std::size_t N> |
| ArrayRef<T> makeArrayRef(const std::array<T, N>& Arr) { |
| return Arr; |
| } |
|
|
| |
| template <typename T> |
| ArrayRef<T> makeArrayRef(const ArrayRef<T>& Vec) { |
| return Vec; |
| } |
|
|
| |
| template <typename T> |
| ArrayRef<T>& makeArrayRef(ArrayRef<T>& Vec) { |
| return Vec; |
| } |
|
|
| |
| template <typename T, size_t N> |
| ArrayRef<T> makeArrayRef(const T (&Arr)[N]) { |
| return ArrayRef<T>(Arr); |
| } |
|
|
| |
| |
| |
|
|
| template <typename T> |
| bool operator==(c10::ArrayRef<T> a1, c10::ArrayRef<T> a2) { |
| return a1.equals(a2); |
| } |
|
|
| template <typename T> |
| bool operator!=(c10::ArrayRef<T> a1, c10::ArrayRef<T> a2) { |
| return !a1.equals(a2); |
| } |
|
|
| template <typename T> |
| bool operator==(const std::vector<T>& a1, c10::ArrayRef<T> a2) { |
| return c10::ArrayRef<T>(a1).equals(a2); |
| } |
|
|
| template <typename T> |
| bool operator!=(const std::vector<T>& a1, c10::ArrayRef<T> a2) { |
| return !c10::ArrayRef<T>(a1).equals(a2); |
| } |
|
|
| template <typename T> |
| bool operator==(c10::ArrayRef<T> a1, const std::vector<T>& a2) { |
| return a1.equals(c10::ArrayRef<T>(a2)); |
| } |
|
|
| template <typename T> |
| bool operator!=(c10::ArrayRef<T> a1, const std::vector<T>& a2) { |
| return !a1.equals(c10::ArrayRef<T>(a2)); |
| } |
|
|
| using IntArrayRef = ArrayRef<int64_t>; |
|
|
| |
| |
| C10_DEFINE_DEPRECATED_USING(IntList, ArrayRef<int64_t>) |
|
|
| } |
|
|