P99
p99_map.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-2014 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_MAP_H_
23 # define P99_MAP_H_
24 
31 #include "p99_for.h"
32 
43 #define P00_ACCESSOR(NAME, X, I) P99_IF_EMPTY(NAME)([I])((NAME)[I])
44 #define P00_VASSIGN(NAME, X, I) X = P00_ACCESSOR(NAME, X, I)
45 #define P00_STRLEN(NAME, X, I) strlen(X)
46 #define P00_SIZEOF(NAME, X, I) sizeof(X)
47 #define P00_TYPD(NAME, X, I) typedef X P99_PASTE2(NAME, I)
48 #define P00_DESIGNATE(NAME, X, I) X = (NAME)X
49 #define P00_ADD(NAME, I, REC, RES) P99_ADD(RES, REC)
50 
51 #define P00_STRLENS(N, ...) P99_FOR(,N, P00_SUM, P00_STRLEN, __VA_ARGS__)
52 #define P00_SIZEOFS(N, ...) P99_FOR(,N, P00_SUM, P00_SIZEOF, __VA_ARGS__)
53 #define P00_ADDS(N, ...) P99_FOR(, N, P00_ADD, P00_IDT, __VA_ARGS__)
54 
55 #define P00_POW0(X, _1, _2) (X)
56 #define P00_POW(X, _1, REC, _3) (X) * REC
57 
65 P00_DOCUMENT_NUMBER_ARGUMENT(P99_IPOW, 0)
66 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IPOW, 1)
67 #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,))))
68 
73 #define P99_STRLENS(...) P00_STRLENS(P99_NARG(__VA_ARGS__),__VA_ARGS__)
74 
79 #define P99_SIZEOFS(...) P00_SIZEOFS(P99_NARG(__VA_ARGS__),__VA_ARGS__)
80 
84 #define P99_ADDS(...) P00_ADDS(P99_NARG(__VA_ARGS__),__VA_ARGS__)
85 
86 #ifndef P00_DOXYGEN
87 P99_DECLARE_STRUCT(p00_strcat_state);
88 #endif
89 
90 struct p00_strcat_state {
91  char*restrict p00_buf;
92  char*restrict p00_pos;
93 };
94 
95 #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
97 char *p00_stpcpy(char *restrict p00_des, const char *restrict p00_src) {
98  return stpcpy(p00_des, p00_src);
99 }
100 #else
102 char *p00_stpcpy(char *restrict p00_des, const char *restrict p00_src) {
103  for (;;) {
104  *p00_des = *p00_src;
105  if (!*p00_src) break;
106  ++p00_des; ++p00_src;
107  }
108  return p00_des;
109 }
110 #endif
111 
112 
114 p00_strcat_state* p00_strcat(p00_strcat_state *restrict p00_des, char const*restrict p00_src) {
115  if (!p00_des->p00_pos) p00_des->p00_pos = strchr(p00_des->p00_buf, 0);
116  p00_des->p00_pos = p00_stpcpy(p00_des->p00_pos, p00_src);
117  return p00_des;
118 }
119 
121 char* p00_strcat_terminate(p00_strcat_state *restrict p00_des) {
122  return p00_des->p00_buf;
123 }
124 
143 #define P99_STRCATS(TARG, ...) \
144 p00_strcat_terminate \
145 (P99_BIGFUNC \
146  (p00_strcat, \
147  P99_NARG(TARG, __VA_ARGS__), \
148  (&(p00_strcat_state){ .p00_buf = (TARG), .p00_pos = 0 }), \
149  __VA_ARGS__))
150 
163 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_JOIN, 0)
164 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_JOIN, 1)
165 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_JOIN, 2)
166 #define P99_JOIN(...) P99_STRCATS((char[P99_SIZEOFS(__VA_ARGS__) + 1]){ 0 }, __VA_ARGS__)
167 
177 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 0)
178 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 1)
179 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 2)
180 #define P99_STRDUP(...) P99_STRCATS(calloc(P99_STRLENS(__VA_ARGS__) + 16, 1), __VA_ARGS__)
181 
186 P00_DOCUMENT_NUMBER_ARGUMENT(P99_POSS, 0)
187 #define P99_POSS(N) P99_FOR(,N, P00_SEQ, P00_POS,)
188 
189 
190 #define P00_ACCESSORS(X, ...) P99_FOR(X, __VA_ARGS__, P00_SEQ, P00_ACCESSOR, )
191 
197 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ACCESSORS, 0)
198 P00_DOCUMENT_NUMBER_ARGUMENT(P99_ACCESSORS, 1)
199 #define P99_ACCESSORS(X, N) P00_ACCESSORS(X, N)
200 
201 
209 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_VASSIGNS, 0)
210 #define P99_VASSIGNS(NAME, ...) \
211 P99_IF_LT(P99_NARG(__VA_ARGS__),2) \
212 (P99_IF_VOID(__VA_ARGS__)((void)0)(__VA_ARGS__ = (NAME)[0])) \
213  (P99_FOR(NAME, P00_NARG(__VA_ARGS__),P00_SEP, P00_VASSIGN, __VA_ARGS__))
214 
215 #define P00_TYPEDEFS(NAME, N, ...) \
216  P99_IF_VOID(__VA_ARGS__) \
217  (P99_MACRO_END(NAME, _eat_the_semicolon_, N)) \
218  (P99_FOR(NAME, N, P00_SEP, P00_TYPD, __VA_ARGS__))
219 
227 #define P99_TYPEDEFS(NAME, ...) \
228 P00_TYPEDEFS(NAME, P99_NARG(__VA_ARGS__), __VA_ARGS__)
229 
230 #define P00_DESIGNATED(VAR, N, ...) P99_FOR(VAR, N, P00_SEQ, P00_DESIGNATE, __VA_ARGS__)
231 
249 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_DESIGNATED, 0)
250 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_DESIGNATED, 1)
251 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_DESIGNATED, 2)
252 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_DESIGNATED, 3)
253 #define P99_DESIGNATED(VAR, ...) { P00_DESIGNATED(VAR, P99_NARG(__VA_ARGS__), __VA_ARGS__) }
254 
267 #define P99_ADESIGNATED(VAR, N) P99_DESIGNATED(VAR, P99_ACCESSORS(, N))
268 
294 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_LCOPY, 1)
295 P00_DOCUMENT_TYPE_ARGUMENT(P99_LCOPY, 0)
296 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_LCOPY, 2)
297 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_LCOPY, 3)
298 P00_DOCUMENT_DESIGNATOR_ARGUMENT(P99_LCOPY, 4)
299 #define P99_LCOPY(TYPE, VAR, ...) ((TYPE)P99_DESIGNATED(VAR, __VA_ARGS__))
300 
301 
302 #define P00_ACOPY4(TYPE, N, VAR, ...) ((TYPE[N])P99_DESIGNATED(VAR, P00_ACCESSORS(, __VA_ARGS__)))
303 
304 #define P00_ACOPY3(TYPE, N, VAR) P00_ACOPY4(TYPE, N, VAR, N)
305 
306 #ifdef P00_DOXYGEN
307 
321 #define P99_ACOPY(TYPE, N, VAR, M)
322 #else
323 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ACOPY, 2)
324 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_ACOPY, 4)
325 #define P99_ACOPY(TYPE, N, ...) \
326 P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
327 (P00_ACOPY3(TYPE, N, __VA_ARGS__)) \
328 (P00_ACOPY4(TYPE, N, __VA_ARGS__))
329 #endif
330 
331 #ifdef P00_DOXYGEN
332 
355 #define P99_AASSIGN(TARGET, SOURCE, N)
356 #else
357 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_AASSIGN, 0)
358 P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_AASSIGN, 1)
359 #define P99_AASSIGN(TARGET, SOURCE, N) P99_BLOCK(P99_VASSIGNS(SOURCE, P99_ACCESSORS(TARGET, N));)
360 #endif
361 
365 #endif /* !P99_MAP_H_ */
P99_JOIN
#define P99_JOIN(...)
Concatenate all arguments.
Definition: p99_map.h:166
p99_for.h
A preprocessor for loop implementation and some derived list handling macros.
P99_STRDUP
#define P99_STRDUP(...)
Concatenate all arguments.
Definition: p99_map.h:180
P99_DESIGNATED
#define P99_DESIGNATED(VAR,...)
Construct a designated initializer by copying fields of VAR.
Definition: p99_map.h:253
p99_inline
#define p99_inline
Try to force a function always to be inlined.
Definition: p99_compiler.h:496
P99_ACCESSORS
#define P99_ACCESSORS(X, N)
Definition: p99_map.h:199
P99_AASSIGN
#define P99_AASSIGN(TARGET, SOURCE, N)
Assign the content of array SOURCE to TARGET.
Definition: p99_map.h:355
P99_DECLARE_STRUCT
#define P99_DECLARE_STRUCT(NAME)
forward declaration of a struct NAME
Definition: p99_type.h:59
P99_VASSIGNS
#define P99_VASSIGNS(NAME,...)
Vector-assign to a list.
Definition: p99_map.h:210
P99_IPOW
#define P99_IPOW(N, X)
Compute the Nth multiplicative integer power of X.
Definition: p99_map.h:67
P99_POSS
#define P99_POSS(N)
Produce a list of length N that has the contents of 0, 1, , N-1.
Definition: p99_map.h:187
P99_LCOPY
#define P99_LCOPY(TYPE, VAR,...)
Construct a compound literal of type TYPE by copying fields of VAR.
Definition: p99_map.h:299
P99_ACOPY
#define P99_ACOPY(TYPE, N, VAR, M)
Expand to an array literal of type TYPE[N] copying from another array.
Definition: p99_map.h:321