Blender  V2.93
util_array.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2018 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __UTIL_ARRAY_H__
18 #define __UTIL_ARRAY_H__
19 
20 #include <cassert>
21 #include <cstring>
22 
25 #include "util/util_types.h"
26 #include "util/util_vector.h"
27 
29 
30 /* Simplified version of vector, serving multiple purposes:
31  * - somewhat faster in that it does not clear memory on resize/alloc,
32  * this was actually showing up in profiles quite significantly. it
33  * also does not run any constructors/destructors
34  * - if this is used, we are not tempted to use inefficient operations
35  * - aligned allocation for CPU native data types */
36 
37 template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class array {
38  public:
40  {
41  }
42 
43  explicit array(size_t newsize)
44  {
45  if (newsize == 0) {
46  data_ = NULL;
47  datasize_ = 0;
48  capacity_ = 0;
49  }
50  else {
51  data_ = mem_allocate(newsize);
52  datasize_ = newsize;
54  }
55  }
56 
57  array(const array &from)
58  {
59  if (from.datasize_ == 0) {
60  data_ = NULL;
61  datasize_ = 0;
62  capacity_ = 0;
63  }
64  else {
65  data_ = mem_allocate(from.datasize_);
66  if (from.datasize_ > 0) {
67  memcpy(data_, from.data_, from.datasize_ * sizeof(T));
68  }
69  datasize_ = from.datasize_;
71  }
72  }
73 
75  {
76  if (this != &from) {
77  resize(from.size());
78  if (datasize_ > 0) {
79  memcpy((void *)data_, from.data_, datasize_ * sizeof(T));
80  }
81  }
82 
83  return *this;
84  }
85 
87  {
88  resize(from.size());
89 
90  if (from.size() > 0 && datasize_ > 0) {
91  memcpy(data_, &from[0], datasize_ * sizeof(T));
92  }
93 
94  return *this;
95  }
96 
98  {
100  }
101 
102  bool operator==(const array<T> &other) const
103  {
104  if (datasize_ != other.datasize_) {
105  return false;
106  }
107  if (datasize_ == 0) {
108  return true;
109  }
110 
111  return memcmp(data_, other.data_, datasize_ * sizeof(T)) == 0;
112  }
113 
114  bool operator!=(const array<T> &other) const
115  {
116  return !(*this == other);
117  }
118 
120  {
121  if (this != &from) {
122  clear();
123 
124  data_ = from.data_;
125  datasize_ = from.datasize_;
126  capacity_ = from.capacity_;
127 
128  from.data_ = NULL;
129  from.datasize_ = 0;
130  from.capacity_ = 0;
131  }
132  }
133 
134  void set_data(T *ptr_, size_t datasize)
135  {
136  clear();
137  data_ = ptr_;
138  datasize_ = datasize;
139  capacity_ = datasize;
140  }
141 
143  {
144  T *ptr = data_;
145  data_ = NULL;
146  clear();
147  return ptr;
148  }
149 
150  T *resize(size_t newsize)
151  {
152  if (newsize == 0) {
153  clear();
154  }
155  else if (newsize != datasize_) {
156  if (newsize > capacity_) {
157  T *newdata = mem_allocate(newsize);
158  if (newdata == NULL) {
159  /* Allocation failed, likely out of memory. */
160  clear();
161  return NULL;
162  }
163  else if (data_ != NULL) {
164  memcpy(
165  (void *)newdata, data_, ((datasize_ < newsize) ? datasize_ : newsize) * sizeof(T));
167  }
168  data_ = newdata;
169  capacity_ = newsize;
170  }
171  datasize_ = newsize;
172  }
173  return data_;
174  }
175 
176  T *resize(size_t newsize, const T &value)
177  {
178  size_t oldsize = size();
179  resize(newsize);
180 
181  for (size_t i = oldsize; i < size(); i++) {
182  data_[i] = value;
183  }
184 
185  return data_;
186  }
187 
188  void clear()
189  {
190  if (data_ != NULL) {
192  data_ = NULL;
193  }
194  datasize_ = 0;
195  capacity_ = 0;
196  }
197 
198  size_t empty() const
199  {
200  return datasize_ == 0;
201  }
202 
203  size_t size() const
204  {
205  return datasize_;
206  }
207 
208  T *data()
209  {
210  return data_;
211  }
212 
213  const T *data() const
214  {
215  return data_;
216  }
217 
218  T &operator[](size_t i) const
219  {
220  assert(i < datasize_);
221  return data_[i];
222  }
223 
224  T *begin()
225  {
226  return data_;
227  }
228 
229  const T *begin() const
230  {
231  return data_;
232  }
233 
234  T *end()
235  {
236  return data_ + datasize_;
237  }
238 
239  const T *end() const
240  {
241  return data_ + datasize_;
242  }
243 
244  void reserve(size_t newcapacity)
245  {
246  if (newcapacity > capacity_) {
247  T *newdata = mem_allocate(newcapacity);
248  if (data_ != NULL) {
249  memcpy(newdata, data_, ((datasize_ < newcapacity) ? datasize_ : newcapacity) * sizeof(T));
251  }
252  data_ = newdata;
253  capacity_ = newcapacity;
254  }
255  }
256 
257  size_t capacity() const
258  {
259  return capacity_;
260  }
261 
262  // do not use this method unless you are sure the code is not performance critical
263  void push_back_slow(const T &t)
264  {
265  if (capacity_ == datasize_) {
266  reserve(datasize_ == 0 ? 1 : (size_t)((datasize_ + 1) * 1.2));
267  }
268 
269  data_[datasize_++] = t;
270  }
271 
272  void push_back_reserved(const T &t)
273  {
274  assert(datasize_ < capacity_);
275  push_back_slow(t);
276  }
277 
278  void append(const array<T> &from)
279  {
280  if (from.size()) {
281  size_t old_size = size();
282  resize(old_size + from.size());
283  memcpy(data_ + old_size, from.data(), sizeof(T) * from.size());
284  }
285  }
286 
287  protected:
288  inline T *mem_allocate(size_t N)
289  {
290  if (N == 0) {
291  return NULL;
292  }
293  T *mem = (T *)util_aligned_malloc(sizeof(T) * N, alignment);
294  if (mem != NULL) {
295  util_guarded_mem_alloc(sizeof(T) * N);
296  }
297  else {
298  throw std::bad_alloc();
299  }
300  return mem;
301  }
302 
303  inline void mem_free(T *mem, size_t N)
304  {
305  if (mem != NULL) {
306  util_guarded_mem_free(sizeof(T) * N);
307  util_aligned_free(mem);
308  }
309  }
310 
312  size_t datasize_;
313  size_t capacity_;
314 };
315 
317 
318 #endif /* __UTIL_ARRAY_H__ */
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
void append(const array< T > &from)
Definition: util_array.h:278
void steal_data(array &from)
Definition: util_array.h:119
T & operator[](size_t i) const
Definition: util_array.h:218
T * end()
Definition: util_array.h:234
array & operator=(const array &from)
Definition: util_array.h:74
T * steal_pointer()
Definition: util_array.h:142
bool operator!=(const array< T > &other) const
Definition: util_array.h:114
const T * end() const
Definition: util_array.h:239
size_t capacity_
Definition: util_array.h:313
~array()
Definition: util_array.h:97
T * data()
Definition: util_array.h:208
array()
Definition: util_array.h:39
size_t size() const
Definition: util_array.h:203
array(size_t newsize)
Definition: util_array.h:43
size_t empty() const
Definition: util_array.h:198
array & operator=(const vector< T > &from)
Definition: util_array.h:86
T * begin()
Definition: util_array.h:224
size_t datasize_
Definition: util_array.h:312
const T * data() const
Definition: util_array.h:213
size_t capacity() const
Definition: util_array.h:257
void push_back_reserved(const T &t)
Definition: util_array.h:272
void set_data(T *ptr_, size_t datasize)
Definition: util_array.h:134
const T * begin() const
Definition: util_array.h:229
T * resize(size_t newsize)
Definition: util_array.h:150
void mem_free(T *mem, size_t N)
Definition: util_array.h:303
T * data_
Definition: util_array.h:311
T * mem_allocate(size_t N)
Definition: util_array.h:288
void reserve(size_t newcapacity)
Definition: util_array.h:244
T * resize(size_t newsize, const T &value)
Definition: util_array.h:176
void push_back_slow(const T &t)
Definition: util_array.h:263
void clear()
Definition: util_array.h:188
bool operator==(const array< T > &other) const
Definition: util_array.h:102
array(const array &from)
Definition: util_array.h:57
StackEntry * from
#define CCL_NAMESPACE_END
#define T
params N
void util_aligned_free(void *ptr)
CCL_NAMESPACE_BEGIN void * util_aligned_malloc(size_t size, int alignment)
void util_guarded_mem_free(size_t n)
void util_guarded_mem_alloc(size_t n)
PointerRNA * ptr
Definition: wm_files.c:3157