21 Span(T* ptr,
size_t size) : size(size), contents(ptr) {}
23 Span(
const Span& other) : size(other.size), contents(other.contents) {}
25 Span(Span&& other) noexcept : size(other.size), contents(other.contents) {
27 other.contents =
nullptr;
31 std::enable_if_t<std::is_convertible_v<U*, T*>,
int> = 0>
32 Span(
const Span<U>& other)
33 : size(other.GetSize()), contents(std::move(other.contents)) {}
36 std::enable_if_t<std::is_convertible_v<U*, T*>,
int> = 0>
37 Span(Span<U>&& other) noexcept
38 : size(other.GetSize()), contents(std::move(other.contents)) {
40 other.contents =
nullptr;
44 std::enable_if_t<std::is_convertible_v<U*, T*>,
int> = 0>
45 Span& operator=(
const Span<U>& other) {
47 contents = other.contents;
53 std::enable_if_t<std::is_convertible_v<U*, T*>,
int> = 0>
54 Span& operator=(Span<U>&& other)
noexcept {
55 if (
this !=
reinterpret_cast<Span<T>*
>(&other)) {
57 contents = other.contents;
59 other.contents =
nullptr;
64 Span& operator=(
const Span& other) {
66 contents = other.contents;
69 Span& operator=(Span&& other)
noexcept {
71 contents = other.contents;
74 other.contents =
nullptr;
84 [[nodiscard]]
const T& GetBegin()
const {
88 [[nodiscard]] T& GetBegin() {
92 [[nodiscard]]
const T& GetEnd()
const {
93 return contents[size];
96 [[nodiscard]] T& GetEnd() {
97 return contents[size];
100 bool TryGet(T& outValue,
size_t index) {
102 outValue = contents[index];
109 size_t GetSize()
const {
113 Span<T> GetSubspan(
size_t firstIndex,
size_t count) {
114 GS_ASSERT_ENGINE_WITH_MESSAGE(count == 0 || firstIndex + count <= size,
"Array index is invalid.");
115 return Span<T>{ &contents[firstIndex], count };
118 T& operator[](
size_t index) {
119 GS_ASSERT_ENGINE_WITH_MESSAGE(index < size,
"Array index is invalid.");
120 return contents[index];
123 const T& operator[](
size_t index)
const {
124 GS_ASSERT_ENGINE_WITH_MESSAGE(index < size,
"Array index is invalid.");
125 return contents[index];
128 [[nodiscard]]
constexpr Iterator begin()
noexcept {
129 return Iterator(contents);
132 [[nodiscard]]
constexpr ConstIterator begin()
const noexcept {
133 return ConstIterator(contents);
136 [[nodiscard]]
constexpr Iterator end()
noexcept {
137 return Iterator(&contents[size]);
140 [[nodiscard]]
constexpr ConstIterator end()
const noexcept {
141 return ConstIterator(&contents[size]);
144 [[nodiscard]]
constexpr ReverseIterator rbegin()
noexcept {
145 return ReverseIterator(end());
148 [[nodiscard]]
constexpr ConstReverseIterator rbegin()
const noexcept {
149 return ConstReverseIterator(end());
152 [[nodiscard]]
constexpr ReverseIterator rend()
noexcept {
153 return ReverseIterator(begin());
156 [[nodiscard]]
constexpr ConstReverseIterator rend()
const noexcept {
157 return ConstReverseIterator(begin());
160 [[nodiscard]]
constexpr ConstIterator cbegin()
const noexcept {
161 return ConstIterator(contents);
164 [[nodiscard]]
constexpr ConstIterator cend()
const noexcept {
165 return ConstIterator(&contents[size]);
168 [[nodiscard]]
constexpr ConstReverseIterator crbegin()
const noexcept {
169 return ConstReverseIterator(end());
172 [[nodiscard]]
constexpr ConstReverseIterator crend()
const noexcept {
173 return ConstReverseIterator(begin());
177 T* contents =
nullptr;