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 This software was developed in the APRIL Robotics Lab under the
4 direction of Edwin Olson, ebolson@umich.edu. This software may be
5 available under alternative licensing terms; contact the address above.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 1. Redistributions of source code must retain the above copyright notice, this
9  list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 The views and conclusions contained in the software and documentation are those
24 of the authors and should not be interpreted as representing official policies,
25 either expressed or implied, of the Regents of The University of Michigan.
26 */
27 
28 #pragma once
29 
30 #include <stddef.h>
31 #include <assert.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
42 typedef struct zarray zarray_t;
43 struct zarray
44 {
45  size_t el_sz; // size of each element
46 
47  int size; // how many elements?
48  int alloc; // we've allocated storage for how many elements?
49  char *data;
50 };
51 
57 static inline zarray_t *zarray_create(size_t el_sz)
58 {
59  assert(el_sz > 0);
60 
61  zarray_t *za = (zarray_t*) calloc(1, sizeof(zarray_t));
62  za->el_sz = el_sz;
63  return za;
64 }
65 
70 static inline void zarray_destroy(zarray_t *za)
71 {
72  if (za == NULL)
73  return;
74 
75  if (za->data != NULL)
76  free(za->data);
77  memset(za, 0, sizeof(zarray_t));
78  free(za);
79 }
80 
82 static inline zarray_t *zarray_copy(const zarray_t *za)
83 {
84  assert(za != NULL);
85 
86  zarray_t *zb = (zarray_t*) calloc(1, sizeof(zarray_t));
87  zb->el_sz = za->el_sz;
88  zb->size = za->size;
89  zb->alloc = za->alloc;
90  zb->data = (char*) malloc(zb->alloc * zb->el_sz);
91  memcpy(zb->data, za->data, za->size * za->el_sz);
92  return zb;
93 }
94 
95 static int iceillog2(int v)
96 {
97  v--;
98  v |= v >> 1;
99  v |= v >> 2;
100  v |= v >> 4;
101  v |= v >> 8;
102  v |= v >> 16;
103  v++;
104  return v;
105 }
106 
112 static inline zarray_t *zarray_copy_subset(const zarray_t *za,
113  int start_idx,
114  int end_idx_exclusive)
115 {
116  zarray_t *out = (zarray_t*) calloc(1, sizeof(zarray_t));
117  out->el_sz = za->el_sz;
118  out->size = end_idx_exclusive - start_idx;
119  out->alloc = iceillog2(out->size); // round up pow 2
120  out->data = (char*) malloc(out->alloc * out->el_sz);
121  memcpy(out->data, za->data +(start_idx*out->el_sz), out->size*out->el_sz);
122  return out;
123 }
124 
130 static inline int zarray_size(const zarray_t *za)
131 {
132  assert(za != NULL);
133 
134  return za->size;
135 }
136 
141 /*
142 JUST CALL zarray_size
143 int zarray_isempty(const zarray_t *za)
144 {
145  assert(za != NULL);
146  if (za->size <= 0)
147  return 1;
148  else
149  return 0;
150 }
151 */
152 
153 
158 static inline void zarray_ensure_capacity(zarray_t *za, int capacity)
159 {
160  assert(za != NULL);
161 
162  if (capacity <= za->alloc)
163  return;
164 
165  while (za->alloc < capacity) {
166  za->alloc *= 2;
167  if (za->alloc < 8)
168  za->alloc = 8;
169  }
170 
171  za->data = (char*) realloc(za->data, za->alloc * za->el_sz);
172 }
173 
179 static inline void zarray_add(zarray_t *za, const void *p)
180 {
181  assert(za != NULL);
182  assert(p != NULL);
183 
184  zarray_ensure_capacity(za, za->size + 1);
185 
186  memcpy(&za->data[za->size*za->el_sz], p, za->el_sz);
187  za->size++;
188 }
189 
195 static inline void zarray_get(const zarray_t *za, int idx, void *p)
196 {
197  assert(za != NULL);
198  assert(p != NULL);
199  assert(idx >= 0);
200  assert(idx < za->size);
201 
202  memcpy(p, &za->data[idx*za->el_sz], za->el_sz);
203 }
204 
212 inline static void zarray_get_volatile(const zarray_t *za, int idx, void *p)
213 {
214  assert(za != NULL);
215  assert(p != NULL);
216  assert(idx >= 0);
217  assert(idx < za->size);
218 
219  *((void**) p) = &za->data[idx*za->el_sz];
220 }
221 
222 inline static void zarray_truncate(zarray_t *za, int sz)
223 {
224  assert(za != NULL);
225  assert(sz <= za->size);
226  za->size = sz;
227 }
228 
234 static inline void zarray_remove_index(zarray_t *za, int idx, int shuffle)
235 {
236  assert(za != NULL);
237  assert(idx >= 0);
238  assert(idx < za->size);
239 
240  if (shuffle) {
241  if (idx < za->size-1)
242  memcpy(&za->data[idx*za->el_sz], &za->data[(za->size-1)*za->el_sz], za->el_sz);
243  za->size--;
244  return;
245  } else {
246  // size = 10, idx = 7. Should copy 2 entries (at idx=8 and idx=9).
247  // size = 10, idx = 9. Should copy 0 entries.
248  int ncopy = za->size - idx - 1;
249  if (ncopy > 0)
250  memmove(&za->data[idx*za->el_sz], &za->data[(idx+1)*za->el_sz], ncopy*za->el_sz);
251  za->size--;
252  return;
253  }
254 }
255 
270 // remove the entry whose value is equal to the value pointed to by p.
271 // if shuffle is true, the last element in the array will be placed in
272 // the newly-open space; if false, the zarray is compacted.
273 static inline int zarray_remove_value(zarray_t *za, const void *p, int shuffle)
274 {
275  assert(za != NULL);
276  assert(p != NULL);
277 
278  for (int idx = 0; idx < za->size; idx++) {
279  if (!memcmp(p, &za->data[idx*za->el_sz], za->el_sz)) {
280  zarray_remove_index(za, idx, shuffle);
281  return 1;
282  }
283  }
284 
285  return 0;
286 }
287 
288 
296 static inline void zarray_insert(zarray_t *za, int idx, const void *p)
297 {
298  assert(za != NULL);
299  assert(p != NULL);
300  assert(idx >= 0);
301  assert(idx <= za->size);
302 
303  zarray_ensure_capacity(za, za->size + 1);
304  // size = 10, idx = 7. Should copy three entries (idx=7, idx=8, idx=9)
305  int ncopy = za->size - idx;
306 
307  memmove(&za->data[(idx+1)*za->el_sz], &za->data[idx*za->el_sz], ncopy*za->el_sz);
308  memcpy(&za->data[idx*za->el_sz], p, za->el_sz);
309 
310  za->size++;
311 }
312 
313 
319 static inline void zarray_set(zarray_t *za, int idx, const void *p, void *outp)
320 {
321  assert(za != NULL);
322  assert(p != NULL);
323  assert(idx >= 0);
324  assert(idx < za->size);
325 
326  if (outp != NULL)
327  memcpy(outp, &za->data[idx*za->el_sz], za->el_sz);
328 
329  memcpy(&za->data[idx*za->el_sz], p, za->el_sz);
330 }
331 
339 static inline void zarray_map(zarray_t *za, void (*f)(void*))
340 {
341  assert(za != NULL);
342  assert(f != NULL);
343 
344  for (int idx = 0; idx < za->size; idx++)
345  f(&za->data[idx*za->el_sz]);
346 }
347 
358  void zarray_vmap(zarray_t *za, void (*f)());
359 
365 static inline void zarray_clear(zarray_t *za)
366 {
367  assert(za != NULL);
368  za->size = 0;
369 }
370 
377 static inline int zarray_contains(const zarray_t *za, const void *p)
378 {
379  assert(za != NULL);
380  assert(p != NULL);
381 
382  for (int idx = 0; idx < za->size; idx++) {
383  if (!memcmp(p, &za->data[idx*za->el_sz], za->el_sz)) {
384  return 1;
385  }
386  }
387 
388  return 0;
389 }
390 
406 static inline void zarray_sort(zarray_t *za, int (*compar)(const void*, const void*))
407 {
408  assert(za != NULL);
409  assert(compar != NULL);
410  if (za->size == 0)
411  return;
412 
413  qsort(za->data, za->size, za->el_sz, compar);
414 }
415 
420  int zstrcmp(const void * a_pp, const void * b_pp);
421 
426 // returns -1 if not in array. Remember p is a pointer to the item.
427 static inline int zarray_index_of(const zarray_t *za, const void *p)
428 {
429  assert(za != NULL);
430  assert(p != NULL);
431 
432  for (int i = 0; i < za->size; i++) {
433  if (!memcmp(p, &za->data[i*za->el_sz], za->el_sz))
434  return i;
435  }
436 
437  return -1;
438 }
439 
444 static inline void zarray_add_range(zarray_t *dest, const zarray_t *source, int start, int end)
445 {
446  assert(dest->el_sz == source->el_sz);
447  assert(dest != NULL);
448  assert(source != NULL);
449  assert(start >= 0);
450  assert(end <= source->size);
451  if (start == end) {
452  return;
453  }
454  assert(start < end);
455 
456  int count = end - start;
457  zarray_ensure_capacity(dest, dest->size + count);
458 
459  memcpy(&dest->data[dest->size*dest->el_sz], &source->data[source->el_sz*start], dest->el_sz*count);
460  dest->size += count;
461 }
462 
463 #ifdef __cplusplus
464 }
465 #endif
static int zarray_index_of(const zarray_t *za, const void *p)
Definition: zarray.h:427
static int zarray_contains(const zarray_t *za, const void *p)
Definition: zarray.h:377
static void zarray_get_volatile(const zarray_t *za, int idx, void *p)
Definition: zarray.h:212
static void zarray_sort(zarray_t *za, int(*compar)(const void *, const void *))
Definition: zarray.h:406
static int zarray_remove_value(zarray_t *za, const void *p, int shuffle)
Definition: zarray.h:273
static int zarray_size(const zarray_t *za)
Definition: zarray.h:130
static void zarray_ensure_capacity(zarray_t *za, int capacity)
Definition: zarray.h:158
static void zarray_destroy(zarray_t *za)
Definition: zarray.h:70
static void zarray_set(zarray_t *za, int idx, const void *p, void *outp)
Definition: zarray.h:319
static void zarray_remove_index(zarray_t *za, int idx, int shuffle)
Definition: zarray.h:234
static void zarray_add_range(zarray_t *dest, const zarray_t *source, int start, int end)
Definition: zarray.h:444
static zarray_t * zarray_create(size_t el_sz)
Definition: zarray.h:57
char * data
Definition: zarray.h:49
static zarray_t * zarray_copy(const zarray_t *za)
Definition: zarray.h:82
static void zarray_map(zarray_t *za, void(*f)(void *))
Definition: zarray.h:339
static zarray_t * zarray_copy_subset(const zarray_t *za, int start_idx, int end_idx_exclusive)
Definition: zarray.h:112
int alloc
Definition: zarray.h:48
static void zarray_truncate(zarray_t *za, int sz)
Definition: zarray.h:222
static void zarray_get(const zarray_t *za, int idx, void *p)
Definition: zarray.h:195
Definition: zarray.h:43
size_t el_sz
Definition: zarray.h:45
int size
Definition: zarray.h:47
void zarray_vmap(zarray_t *za, void(*f)())
Definition: zarray.c:44
static void zarray_clear(zarray_t *za)
Definition: zarray.h:365
static void zarray_insert(zarray_t *za, int idx, const void *p)
Definition: zarray.h:296
int zstrcmp(const void *a_pp, const void *b_pp)
Definition: zarray.c:33
static int iceillog2(int v)
Definition: zarray.h:95
static void zarray_add(zarray_t *za, const void *p)
Definition: zarray.h:179


apriltag
Author(s): Edwin Olson , Max Krogius
autogenerated on Mon Jun 26 2023 02:26:35