22 #ifndef P99_GENERIC_H_
23 # define P99_GENERIC_H_
36 #define P00_GENERIC_TYPE(T, ...) T
37 #define P00_GENERIC_SIZE_(UI, ...) char(*)[UI]
38 #define P00_GENERIC_EXP_(T, ...) (__VA_ARGS__)
39 #define P00_GENERIC_LIT_(T, EXP) (EXP){ 0 }
41 #define P00_GENERIC_SIZE_LIT(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_SIZE_, P00_GENERIC_LIT_, EXP, PAIR, I)
42 #define P00_GENERIC_SIZE(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_SIZE_, P00_GENERIC_EXP_, EXP, PAIR, I)
43 #define P00_GENERIC_EXP(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_TYPE, P00_GENERIC_EXP_, EXP, PAIR, I)
44 #define P00_GENERIC_LIT(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_TYPE, P00_GENERIC_LIT_, EXP, PAIR, I)
46 #if p99_has_extension(c_generic_selections)
48 #define P00_GENERIC_EXPRESSION(TOP, EOP, EXP, PAIR, I) \
51 #define P00_GENERIC_(N, MOP, EXP, DEF, ...) \
55 P99_IF_EMPTY(DEF)()(default: (DEF),) \
56 P99_FOR((EXP), N, P00_SEQ, MOP, __VA_ARGS__) \
59 #elif defined(__GNUC__)
61 #define P00_GENERIC_CLOSE(A,B,C) )
63 #define P00_GENERIC_EXPRESSION(TOP, EOP, EXP, PAIR, I) \
64 __builtin_choose_expr \
65 (__builtin_types_compatible_p(__typeof__ EXP, TOP PAIR), \
85 #if p99_has_attribute(error)
86 __attribute__((__error__(
"Invalid choice in type generic expression")))
88 extern size_t p00_invalid_type_in_generic(
char const*);
90 #define P00_INVALID_TYPE_IN_GENERIC(EXP, STR) \
91 p00_invalid_type_in_generic(__FILE__ \
92 P99_STRINGIFY(:__LINE__) \
93 ": invalid type generic choice `" \
98 #define P00_GENERIC_(N, MOP, EXP, DEF, ...) \
99 P99_FOR((EXP), N, P00_SEQ, MOP, __VA_ARGS__), \
100 P99_IF_EMPTY(DEF)(P00_INVALID_TYPE_IN_GENERIC(EXP, #__VA_ARGS__))(DEF) \
101 P99_FOR(, N, P00_SER, P00_GENERIC_CLOSE, P99_DUPL(N, ))
105 #define P00_GENERIC0(MOP, EXP, DEF, ...) \
108 P99_NARG(__VA_ARGS__), \
114 #define P00_GENERIC(N, ...) P99_IF_LT(N, 3)()(P00_GENERIC0(__VA_ARGS__))
118 #define P99_GENERIC(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_EXP, __VA_ARGS__)
122 #define P99_GENERIC_LIT(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_LIT, __VA_ARGS__)
124 #define P00_GENERIC_SIZE0(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_SIZE, __VA_ARGS__)
129 #define P99_GENERIC_SIZE(UI, ...) P00_GENERIC_SIZE0((char(*)[(size_t)(UI)]){ 0 }, __VA_ARGS__)
131 #define P00_GENERIC_SIZE_LIT0(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_SIZE_LIT, __VA_ARGS__)
136 #define P99_GENERIC_SIZE_LIT(UI, ...) P00_GENERIC_SIZE_LIT0((char(*)[(size_t)(UI)]){ 0 }, __VA_ARGS__)
139 #if p99_has_extension(c_generic_selections)
141 # define P99_TYPED_TERN(COND, YES, NO) \
143 ((char(*)[1 + !!(COND)]){ 0 }, \
145 (char(*)[2], (YES))))
147 #elif defined(__GNUC__)
149 # define P99_TYPED_TERN __builtin_choose_expr
153 #define P99_TYPED_TERN(COND, YES, NO) only_implemented_with_C11_or_gcc
161 #ifndef __STDC_NO_COMPLEX__
168 (float _Complex, p99_crealf), \
169 (double _Complex, p99_creal)) \
178 (float _Complex, p99_cimagf), \
179 (double _Complex, p99_cimag)) \
183 #define P00_CHAR_SIGNED (CHAR_MAX < UCHAR_MAX)
185 #define P00_RVALUE(X) (1 ? (X) : (X))
187 #define P00_SVALUE(X) ((X)+0)
189 #define P00_SVALUE_SIG(T, X) \
190 (T, (T)(intmax_t)(X)), \
191 (T const, (T)(intmax_t)(X)), \
192 (T volatile, (T)(intmax_t)(X)), \
193 (T const volatile, (T)(intmax_t)(X)), \
194 (_Atomic(T), (T)(intmax_t)(X)), \
195 (_Atomic(T) const, (T)(intmax_t)(X)), \
196 (_Atomic(T) volatile, (T)(intmax_t)(X)), \
197 (_Atomic(T) const volatile, (T)(intmax_t)(X))
199 #define P00_SVALUE_UNS(T, X) \
200 (T, (T)(uintmax_t)(X)), \
201 (T const, (T)(uintmax_t)(X)), \
202 (T volatile, (T)(uintmax_t)(X)), \
203 (T const volatile, (T)(uintmax_t)(X)), \
204 (_Atomic(T), (T)(uintmax_t)(X)), \
205 (_Atomic(T) const, (T)(uintmax_t)(X)), \
206 (_Atomic(T) volatile, (T)(uintmax_t)(X)), \
207 (_Atomic(T) const volatile, (T)(uintmax_t)(X))
209 #define P00_SVALUE_QUAL(X, Q) \
210 (char Q, ((char)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar)(intmax_t)(X), (uchar)(uintmax_t)(X)))), \
211 (_Atomic(char) Q, ((char)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar)(intmax_t)(X), (uchar)(uintmax_t)(X))))
213 #define P00_SVALUE_CHAR(X) \
214 P00_SVALUE_QUAL(X, ), \
215 P00_SVALUE_QUAL(X, const), \
216 P00_SVALUE_QUAL(X, volatile), \
217 P00_SVALUE_QUAL(X, const volatile)
219 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SVALUE, 0)
220 #define P99_SVALUE(X) \
256 P00_SVALUE_CHAR(X), \
257 P00_SVALUE_SIG(schar, X), \
258 P00_SVALUE_SIG(sshort, X), \
259 P00_SVALUE_UNS(_Bool, X), \
260 P00_SVALUE_UNS(uchar, X), \
261 P00_SVALUE_UNS(ushort, X))
263 #define P00_QVALUE_SIG(T, X) \
264 (T, (T)(intmax_t)(X)), \
265 (T const, (T const)(intmax_t const)(X)), \
266 (T volatile, (T volatile)(intmax_t volatile)(X)), \
267 (T const volatile, (T const volatile)(intmax_t const volatile)(X)), \
268 (_Atomic(T), (T)(intmax_t)(X)), \
269 (_Atomic(T) const, (T const)(intmax_t const)(X)), \
270 (_Atomic(T) volatile, (T volatile)(intmax_t volatile)(X)), \
271 (_Atomic(T) const volatile, (T const volatile)(intmax_t const volatile)(X))
273 #define P00_QVALUE_UNS(T, X) \
274 (T, (T)(uintmax_t)(X)), \
275 (T const, (T const)(uintmax_t const)(X)), \
276 (T volatile, (T volatile)(uintmax_t volatile)(X)), \
277 (T const volatile, (T const volatile)(uintmax_t const volatile)(X)), \
278 (_Atomic(T), (T)(uintmax_t)(X)), \
279 (_Atomic(T) const, (T const)(uintmax_t const)(X)), \
280 (_Atomic(T) volatile, (T volatile)(uintmax_t volatile)(X)), \
281 (_Atomic(T) const volatile, (T const volatile)(uintmax_t const volatile)(X))
283 #define P00_QVALUE_QUAL(X, Q) \
284 (char Q, ((char Q)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar Q)(intmax_t Q)(X), (uchar Q)(uintmax_t Q)(X)))), \
285 (_Atomic(char) Q, ((char Q)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar Q)(intmax_t Q)(X), (uchar Q)(uintmax_t Q)(X))))
287 #define P00_QVALUE_CHAR(X) \
288 P00_QVALUE_QUAL(X, ), \
289 P00_QVALUE_QUAL(X, const), \
290 P00_QVALUE_QUAL(X, volatile), \
291 P00_QVALUE_QUAL(X, const volatile)
295 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_QVALUE, 0)
296 #define P99_QVALUE(X) \
299 P00_QVALUE_CHAR(X), \
300 P00_QVALUE_SIG(schar, X), \
301 P00_QVALUE_SIG(sshort, X), \
302 P00_QVALUE_UNS(_Bool, X), \
303 P00_QVALUE_UNS(uchar, X), \
304 P00_QVALUE_UNS(ushort, X))
307 #define P00_TYPE_CHOICE(YES, T, I) (T, YES)
312 #define P99_TYPE_CHOICE(EXP, YES, NO, ...) \
316 P99_FOR(YES, P99_NARG(__VA_ARGS__), P00_SEQ, P00_TYPE_CHOICE, __VA_ARGS__))
319 #define P99_TYPE_UNSIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_UNSIGNED_TYPES)
321 #define P99_TYPE_SIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_SIGNED_TYPES)
323 #define P99_TYPE_REAL_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_FLOATING_TYPES)
324 #ifndef __STDC_NO_COMPLEX__
326 # define P99_TYPE_COMPLEX(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_COMPLEX_TYPES)
329 #define P99_TYPE_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_FLOATING_TYPES)
331 #define P99_TYPE_BASIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_BASIC_TYPES)
333 #define P99_TYPE_CHARACTER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_CHARACTER_TYPES)
335 #define P99_TYPE_INTEGER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_INTEGER_TYPES)
337 #define P99_TYPE_REAL(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_TYPES)
339 #define P99_TYPE_ARITHMETIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_ARITHMETIC_TYPES)
341 #define P00_SIZE_CHOICE(YES, UI, I) (char(*)[(size_t)(UI)], YES)
346 #define P99_SIZE_CHOICE(UI, YES, NO, ...) \
348 ((char(*)[(size_t)(UI)])0, \
350 P99_FOR(YES, P99_NARG(__VA_ARGS__), P00_SEQ, P00_SIZE_CHOICE, __VA_ARGS__))
354 #define P99_SIZE_INDICATOR(UI, ...) P99_SIZE_CHOICE(UI, 1, 0, __VA_ARGS__)
357 #define P00_DECLARE_INLINE_EXPRESSION1(EXT, BASE, EXP, A) \
360 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
361 (P99_BUILTIN_TYPE(EXT) A) \
366 #define P00_DECLARE_INLINE_EXPRESSION2(EXT, BASE, EXP, A, B) \
369 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
370 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B) \
375 #define P00_DECLARE_INLINE_EXPRESSION3(EXT, BASE, EXP, A, B, C) \
377 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
378 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
379 P99_BUILTIN_TYPE(EXT) C) \
384 #define P00_DECLARE_INLINE_EXPRESSION4(EXT, BASE, EXP, A, B, C, D) \
386 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
387 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
388 P99_BUILTIN_TYPE(EXT) C, P99_BUILTIN_TYPE(EXT) D) \
393 #define P00_DECLARE_INLINE_EXPRESSION5(EXT, BASE, EXP, A, B, C, D, E) \
395 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
396 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
397 P99_BUILTIN_TYPE(EXT) C, P99_BUILTIN_TYPE(EXT) D, \
398 P99_BUILTIN_TYPE(EXT) E) \
403 #define P00_DECLARE_INLINE_EXPRESSION6(EXT, BASE, EXP, A, B, C, D, E, F) \
405 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
406 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
407 P99_BUILTIN_TYPE(EXT) C, P99_BUILTIN_TYPE(EXT) D, \
408 P99_BUILTIN_TYPE(EXT) E, P99_BUILTIN_TYPE(EXT) F) \
416 #define P99_DECLARE_INLINE_EXPRESSION(...) \
417 P99_PASTE2(P00_DECLARE_INLINE_EXPRESSION, P99_MINUS(P99_NARG(__VA_ARGS__), 3))(__VA_ARGS__)
419 #define P00_DECLARE_INLINE_EXPRESSION_(...) P99_DECLARE_INLINE_EXPRESSION(__VA_ARGS__)
420 #define P00_DECLARE_INLINE_EXPRESSION(ARGS, EXT, I) P00_DECLARE_INLINE_EXPRESSION_(EXT, P00_ROBUST ARGS)
423 #define P99_DECLARE_INLINE_EXPRESSIONS(NEPL, ...) \
424 P99_FOR(NEPL, P99_NARG(__VA_ARGS__), P00_SER, P00_DECLARE_INLINE_EXPRESSION, __VA_ARGS__) \
425 P99_MACRO_END(P99_DECLARE_INLINE_EXPRESSIONS, __VA_ARGS__)
427 extern void p00_invalid_function(
void*, ...);
429 #define P00_GEN_EXPR(BASE, EXT, I) (P99_BUILTIN_TYPE(EXT), P99_PASTE3(p00_gen_, BASE, EXT))
433 #define P99_GEN_EXPR(BASE, EXPR, ...) \
435 p00_invalid_function, \
436 P99_FOR(BASE, P99_NARG(__VA_ARGS__), P00_SEQ, P00_GEN_EXPR, __VA_ARGS__))
442 (p00_a >= p00_b) ? p00_a : p00_b,
449 #define P99_GEN_MAX(A, B) \
450 P99_GEN_EXPR(maximum, ((A) >= (B)) ? (A) : (B), \
456 (p00_a <= p00_b) ? p00_a : p00_b,
463 #define P99_GEN_MIN(A, B) \
464 P99_GEN_EXPR(minimum, ((A) <= (B)) ? (A) : (B), \
471 (p00_a >= 0) ? p00_a : -p00_a,
484 #define P99_GEN_ABS(A) P99_GEN_EXPR(abs, ((A) >= 0) ? (A) : -(A), P99_STD_REAL_EXTS)(A)
486 #define p00_gen_sind sin
487 #define p00_gen_sinf sinf
488 #define p00_gen_sinld sinl
489 #define p00_gen_sindc csin
490 #define p00_gen_sinfc csinf
491 #define p00_gen_sinldc csinl
494 #define P99_GEN_SIN(A) P99_GEN_EXPR(sin, (A), P99_STD_FLOATING_EXTS)(A)
496 inline int* p00_generic_test(
int * p00_a) {
707 #define P99_GENERIC(...)
728 #define P99_GENERIC_LIT(...)
761 #define P99_GENERIC_SIZE(UI, ...)
771 #define P99_GENERIC_SIZE_LIT(UI, ...)
782 #define P99_TYPED_TERN(COND, YES, NO)
790 #define P00_TYPE_CHOICE(YES, T, I) (T, YES)
799 #define P99_TYPE_CHOICE(EXP, YES, NO, ...)
807 #define P99_TYPE_UNSIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_UNSIGNED_TYPES)
808 #define P99_TYPE_SIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_SIGNED_TYPES)
809 #define P99_TYPE_REAL_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_FLOATING_TYPES)
810 #define P99_TYPE_COMPLEX(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_COMPLEX_TYPES)
811 #define P99_TYPE_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_FLOATING_TYPES)
812 #define P99_TYPE_BASIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_BASIC_TYPES)
813 #define P99_TYPE_CHARACTER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_CHARACTER_TYPES)
814 #define P99_TYPE_INTEGER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_INTEGER_TYPES)
815 #define P99_TYPE_REAL(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_TYPES)
816 #define P99_TYPE_ARITHMETIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_ARITHMETIC_TYPES)
835 #define P99_SIZE_CHOICE(UI, YES, NO, ...)
856 #define P99_SIZE_INDICATOR(UI, ...)
890 #define P99_DECLARE_INLINE_EXPRESSION(EXT, BASE, EXP, ...)
926 #define P99_DECLARE_INLINE_EXPRESSIONS(NEPL, ...)
928 extern void p00_invalid_function(
void*, ...);
1000 #define P99_GEN_EXPR(BASE, EXPR, ...)
1002 #define P99_GEN_MAX(A, B) \
1003 P99_GEN_EXPR(maximum, ((A) >= (B)) ? (A) : (B), \
1008 #define P99_GEN_MIN(A, B) \
1009 P99_GEN_EXPR(minimum, ((A) <= (B)) ? (A) : (B), \
1015 #define P99_GEN_ABS(A) P99_GEN_EXPR(abs, ((A) >= 0) ? (A) : -(A), P99_STD_REAL_EXTS)(A)
1023 #define P99_GEN_SIN(A) P99_GEN_EXPR(sin, (A), P99_STD_FLOATING_EXTS)(A)
1039 #define P00_OVALUES_(X, T, I) (T*, X[0])
1040 #define P00_OVALUES(X, ...) P99_FOR(X, P99_NARG(__VA_ARGS__), P00_SEQ, P00_OVALUES_, __VA_ARGS__)
1041 #define P00_OVALUE_(X, DEF, ...) P99_GENERIC(X, DEF, __VA_ARGS__)
1043 #define P00_OVALUES1_(X, T, I) (T*, X)
1044 #define P00_OVALUES1(X, ...) P99_FOR(X, P99_NARG(__VA_ARGS__), P00_SEQ, P00_OVALUES1_, __VA_ARGS__)
1045 #define P00_OVALUE1_(X, ...) P99_GENERIC(&(X[0]), , P00_OVALUES1(X, __VA_ARGS__))
1047 #define P00_AVALUES_(X, T, I) (T*, *(T(*)[1])X)
1048 #define P00_AVALUES(X, ...) P99_FOR(X, P99_NARG(__VA_ARGS__), P00_SEQ, P00_AVALUES_, __VA_ARGS__)
1049 #define P00_AVALUE_(X, DEF, ...) P99_GENERIC(X, DEF, __VA_ARGS__)
1069 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_OVALUE, 0)
1073 #define P99_OVALUE(X, ...)
1090 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_AVALUE, 0)
1094 #define P99_AVALUE(X, ...)
1116 #define P99_OBJSIZE(X, ...)
1134 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_OBJLEN, 0)
1138 #define P99_OBJLEN(X, ...)
1140 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_OVALUE, 0)
1144 #define P99_OVALUE(X, ...) P00_OVALUE_((X), P00_OVALUE1_((X), __VA_ARGS__), P00_OVALUES((X), __VA_ARGS__))
1146 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_AVALUE, 0)
1150 #define P99_AVALUE(X, ...) P00_AVALUE_((X), P00_OVALUE1_((X), __VA_ARGS__), P00_AVALUES((X), __VA_ARGS__))
1156 #define P99_OBJSIZE(X, ...) (sizeof P99_OVALUE(X, __VA_ARGS__))
1158 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_OBJLEN, 0)
1162 #define P99_OBJLEN(X, ...) (P99_OBJSIZE(X, __VA_ARGS__)/(sizeof (X)[0]))
1178 #define P00_SPRINT_DEFINE(T, ...) \
1180 char const* P99_PASTE2(p00_sprint_, T)(T p00_val, char*restrict p00_str, unsigned p00_form) { \
1181 enum { p00_len = P99_NARG(__VA_ARGS__), }; \
1182 static char const*const p00_format[p00_len] = { __VA_ARGS__ }; \
1183 char const*const p00_f = (p00_form < p00_len) \
1184 ? p00_format[p00_form] \
1186 sprintf(p00_str, p00_f, p00_val); \
1189 P99_MACRO_END(P00_SPRINT_DEFINE, T)
1191 P00_SPRINT_DEFINE(
char,
"%c");
1192 P00_SPRINT_DEFINE(
schar,
"%hhd");
1193 P00_SPRINT_DEFINE(
uchar,
"%hhu",
"%#hhX",
"%#hho");
1194 P00_SPRINT_DEFINE(
short,
"%hd");
1195 P00_SPRINT_DEFINE(
ushort,
"%hu",
"%#hX",
"%#ho");
1196 P00_SPRINT_DEFINE(
int,
"%d");
1197 P00_SPRINT_DEFINE(
unsigned,
"%u",
"%#X",
"%#o");
1198 P00_SPRINT_DEFINE(
long,
"%ld");
1199 P00_SPRINT_DEFINE(
ulong,
"%lu",
"%#lX",
"%#lo");
1200 P00_SPRINT_DEFINE(
llong,
"%lld");
1201 P00_SPRINT_DEFINE(
ullong,
"%llu",
"%#llX",
"%#llo");
1202 P00_SPRINT_DEFINE(
float,
"%g",
"%a");
1203 P00_SPRINT_DEFINE(
double,
"%g",
"%a");
1204 P00_SPRINT_DEFINE(
ldouble,
"%Lg",
"%La");
1208 char const* p00_sprint__Bool(_Bool p00_val,
char*restrict p00_str,
unsigned p00_form) {
1211 char const*
const p00_format[] = {
1216 register unsigned const p00_len =
P99_ALEN(p00_format) / 2;
1217 if (p00_form >= p00_len) p00_form = 0;
1218 return p00_format[p00_form * 2 + p00_val];
1223 char const volatile* p00_sprint_charp(
char const volatile* p00_val,
char*restrict p00_str,
unsigned p00_form) {
1230 char const* p00_sprint_voidp(
void const volatile* p00_val,
char*restrict p00_str,
unsigned p00_form) {
1232 sprintf(p00_str,
"%p", p00_val);
1236 #ifndef __STDC_NO_COMPLEX__
1238 char const* p00_sprint_cfloat(
cfloat p00_val,
char*restrict p00_str,
unsigned p00_form) {
1239 char const*
const p00_format[] = {
"(%g, %g)",
"(%a, %a)", };
1240 register unsigned const p00_len =
P99_ALEN(p00_format);
1241 char const*
const p00_f = (p00_form < p00_len)
1242 ? p00_format[p00_form]
1244 sprintf(p00_str, p00_f, creal(p00_val), cimag(p00_val));
1249 char const* p00_sprint_cdouble(
cdouble p00_val,
char*restrict p00_str,
unsigned p00_form) {
1250 char const*
const p00_format[] = {
"(%g, %g)",
"(%a, %a)", };
1251 register unsigned const p00_len =
P99_ALEN(p00_format);
1252 char const*
const p00_f = (p00_form < p00_len)
1253 ? p00_format[p00_form]
1255 sprintf(p00_str, p00_f, creal(p00_val), cimag(p00_val));
1260 char const* p00_sprint_cldouble(
cldouble p00_val,
char*restrict p00_str,
unsigned p00_form) {
1261 char const*
const p00_format[] = {
"(%Lg, %Lg)",
"(%La, %La)", };
1262 register unsigned const p00_len =
P99_ALEN(p00_format);
1263 char const*
const p00_f = (p00_form < p00_len)
1264 ? p00_format[p00_form]
1266 sprintf(p00_str, p00_f, creal(p00_val), cimag(p00_val));
1273 #define UINT64_D19 UINT64_C(10000000000000000000)
1275 void p00_sprint_p99x_uintmax_u_ite(
p99x_uintmax p00_val,
char*restrict p00_str) {
1276 uint64_t p00_ar[2*
sizeof(
p99x_uintmax)/
sizeof(uint64_t)];
1278 for (; p00_val >= UINT64_D19; ++p00_pos) {
1281 p00_ar[p00_pos] = (uint64_t)(p00_val % UINT64_D19);
1282 p00_val /= UINT64_D19;
1284 p00_str += sprintf(p00_str,
"%" PRIu64, (uint64_t)p00_val);
1287 p00_str += sprintf(p00_str,
"%019" PRIu64, p00_ar[p00_pos]);
1291 char* p00_sprint_p99x_uintmax_u(
p99x_uintmax p00_val,
char*restrict p00_str) {
1292 p00_sprint_p99x_uintmax_u_ite(p00_val, p00_str);
1295 #define UINT64_O21 (~(UINT64_C(1)<<63))
1297 void p00_sprint_p99x_uintmax_o_ite(
p99x_uintmax p00_val,
char*restrict p00_str) {
1298 uint64_t p00_ar[3*
sizeof(
p99x_uintmax)/
sizeof(uint64_t)];
1302 p00_ar[p00_pos] = ((uint64_t)p00_val) & UINT64_O21;
1304 if (!p00_val)
break;
1307 p00_str += sprintf(p00_str,
"%#" PRIo64, p00_ar[p00_pos]);
1310 p00_str += sprintf(p00_str,
"%021" PRIo64, p00_ar[p00_pos]);
1314 char* p00_sprint_p99x_uintmax_o(
p99x_uintmax p00_val,
char*restrict p00_str) {
1315 p00_sprint_p99x_uintmax_o_ite(p00_val, p00_str);
1319 void p00_sprint_p99x_uintmax_X_ite(
p99x_uintmax p00_val,
char*restrict p00_str) {
1320 uint64_t p00_ar[2*
sizeof(
p99x_uintmax)/
sizeof(uint64_t)];
1324 p00_ar[p00_pos] = (uint64_t)p00_val;
1326 if (!p00_val)
break;
1329 p00_str += sprintf(p00_str,
"%#" PRIX64, p00_ar[p00_pos]);
1332 p00_str += sprintf(p00_str,
"%016" PRIX64, p00_ar[p00_pos]);
1336 char const* p00_sprint_p99x_uintmax_X(
p99x_uintmax p00_val,
char*restrict p00_str) {
1337 p00_sprint_p99x_uintmax_X_ite(p00_val, p00_str);
1342 char const* p00_sprint_p99x_intmax(
p99x_intmax p00_val,
char*restrict p00_str,
unsigned p00_form) {
1346 p00_sprint_p99x_uintmax_u(-p00_val, p00_str + 1);
1348 p00_sprint_p99x_uintmax_u(p00_val, p00_str);
1354 char const* p00_sprint_p99x_uintmax(
p99x_uintmax p00_val,
char*restrict p00_str,
unsigned p00_form) {
1356 default:
return p00_sprint_p99x_uintmax_u(p00_val, p00_str);
1357 case 1:
return p00_sprint_p99x_uintmax_X(p00_val, p00_str);
1358 case 2:
return p00_sprint_p99x_uintmax_o(p00_val, p00_str);
1363 #define P00_SPRINT(NAME, T, I) (T, P99_PASTE2(p00_sprint_, T))
1365 #define P00_SPRINT_LIST_(...) \
1366 P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEQ, P00_SPRINT, __VA_ARGS__)
1368 #define P00_SPRINT_LIST() P00_SPRINT_LIST_(P99_EXT_ARITHMETIC_TYPES)
1370 #define P00_SPRINT_FORMAT_(X, A, ...) \
1371 P99_GENERIC((X)+0, \
1373 (char*, p00_sprint_charp), \
1374 (char const*, p00_sprint_charp), \
1376 P99_GENERIC((X)+0, \
1380 (char[(sizeof(X+0)*22+64)/8]){ 0 }, \
1386 #define P00_SPRINT_FORMAT(...) P00_SPRINT_FORMAT_(__VA_ARGS__)
1415 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_FORMAT, 0)
1416 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_FORMAT, 2)
1417 #define P99_FORMAT(...) \
1419 (P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
1427 #define P99_FORMATS(...) P99_SEQ(P99_FORMAT, __VA_ARGS__)
1428 #define P00_PRINTF(...) printf(__VA_ARGS__)
1430 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_PRINTF, 1)
1431 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_PRINTF, 2)
1432 P00_DOCUMENT_PERMITTED_ARGUMENT(
P99_PRINTF, 3)
1433 #define P99_PRINTF(FORMAT, ...) printf(FORMAT, P99_FORMATS(__VA_ARGS__))
1435 #define P00_FPRINTF(...) fprintf(__VA_ARGS__)
1439 #define P99_FPRINTF(F, FORMAT, ...) fprintf(F, FORMAT, P99_FORMATS(__VA_ARGS__))
1441 #define P00_SPRINTF(...) sprintf(__VA_ARGS__)
1445 #define P99_SPRINTF(S, FORMAT, ...) sprintf(S, FORMAT, P99_FORMATS(__VA_ARGS__))
1447 #define P00_SNPRINTF(...) snprintf(__VA_ARGS__)
1451 #define P99_SNPRINTF(S, N, FORMAT, ...) snprintf(S, N, FORMAT, P99_FORMATS(__VA_ARGS__))
1457 #define P00_DEFINE_IN_RANGE(T) \
1458 P99_CONST_FUNCTION \
1460 bool P99_PASTE2(p00_in_range_, T)(T p00_r, T p00_s, T p00_len) { \
1461 return (p00_r >= p00_s) && ((p00_r - p00_s) < p00_len); \
1466 bool p00_in_range_voidp(
void* p00_r_,
void* p00_s_,
size_t p00_len) {
1467 unsigned char* p00_r = p00_r_;
1468 unsigned char* p00_s = p00_s_;
1469 return (p00_r >= p00_s) && ((size_t)(p00_r - p00_s) < p00_len);
1476 #define P00_IN_RANGE_PART(NAME, T, I) (T, P99_PASTE2(p00_in_range_, T))
1479 #define P00_IN_RANGE_LIST_(...) \
1480 P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEQ, P00_IN_RANGE_PART, __VA_ARGS__)
1482 #define P00_IN_RANGE_LIST() P00_IN_RANGE_LIST_(P99_EXT_REAL_TYPES)
1484 #define P00_IN_RANGE(R, S, L, ...) \
1485 P99_GENERIC((1 ? (R) : (S)), p00_in_range_voidp, __VA_ARGS__)((R), (S), (L))
1499 #define P99_IN_RANGE(R, S, L) P00_IN_RANGE((R), (S), (L), P00_IN_RANGE_LIST())
1507 #define P00_VOID_QUAL_(QUAL, ...) (void QUAL*, __VA_ARGS__)
1508 #define P00_VOID_QUAL(LIST) P00_VOID_QUAL_ LIST
1510 #define P00_VOIDIFY_LIST(...) P99_SEQ(P00_VOID_QUAL, __VA_ARGS__)
1554 #define P99_GENERIC_PQUALIFIED(PEXP, ...) \
1561 (1 ? (PEXP) : (void*)1),, \
1562 P00_VOIDIFY_LIST(__VA_ARGS__))
1586 #define P99_GENERIC_PCONST(PEXP, NCONST, CONST) \
1587 P99_GENERIC((1 ? (PEXP) : (void volatile*)1),, \
1588 P00_VOID_QUAL_(volatile, NCONST), \
1589 P00_VOID_QUAL_(volatile const, CONST) \
1606 #define P99_GENERIC_PVOLATILE(PEXP, NVOLATILE, VOLATILE) \
1607 P99_GENERIC((1 ? (PEXP) : (void const*)1),, \
1608 P00_VOID_QUAL_(const, NVOLATILE), \
1609 P00_VOID_QUAL_(const volatile, VOLATILE) \
1626 #define P99_GENERIC_PCONSTVOLATILE(PEXP, NON, FULL) \
1627 P99_GENERIC((1 ? (PEXP) : (void*)1), \
1629 P00_VOID_QUAL_(const volatile, VOLATILE) \
1640 #define P99_GENERIC_TQUALIFIED(T, ...) \
1641 P99_GENERIC_PQUALIFIED((&(T)P99_INIT), ...)
1650 #define P99_GENERIC_TCONST(T, NCONST, CONST) \
1651 P99_GENERIC_PCONST((&(T)P99_INIT), NCONST, CONST)
1660 #define P99_GENERIC_TVOLATILE(T, NVOLATILE, VOLATILE) \
1661 P99_GENERIC_PVOLATILE((&(T)P99_INIT), NVOLATILE, VOLATILE)
1670 #define P99_GENERIC_TCONSTVOLATILE(T, NON, FULL) \
1671 P99_GENERIC_PCONSTVOLATILE((&(T)P99_INIT), NON, FULL)
1684 #define P00_GENERIC_VOIDPTR_OR_INTEGER(PEXP, TRUE, FALSE) \
1685 P99_GENERIC((1 ? (void*)0 : (PEXP)), \
1690 #define P00_IS_VOIDPTR_OR_INTEGER(PEXP) P00_GENERIC_VOIDPTR_OR_INTEGER(PEXP, true, false)
1692 typedef struct p00_nullptr_test p00_nullptr_test;
1694 #define P00_GENERIC_NULLPTR_CONSTANT(PEXP, TRUE, FALSE) \
1695 P99_GENERIC((1 ? (p00_nullptr_test*)0 : (PEXP)), \
1697 (p00_nullptr_test*, TRUE) \
1700 #define P00_IS_NULLPTR_CONSTANT(PEXP) P00_GENERIC_NULLPTR_CONSTANT(PEXP, true, false)
1702 #define P99_GENERIC_NULLPTR_CONSTANT_(PEXP, TRUE, FALSE) \
1703 P00_GENERIC_NULLPTR_CONSTANT(PEXP, \
1707 #define P99_GENERIC_NULLPTR_CONSTANT(PEXP, TRUE, FALSE) \
1708 P99_GENERIC_NULLPTR_CONSTANT_(P00_GENERIC_VOIDPTR_OR_INTEGER(PEXP, PEXP, (void*)1), \
1740 #define P99_IS_NULLPTR_CONSTANT(PEXP) P99_GENERIC_NULLPTR_CONSTANT((PEXP), true, false)
1744 #define P99_GENERIC_INTEGRAL_CONSTANT(EXP, TRUE, FALSE) \
1745 P99_GENERIC((EXP), \
1746 P99_GENERIC_NULLPTR_CONSTANT((void*)(ptrdiff_t)((EXP)-(EXP)), TRUE, FALSE), \
1749 (void const*, FALSE), \
1750 (void volatile*, FALSE), \
1751 (void const volatile*, FALSE) \
1789 #define P99_IS_INTEGRAL_CONSTANT(EXP) P99_GENERIC_INTEGRAL_CONSTANT((EXP), true, false)
1794 #define P99_GENERIC_NULLPTR(PEXP, TRUE, FALSE) \
1795 (P99_GENERIC_NULLPTR_CONSTANT(PEXP, TRUE, FALSE) \
1796 &&!P99_GENERIC_INTEGRAL_CONSTANT(PEXP, TRUE, FALSE))
1810 #define P99_IS_NULLPTR(PEXP) P99_GENERIC_NULLPTR((PEXP), true, false)