P99
p99_new.h
Go to the documentation of this file.
1 /* This may look like nonsense, but it really is -*- mode: C; coding: utf-8 -*- */
2 /* */
3 /* Except for parts copied from previous work and as explicitly stated below, */
4 /* the authors and copyright holders for this work are as follows: */
5 /* (C) copyright 2010-2013 Jens Gustedt, INRIA, France */
6 /* (C) copyright 2012 William Morris */
7 /* */
8 /* This file is free software; it is part of the P99 project. */
9 /* */
10 /* Licensed under the Apache License, Version 2.0 (the "License"); */
11 /* you may not use this file except in compliance with the License. */
12 /* You may obtain a copy of the License at */
13 /* */
14 /* http://www.apache.org/licenses/LICENSE-2.0 */
15 /* */
16 /* Unless required by applicable law or agreed to in writing, software */
17 /* distributed under the License is distributed on an "AS IS" BASIS, */
18 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
19 /* See the License for the specific language governing permissions and */
20 /* limitations under the License. */
21 /* */
22 #ifndef P99_NEW_H_
23 # define P99_NEW_H_
24 
25 #include "p99_c99.h"
26 #include "p99_int.h"
27 
41 P99_MACRO_END(dummy);
42 
63 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_PZERO, 0)
64 #define P99_PZERO(X, N) (memset((X), 0, sizeof(X[0]) * N))
65 
77 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TZERO, 0)
78 #define P99_TZERO(X) (memset(&(X), 0, sizeof(X)))
79 
81 unsigned char
82 (*p00_memcpy(size_t p00_len, unsigned char (*p00_tar)[p00_len], unsigned char const (*p00_src)[p00_len]))[] {
83  memcpy(&(*p00_tar)[0], &(*p00_src)[0], p00_len);
84  return p00_tar;
85 }
86 
87 P00_DOCUMENT_TYPE_ARGUMENT(P99_ASUB, 1)
88 #define P99_ASUB(X, T, N, L) \
89 ( \
90  (T(*)[L \
91  /* check for validity \
92  / !!(L && (sizeof(T[N+L]) < sizeof(*X)))*/]) \
93  (P99_LVAL(T*, &((*X)[N]))) \
94 )
95 
97 unsigned char
98 (*p00_initialize(size_t p00_len, unsigned char (*p00_base)[p00_len], size_t p00_init))[] {
99  for (; (p00_init * 2u) <= p00_len; p00_init *= 2u) {
100  p00_memcpy(p00_init,
101  P99_ASUB(p00_base, unsigned char, p00_init, p00_init),
102  P99_ASUB(p00_base, unsigned char const, 0, p00_init));
103  }
104  if (p00_len > p00_init) {
105  p00_len -= p00_init;
106  p00_memcpy(p00_len,
107  P99_ASUB(p00_base, unsigned char, p00_init, p00_len),
108  P99_ASUB(p00_base, unsigned char const, 0, p00_len));
109  }
110  return p00_base;
111 }
112 
113 #if ((P99_COMPILER & P99_COMPILER_GNU) && (P99_GCC_VERSION < 40704UL))
114 # define P00_ABLESS_BUG 1
115 #endif
116 
117 #if defined(P99_TYPEOF) && !P00_ABLESS_BUG
118 # define P00_ABLESS(X, ...) ((P99_TYPEOF(__VA_ARGS__)*restrict)(unsigned char(*)[sizeof(__VA_ARGS__)]){ X })
119 #else
120 # define P00_ABLESS(X, ...) ((void*restrict)(unsigned char(*)[sizeof(__VA_ARGS__)]){ X })
121 #endif
122 
123 #define P00_APLAIN(X, N) ((unsigned char(*)[N])(X))
124 #define P99_APLAIN(...) \
125 (P99_IF_LT_2(P99_NARG(__VA_ARGS__)) \
126  (P00_APLAIN(__VA_ARGS__, sizeof(*__VA_ARGS__))) \
127  (P00_APLAIN(__VA_ARGS__)) \
128  )
129 
131 void* p00_memset(void* p00_tar, void const* p00_src, size_t p00_size, size_t p00_nb) {
132  p00_initialize(p00_nb * p00_size,
133  P00_APLAIN(memcpy(p00_tar, p00_src, p00_size), p00_size),
134  p00_size);
135  return p00_tar;
136 }
137 
151 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MEMSET, 1)
152 #define P99_MEMSET(TA, SO, N) p00_memset((TA), (void const*)&(SO), sizeof(SO), N)
153 
164 P00_DOCUMENT_TYPE_ARGUMENT(P99_MEMZERO, 0)
165 #define P99_MEMZERO(T, TA, N) p00_memset((TA), (void const*)&P99_LVAL(const T), sizeof(T), N)
166 
191 #define P99_MALLOC(X) malloc(sizeof(X))
192 
193 
194 #define P00_VMALLOC(X) P00_ABLESS(P99_MALLOC(X), X)
195 
196 #define P00_INITIALIZE(X, L) \
197 p00_initialize(sizeof(*X), \
198  P00_APLAIN(memcpy((X), (L), sizeof(*L)), sizeof(*X)), \
199  sizeof(*L))
200 
201 P00_DOCUMENT_WARN_VLA_ARGUMENT(P99_INITIALIZE, 0)
202 P00_DOCUMENT_WARN_VLA_ARGUMENT(P99_INITIALIZE, 1)
203 #define P99_INITIALIZE(X, L) P00_ABLESS(P00_INITIALIZE((X), (L)), *(X))
204 
205 #define P00_ALLOC(X, L) \
206 P00_ABLESS(p00_initialize(sizeof(X), \
207  P00_APLAIN(memcpy(P99_MALLOC(X), (&L), sizeof(L)), sizeof(X)), \
208  sizeof(L)), \
209  (X))
210 
211 #define P99_ALLOC(...) P99_IF_GT(P99_NARG(__VA_ARGS__), 1)(P00_ALLOC(__VA_ARGS__))(P00_VMALLOC(__VA_ARGS__))
212 
229 #define P99_REALLOC(X, T) realloc((X), sizeof(T))
230 
232 void* p00_calloc(void const* p00_src, size_t p00_size, size_t p00_nb) {
233  return p00_memset(malloc(p00_size*p00_nb), p00_src, p00_size, p00_nb);
234 }
235 
236 #define P00_CALLOC0(T, N) p00_calloc((void const*)&P99_LVAL(const T), sizeof(T), N)
237 #define P00_CALLOC(...) P00_CALLOC0(__VA_ARGS__)
238 
239 #ifdef P00_DOXYGEN
240 
268 P00_DOCUMENT_TYPE_ARGUMENT(P99_CALLOC, 0)
269 #define P99_CALLOC(T, N)
270 #else
271 P00_DOCUMENT_TYPE_ARGUMENT(P99_CALLOC, 0)
272 #define P99_CALLOC(...) P00_CALLOC(P99_CALL_DEFARG_LIST(P00_CALLOC, 2, __VA_ARGS__))
273 #endif
274 
275 #define P00_CALLOC_defarg_1() 1
276 
277 #define P00_NEW(T) P99_PASTE2(T, _init)(P99_MALLOC(T))
278 
279 #define P00_NEW_ARGS(T, ...) P99_PASTE2(T, _init)(P99_MALLOC(T), __VA_ARGS__)
280 
281 
315 #define P99_NEW(...) P99_IF_LT(P99_NARG(__VA_ARGS__), 2)(P00_NEW(__VA_ARGS__))(P00_NEW_ARGS(__VA_ARGS__))
316 
317 #ifdef P00_DOXYGEN
318 
328 P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_DELETE, 0)
329 #define P99_DECLARE_DELETE(T) \
330  \
331  \
332  \
333  \
334  \
335  void P99_PASTE2(T, _delete)(T const*p00_el) { }
336 
337 #define P99_DEFINE_DELETE(T) P99_INSTANTIATE(void, P99_PASTE2(T, _delete), T const*)
338 #else
339 P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_DELETE, 0)
340 #define P99_DECLARE_DELETE(...) \
341 P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
342 (P00_DECLARE_DELETE(__VA_ARGS__, p99_inline)) \
343 (P00_DECLARE_DELETE(__VA_ARGS__)) \
344 P99_MACRO_END(P99_DECLARE_DELETE)
345 #define P99_DEFINE_DELETE(...) P00_DEFINE_DELETE(__VA_ARGS__,)
346 #endif
347 
348 #define P00_DECLARE_DELETE(T, ...) \
349 __VA_ARGS__ \
350 void P99_PASTE2(T, _delete)(T const*p00_el) { \
351  if (p00_el) { \
352  T* p00_e = (T*)p00_el; \
353  P99_PASTE2(T, _destroy)(p00_e); \
354  free((void*)p00_e); \
355  } \
356 }
357 
358 #define P00_DEFINE_DELETE(T, ...) P99_INSTANTIATE(void, P99_PASTE2(T, _delete), T const*)
359 
362 size_t p99_maxof(size_t p00_m, size_t p00_n) {
363  return p00_m < p00_n ? p00_n : p00_m;
364 }
365 
366 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MINOF, 0)
367 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MINOF, 1)
368 #define P99_MAXOF(A, B) ((A) < (B) ? (B) : (A))
369 
370 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MAXOF, 0)
371 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MAXOF, 1)
372 #define P99_MINOF(A, B) ((A) < (B) ? (A) : (B))
373 
374 #define P00_SIZEOF2(T, ...) sizeof(P99_TOKJOIN(., P99_LVAL(const T), __VA_ARGS__))
375 
376 #ifdef P00_DOXYGEN
377 
382 #define P99_SIZEOF(T, F, ...) P99_IF_EQ(P99_NARG(__VA_ARGS__), 1)(sizeof(__VA_ARGS__))(P00_SIZEOF2(__VA_ARGS__))
383 #else
384 #define P99_SIZEOF(...) P99_IF_EQ(P99_NARG(__VA_ARGS__), 1)(sizeof(__VA_ARGS__))(P00_SIZEOF2(__VA_ARGS__))
385 #endif
386 
446 P00_DOCUMENT_TYPE_ARGUMENT(P99_FHEAD, 0)
447 #define P99_FHEAD(T, F, P) ((T*)(((char*)P) - offsetof(T, F)))
448 
454 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FSIZEOF, 2)
455 P00_DOCUMENT_TYPE_ARGUMENT(P99_FSIZEOF, 0)
456 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FSIZEOF, 1)
457 #define P99_FSIZEOF(T, F, N) P99_MAXOF(sizeof(T), offsetof(T, F) + P99_SIZEOF(T, F[0]) * N)
458 #define P00_FSIZEOF(T, F, M) p99_maxof(sizeof(T), offsetof(T, F) + M)
459 
460 #define P00_FREALLOC(P, T, F, M) realloc(P, P00_FSIZEOF(T, F, M))
461 
472 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FREALLOC, 3)
473 P00_DOCUMENT_TYPE_ARGUMENT(P99_FREALLOC, 1)
474 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FREALLOC, 2)
475 #define P99_FREALLOC(P, T, F, N) realloc(P, P99_FSIZEOF(T, F, N))
476 
484 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FMALLOC, 2)
485 P00_DOCUMENT_TYPE_ARGUMENT(P99_FMALLOC, 0)
486 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FMALLOC, 1)
487 #define P99_FMALLOC(T, F, N) malloc(P99_FSIZEOF(T, F, N))
488 #define P00_FMALLOC(T, F, M) malloc(P00_FSIZEOF(T, F, M))
489 
496 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FCALLOC, 2)
497 P00_DOCUMENT_TYPE_ARGUMENT(P99_FCALLOC, 0)
498 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FCALLOC, 1)
499 #define P99_FCALLOC(T, F, N) calloc(P99_FSIZEOF(T, F, N),1)
500 #define P00_FCALLOC(T, F, M) calloc(P00_FSIZEOF(T, F, M),1)
501 
510 #endif /* !P99_NEW_H_ */
P99_FREALLOC
#define P99_FREALLOC(P, T, F, N)
Reallocate an instance P of struct T such that it is able to hold N items in flexible struct member F...
Definition: p99_new.h:474
P99_INITIALIZE
#define P99_INITIALIZE(X, L)
Definition: p99_new.h:202
p99_c99.h
C99 specific include files that are required by the standard.
P99_MEMZERO
#define P99_MEMZERO(T, TA, N)
A type oriented replacement for memset with argument 0.
Definition: p99_new.h:164
P99_FMALLOC
#define P99_FMALLOC(T, F, N)
Allocate an instance of struct T that is able to hold N items in flexible struct member F.
Definition: p99_new.h:486
P99_DECLARE_DELETE
#define P99_DECLARE_DELETE(T)
Declare a ‘delete’ operator for type T.
Definition: p99_new.h:328
P99_PZERO
#define P99_PZERO(X, N)
Zero out all bits in the object to which X points.
Definition: p99_new.h:64
P99_MAXOF
#define P99_MAXOF(A, B)
Definition: p99_new.h:367
p99_maxof
size_t p99_maxof(size_t p00_m, size_t p00_n)
Definition: p99_new.h:361
P99_MINOF
#define P99_MINOF(A, B)
Definition: p99_new.h:371
P99_FSIZEOF
#define P99_FSIZEOF(T, F, N)
Compute the size for an instance of struct T that is able to hold N items in flexible struct member F...
Definition: p99_new.h:456
p99_inline
#define p99_inline
Try to force a function always to be inlined.
Definition: p99_compiler.h:496
P99_TZERO
#define P99_TZERO(X)
Zero out all bits in the object X.
Definition: p99_new.h:78
P99_CALLOC
#define P99_CALLOC(T, N)
A type oriented replacement for calloc.
Definition: p99_new.h:268
P99_FHEAD
#define P99_FHEAD(T, F, P)
For a pointer P to a flexible struct member F in struct T find the start address of the container.
Definition: p99_new.h:446
P99_FCALLOC
#define P99_FCALLOC(T, F, N)
Allocate an instance of struct T that is able to hold N items in flexible struct member F.
Definition: p99_new.h:498
P99_CONST_FUNCTION
#define P99_CONST_FUNCTION
On architectures that support this, assert that a function is "const", i.e only depends on parameters...
Definition: p99_compiler.h:622
P99_ASUB
#define P99_ASUB(X, T, N, L)
Definition: p99_new.h:88
P99_MEMSET
#define P99_MEMSET(TA, SO, N)
A type oriented replacement for memset.
Definition: p99_new.h:151
P99_MACRO_END
#define P99_MACRO_END(...)
A meta macro that forces the addition of a semicolon after a call to the macro that it terminates.
Definition: p99_compiler.h:941
p99_int.h
Macros handling integer types and initialization.