FMI Library: part of JModelica.org
jm_vector_template.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2012 Modelon AB
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the BSD style license.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  FMILIB_License.txt file for more details.
11 
12  You should have received a copy of the FMILIB_License.txt file
13  along with this program. If not, contact Modelon AB <http://www.modelon.com>.
14 */
15 
25 #include <stdlib.h>
26 #include <string.h>
27 #include "jm_vector.h"
28 
33 #ifndef JM_TEMPLATE_INSTANCE_TYPE
34 #error "JM_TEMPLATE_INSTANCE_TYPE must be defined before including this file"
35 #endif
36 
38  size_t reserve;
41  if(c)
42  cc = c;
43  else
45 
46  reserve = capacity;
47  if(reserve < size) reserve = size;
52  if(!v) return 0;
53  v->capacity = reserve;
54  }
55  else {
57  if(!v) return 0;
58  v->capacity = JM_VECTOR_MINIMAL_CAPACITY;
59  }
60  v->callbacks = cc;
61  v->items = &(v->preallocated[0]);
62  v->size = size;
63  return v;
64 }
65 
67  if(!a) return;
69  a->callbacks->free(a);
70 }
71 
73  if(c)
74  a->callbacks = c;
75  else
76  a->callbacks = jm_get_default_callbacks();
77  a->items = a->preallocated;
78  a->size = 0;
79  a->capacity = JM_VECTOR_MINIMAL_CAPACITY;
80 
81  if(initSize > a->size)
82  return jm_vector_resize(JM_TEMPLATE_INSTANCE_TYPE)(a, initSize);
83  return 0;
84 }
85 
87  if(size > a->capacity) {
89  a->size = a->capacity;
90  return a->capacity;
91  }
92  }
93  a->size = size;
94  return size;
95 }
96 
98  void* newmem;
99  if(size <= a->capacity) return a->capacity;
100  newmem = a->callbacks->malloc(size * sizeof(JM_TEMPLATE_INSTANCE_TYPE));
101  if(!newmem) return a->capacity;
102  memcpy(newmem, a->items, a->size * sizeof(JM_TEMPLATE_INSTANCE_TYPE));
103  if(a->items != a->preallocated) a->callbacks->free((void*)(a->items));
104  a->items = newmem;
105  a->capacity = size;
106  return a->capacity;
107 }
108 
110  size_t destsize = jm_vector_resize(JM_TEMPLATE_INSTANCE_TYPE)(destination, source->size);
111  if(destsize > 0) {
112  memcpy((void*)destination->items, (void*)source->items, sizeof(JM_TEMPLATE_INSTANCE_TYPE)*destsize);
113  }
114  return destination->size;
115 }
116 
118  size_t oldsize, newsize;
119  oldsize = jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(destination);
120  newsize = jm_vector_resize(JM_TEMPLATE_INSTANCE_TYPE)(destination, source->size + oldsize);
121  memcpy((void*)(destination->items + oldsize), (void*)source->items, sizeof(JM_TEMPLATE_INSTANCE_TYPE)*(newsize - oldsize));
122  return (newsize - oldsize);
123 }
124 
126  size_t reserve;
128  if(index >= a->size) return 0;
129  if(a->size == a->capacity) {
130  if(a->capacity > JM_VECTOR_MAX_MEMORY_CHUNK)
131  reserve = JM_VECTOR_MAX_MEMORY_CHUNK + a->capacity;
132  else
133  reserve = a->capacity * 2;
134  if( jm_vector_reserve(JM_TEMPLATE_INSTANCE_TYPE)(a, reserve) != reserve) return 0;
135  }
136  assert(a->size < a->capacity);
137  memmove((void*)(a->items+index+1),(void*)(a->items+index), (a->size - index)*sizeof(JM_TEMPLATE_INSTANCE_TYPE));
138  a->items[index] = item;
139  pitem = &(a->items[index]);
140  a->size++;
141  return pitem;
142 }
143 
145  size_t reserve;
147  if(a->size == a->capacity) {
148  if(a->capacity > JM_VECTOR_MAX_MEMORY_CHUNK)
149  reserve = JM_VECTOR_MAX_MEMORY_CHUNK + a->capacity;
150  else
151  reserve = a->capacity * 2;
152  if( jm_vector_reserve(JM_TEMPLATE_INSTANCE_TYPE)(a, reserve) != reserve) return 0;
153  }
154  assert(a->size < a->capacity);
155  pitem = &(a->items[a->size]);
156  a->size++;
157  return pitem;
158 }
159 
162  if(!pitem) return 0;
163  *pitem = item;
164  return pitem;
165 }
166 
168  size_t n =v->size - index -1;
169  assert(index < v->size);
170  if(n) {
171  memmove((void*)&(v->items[index]),(void*) &(v->items[index+1]), n * sizeof(JM_TEMPLATE_INSTANCE_TYPE));
172  }
173  v->size--;
174 }
175 
178  memset((void*)a->items,0,a->size * sizeof(JM_TEMPLATE_INSTANCE_TYPE));
179  }
180 }
181 
183  void (*f)(JM_TEMPLATE_INSTANCE_TYPE, void*), void * data) {
184  size_t i;
185  for(i = 0; i < jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(a); i++)
186  f(jm_vector_get_item(JM_TEMPLATE_INSTANCE_TYPE)(a, i), data);
187 }
188 
189 void jm_vector_foreach(JM_TEMPLATE_INSTANCE_TYPE)(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)* a,
190  void (*f)(JM_TEMPLATE_INSTANCE_TYPE)) {
191  size_t i;
192  for(i = 0; i < jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(a); i++)
193  f(jm_vector_get_item(JM_TEMPLATE_INSTANCE_TYPE)(a, i));
194 }
195 
196 void jm_vector_qsort(JM_TEMPLATE_INSTANCE_TYPE)(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)* v, jm_compare_ft f) {
197  if(jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(v) > 1) {
198  qsort((void*)v->items, jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(v), sizeof(JM_TEMPLATE_INSTANCE_TYPE),f);
199  }
200 }
201 
202 #define jm_vector_ptr2index(T) jm_mangle(jm_vector_ptr2index, T)
203 
204 static size_t jm_vector_ptr2index(JM_TEMPLATE_INSTANCE_TYPE)(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)* v, JM_TEMPLATE_INSTANCE_TYPE* itemp) {
205  if(itemp)
206  return (itemp - v->items);
207  else
208  return jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(v);
209 }
210 
211 
212 size_t jm_vector_bsearch_index(JM_TEMPLATE_INSTANCE_TYPE)(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)* v, JM_TEMPLATE_INSTANCE_TYPE* key, jm_compare_ft f) {
213  return jm_vector_ptr2index(JM_TEMPLATE_INSTANCE_TYPE)(v, jm_vector_bsearch(JM_TEMPLATE_INSTANCE_TYPE)(v, key,f));
214 }
215 
216 JM_TEMPLATE_INSTANCE_TYPE* jm_vector_bsearch(JM_TEMPLATE_INSTANCE_TYPE)(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)* v, JM_TEMPLATE_INSTANCE_TYPE* key, jm_compare_ft f) {
217  return bsearch(key, v->items,
218  jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(v),
219  sizeof(JM_TEMPLATE_INSTANCE_TYPE),
220  f);
221 }
222 
223 JM_TEMPLATE_INSTANCE_TYPE* jm_vector_find(JM_TEMPLATE_INSTANCE_TYPE)(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)* a, JM_TEMPLATE_INSTANCE_TYPE* itemp, jm_compare_ft f) {
224  size_t i = jm_vector_get_size(JM_TEMPLATE_INSTANCE_TYPE)(a);
225  while(i--) {
226  JM_TEMPLATE_INSTANCE_TYPE* cur = jm_vector_get_itemp(JM_TEMPLATE_INSTANCE_TYPE)(a, i);
227  if(f(cur, itemp) == 0)
228  return cur;
229  };
230  return 0;
231 }
232 
233 size_t jm_vector_find_index(JM_TEMPLATE_INSTANCE_TYPE)(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)* v, JM_TEMPLATE_INSTANCE_TYPE* itemp, jm_compare_ft f) {
234  return jm_vector_ptr2index(JM_TEMPLATE_INSTANCE_TYPE)(v,jm_vector_find(JM_TEMPLATE_INSTANCE_TYPE)(v, itemp, f));
235 }
236 
#define jm_vector_append(T)
Definition: jm_vector.h:234
#define jm_vector_find_index(T)
Definition: jm_vector.h:162
size_t jm_callbacks * c
FMILIB_EXPORT jm_callbacks * jm_get_default_callbacks(void)
Get default callbacks. The function never returns NULL.
#define jm_vector_copy(T)
Definition: jm_vector.h:220
#define jm_vector_foreach_c(T)
Definition: jm_vector.h:271
#define jm_vector_bsearch_index(T)
Definition: jm_vector.h:181
#define jm_vector_ptr2index(T)
#define jm_vector_free(T)
Definition: jm_vector.h:68
#define jm_vector_free_data(T)
Definition: jm_vector.h:90
size_t capacity
#define jm_vector_bsearch(T)
Definition: jm_vector.h:180
#define jm_vector_alloc(T)
Definition: jm_vector.h:62
int(* jm_compare_ft)(const void *, const void *)
Function type for item comparison. Can be generated with jm_define_comp_f.
Definition: jm_vector.h:127
#define jm_vector_reserve(T)
Definition: jm_vector.h:213
#define JM_VECTOR_MAX_MEMORY_CHUNK
Definition: jm_vector.h:279
#define jm_vector_insert(T)
Definition: jm_vector.h:241
#define jm_vector_zero(T)
Definition: jm_vector.h:193
jm_vector(JM_TEMPLATE_INSTANCE_TYPE)*jm_vector_alloc(JM_TEMPLATE_INSTANCE_TYPE)(size_t size
#define jm_vector_qsort(T)
Definition: jm_vector.h:170
v size
#define jm_vector_push_back(T)
Definition: jm_vector.h:262
return v
#define jm_vector_get_item(T)
Definition: jm_vector.h:102
#define jm_vector_init(T)
jm_vector_init initializes a vector allocated on stack.
Definition: jm_vector.h:82
#define jm_vector_get_size(T)
Definition: jm_vector.h:96
jm_malloc_f malloc
Allocate non-initialized memory.
Definition: jm_callbacks.h:75
#define jm_vector_foreach(T)
Definition: jm_vector.h:270
#define JM_VECTOR_MINIMAL_CAPACITY
Definition: jm_vector.h:276
#define jm_vector_resize1(T)
Definition: jm_vector.h:255
#define jm_vector_remove_item(T)
Definition: jm_vector.h:248
#define jm_vector_find(T)
jm_vector_find functions use linear search to find items in a vector. JM_COMPAR_OP is used for compar...
Definition: jm_vector.h:161
The callbacks struct is sent to all the modules in the library.
Definition: jm_callbacks.h:73
#define jm_vector_get_itemp(T)
Definition: jm_vector.h:108
jm_callbacks * cc
#define jm_vector_resize(T)
Definition: jm_vector.h:205
void jm_vector_free() JM_TEMPLATE_INSTANCE_TYPE(jm_vector(JM_TEMPLATE_INSTANCE_TYPE)*a)