1 // 2 // Copyright 2025 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // Span.h: 7 // Basic implementation of C++20's span. 8 // 9 10 #ifndef COMMON_SPAN_H_ 11 #define COMMON_SPAN_H_ 12 13 #include <type_traits> 14 15 #include "common/log_utils.h" 16 17 namespace angle 18 { 19 20 // Basic implementation of C++20's span. 21 // See the reference for std::span here: https://en.cppreference.com/w/cpp/container/span 22 template <typename T> 23 class Span 24 { 25 public: 26 typedef size_t size_type; 27 28 constexpr Span() = default; Span(T * ptr,size_type size)29 constexpr Span(T *ptr, size_type size) : mData(ptr), mSize(size) {} 30 31 template <typename V, 32 typename = std::enable_if_t<std::remove_reference_t<V>::is_pool_allocated>> Span(V && vec)33 constexpr Span(V &&vec) : mData(vec.data()), mSize(vec.size()) 34 {} 35 36 template <typename V, 37 typename = std::enable_if_t<std::remove_reference_t<V>::is_pool_allocated>> 38 constexpr Span &operator=(V &&vec) 39 { 40 mData = vec.data(); 41 mSize = vec.size(); 42 return *this; 43 } 44 45 constexpr bool operator==(const Span &that) const 46 { 47 if (mSize != that.mSize) 48 { 49 return false; 50 } 51 52 if (mData == that.mData) 53 { 54 return true; 55 } 56 57 for (size_type index = 0; index < mSize; ++index) 58 { 59 if (mData[index] != that.mData[index]) 60 { 61 return false; 62 } 63 } 64 65 return true; 66 } 67 constexpr bool operator!=(const Span &that) const { return !(*this == that); } 68 data()69 constexpr T *data() const { return mData; } size()70 constexpr size_type size() const { return mSize; } empty()71 constexpr bool empty() const { return mSize == 0; } 72 73 constexpr T &operator[](size_type index) const { return mData[index]; } front()74 constexpr T &front() const { return mData[0]; } back()75 constexpr T &back() const { return mData[mSize - 1]; } 76 begin()77 constexpr T *begin() const { return mData; } end()78 constexpr T *end() const { return mData + mSize; } 79 rbegin()80 constexpr std::reverse_iterator<T *> rbegin() const 81 { 82 return std::make_reverse_iterator(end()); 83 } rend()84 constexpr std::reverse_iterator<T *> rend() const 85 { 86 return std::make_reverse_iterator(begin()); 87 } 88 first(size_type count)89 constexpr Span first(size_type count) const 90 { 91 ASSERT(count <= mSize); 92 return count == 0 ? Span() : Span(mData, count); 93 } last(size_type count)94 constexpr Span last(size_type count) const 95 { 96 ASSERT(count <= mSize); 97 return count == 0 ? Span() : Span(mData + mSize - count, count); 98 } subspan(size_type offset,size_type count)99 constexpr Span subspan(size_type offset, size_type count) const 100 { 101 ASSERT(offset + count <= mSize); 102 return count == 0 ? Span() : Span(mData + offset, count); 103 } 104 105 private: 106 T *mData = nullptr; 107 size_t mSize = 0; 108 }; 109 110 } // namespace angle 111 112 #endif // COMMON_SPAN_ 113