00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef P99_NEW_H_
00015 # define P99_NEW_H_
00016
00017 #include "p99_c99.h"
00018 #include "p99_int.h"
00019
00033 P99_MACRO_END(dummy);
00034
00055 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_PZERO, 0)
00056 #define P99_PZERO(X, N) (memset((X), 0, sizeof(X[0]) * N))
00057
00069 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TZERO, 0)
00070 #define P99_TZERO(X) (memset(&(X), 0, sizeof(X)))
00071
00072 p99_inline
00073 unsigned char
00074 (*p00_memcpy(size_t p00_len, unsigned char (*p00_tar)[p00_len], unsigned char const (*p00_src)[p00_len]))[] {
00075 memcpy(&(*p00_tar)[0], &(*p00_src)[0], p00_len);
00076 return p00_tar;
00077 }
00078
00079 P00_DOCUMENT_TYPE_ARGUMENT(P99_ASUB, 1)
00080 #define P99_ASUB(X, T, N, L) \
00081 ( \
00082 (T(*)[L \
00083
00084 ]) \
00085 (P99_LVAL(T*, &((*X)[N]))) \
00086 )
00087
00088 p99_inline
00089 unsigned char
00090 (*p00_initialize(size_t p00_len, unsigned char (*p00_base)[p00_len], size_t p00_init))[] {
00091 for (; (p00_init * 2u) <= p00_len; p00_init *= 2u) {
00092 p00_memcpy(p00_init,
00093 P99_ASUB(p00_base, unsigned char, p00_init, p00_init),
00094 P99_ASUB(p00_base, unsigned char const, 0, p00_init));
00095 }
00096 if (p00_len > p00_init) {
00097 p00_len -= p00_init;
00098 p00_memcpy(p00_len,
00099 P99_ASUB(p00_base, unsigned char, p00_init, p00_len),
00100 P99_ASUB(p00_base, unsigned char const, 0, p00_len));
00101 }
00102 return p00_base;
00103 }
00104
00105 #if ((P99_COMPILER & P99_COMPILER_GNU) && (P99_GCC_VERSION < 40704UL))
00106 # define P00_ABLESS_BUG 1
00107 #endif
00108
00109 #if defined(P99_TYPEOF) && !P00_ABLESS_BUG
00110 # define P00_ABLESS(X, ...) ((P99_TYPEOF(__VA_ARGS__)*restrict)(unsigned char(*)[sizeof(__VA_ARGS__)]){ X })
00111 #else
00112 # define P00_ABLESS(X, ...) ((void*restrict)(unsigned char(*)[sizeof(__VA_ARGS__)]){ X })
00113 #endif
00114
00115 #define P00_APLAIN(X, N) ((unsigned char(*)[N])(X))
00116 #define P99_APLAIN(...) \
00117 (P99_IF_LT_2(P99_NARG(__VA_ARGS__)) \
00118 (P00_APLAIN(__VA_ARGS__, sizeof(*__VA_ARGS__))) \
00119 (P00_APLAIN(__VA_ARGS__)) \
00120 )
00121
00122 p99_inline
00123 void* p00_memset(void* p00_tar, void const* p00_src, size_t p00_size, size_t p00_nb) {
00124 p00_initialize(p00_nb * p00_size,
00125 P00_APLAIN(memcpy(p00_tar, p00_src, p00_size), p00_size),
00126 p00_size);
00127 return p00_tar;
00128 }
00129
00143 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_MEMSET, 1)
00144 #define P99_MEMSET(TA, SO, N) p00_memset((TA), (void const*)&(SO), sizeof(SO), N)
00145
00156 P00_DOCUMENT_TYPE_ARGUMENT(P99_MEMZERO, 0)
00157 #define P99_MEMZERO(T, TA, N) p00_memset((TA), (void const*)&P99_LVAL(const T), sizeof(T), N)
00158
00183 #define P99_MALLOC(X) malloc(sizeof(X))
00184
00185
00186 #define P00_VMALLOC(X) P00_ABLESS(P99_MALLOC(X), X)
00187
00188 #define P00_INITIALIZE(X, L) \
00189 p00_initialize(sizeof(*X), \
00190 P00_APLAIN(memcpy((X), (L), sizeof(*L)), sizeof(*X)), \
00191 sizeof(*L))
00192
00193 P00_DOCUMENT_WARN_VLA_ARGUMENT(P99_INITIALIZE, 0)
00194 P00_DOCUMENT_WARN_VLA_ARGUMENT(P99_INITIALIZE, 1)
00195 #define P99_INITIALIZE(X, L) P00_ABLESS(P00_INITIALIZE((X), (L)), *(X))
00196
00197 #define P00_ALLOC(X, L) \
00198 P00_ABLESS(p00_initialize(sizeof(X), \
00199 P00_APLAIN(memcpy(P99_MALLOC(X), (&L), sizeof(L)), sizeof(X)), \
00200 sizeof(L)), \
00201 (X))
00202
00203 #define P99_ALLOC(...) P99_IF_GT(P99_NARG(__VA_ARGS__), 1)(P00_ALLOC(__VA_ARGS__))(P00_VMALLOC(__VA_ARGS__))
00204
00221 #define P99_REALLOC(X, T) realloc((X), sizeof(T))
00222
00223 p99_inline
00224 void* p00_calloc(void const* p00_src, size_t p00_size, size_t p00_nb) {
00225 return p00_memset(malloc(p00_size*p00_nb), p00_src, p00_size, p00_nb);
00226 }
00227
00228 #define P00_CALLOC0(T, N) p00_calloc((void const*)&P99_LVAL(const T), sizeof(T), N)
00229 #define P00_CALLOC(...) P00_CALLOC0(__VA_ARGS__)
00230
00231 #ifdef P00_DOXYGEN
00232
00260 P00_DOCUMENT_TYPE_ARGUMENT(P99_CALLOC, 0)
00261 #define P99_CALLOC(T, N)
00262 #else
00263 P00_DOCUMENT_TYPE_ARGUMENT(P99_CALLOC, 0)
00264 #define P99_CALLOC(...) P00_CALLOC(P99_CALL_DEFARG_LIST(P00_CALLOC, 2, __VA_ARGS__))
00265 #endif
00266
00267 #define P00_CALLOC_defarg_1() 1
00268
00269 #define P00_NEW(T) P99_PASTE2(T, _init)(P99_MALLOC(T))
00270
00271 #define P00_NEW_ARGS(T, ...) P99_PASTE2(T, _init)(P99_MALLOC(T), __VA_ARGS__)
00272
00273
00307 #define P99_NEW(...) P99_IF_LT(P99_NARG(__VA_ARGS__), 2)(P00_NEW(__VA_ARGS__))(P00_NEW_ARGS(__VA_ARGS__))
00308
00309 #ifdef P00_DOXYGEN
00310
00320 P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_DELETE, 0)
00321 #define P99_DECLARE_DELETE(T) \
00322 \
00323 \
00324 \
00325 \
00326 \
00327 void P99_PASTE2(T, _delete)(T const*p00_el) { }
00328
00329 #define P99_DEFINE_DELETE(T) P99_INSTANTIATE(void, P99_PASTE2(T, _delete), T const*)
00330 #else
00331 P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_DELETE, 0)
00332 #define P99_DECLARE_DELETE(...) \
00333 P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
00334 (P00_DECLARE_DELETE(__VA_ARGS__, p99_inline)) \
00335 (P00_DECLARE_DELETE(__VA_ARGS__)) \
00336 P99_MACRO_END(P99_DECLARE_DELETE)
00337 #define P99_DEFINE_DELETE(...) P00_DEFINE_DELETE(__VA_ARGS__,)
00338 #endif
00339
00340 #define P00_DECLARE_DELETE(T, ...) \
00341 __VA_ARGS__ \
00342 void P99_PASTE2(T, _delete)(T const*p00_el) { \
00343 if (p00_el) { \
00344 T* p00_e = (T*)p00_el; \
00345 P99_PASTE2(T, _destroy)(p00_e); \
00346 free((void*)p00_e); \
00347 } \
00348 }
00349
00350 #define P00_DEFINE_DELETE(T, ...) P99_INSTANTIATE(void, P99_PASTE2(T, _delete), T const*)
00351
00352 P99_CONST_FUNCTION
00353 p99_inline
00354 size_t p99_maxof(size_t p00_m, size_t p00_n) {
00355 return p00_m < p00_n ? p00_n : p00_m;
00356 }
00357
00358 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MINOF, 0)
00359 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MINOF, 1)
00360 #define P99_MAXOF(A, B) ((A) < (B) ? (B) : (A))
00361
00362 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MAXOF, 0)
00363 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_MAXOF, 1)
00364 #define P99_MINOF(A, B) ((A) < (B) ? (A) : (B))
00365
00366 #define P00_SIZEOF2(T, ...) sizeof(P99_TOKJOIN(., P99_LVAL(const T), __VA_ARGS__))
00367
00368 #ifdef P00_DOXYGEN
00369
00374 #define P99_SIZEOF(T, F, ...) P99_IF_EQ(P99_NARG(__VA_ARGS__), 1)(sizeof(__VA_ARGS__))(P00_SIZEOF2(__VA_ARGS__))
00375 #else
00376 #define P99_SIZEOF(...) P99_IF_EQ(P99_NARG(__VA_ARGS__), 1)(sizeof(__VA_ARGS__))(P00_SIZEOF2(__VA_ARGS__))
00377 #endif
00378
00438 P00_DOCUMENT_TYPE_ARGUMENT(P99_FHEAD, 0)
00439 #define P99_FHEAD(T, F, P) ((T*)(((char*)P) - offsetof(T, F)))
00440
00446 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FSIZEOF, 2)
00447 P00_DOCUMENT_TYPE_ARGUMENT(P99_FSIZEOF, 0)
00448 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FSIZEOF, 1)
00449 #define P99_FSIZEOF(T, F, N) P99_MAXOF(sizeof(T), offsetof(T, F) + P99_SIZEOF(T, F[0]) * N)
00450 #define P00_FSIZEOF(T, F, M) p99_maxof(sizeof(T), offsetof(T, F) + M)
00451
00452 #define P00_FREALLOC(P, T, F, M) realloc(P, P00_FSIZEOF(T, F, M))
00453
00464 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FREALLOC, 3)
00465 P00_DOCUMENT_TYPE_ARGUMENT(P99_FREALLOC, 1)
00466 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FREALLOC, 2)
00467 #define P99_FREALLOC(P, T, F, N) realloc(P, P99_FSIZEOF(T, F, N))
00468
00476 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FMALLOC, 2)
00477 P00_DOCUMENT_TYPE_ARGUMENT(P99_FMALLOC, 0)
00478 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FMALLOC, 1)
00479 #define P99_FMALLOC(T, F, N) malloc(P99_FSIZEOF(T, F, N))
00480 #define P00_FMALLOC(T, F, M) malloc(P00_FSIZEOF(T, F, M))
00481
00488 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FCALLOC, 2)
00489 P00_DOCUMENT_TYPE_ARGUMENT(P99_FCALLOC, 0)
00490 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FCALLOC, 1)
00491 #define P99_FCALLOC(T, F, N) calloc(P99_FSIZEOF(T, F, N),1)
00492 #define P00_FCALLOC(T, F, M) calloc(P00_FSIZEOF(T, F, M),1)
00493
00502 #endif