P99
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
p99_new.h
Go to the documentation of this file.
00001 /* This may look like nonsense, but it really is -*- mode: C -*-              */
00002 /*                                                                            */
00003 /* Except for parts copied from previous work and as explicitly stated below, */
00004 /* the authors and copyright holders for this work are as follows:            */
00005 /* (C) copyright  2010-2013 Jens Gustedt, INRIA, France                       */
00006 /* (C) copyright  2012 William Morris                                         */
00007 /*                                                                            */
00008 /* This file is free software; it is part of the P99 project.                 */
00009 /* You can redistribute it and/or modify it under the terms of the QPL as     */
00010 /* given in the file LICENSE. It is distributed without any warranty;         */
00011 /* without even the implied warranty of merchantability or fitness for a      */
00012 /* particular purpose.                                                        */
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        /* check for validity                                   \
00084           / !!(L && (sizeof(T[N+L]) < sizeof(*X)))*/])         \
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      /* !P99_NEW_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines