zarray.h
Go to the documentation of this file.
1 /* Copyright (C) 2013-2016, The Regents of The University of Michigan.
2 All rights reserved.
3 
4 This software was developed in the APRIL Robotics Lab under the
5 direction of Edwin Olson, ebolson@umich.edu. This software may be
6 available under alternative licensing terms; contact the address above.
7 
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 
11 1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 The views and conclusions contained in the software and documentation are those
29 of the authors and should not be interpreted as representing official policies,
30 either expressed or implied, of the Regents of The University of Michigan.
31 */
32 
33 #ifndef _ZARRAY_H
34 #define _ZARRAY_H
35 
36 #include <stddef.h>
37 #include <assert.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
48 typedef struct zarray zarray_t;
49 struct zarray
50 {
51  size_t el_sz; // size of each element
52 
53  int size; // how many elements?
54  int alloc; // we've allocated storage for how many elements?
55  char *data;
56 };
57 
63 static inline zarray_t *zarray_create(size_t el_sz)
64 {
65  assert(el_sz > 0);
66 
67  zarray_t *za = (zarray_t*) calloc(1, sizeof(zarray_t));
68  za->el_sz = el_sz;
69  return za;
70 }
71 
76 static inline void zarray_destroy(zarray_t *za)
77 {
78  if (za == NULL)
79  return;
80 
81  if (za->data != NULL)
82  free(za->data);
83  memset(za, 0, sizeof(zarray_t));
84  free(za);
85 }
86 
88 static inline zarray_t *zarray_copy(const zarray_t *za)
89 {
90  assert(za != NULL);
91 
92  zarray_t *zb = (zarray_t*) calloc(1, sizeof(zarray_t));
93  zb->el_sz = za->el_sz;
94  zb->size = za->size;
95  zb->alloc = za->alloc;
96  zb->data = (char*) malloc(zb->alloc * zb->el_sz);
97  memcpy(zb->data, za->data, za->size * za->el_sz);
98  return zb;
99 }
100 
101 static int iceillog2(int v)
102 {
103  v--;
104  v |= v >> 1;
105  v |= v >> 2;
106  v |= v >> 4;
107  v |= v >> 8;
108  v |= v >> 16;
109  v++;
110  return v;
111 }
112 
118 static inline zarray_t *zarray_copy_subset(const zarray_t *za,
119  int start_idx,
120  int end_idx_exclusive)
121 {
122  zarray_t *out = (zarray_t*) calloc(1, sizeof(zarray_t));
123  out->el_sz = za->el_sz;
124  out->size = end_idx_exclusive - start_idx;
125  out->alloc = iceillog2(out->size); // round up pow 2
126  out->data = (char*) malloc(out->alloc * out->el_sz);
127  memcpy(out->data, za->data +(start_idx*out->el_sz), out->size*out->el_sz);
128  return out;
129 }
130 
136 static inline int zarray_size(const zarray_t *za)
137 {
138  assert(za != NULL);
139 
140  return za->size;
141 }
142 
147 /*
148 JUST CALL zarray_size
149 int zarray_isempty(const zarray_t *za)
150 {
151  assert(za != NULL);
152  if (za->size <= 0)
153  return 1;
154  else
155  return 0;
156 }
157 */
158 
159 
164 static inline void zarray_ensure_capacity(zarray_t *za, int capacity)
165 {
166  assert(za != NULL);
167 
168  if (capacity <= za->alloc)
169  return;
170 
171  while (za->alloc < capacity) {
172  za->alloc *= 2;
173  if (za->alloc < 8)
174  za->alloc = 8;
175  }
176 
177  za->data = (char*) realloc(za->data, za->alloc * za->el_sz);
178 }
179 
185 static inline void zarray_add(zarray_t *za, const void *p)
186 {
187  assert(za != NULL);
188  assert(p != NULL);
189 
190  zarray_ensure_capacity(za, za->size + 1);
191 
192  memcpy(&za->data[za->size*za->el_sz], p, za->el_sz);
193  za->size++;
194 }
195 
201 static inline void zarray_get(const zarray_t *za, int idx, void *p)
202 {
203  assert(za != NULL);
204  assert(p != NULL);
205  assert(idx >= 0);
206  assert(idx < za->size);
207 
208  memcpy(p, &za->data[idx*za->el_sz], za->el_sz);
209 }
210 
218 inline static void zarray_get_volatile(const zarray_t *za, int idx, void *p)
219 {
220  assert(za != NULL);
221  assert(p != NULL);
222  assert(idx >= 0);
223  assert(idx < za->size);
224 
225  *((void**) p) = &za->data[idx*za->el_sz];
226 }
227 
228 inline static void zarray_truncate(zarray_t *za, int sz)
229 {
230  assert(za != NULL);
231  assert(sz <= za->size);
232  za->size = sz;
233 }
234 
246 static inline size_t zarray_copy_data(const zarray_t *za, void *buffer, size_t buffer_bytes)
247 {
248  assert(za != NULL);
249  assert(buffer != NULL);
250  assert(buffer_bytes >= za->el_sz * za->size);
251  memcpy(buffer, za->data, za->el_sz * za->size);
252  return za->el_sz * za->size;
253 }
254 
260 static inline void zarray_remove_index(zarray_t *za, int idx, int shuffle)
261 {
262  assert(za != NULL);
263  assert(idx >= 0);
264  assert(idx < za->size);
265 
266  if (shuffle) {
267  if (idx < za->size-1)
268  memcpy(&za->data[idx*za->el_sz], &za->data[(za->size-1)*za->el_sz], za->el_sz);
269  za->size--;
270  return;
271  } else {
272  // size = 10, idx = 7. Should copy 2 entries (at idx=8 and idx=9).
273  // size = 10, idx = 9. Should copy 0 entries.
274  int ncopy = za->size - idx - 1;
275  if (ncopy > 0)
276  memmove(&za->data[idx*za->el_sz], &za->data[(idx+1)*za->el_sz], ncopy*za->el_sz);
277  za->size--;
278  return;
279  }
280 }
281 
296 // remove the entry whose value is equal to the value pointed to by p.
297 // if shuffle is true, the last element in the array will be placed in
298 // the newly-open space; if false, the zarray is compacted.
299 static inline int zarray_remove_value(zarray_t *za, const void *p, int shuffle)
300 {
301  assert(za != NULL);
302  assert(p != NULL);
303 
304  for (int idx = 0; idx < za->size; idx++) {
305  if (!memcmp(p, &za->data[idx*za->el_sz], za->el_sz)) {
306  zarray_remove_index(za, idx, shuffle);
307  return 1;
308  }
309  }
310 
311  return 0;
312 }
313 
314 
322 static inline void zarray_insert(zarray_t *za, int idx, const void *p)
323 {
324  assert(za != NULL);
325  assert(p != NULL);
326  assert(idx >= 0);
327  assert(idx <= za->size);
328 
329  zarray_ensure_capacity(za, za->size + 1);
330  // size = 10, idx = 7. Should copy three entries (idx=7, idx=8, idx=9)
331  int ncopy = za->size - idx;
332 
333  memmove(&za->data[(idx+1)*za->el_sz], &za->data[idx*za->el_sz], ncopy*za->el_sz);
334  memcpy(&za->data[idx*za->el_sz], p, za->el_sz);
335 
336  za->size++;
337 }
338 
339 
345 static inline void zarray_set(zarray_t *za, int idx, const void *p, void *outp)
346 {
347  assert(za != NULL);
348  assert(p != NULL);
349  assert(idx >= 0);
350  assert(idx < za->size);
351 
352  if (outp != NULL)
353  memcpy(outp, &za->data[idx*za->el_sz], za->el_sz);
354 
355  memcpy(&za->data[idx*za->el_sz], p, za->el_sz);
356 }
357 
365 static inline void zarray_map(zarray_t *za, void (*f)(void*))
366 {
367  assert(za != NULL);
368  assert(f != NULL);
369 
370  for (int idx = 0; idx < za->size; idx++)
371  f(&za->data[idx*za->el_sz]);
372 }
373 
384  void zarray_vmap(zarray_t *za, void (*f)());
385 
391 static inline void zarray_clear(zarray_t *za)
392 {
393  assert(za != NULL);
394  za->size = 0;
395 }
396 
403 static inline int zarray_contains(const zarray_t *za, const void *p)
404 {
405  assert(za != NULL);
406  assert(p != NULL);
407 
408  for (int idx = 0; idx < za->size; idx++) {
409  if (!memcmp(p, &za->data[idx*za->el_sz], za->el_sz)) {
410  return 1;
411  }
412  }
413 
414  return 0;
415 }
416 
432 static inline void zarray_sort(zarray_t *za, int (*compar)(const void*, const void*))
433 {
434  assert(za != NULL);
435  assert(compar != NULL);
436  if (za->size == 0)
437  return;
438 
439  qsort(za->data, za->size, za->el_sz, compar);
440 }
441 
446  int zstrcmp(const void * a_pp, const void * b_pp);
447 
452 // returns -1 if not in array. Remember p is a pointer to the item.
453 static inline int zarray_index_of(const zarray_t *za, const void *p)
454 {
455  assert(za != NULL);
456  assert(p != NULL);
457 
458  for (int i = 0; i < za->size; i++) {
459  if (!memcmp(p, &za->data[i*za->el_sz], za->el_sz))
460  return i;
461  }
462 
463  return -1;
464 }
465 
466 
467 
472 static inline void zarray_add_all(zarray_t * dest, const zarray_t * source)
473 {
474  assert(dest->el_sz == source->el_sz);
475 
476  // Don't allocate on stack because el_sz could be larger than ~8 MB
477  // stack size
478  char *tmp = (char*)calloc(1, dest->el_sz);
479 
480  for (int i = 0; i < zarray_size(source); i++) {
481  zarray_get(source, i, tmp);
482  zarray_add(dest, tmp);
483  }
484 
485  free(tmp);
486 }
487 
488 #ifdef __cplusplus
489 }
490 #endif
491 
492 #endif
static int zarray_index_of(const zarray_t *za, const void *p)
Definition: zarray.h:453
static int zarray_contains(const zarray_t *za, const void *p)
Definition: zarray.h:403
static void zarray_get_volatile(const zarray_t *za, int idx, void *p)
Definition: zarray.h:218
static void zarray_sort(zarray_t *za, int(*compar)(const void *, const void *))
Definition: zarray.h:432
static int zarray_remove_value(zarray_t *za, const void *p, int shuffle)
Definition: zarray.h:299
static int zarray_size(const zarray_t *za)
Definition: zarray.h:136
static void zarray_ensure_capacity(zarray_t *za, int capacity)
Definition: zarray.h:164
static void zarray_destroy(zarray_t *za)
Definition: zarray.h:76
static void zarray_set(zarray_t *za, int idx, const void *p, void *outp)
Definition: zarray.h:345
static void zarray_remove_index(zarray_t *za, int idx, int shuffle)
Definition: zarray.h:260
static zarray_t * zarray_create(size_t el_sz)
Definition: zarray.h:63
char * data
Definition: zarray.h:55
static zarray_t * zarray_copy(const zarray_t *za)
Definition: zarray.h:88
static size_t zarray_copy_data(const zarray_t *za, void *buffer, size_t buffer_bytes)
Definition: zarray.h:246
static void zarray_map(zarray_t *za, void(*f)(void *))
Definition: zarray.h:365
static zarray_t * zarray_copy_subset(const zarray_t *za, int start_idx, int end_idx_exclusive)
Definition: zarray.h:118
int alloc
Definition: zarray.h:54
static void zarray_truncate(zarray_t *za, int sz)
Definition: zarray.h:228
static void zarray_get(const zarray_t *za, int idx, void *p)
Definition: zarray.h:201
Definition: zarray.h:49
size_t el_sz
Definition: zarray.h:51
int size
Definition: zarray.h:53
void zarray_vmap(zarray_t *za, void(*f)())
Definition: zarray.c:51
static void zarray_clear(zarray_t *za)
Definition: zarray.h:391
static void zarray_add_all(zarray_t *dest, const zarray_t *source)
Definition: zarray.h:472
static void zarray_insert(zarray_t *za, int idx, const void *p)
Definition: zarray.h:322
int zstrcmp(const void *a_pp, const void *b_pp)
Definition: zarray.c:40
static int iceillog2(int v)
Definition: zarray.h:101
static void zarray_add(zarray_t *za, const void *p)
Definition: zarray.h:185


apriltags2
Author(s): Danylo Malyuta
autogenerated on Fri Oct 19 2018 04:02:32