P99
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
p99_map.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_MAP_H_
00015 # define    P99_MAP_H_
00016 
00023 #include "p99_for.h"
00024 
00035 #define P00_ACCESSOR(NAME, X, I) P99_IF_EMPTY(NAME)([I])((NAME)[I])
00036 #define P00_VASSIGN(NAME, X, I) X = P00_ACCESSOR(NAME, X, I)
00037 #define P00_STRLEN(NAME, X, I) strlen(X)
00038 #define P00_SIZEOF(NAME, X, I) sizeof(X)
00039 #define P00_TYPD(NAME, X, I) typedef X P99_PASTE2(NAME, I)
00040 #define P00_DESIGNATE(NAME, X, I) X = (NAME)X
00041 #define P00_ADD(NAME, I, REC, RES) P99_ADD(RES, REC)
00042 
00043 #define P00_STRLENS(N, ...) P99_FOR(,N, P00_SUM, P00_STRLEN, __VA_ARGS__)
00044 #define P00_SIZEOFS(N, ...) P99_FOR(,N, P00_SUM, P00_SIZEOF, __VA_ARGS__)
00045 #define P00_ADDS(N, ...) P99_FOR(, N, P00_ADD, P00_IDT, __VA_ARGS__)
00046 
00047 #define P00_POW0(X, _1, _2) (X)
00048 #define P00_POW(X, _1, REC, _3) (X) * REC
00049 
00057 P00_DOCUMENT_NUMBER_ARGUMENT(P99_IPOW, 0)
00058 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IPOW, 1)
00059 #define P99_IPOW(N, X) P99_IF_EQ(N,0)(P99_SIGN_PROMOTE(1, X))((P99_FOR(X, N, P00_POW, P00_POW0, P99_REP(N,))))
00060 
00065 #define P99_STRLENS(...) P00_STRLENS(P99_NARG(__VA_ARGS__),__VA_ARGS__)
00066 
00071 #define P99_SIZEOFS(...) P00_SIZEOFS(P99_NARG(__VA_ARGS__),__VA_ARGS__)
00072 
00076 #define P99_ADDS(...) P00_ADDS(P99_NARG(__VA_ARGS__),__VA_ARGS__)
00077 
00078 #ifndef P00_DOXYGEN
00079 P99_DECLARE_STRUCT(p00_strcat_state);
00080 #endif
00081 
00082 struct p00_strcat_state {
00083   char*restrict p00_buf;
00084   char*restrict p00_pos;
00085 };
00086 
00087 #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
00088 p99_inline
00089 char *p00_stpcpy(char *restrict p00_des, const char *restrict p00_src) {
00090   return stpcpy(p00_des, p00_src);
00091 }
00092 #else
00093 p99_inline
00094 char *p00_stpcpy(char *restrict p00_des, const char *restrict p00_src) {
00095   for (;;) {
00096     *p00_des = *p00_src;
00097     if (!*p00_src) break;
00098     ++p00_des; ++p00_src;
00099   }
00100   return p00_des;
00101 }
00102 #endif
00103 
00104 
00105 p99_inline
00106 p00_strcat_state* p00_strcat(p00_strcat_state *restrict p00_des, char const*restrict p00_src) {
00107   if (!p00_des->p00_pos) p00_des->p00_pos = strchr(p00_des->p00_buf, 0);
00108   p00_des->p00_pos = p00_stpcpy(p00_des->p00_pos, p00_src);
00109   return p00_des;
00110 }
00111 
00112 P99_PURE_FUNCTION
00113 p99_inline
00114 char* p00_strcat_terminate(p00_strcat_state *restrict p00_des) {
00115   return p00_des->p00_buf;
00116 }
00117 
00136 #define P99_STRCATS(TARG, ...)                                 \
00137 p00_strcat_terminate                                           \
00138 (P99_BIGFUNC                                                   \
00139  (p00_strcat,                                                  \
00140   P99_NARG(TARG, __VA_ARGS__),                                 \
00141   (&(p00_strcat_state){ .p00_buf = (TARG), .p00_pos = 0  }),   \
00142    __VA_ARGS__))
00143 
00156 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_JOIN, 0)
00157 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_JOIN, 1)
00158 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_JOIN, 2)
00159 #define P99_JOIN(...) P99_STRCATS((char[P99_SIZEOFS(__VA_ARGS__) + 1]){ 0 }, __VA_ARGS__)
00160 
00170 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 0)
00171 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 1)
00172 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 2)
00173 #define P99_STRDUP(...) P99_STRCATS(memset(malloc(P99_STRLENS(__VA_ARGS__) + 1), 0, 1), __VA_ARGS__)
00174 
00179 P00_DOCUMENT_NUMBER_ARGUMENT(P99_POSS, 0)
00180 #define P99_POSS(N) P99_FOR(,N, P00_SEQ, P00_POS,)
00181 
00182 
00183 #define P00_ACCESSORS(X, ...) P99_FOR(X, __VA_ARGS__, P00_SEQ, P00_ACCESSOR, )
00184 
00190 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ACCESSORS, 0)
00191 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ACCESSORS, 1)
00192 #define P99_ACCESSORS(X, N) P00_ACCESSORS(X, N)
00193 
00194 
00202 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_VASSIGNS, 0)
00203 #define P99_VASSIGNS(NAME, ...)                                            \
00204 P99_IF_LT(P99_NARG(__VA_ARGS__),2)                                         \
00205 (P99_IF_VOID(__VA_ARGS__)((void)0)(__VA_ARGS__ = (NAME)[0]))               \
00206   (P99_FOR(NAME, P00_NARG(__VA_ARGS__),P00_SEP, P00_VASSIGN, __VA_ARGS__))
00207 
00208 #define P00_TYPEDEFS(NAME, N, ...)                             \
00209   P99_IF_VOID(__VA_ARGS__)                                     \
00210   (P99_MACRO_END(NAME, _eat_the_semicolon_, N))                \
00211   (P99_FOR(NAME, N, P00_SEP, P00_TYPD, __VA_ARGS__))
00212 
00220 #define P99_TYPEDEFS(NAME, ...)                                \
00221 P00_TYPEDEFS(NAME, P99_NARG(__VA_ARGS__), __VA_ARGS__)
00222 
00223 #define P00_DESIGNATED(VAR, N, ...) P99_FOR(VAR, N, P00_SEQ, P00_DESIGNATE, __VA_ARGS__)
00224 
00242 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_DESIGNATED, 0)
00243 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_DESIGNATED, 1)
00244 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_DESIGNATED, 2)
00245 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_DESIGNATED, 3)
00246 #define P99_DESIGNATED(VAR, ...) { P00_DESIGNATED(VAR, P99_NARG(__VA_ARGS__), __VA_ARGS__) }
00247 
00260 #define P99_ADESIGNATED(VAR, N) P99_DESIGNATED(VAR, P99_ACCESSORS(, N))
00261 
00287 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_LCOPY, 1)
00288 P00_DOCUMENT_TYPE_ARGUMENT(P99_LCOPY, 0)
00289 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_LCOPY, 2)
00290 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_LCOPY, 3)
00291 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_LCOPY, 4)
00292 #define P99_LCOPY(TYPE, VAR, ...) ((TYPE)P99_DESIGNATED(VAR, __VA_ARGS__))
00293 
00294 
00295 #define P00_ACOPY4(TYPE, N, VAR, ...) ((TYPE[N])P99_DESIGNATED(VAR, P00_ACCESSORS(, __VA_ARGS__)))
00296 
00297 #define P00_ACOPY3(TYPE, N, VAR) P00_ACOPY4(TYPE, N, VAR, N)
00298 
00299 #ifdef P00_DOXYGEN
00300 
00314 #define P99_ACOPY(TYPE, N, VAR, M)
00315 #else
00316 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ACOPY, 2)
00317 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_ACOPY, 4)
00318 #define P99_ACOPY(TYPE, N, ...)                                \
00319 P99_IF_LT(P99_NARG(__VA_ARGS__), 2)                            \
00320 (P00_ACOPY3(TYPE, N, __VA_ARGS__))                             \
00321 (P00_ACOPY4(TYPE, N, __VA_ARGS__))
00322 #endif
00323 
00324 #ifdef P00_DOXYGEN
00325 
00348 #define P99_AASSIGN(TARGET, SOURCE, N)
00349 #else
00350 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_AASSIGN, 0)
00351 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_AASSIGN, 1)
00352 #define P99_AASSIGN(TARGET, SOURCE, N) P99_BLOCK(P99_VASSIGNS(SOURCE, P99_ACCESSORS(TARGET, N));)
00353 #endif
00354 
00358 #endif      /* !P99_MAP_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines