Blender V4.3
BLI_generic_span.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
11#include "BLI_cpp_type.hh"
12#include "BLI_span.hh"
13
14namespace blender {
15
19class GSpan {
20 protected:
21 const CPPType *type_ = nullptr;
22 const void *data_ = nullptr;
24
25 public:
26 GSpan() = default;
27
28 GSpan(const CPPType *type, const void *buffer, int64_t size)
29 : type_(type), data_(buffer), size_(size)
30 {
31 BLI_assert(size >= 0);
32 BLI_assert(buffer != nullptr || size == 0);
33 BLI_assert(size == 0 || type != nullptr);
34 BLI_assert(type == nullptr || type->pointer_has_valid_alignment(buffer));
35 }
36
37 GSpan(const CPPType &type, const void *buffer, int64_t size) : GSpan(&type, buffer, size) {}
38
39 GSpan(const CPPType &type) : type_(&type) {}
40
41 GSpan(const CPPType *type) : type_(type) {}
42
43 template<typename T>
45 : GSpan(CPPType::get<T>(), static_cast<const void *>(array.data()), array.size())
46 {
47 }
48
49 const CPPType &type() const
50 {
51 BLI_assert(type_ != nullptr);
52 return *type_;
53 }
54
55 const CPPType *type_ptr() const
56 {
57 return type_;
58 }
59
60 bool is_empty() const
61 {
62 return size_ == 0;
63 }
64
65 int64_t size() const
66 {
67 return size_;
68 }
69
71 {
72 return type_->size() * size_;
73 }
74
75 const void *data() const
76 {
77 return data_;
78 }
79
80 const void *operator[](int64_t index) const
81 {
82 BLI_assert(index < size_);
83 return POINTER_OFFSET(data_, type_->size() * index);
84 }
85
86 template<typename T> Span<T> typed() const
87 {
88 BLI_assert(size_ == 0 || type_ != nullptr);
89 BLI_assert(type_ == nullptr || type_->is<T>());
90 return Span<T>(static_cast<const T *>(data_), size_);
91 }
92
93 GSpan slice(const int64_t start, int64_t size) const
94 {
95 BLI_assert(start >= 0);
96 BLI_assert(size >= 0);
97 BLI_assert(start + size <= size_ || size == 0);
98 return GSpan(type_, POINTER_OFFSET(data_, type_->size() * start), size);
99 }
100
101 GSpan slice(const IndexRange range) const
102 {
103 return this->slice(range.start(), range.size());
104 }
105
106 GSpan drop_front(const int64_t n) const
107 {
108 BLI_assert(n >= 0);
109 const int64_t new_size = std::max<int64_t>(0, size_ - n);
110 return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * n), new_size);
111 }
112
113 GSpan drop_back(const int64_t n) const
114 {
115 BLI_assert(n >= 0);
116 const int64_t new_size = std::max<int64_t>(0, size_ - n);
117 return GSpan(*type_, data_, new_size);
118 }
119
120 GSpan take_front(const int64_t n) const
121 {
122 BLI_assert(n >= 0);
123 const int64_t new_size = std::min<int64_t>(size_, n);
124 return GSpan(*type_, data_, new_size);
125 }
126
127 GSpan take_back(const int64_t n) const
128 {
129 BLI_assert(n >= 0);
130 const int64_t new_size = std::min<int64_t>(size_, n);
131 return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * (size_ - new_size)), new_size);
132 }
133};
134
140 protected:
141 const CPPType *type_ = nullptr;
142 void *data_ = nullptr;
144
145 public:
146 GMutableSpan() = default;
147
148 GMutableSpan(const CPPType *type, void *buffer, int64_t size)
149 : type_(type), data_(buffer), size_(size)
150 {
151 BLI_assert(size >= 0);
152 BLI_assert(buffer != nullptr || size == 0);
153 BLI_assert(size == 0 || type != nullptr);
154 BLI_assert(type == nullptr || type->pointer_has_valid_alignment(buffer));
155 }
156
157 GMutableSpan(const CPPType &type, void *buffer, int64_t size) : GMutableSpan(&type, buffer, size)
158 {
159 }
160
161 GMutableSpan(const CPPType &type) : type_(&type) {}
162
163 GMutableSpan(const CPPType *type) : type_(type) {}
164
165 template<typename T>
167 : GMutableSpan(CPPType::get<T>(), static_cast<void *>(array.begin()), array.size())
168 {
169 }
170
171 operator GSpan() const
172 {
173 return GSpan(type_, data_, size_);
174 }
175
176 const CPPType &type() const
177 {
178 BLI_assert(type_ != nullptr);
179 return *type_;
180 }
181
182 const CPPType *type_ptr() const
183 {
184 return type_;
185 }
186
187 bool is_empty() const
188 {
189 return size_ == 0;
190 }
191
192 int64_t size() const
193 {
194 return size_;
195 }
196
198 {
199 return type_->size() * size_;
200 }
201
202 void *data() const
203 {
204 return data_;
205 }
206
207 void *operator[](int64_t index) const
208 {
209 BLI_assert(index >= 0);
210 BLI_assert(index < size_);
211 return POINTER_OFFSET(data_, type_->size() * index);
212 }
213
214 template<typename T> MutableSpan<T> typed() const
215 {
216 BLI_assert(size_ == 0 || type_ != nullptr);
217 BLI_assert(type_ == nullptr || type_->is<T>());
218 return MutableSpan<T>(static_cast<T *>(data_), size_);
219 }
220
221 GMutableSpan slice(const int64_t start, int64_t size) const
222 {
223 BLI_assert(start >= 0);
224 BLI_assert(size >= 0);
225 BLI_assert(start + size <= size_ || size == 0);
226 return GMutableSpan(type_, POINTER_OFFSET(data_, type_->size() * start), size);
227 }
228
230 {
231 return this->slice(range.start(), range.size());
232 }
233
235 {
236 BLI_assert(n >= 0);
237 const int64_t new_size = std::max<int64_t>(0, size_ - n);
238 return GMutableSpan(*type_, POINTER_OFFSET(data_, type_->size() * n), new_size);
239 }
240
242 {
243 BLI_assert(n >= 0);
244 const int64_t new_size = std::max<int64_t>(0, size_ - n);
245 return GMutableSpan(*type_, data_, new_size);
246 }
247
249 {
250 BLI_assert(n >= 0);
251 const int64_t new_size = std::min<int64_t>(size_, n);
252 return GMutableSpan(*type_, data_, new_size);
253 }
254
256 {
257 BLI_assert(n >= 0);
258 const int64_t new_size = std::min<int64_t>(size_, n);
259 return GMutableSpan(
260 *type_, POINTER_OFFSET(data_, type_->size() * (size_ - new_size)), new_size);
261 }
262
268 void copy_from(GSpan values)
269 {
270 BLI_assert(type_ == &values.type());
271 BLI_assert(size_ == values.size());
272 type_->copy_assign_n(values.data(), data_, size_);
273 }
274};
275
276} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:50
#define POINTER_OFFSET(v, ofs)
bool is() const
void copy_assign_n(const void *src, void *dst, int64_t n) const
int64_t size() const
GMutableSpan(const CPPType *type)
void * operator[](int64_t index) const
void copy_from(GSpan values)
GMutableSpan(MutableSpan< T > array)
int64_t size_in_bytes() const
GMutableSpan take_front(const int64_t n) const
GMutableSpan take_back(const int64_t n) const
GMutableSpan slice(const int64_t start, int64_t size) const
const CPPType * type_ptr() const
GMutableSpan drop_back(const int64_t n) const
const CPPType & type() const
GMutableSpan(const CPPType &type)
GMutableSpan(const CPPType *type, void *buffer, int64_t size)
MutableSpan< T > typed() const
GMutableSpan(const CPPType &type, void *buffer, int64_t size)
GMutableSpan drop_front(const int64_t n) const
GMutableSpan slice(IndexRange range) const
const CPPType * type_ptr() const
Span< T > typed() const
const CPPType & type() const
GSpan(const CPPType *type, const void *buffer, int64_t size)
GSpan drop_back(const int64_t n) const
GSpan drop_front(const int64_t n) const
GSpan slice(const IndexRange range) const
GSpan(Span< T > array)
int64_t size_in_bytes() const
bool is_empty() const
GSpan take_back(const int64_t n) const
GSpan(const CPPType &type, const void *buffer, int64_t size)
GSpan(const CPPType &type)
GSpan slice(const int64_t start, int64_t size) const
const void * data_
GSpan()=default
const void * data() const
GSpan(const CPPType *type)
const CPPType * type_
GSpan take_front(const int64_t n) const
int64_t size() const
const void * operator[](int64_t index) const
constexpr int64_t start() const
__int64 int64_t
Definition stdint.h:89