csnip  0.1
mem.h
Go to the documentation of this file.
1 #ifndef CSNIP_MEM_H
2 #define CSNIP_MEM_H
3 
4 #include <stddef.h>
5 #include <stdint.h>
6 #include <stdlib.h>
7 
8 #include <csnip/err.h>
9 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
38 void* csnip_mem_aligned_alloc(size_t nAlign, size_t nSize, int* err);
39 
47 void csnip_mem_aligned_free(void* mem);
48 
49 #ifdef __cplusplus
50 }
51 #endif
52 
53 #ifndef __cplusplus
54 
55 /* Memory macros, C version.
56  */
57 
58 #include <stdlib.h>
59 
81 #define csnip_mem_Alloc(nMember, ptr, err) \
82  do { \
83  if ((nMember) < 0 || \
84  SIZE_MAX / sizeof(*(ptr)) < (nMember)) \
85  { \
86  (ptr) = NULL; \
87  csnip_err_Raise(csnip_err_RANGE, err); \
88  break; \
89  } \
90  if (((ptr) = malloc(sizeof(*(ptr)) * (nMember))) == NULL) \
91  csnip_err_Raise(csnip_err_NOMEM, err); \
92  } while(0)
93 
99 #define csnip_mem_Alloc0(nMember, ptr, err) \
100  do { \
101  if ((nMember) < 0) { \
102  (ptr) = NULL; \
103  csnip_err_Raise(csnip_err_RANGE, err); \
104  break; \
105  } \
106  if (((ptr) = calloc((nMember), sizeof(*(ptr)))) == NULL) \
107  csnip_err_Raise(csnip_err_NOMEM, err); \
108  } while(0)
109 
119 #define csnip_mem_AlignedAlloc(nMember, nAlign, ptr, err) \
120  csnip_mem__AlignedAlloc((nMember), (nAlign), (ptr), (err))
121 
123 #define csnip_mem__AlignedAlloc(nMember, nAlign, ptr, err) \
124  do { \
125  if (nAlign < 0 || nAlign > SIZE_MAX ||nMember < 0 || \
126  SIZE_MAX / sizeof(*ptr) < nMember) \
127  { \
128  ptr = NULL; \
129  csnip_err_Raise(csnip_err_RANGE, err); \
130  break; \
131  } \
132  int csnip__err; \
133  ptr = csnip_mem_aligned_alloc(nAlign, nMember * sizeof(*ptr), \
134  &csnip__err); \
135  if (ptr == NULL) \
136  csnip_err_Raise(csnip__err, err); \
137  } while(0);
155 #define csnip_mem_Realloc(nMember, ptr, err) \
156  csnip_mem__Realloc((nMember), (ptr), (err), csnip__p)
157 
159 #define csnip_mem__Realloc(nMember, ptr, err, p) \
160  do { \
161  if (nMember < 0 || \
162  SIZE_MAX / sizeof(*ptr) < nMember) { \
163  csnip_err_Raise(csnip_err_RANGE, err); \
164  break; \
165  } \
166  void* p = realloc(ptr, sizeof(*ptr) * nMember); \
167  if (p == NULL) { \
168  csnip_err_Raise(csnip_err_NOMEM, err); \
169  break; \
170  } \
171  ptr = p; \
172  } while(0)
185 #define csnip_mem_Free(ptr) \
186  do { \
187  free(ptr); \
188  (ptr) = NULL; \
189  } while(0)
190 
199 #define csnip_mem_AlignedFree(ptr) \
200  do { \
201  csnip_mem_aligned_free(ptr); \
202  (ptr) = NULL; \
203  } while (0)
204 
205 #else
211 #include <cstdlib>
212 
213 template<typename T>
214  inline T* csnip_mem_alloc_cxx(size_t nMemb, T* typeselect, int* err)
215 {
216  (void)typeselect;
217  if (SIZE_MAX / sizeof(T) < nMemb) {
218  *err = csnip_err_RANGE;
219  return NULL;
220  }
221  return (T*)std::malloc(sizeof(T) * nMemb);
222 }
223 
224 template<typename T>
225  inline T* csnip_mem_calloc_cxx(size_t nMemb, T* typeselect, int* err)
226 {
227  (void)typeselect;
228  if (SIZE_MAX / sizeof(T) < nMemb) {
229  *err = csnip_err_RANGE;
230  return NULL;
231  }
232  return (T*)std::calloc(nMemb, sizeof(T));
233 }
234 
235 template<typename T>
236  inline T* csnip_mem_aligned_alloc_cxx(size_t nMemb, size_t nAlign, T* typeselect, int* err)
237 {
238  (void)typeselect;
239  if (SIZE_MAX / sizeof(T) < nMemb) {
240  *err = csnip_err_RANGE;
241  return NULL;
242  }
243  return (T*)csnip_mem_aligned_alloc(nAlign, nMemb * sizeof(T), err);
244 }
245 
246 template<typename T>
247  inline void csnip_mem_realloc_cxx(size_t nMemb, T** orig, int* err)
248 {
249  if (SIZE_MAX / sizeof(T) < nMemb) {
250  *err = csnip_err_RANGE;
251  return;
252  }
253  T* new_ptr = (T*)std::realloc(*orig, sizeof(T) * nMemb);
254  if (new_ptr) {
255  *orig = new_ptr;
256  } else {
257  *err = csnip_err_NOMEM;
258  }
259 }
260 
261 #define csnip_mem_Alloc(nMember, ptr, err) \
262  do { \
263  int csnip__err = 0; \
264  (ptr) = NULL; \
265  (ptr) = csnip_mem_alloc_cxx((nMember), (ptr), &csnip__err); \
266  if ((ptr) == NULL) { \
267  csnip_err_Raise(csnip__err, err); \
268  } \
269  } while(0)
270 
271 #define csnip_mem_Alloc0(nMember, ptr, err) \
272  do { \
273  int csnip__err = 0; \
274  (ptr) = NULL; \
275  (ptr) = csnip_mem_calloc_cxx((nMember), (ptr), &csnip__err); \
276  if ((ptr) == NULL) { \
277  csnip_err_Raise(csnip__err, err); \
278  } \
279  } while(0)
280 
281 #define csnip_mem_AlignedAlloc(nMember, nAlign, ptr, err) \
282  do { \
283  int csnip__err = 0; \
284  (ptr) = NULL; \
285  (ptr) = csnip_mem_aligned_alloc_cxx((nMember), (nAlign), \
286  (ptr), &csnip__err); \
287  if ((ptr) == NULL) { \
288  csnip_err_Raise(csnip__err, err); \
289  } \
290  } while(0)
291 
292 #define csnip_mem_Realloc(nMember, ptr, err) \
293  do { \
294  int csnip__err = 0; \
295  csnip_mem_realloc_cxx((nMember), &(ptr), &csnip__err);\
296  if (csnip__err) { \
297  csnip_err_Raise(csnip__err, err); \
298  } \
299  } while(0)
300 
301 
302 #define csnip_mem_Free(ptr) \
303  do { \
304  std::free(ptr); \
305  (ptr) = NULL; \
306  } while(0)
307 
308 #define csnip_mem_AlignedFree(ptr) \
309  do { \
310  csnip_mem_aligned_free(ptr); \
311  (ptr) = NULL; \
312  } while (0)
313 
316 #endif
317 
320 #endif /* CSNIP_MEM_H */
321 
322 #if defined(CSNIP_SHORT_NAMES) && !defined(CSNIP_MEM_HAVE_SHORT_NAMES)
323 #define mem_aligned_alloc csnip_mem_aligned_alloc
324 #define mem_Alloc csnip_mem_Alloc
325 #define mem_Alloc0 csnip_mem_Alloc0
326 #define mem_AlignedAlloc csnip_mem_AlignedAlloc
327 #define mem_Realloc csnip_mem_Realloc
328 #define mem_Free csnip_mem_Free
329 #define mem_AlignedFree csnip_mem_AlignedFree
330 #define CSNIP_MEM_HAVE_SHORT_NAMES
331 #endif
Error handling.
#define csnip_err_RANGE
Range error.
Definition: err.h:96
#define csnip_err_NOMEM
Out of memory.
Definition: err.h:94
void csnip_mem_aligned_free(void *mem)
Free aligned memory.
void * csnip_mem_aligned_alloc(size_t nAlign, size_t nSize, int *err)
Allocate aligned memory.