Blender V4.3
BLI_generic_array.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
18#include "BLI_allocator.hh"
19#include "BLI_cpp_type.hh"
20#include "BLI_generic_span.hh"
21
22namespace blender {
23
24template<
29 typename Allocator = GuardedAllocator>
30class GArray {
31 protected:
34 const CPPType *type_ = nullptr;
35 void *data_ = nullptr;
37
39
40 public:
46 GArray(Allocator allocator = {}) noexcept : allocator_(allocator) {}
47
48 GArray(NoExceptConstructor, Allocator allocator = {}) noexcept : GArray(allocator) {}
49
54 GArray(const CPPType &type, int64_t size, Allocator allocator = {}) : GArray(type, allocator)
55 {
56 BLI_assert(size >= 0);
57 size_ = size;
58 data_ = this->allocate(size_);
60 }
61
65 GArray(const CPPType &type, Allocator allocator = {}) : GArray(allocator)
66 {
67 type_ = &type;
68 }
69
74 GArray(const CPPType &type, void *buffer, int64_t size, Allocator allocator = {})
75 : GArray(type, allocator)
76 {
77 BLI_assert(size >= 0);
78 BLI_assert(buffer != nullptr || size == 0);
80
81 data_ = buffer;
82 size_ = size;
83 }
84
88 GArray(const GSpan span, Allocator allocator = {}) : GArray(span.type(), span.size(), allocator)
89 {
90 /* Use copy assign rather than construct since the memory is already initialized. */
92 }
93
97 GArray(const GArray &other) : GArray(other.as_span(), other.allocator()) {}
98
102 GArray(GArray &&other)
103 : type_(other.type_), data_(other.data_), size_(other.size_), allocator_(other.allocator_)
104 {
105 other.data_ = nullptr;
106 other.size_ = 0;
107 }
108
110 {
111 if (data_ != nullptr) {
113 this->deallocate(data_);
114 }
115 }
116
117 GArray &operator=(const GArray &other)
118 {
119 return copy_assign_container(*this, other);
120 }
121
123 {
124 return move_assign_container(*this, std::move(other));
125 }
126
127 const CPPType &type() const
128 {
129 BLI_assert(type_ != nullptr);
130 return *type_;
131 }
132
133 bool is_empty() const
134 {
135 return size_ == 0;
136 }
137
141 int64_t size() const
142 {
143 return size_;
144 }
145
149 const void *data() const
150 {
151 return data_;
152 }
153 void *data()
154 {
155 return data_;
156 }
157
158 const void *operator[](int64_t index) const
159 {
160 BLI_assert(index < size_);
161 return POINTER_OFFSET(data_, type_->size() * index);
162 }
163
164 void *operator[](int64_t index)
165 {
166 BLI_assert(index < size_);
167 return POINTER_OFFSET(data_, type_->size() * index);
168 }
169
170 operator GSpan() const
171 {
172 BLI_assert(size_ == 0 || type_ != nullptr);
173 return GSpan(type_, data_, size_);
174 }
175
176 operator GMutableSpan()
177 {
178 BLI_assert(size_ == 0 || type_ != nullptr);
179 return GMutableSpan(type_, data_, size_);
180 }
181
183 {
184 return *this;
185 }
186
188 {
189 return *this;
190 }
191
195 Allocator &allocator()
196 {
197 return allocator_;
198 }
199 const Allocator &allocator() const
200 {
201 return allocator_;
202 }
203
208 void reinitialize(const int64_t new_size)
209 {
210 BLI_assert(new_size >= 0);
211 int64_t old_size = size_;
212
214 size_ = 0;
215
216 if (new_size <= old_size) {
217 type_->default_construct_n(data_, new_size);
218 }
219 else {
220 void *new_data = this->allocate(new_size);
221 try {
222 type_->default_construct_n(new_data, new_size);
223 }
224 catch (...) {
225 this->deallocate(new_data);
226 throw;
227 }
228 if (this->data_) {
229 this->deallocate(data_);
230 }
231 data_ = new_data;
232 }
233
234 size_ = new_size;
235 }
236
237 private:
238 void *allocate(int64_t size)
239 {
240 const int64_t item_size = type_->size();
241 const int64_t alignment = type_->alignment();
242 return allocator_.allocate(size_t(size) * item_size, alignment, AT);
243 }
244
245 void deallocate(void *ptr)
246 {
247 allocator_.deallocate(ptr);
248 }
249};
250
251} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:50
#define POINTER_OFFSET(v, ofs)
#define BLI_NO_UNIQUE_ADDRESS
void default_construct_n(void *ptr, int64_t n) const
void destruct_n(void *ptr, int64_t n) const
void copy_assign_n(const void *src, void *dst, int64_t n) const
bool pointer_has_valid_alignment(const void *ptr) const
int64_t size() const
int64_t alignment() const
Allocator & allocator()
GMutableSpan as_mutable_span()
void * operator[](int64_t index)
GArray & operator=(const GArray &other)
const CPPType & type() const
BLI_NO_UNIQUE_ADDRESS Allocator allocator_
const void * operator[](int64_t index) const
int64_t size() const
GArray(NoExceptConstructor, Allocator allocator={}) noexcept
GArray & operator=(GArray &&other)
void reinitialize(const int64_t new_size)
GArray(const GArray &other)
GArray(Allocator allocator={}) noexcept
GSpan as_span() const
GArray(GArray &&other)
GArray(const CPPType &type, int64_t size, Allocator allocator={})
GArray(const GSpan span, Allocator allocator={})
GArray(const CPPType &type, void *buffer, int64_t size, Allocator allocator={})
const void * data() const
const CPPType * type_
const Allocator & allocator() const
GArray(const CPPType &type, Allocator allocator={})
const void * data() const
Container & copy_assign_container(Container &dst, const Container &src)
Container & move_assign_container(Container &dst, Container &&src) noexcept(std::is_nothrow_move_constructible_v< Container >)
__int64 int64_t
Definition stdint.h:89
PointerRNA * ptr
Definition wm_files.cc:4126