The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
array.h
Go to the documentation of this file.
1 
26 #ifndef ARRAY_H_
27 #define ARRAY_H_
28 
29 #include <mm/dymelor.h>
30 
31 #include <memory.h>
32 
33 // TODO: add some type checking and size checking (is it necessary?)
34 
35 #define INIT_SIZE_ARRAY 8U
36 
37 #define rootsim_array(type) \
38  struct { \
39  type *items; \
40  unsigned count, capacity; \
41  }
42 
43 // you can use the array to directly index items, but do at your risk and peril
44 #define array_items(self) ((self).items)
45 
46 #define array_count(self) ((self).count)
47 
48 #define array_capacity(self) ((self).capacity)
49 
50 #define array_shrink(self) ({ \
51  if (array_count(self) > INIT_SIZE_ARRAY && array_count(self) * 3 <= array_capacity(self)) { \
52  array_capacity(self) /= 2; \
53  array_items(self) = rsrealloc(array_items(self), array_capacity(self) * sizeof(*array_items(self))); \
54  } \
55  })
56 
57 #define array_expand(self) ({ \
58  if(array_count(self) >= array_capacity(self)){\
59  array_capacity(self) *= 2; \
60  array_items(self) = rsrealloc(array_items(self), array_capacity(self) * sizeof(*array_items(self))); \
61  } \
62  })
63 
64 #define array_new(type) ({ \
65  rootsim_array(type) *__newarr; \
66  __newarr = rsalloc(sizeof(*__newarr)); \
67  array_init(*__newarr);\
68  __newarr; \
69  })
70 
71 #define array_free(self) ({ \
72  rsfree(array_items(self)); \
73  rsfree(&(self)); \
74  })
75 
76 #define array_init(self) ({ \
77  array_capacity(self) = INIT_SIZE_ARRAY; \
78  array_items(self) = rsalloc(array_capacity(self) * sizeof(*array_items(self))); \
79  array_count(self) = 0; \
80  })
81 
82 #define array_fini(self) ({ \
83  rsfree(array_items(self)); \
84  })
85 //fixme array_expand doesn't work when reserving with count high since it only doubles once
86 #define array_reserve(self, count) ({ \
87  __typeof__(array_count(self)) __rsvidx = array_count(self); \
88  array_count(self) += (count); \
89  array_expand(self); \
90  &(array_items(self)[__rsvidx]); \
91 })
92 
93 #define array_push(self, elem) ({ \
94  array_expand(self); \
95  array_items(self)[array_count(self)] = (elem); \
96  array_count(self)++; \
97  })
98 
99 #define array_pop(self) ({ \
100  if(unlikely(!array_count(self))) \
101  rootsim_error(true, "pop of an empty array"); \
102  __typeof__(*array_items(self)) __popval; \
103  array_count(self)--; \
104  __popval = array_items(self)[array_count(self)]; \
105  array_shrink(self); \
106  __popval; \
107  })
108 
109 #define array_add_at(self, i, elem) ({ \
110  if(unlikely(array_count(self) <= (i))) \
111  rootsim_error(true, "out of bound add in a dynamic array"); \
112  array_expand(self); \
113  memmove(&(array_items(self)[(i)+1]), &(array_items(self)[(i)]), sizeof(*array_items(self)) * (array_count(self)-(i))); \
114  array_items(self)[(i)] = (elem); \
115  array_count(self)++; \
116  })
117 
118 #define array_lazy_remove_at(self, i) ({ \
119  if(unlikely(array_count(self) <= (i))) \
120  rootsim_error(true, "out of bound removal in a dynamic array"); \
121  __typeof__(*array_items(self)) __rmval; \
122  array_count(self)--; \
123  __rmval = array_items(self)[(i)]; \
124  array_items(self)[(i)] = array_items(self)[array_count(self)]; \
125  array_shrink(self); \
126  __rmval; \
127  })
128 
129 #define array_remove_at(self, i) ({ \
130  if(unlikely(array_count(self) <= (i))) \
131  rootsim_error(true, "out of bound removal in a dynamic array"); \
132  __typeof__(*array_items(self)) __rmval; \
133  array_count(self)--; \
134  __rmval = array_items(self)[(i)]; \
135  memmove(&(array_items(self)[(i)]), &(array_items(self)[(i)+1]), sizeof(*array_items(self)) * (array_count(self)-(i))); \
136  array_shrink(self); \
137  __rmval; \
138  })
139 
140 #define array_remove(self, elem) ({ \
141  typeof(array_count(self)) __cntr = array_count(self); \
142  while(__cntr--){ \
143  if(array_items(self)[__cntr] == (elem)){\
144  array_remove_at(self, __cntr); \
145  break; \
146  } \
147  } \
148  })
149 //this isn't checked CARE! TODO add checking
150 #define array_peek(self) (array_items(self)[array_count(self)-1])
151 //this isn't checked CARE! TODO add checking
152 #define array_get_at(self, i) (array_items(self)[i])
153 
154 #define array_empty(self) (array_count(self) == 0)
155 
156 #define array_dump_size(self) ({ \
157  sizeof(array_count(self)) + array_count(self)*sizeof(*array_items(self)); \
158  })
159 
160 #define array_dump(self, mem_area) ({ \
161  memcpy((mem_area), &array_count(self), sizeof(array_count(self))); \
162  (mem_area) = ((unsigned char *)(mem_area)) + sizeof(array_count(self)); \
163  memcpy((mem_area), array_items(self), array_count(self) * sizeof(*array_items(self))); \
164  mem_area = ((unsigned char *)(mem_area)) + array_count(self) * sizeof(*array_items(self)); \
165  })
166 
167 #define array_load(self, mem_area) ({ \
168  memcpy(&array_count(self), (mem_area), sizeof(array_count(self))); \
169  (mem_area) = ((unsigned char *)(mem_area)) + sizeof(array_count(self)); \
170  array_capacity(self) = max(array_count(self), INIT_SIZE_ARRAY); \
171  array_items(self) = rsalloc(array_capacity(self) * sizeof(*array_items(self))); \
172  memcpy(array_items(self), (mem_area), array_count(self) * sizeof(*array_items(self))); \
173  (mem_area) = ((unsigned char *)(mem_area)) + (array_count(self) * sizeof(*array_items(self))); \
174  })
175 
176 #endif /* ARRAY_H_ */
Dynamic Memory Logger and Restorer (DyMeLoR)