FMI Library: part of JModelica.org
jm_vector.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 
16 #ifndef jm_vector_h_
17 #define jm_vector_h_
18 #include <assert.h>
19 #include <string.h>
20 
21 #include "jm_callbacks.h"
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
44 #define jm_mangle_ex(name, type) name## _ ##type
45 #define jm_mangle(name, type) jm_mangle_ex(name,type)
46 
48 #define jm_vector(T) jm_mangle(jm_vector, T)
49 
62 #define jm_vector_alloc(T) jm_mangle(jm_vector_alloc, T)
63 
68 #define jm_vector_free(T) jm_mangle(jm_vector_free, T)
69 
82 #define jm_vector_init(T) jm_mangle(jm_vector_init, T)
83 
90 #define jm_vector_free_data(T) jm_mangle(jm_vector_free_data, T)
91 
96 #define jm_vector_get_size(T) jm_mangle(jm_vector_get_size, T)
97 
102 #define jm_vector_get_item(T) jm_mangle(jm_vector_get_item, T)
103 
108 #define jm_vector_get_itemp(T) jm_mangle(jm_vector_get_itemp, T)
109 
110 
115 #define jm_vector_get_last(T) jm_mangle(jm_vector_get_last, T)
116 
121 #define jm_vector_get_lastp(T) jm_mangle(jm_vector_get_lastp, T)
122 
127 typedef int (*jm_compare_ft) (const void* , const void*);
128 
140 #define jm_define_comp_f(F, T, COMPAR_OP) \
141  static int F (const void* first, const void* second) { \
142  return COMPAR_OP( (*(T*)first), (*(T*)second)); \
143  } \
144 
145 #define jm_diff(first, second) (int)(first-second)
146 
161 #define jm_vector_find(T) jm_mangle(jm_vector_find, T)
162 #define jm_vector_find_index(T) jm_mangle(jm_vector_find_index, T)
163 
164 /*
165  jm_vector_qsort uses standard quick sort to sort the vector contents.
166  JM_COMPAR_OP is used for comparison.
167 
168  void jm_vector_qsort(T)(jm_vector(T)* v, jm_compare_ft f);
169 */
170 #define jm_vector_qsort(T) jm_mangle(jm_vector_qsort, T)
171 
180 #define jm_vector_bsearch(T) jm_mangle(jm_vector_bsearch, T)
181 #define jm_vector_bsearch_index(T) jm_mangle(jm_vector_bsearch_index, T)
182 
187 #define jm_vector_set_item(T) jm_mangle(jm_vector_set_item, T)
188 
193 #define jm_vector_zero(T) jm_mangle(jm_vector_zero, T)
194 
205 #define jm_vector_resize(T) jm_mangle(jm_vector_resize, T)
206 
213 #define jm_vector_reserve(T) jm_mangle(jm_vector_reserve, T)
214 
220 #define jm_vector_copy(T) jm_mangle(jm_vector_copy, T)
221 
227 #define jm_vector_clone(T) jm_mangle(jm_vector_clone, T)
228 
234 #define jm_vector_append(T) jm_mangle(jm_vector_append, T)
235 
241 #define jm_vector_insert(T) jm_mangle(jm_vector_insert, T)
242 
248 #define jm_vector_remove_item(T) jm_mangle(jm_vector_remove_item, T)
249 
255 #define jm_vector_resize1(T) jm_mangle(jm_vector_resize1, T)
256 
262 #define jm_vector_push_back(T) jm_mangle(jm_vector_push_back, T)
263 
270 #define jm_vector_foreach(T) jm_mangle(jm_vector_foreach, T)
271 #define jm_vector_foreach_c(T) jm_mangle(jm_vector_foreach_c, T)
272 
276 #define JM_VECTOR_MINIMAL_CAPACITY 16
277 
279 #define JM_VECTOR_MAX_MEMORY_CHUNK 1024
280 
282 #define jm_vector_declare_template(T) \
283 typedef struct jm_vector(T) { \
284  jm_callbacks* callbacks; \
285  T *items; \
286  size_t size; \
287  size_t capacity; \
288  T preallocated[JM_VECTOR_MINIMAL_CAPACITY]; \
289 } jm_vector(T); \
290  \
291 extern jm_vector(T)* jm_vector_alloc(T)(size_t size,size_t capacity, jm_callbacks*); \
292  \
293 extern size_t jm_vector_copy(T)(jm_vector(T)* destination, jm_vector(T)* source); \
294 static jm_vector(T)* jm_vector_clone(T)(jm_vector(T)* v) { \
295  jm_vector(T)* ret = jm_vector_alloc(T)(v->size, v->size, v->callbacks);\
296  if(ret) jm_vector_copy(T)(ret, v) ; \
297  return ret; \
298 }\
299  \
300 extern void jm_vector_free(T)(jm_vector(T) * a); \
301  \
302 extern size_t jm_vector_init(T)(jm_vector(T)* a, size_t size,jm_callbacks*); \
303 \
304 static void jm_vector_free_data(T)(jm_vector(T)* a) { \
305  if(a) { \
306  if(a->items != a->preallocated) { \
307  a->callbacks->free((void*)(a->items)); \
308  a->items = a->preallocated; \
309  a->capacity=JM_VECTOR_MINIMAL_CAPACITY;\
310  } \
311  a->size=0; \
312  } \
313 } \
314  \
315 static size_t jm_vector_get_size(T)(jm_vector(T)* a) { return a->size; } \
316 \
317 static T jm_vector_get_item(T)(jm_vector(T)* a, size_t index) { \
318  assert(index < a->size); \
319  return a->items[index]; \
320 }\
321 static T* jm_vector_get_itemp(T)(jm_vector(T)* a, size_t index) { \
322  assert(index < a->size); \
323  return (a->items+index); \
324 }\
325  static T jm_vector_get_last(T)(jm_vector(T)* a) { \
326  assert(a->size); \
327  return (a->items[a->size-1]); \
328 } \
329 static T* jm_vector_get_lastp(T)(jm_vector(T)* a) { \
330  if(a->size) return (a->items+(a->size-1)); \
331  else return 0; \
332 } \
333  static void jm_vector_set_item(T)(jm_vector(T)* a, size_t index, T item) {\
334  *(jm_vector_get_itemp(T)(a, index)) = item; \
335 } \
336 extern size_t jm_vector_resize(T)(jm_vector(T)* a, size_t size); \
337 extern size_t jm_vector_reserve(T)(jm_vector(T)* a, size_t capacity); \
338 extern size_t jm_vector_append(T)(jm_vector(T)* destination, jm_vector(T)* source); \
339 extern T* jm_vector_insert(T)(jm_vector(T)* a, size_t index, T item);\
340 extern T* jm_vector_push_back(T)(jm_vector(T)* a, T item);\
341 extern T* jm_vector_resize1(T)(jm_vector(T)* a);\
342 extern void jm_vector_remove_item(T)(jm_vector(T)* v, size_t index); \
343 extern size_t jm_vector_find_index(T)(jm_vector(T)* a, T *itemp, jm_compare_ft f); \
344 extern T* jm_vector_find(T)(jm_vector(T)* a, T *itemp, jm_compare_ft f); \
345 extern void jm_vector_qsort(T)(jm_vector(T)* v, jm_compare_ft f); \
346 extern size_t jm_vector_bsearch_index(T)(jm_vector(T)* v, T* key, jm_compare_ft f); \
347 extern T* jm_vector_bsearch(T)(jm_vector(T)* v, T* key, jm_compare_ft f); \
348 extern void jm_vector_foreach(T)(jm_vector(T)* a, void (*f)(T)); \
349 extern void jm_vector_foreach_c(T)(jm_vector(T)* a, void (*f)(T, void*), void * data); \
350 extern void jm_vector_zero(T)(jm_vector(T)* a);
351 
353 static jm_string jm_vector_char2string(jm_vector(char)* v) {
354  jm_string str = "";
355  if(v->size) return v->items;
356  return str;
357 }
358 
365 
366 
367 jm_define_comp_f(jm_compare_voidp, int*, jm_diff)
368 jm_define_comp_f(jm_compare_int, int, jm_diff)
369 jm_define_comp_f(jm_compare_char, char, jm_diff)
370 jm_define_comp_f(jm_compare_double, double, jm_diff)
371 jm_define_comp_f(jm_compare_size_t, size_t, jm_diff)
372 jm_define_comp_f(jm_compare_string, jm_string, strcmp)
373 
374 #define jm_diff_name(a, b) strcmp(a.name,b.name)
376 
377 
381 #ifdef __cplusplus
382 }
383 #endif
384 
385 #endif
#define jm_vector_declare_template(T)
Definition: jm_vector.h:282
void * jm_voidp
A void pointer.
Definition: jm_types.h:35
#define jm_diff(first, second)
Definition: jm_vector.h:145
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
Mapping between a string and an integer ID.
Definition: jm_types.h:38
return v
#define jm_define_comp_f(F, T, COMPAR_OP)
A conveniece macro for comparison function definition.
Definition: jm_vector.h:140
const char * jm_string
A constant string.
Definition: jm_types.h:33
#define jm_vector(T)
jm_vector(T) is the type name (i.e., to be used as jm_vector(int) vi;)
Definition: jm_vector.h:48
#define jm_diff_name(a, b)