00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef P99_GENERIC_H_
00015 # define P99_GENERIC_H_
00016
00017 #include "p99_for.h"
00018 #include "p99_typenames.h"
00019 #include "p99_c99.h"
00020
00025 #ifndef P00_DOXYGEN
00026
00027 #define P00_GENERIC_TYPE(T, EXP) T
00028 #define P00_GENERIC_SIZE_(UI, EXP) char(*)[UI]
00029 #define P00_GENERIC_EXP_(T, EXP) (EXP)
00030 #define P00_GENERIC_LIT_(T, EXP) (EXP){ 0 }
00031
00032 #define P00_GENERIC_SIZE_LIT(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_SIZE_, P00_GENERIC_LIT_, EXP, PAIR, I)
00033 #define P00_GENERIC_SIZE(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_SIZE_, P00_GENERIC_EXP_, EXP, PAIR, I)
00034 #define P00_GENERIC_EXP(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_TYPE, P00_GENERIC_EXP_, EXP, PAIR, I)
00035 #define P00_GENERIC_LIT(EXP, PAIR, I) P00_GENERIC_EXPRESSION(P00_GENERIC_TYPE, P00_GENERIC_LIT_, EXP, PAIR, I)
00036
00037 #if p99_has_extension(c_generic_selections)
00038
00039 #define P00_GENERIC_EXPRESSION(TOP, EOP, EXP, PAIR, I) \
00040 TOP PAIR: EOP PAIR
00041
00042 #define P00_GENERIC_(N, MOP, EXP, DEF, ...) \
00043 p99_extension \
00044 _Generic \
00045 ((EXP), \
00046 P99_IF_EMPTY(DEF)()(default: (DEF),) \
00047 P99_FOR((EXP), N, P00_SEQ, MOP, __VA_ARGS__) \
00048 )
00049
00050 #elif defined(__GNUC__)
00051
00052 #define P00_GENERIC_CLOSE(A,B,C) )
00053
00054 #define P00_GENERIC_EXPRESSION(TOP, EOP, EXP, PAIR, I) \
00055 __builtin_choose_expr \
00056 (__builtin_types_compatible_p(__typeof__ EXP, TOP PAIR), \
00057 EOP PAIR
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #if p99_has_attribute(error)
00077 __attribute__((__error__("Invalid choice in type generic expression")))
00078 #endif
00079 extern size_t p00_invalid_type_in_generic(char const*);
00080
00081 #define P00_INVALID_TYPE_IN_GENERIC(EXP, STR) \
00082 p00_invalid_type_in_generic(__FILE__ \
00083 P99_STRINGIFY(:__LINE__) \
00084 ": invalid type generic choice `" \
00085 P99_STRINGIFY(EXP) \
00086 "` for " \
00087 STR)
00088
00089 #define P00_GENERIC_(N, MOP, EXP, DEF, ...) \
00090 P99_FOR((EXP), N, P00_SEQ, MOP, __VA_ARGS__), \
00091 P99_IF_EMPTY(DEF)(P00_INVALID_TYPE_IN_GENERIC(EXP, #__VA_ARGS__))(DEF) \
00092 P99_FOR(, N, P00_SER, P00_GENERIC_CLOSE, P99_DUPL(N, ))
00093
00094 #endif
00095
00096 #define P00_GENERIC0(MOP, EXP, DEF, ...) \
00097 P00_GENERIC_ \
00098 ( \
00099 P99_NARG(__VA_ARGS__), \
00100 P00_ROBUST(MOP), \
00101 P00_ROBUST(EXP), \
00102 P00_ROBUST(DEF), \
00103 __VA_ARGS__)
00104
00105 #define P00_GENERIC(N, ...) P99_IF_LT(N, 3)()(P00_GENERIC0(__VA_ARGS__))
00106
00107 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC, 0)
00108 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC, 2)
00109 #define P99_GENERIC(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_EXP, __VA_ARGS__)
00110
00111 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_LIT, 0)
00112 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_LIT, 2)
00113 #define P99_GENERIC_LIT(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_LIT, __VA_ARGS__)
00114
00115 #define P00_GENERIC_SIZE0(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_SIZE, __VA_ARGS__)
00116
00117 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_SIZE, 0)
00118 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_SIZE, 2)
00119 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_SIZE, 3)
00120 #define P99_GENERIC_SIZE(UI, ...) P00_GENERIC_SIZE0((char(*)[(size_t)(UI)]){ 0 }, __VA_ARGS__)
00121
00122 #define P00_GENERIC_SIZE_LIT0(...) P00_GENERIC(P99_NARG(__VA_ARGS__), P00_GENERIC_SIZE_LIT, __VA_ARGS__)
00123
00124 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_SIZE_LIT, 0)
00125 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_SIZE_LIT, 2)
00126 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GENERIC_SIZE_LIT, 3)
00127 #define P99_GENERIC_SIZE_LIT(UI, ...) P00_GENERIC_SIZE_LIT0((char(*)[(size_t)(UI)]){ 0 }, __VA_ARGS__)
00128
00129
00130 #if p99_has_extension(c_generic_selections)
00131
00132 # define P99_TYPED_TERN(COND, YES, NO) \
00133 (P99_GENERIC \
00134 ((char(*)[1 + !!(COND)]){ 0 }, \
00135 (NO), \
00136 (char(*)[2], (YES))))
00137
00138 #elif defined(__GNUC__)
00139
00140 # define P99_TYPED_TERN __builtin_choose_expr
00141
00142 #else
00143
00144 #define P99_TYPED_TERN(COND, YES, NO) only_implemented_with_C11_or_gcc
00145
00146
00147 #endif
00148
00149
00150
00151
00152 #ifndef __STDC_NO_COMPLEX__
00153 # ifdef creal
00154 # undef creal
00155 # endif
00156 # define creal(A) \
00157 P99_GENERIC((A), \
00158 p99_creall, \
00159 (float _Complex, p99_crealf), \
00160 (float _Complex const, p99_crealf), \
00161 (float _Complex volatile, p99_crealf), \
00162 (float _Complex const volatile, p99_creal), \
00163 (double _Complex, p99_creal), \
00164 (double _Complex const, p99_creal), \
00165 (double _Complex volatile, p99_creal), \
00166 (double _Complex const volatile, p99_creal)) \
00167 (A)
00168
00169 # ifdef cimag
00170 # undef cimag
00171 # endif
00172 # define cimag(A) \
00173 P99_GENERIC((A), \
00174 p99_cimagl, \
00175 (float _Complex, p99_cimagf), \
00176 (float _Complex const, p99_cimagf), \
00177 (float _Complex volatile, p99_cimagf), \
00178 (float _Complex const volatile, p99_cimag), \
00179 (double _Complex, p99_cimag), \
00180 (double _Complex const, p99_cimag), \
00181 (double _Complex volatile, p99_cimag), \
00182 (double _Complex const volatile, p99_cimag)) \
00183 (A)
00184 #endif
00185
00186 #define P00_CHAR_SIGNED (CHAR_MAX < UCHAR_MAX)
00187
00188 #define P00_RVALUE(X) (1 ? (X) : (X))
00189
00190 #define P00_SVALUE(X) ((X)+0)
00191
00192 #define P00_SVALUE_SIG(T, X) \
00193 (T, (T)(intmax_t)(X)), \
00194 (T const, (T)(intmax_t)(X)), \
00195 (T volatile, (T)(intmax_t)(X)), \
00196 (T const volatile, (T)(intmax_t)(X)), \
00197 (_Atomic(T), (T)(intmax_t)(X)), \
00198 (_Atomic(T) const, (T)(intmax_t)(X)), \
00199 (_Atomic(T) volatile, (T)(intmax_t)(X)), \
00200 (_Atomic(T) const volatile, (T)(intmax_t)(X))
00201
00202 #define P00_SVALUE_UNS(T, X) \
00203 (T, (T)(uintmax_t)(X)), \
00204 (T const, (T)(uintmax_t)(X)), \
00205 (T volatile, (T)(uintmax_t)(X)), \
00206 (T const volatile, (T)(uintmax_t)(X)), \
00207 (_Atomic(T), (T)(uintmax_t)(X)), \
00208 (_Atomic(T) const, (T)(uintmax_t)(X)), \
00209 (_Atomic(T) volatile, (T)(uintmax_t)(X)), \
00210 (_Atomic(T) const volatile, (T)(uintmax_t)(X))
00211
00212 #define P00_SVALUE_QUAL(X, Q) \
00213 (char Q, ((char)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar)(intmax_t)(X), (uchar)(uintmax_t)(X)))), \
00214 (_Atomic(char) Q, ((char)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar)(intmax_t)(X), (uchar)(uintmax_t)(X))))
00215
00216 #define P00_SVALUE_CHAR(X) \
00217 P00_SVALUE_QUAL(X, ), \
00218 P00_SVALUE_QUAL(X, const), \
00219 P00_SVALUE_QUAL(X, volatile), \
00220 P00_SVALUE_QUAL(X, const volatile)
00221
00222 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SVALUE, 0)
00223 #define P99_SVALUE(X) \
00224 P99_GENERIC((X), \
00225 P00_SVALUE(X), \
00226 (void*, (X)), \
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 \
00242 \
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 \
00259 P00_SVALUE_CHAR(X), \
00260 P00_SVALUE_SIG(schar, X), \
00261 P00_SVALUE_SIG(sshort, X), \
00262 P00_SVALUE_UNS(_Bool, X), \
00263 P00_SVALUE_UNS(uchar, X), \
00264 P00_SVALUE_UNS(ushort, X))
00265
00266 #define P00_QVALUE_SIG(T, X) \
00267 (T, (T)(intmax_t)(X)), \
00268 (T const, (T const)(intmax_t const)(X)), \
00269 (T volatile, (T volatile)(intmax_t volatile)(X)), \
00270 (T const volatile, (T const volatile)(intmax_t const volatile)(X)), \
00271 (_Atomic(T), (T)(intmax_t)(X)), \
00272 (_Atomic(T) const, (T const)(intmax_t const)(X)), \
00273 (_Atomic(T) volatile, (T volatile)(intmax_t volatile)(X)), \
00274 (_Atomic(T) const volatile, (T const volatile)(intmax_t const volatile)(X))
00275
00276 #define P00_QVALUE_UNS(T, X) \
00277 (T, (T)(uintmax_t)(X)), \
00278 (T const, (T const)(uintmax_t const)(X)), \
00279 (T volatile, (T volatile)(uintmax_t volatile)(X)), \
00280 (T const volatile, (T const volatile)(uintmax_t const volatile)(X)), \
00281 (_Atomic(T), (T)(uintmax_t)(X)), \
00282 (_Atomic(T) const, (T const)(uintmax_t const)(X)), \
00283 (_Atomic(T) volatile, (T volatile)(uintmax_t volatile)(X)), \
00284 (_Atomic(T) const volatile, (T const volatile)(uintmax_t const volatile)(X))
00285
00286 #define P00_QVALUE_QUAL(X, Q) \
00287 (char Q, ((char Q)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar Q)(intmax_t Q)(X), (uchar Q)(uintmax_t Q)(X)))), \
00288 (_Atomic(char) Q, ((char Q)P99_TYPED_TERN(P00_CHAR_SIGNED, (schar Q)(intmax_t Q)(X), (uchar Q)(uintmax_t Q)(X))))
00289
00290 #define P00_QVALUE_CHAR(X) \
00291 P00_QVALUE_QUAL(X, ), \
00292 P00_QVALUE_QUAL(X, const), \
00293 P00_QVALUE_QUAL(X, volatile), \
00294 P00_QVALUE_QUAL(X, const volatile)
00295
00296
00297
00298 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_QVALUE, 0)
00299 #define P99_QVALUE(X) \
00300 P99_GENERIC((X), \
00301 P00_RVALUE(X), \
00302 P00_QVALUE_CHAR(X), \
00303 P00_QVALUE_SIG(schar, X), \
00304 P00_QVALUE_SIG(sshort, X), \
00305 P00_QVALUE_UNS(_Bool, X), \
00306 P00_QVALUE_UNS(uchar, X), \
00307 P00_QVALUE_UNS(ushort, X))
00308
00309
00310 #define P00_TYPE_CHOICE(YES, T, I) (T, YES)
00311
00312 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_CHOICE, 0)
00313 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_CHOICE, 1)
00314 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_CHOICE, 2)
00315 #define P99_TYPE_CHOICE(EXP, YES, NO, ...) \
00316 P99_GENERIC \
00317 ((EXP), \
00318 NO, \
00319 P99_FOR(YES, P99_NARG(__VA_ARGS__), P00_SEQ, P00_TYPE_CHOICE, __VA_ARGS__))
00320
00321 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_UNSIGNED, 0)
00322 #define P99_TYPE_UNSIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_UNSIGNED_TYPES)
00323 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_SIGNED, 0)
00324 #define P99_TYPE_SIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_SIGNED_TYPES)
00325 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_REAL_FLOATING, 0)
00326 #define P99_TYPE_REAL_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_FLOATING_TYPES)
00327 #ifndef __STDC_NO_COMPLEX__
00328 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_COMPLEX, 0)
00329 # define P99_TYPE_COMPLEX(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_COMPLEX_TYPES)
00330 #endif
00331 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_FLOATING, 0)
00332 #define P99_TYPE_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_FLOATING_TYPES)
00333 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_BASIC, 0)
00334 #define P99_TYPE_BASIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_BASIC_TYPES)
00335 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_CHARACTER, 0)
00336 #define P99_TYPE_CHARACTER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_CHARACTER_TYPES)
00337 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_INTEGER, 0)
00338 #define P99_TYPE_INTEGER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_INTEGER_TYPES)
00339 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_REAL, 0)
00340 #define P99_TYPE_REAL(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_TYPES)
00341 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_TYPE_ARITHMETIC, 0)
00342 #define P99_TYPE_ARITHMETIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_ARITHMETIC_TYPES)
00343
00344 #define P00_SIZE_CHOICE(YES, UI, I) (char(*)[(size_t)(UI)], YES)
00345
00346 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SIZE_CHOICE, 0)
00347 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SIZE_CHOICE, 1)
00348 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SIZE_CHOICE, 2)
00349 #define P99_SIZE_CHOICE(UI, YES, NO, ...) \
00350 P99_GENERIC \
00351 ((char(*)[(size_t)(UI)])0, \
00352 NO, \
00353 P99_FOR(YES, P99_NARG(__VA_ARGS__), P00_SEQ, P00_SIZE_CHOICE, __VA_ARGS__))
00354
00355
00356 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SIZE_INDICATOR, 0)
00357 #define P99_SIZE_INDICATOR(UI, ...) P99_SIZE_CHOICE(UI, 1, 0, __VA_ARGS__)
00358
00359
00360 #define P00_DECLARE_INLINE_EXPRESSION1(EXT, BASE, EXP, A) \
00361 P99_CONST_FUNCTION \
00362 p99_inline \
00363 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
00364 (P99_BUILTIN_TYPE(EXT) A) \
00365 { \
00366 return (EXP); \
00367 }
00368
00369 #define P00_DECLARE_INLINE_EXPRESSION2(EXT, BASE, EXP, A, B) \
00370 P99_CONST_FUNCTION \
00371 p99_inline \
00372 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
00373 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B) \
00374 { \
00375 return (EXP); \
00376 }
00377
00378 #define P00_DECLARE_INLINE_EXPRESSION3(EXT, BASE, EXP, A, B, C) \
00379 p99_inline \
00380 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
00381 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
00382 P99_BUILTIN_TYPE(EXT) C) \
00383 { \
00384 return (EXP); \
00385 }
00386
00387 #define P00_DECLARE_INLINE_EXPRESSION4(EXT, BASE, EXP, A, B, C, D) \
00388 p99_inline \
00389 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
00390 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
00391 P99_BUILTIN_TYPE(EXT) C, P99_BUILTIN_TYPE(EXT) D) \
00392 { \
00393 return (EXP); \
00394 }
00395
00396 #define P00_DECLARE_INLINE_EXPRESSION5(EXT, BASE, EXP, A, B, C, D, E) \
00397 p99_inline \
00398 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
00399 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
00400 P99_BUILTIN_TYPE(EXT) C, P99_BUILTIN_TYPE(EXT) D, \
00401 P99_BUILTIN_TYPE(EXT) E) \
00402 { \
00403 return (EXP); \
00404 }
00405
00406 #define P00_DECLARE_INLINE_EXPRESSION6(EXT, BASE, EXP, A, B, C, D, E, F) \
00407 p99_inline \
00408 P99_BUILTIN_TYPE(EXT) P99_PASTE3(p00_gen_, BASE, EXT) \
00409 (P99_BUILTIN_TYPE(EXT) A, P99_BUILTIN_TYPE(EXT) B, \
00410 P99_BUILTIN_TYPE(EXT) C, P99_BUILTIN_TYPE(EXT) D, \
00411 P99_BUILTIN_TYPE(EXT) E, P99_BUILTIN_TYPE(EXT) F) \
00412 { \
00413 return (EXP); \
00414 }
00415
00416 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_DECLARE_INLINE_EXPRESSION, 0)
00417 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_DECLARE_INLINE_EXPRESSION, 1)
00418 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_DECLARE_INLINE_EXPRESSION, 2)
00419 #define P99_DECLARE_INLINE_EXPRESSION(...) \
00420 P99_PASTE2(P00_DECLARE_INLINE_EXPRESSION, P99_MINUS(P99_NARG(__VA_ARGS__), 3))(__VA_ARGS__)
00421
00422 #define P00_DECLARE_INLINE_EXPRESSION_(...) P99_DECLARE_INLINE_EXPRESSION(__VA_ARGS__)
00423 #define P00_DECLARE_INLINE_EXPRESSION(ARGS, EXT, I) P00_DECLARE_INLINE_EXPRESSION_(EXT, P00_ROBUST ARGS)
00424
00425 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_DECLARE_INLINE_EXPRESSIONS, 0)
00426 #define P99_DECLARE_INLINE_EXPRESSIONS(NEPL, ...) \
00427 P99_FOR(NEPL, P99_NARG(__VA_ARGS__), P00_SER, P00_DECLARE_INLINE_EXPRESSION, __VA_ARGS__) \
00428 P99_MACRO_END(P99_DECLARE_INLINE_EXPRESSIONS, __VA_ARGS__)
00429
00430 extern void p00_invalid_function(void*, ...);
00431
00432 #define P00_GEN_EXPR(BASE, EXT, I) (P99_BUILTIN_TYPE(EXT), P99_PASTE3(p00_gen_, BASE, EXT))
00433
00434 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_GEN_EXPR, 0)
00435 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GEN_EXPR, 1)
00436 #define P99_GEN_EXPR(BASE, EXPR, ...) \
00437 P99_GENERIC(EXPR, \
00438 p00_invalid_function, \
00439 P99_FOR(BASE, P99_NARG(__VA_ARGS__), P00_SEQ, P00_GEN_EXPR, __VA_ARGS__))
00440
00441
00442
00443
00444 P99_DECLARE_INLINE_EXPRESSIONS((maximum,
00445 (p00_a >= p00_b) ? p00_a : p00_b,
00446 p00_a, p00_b),
00447 P99_STD_REAL_EXTS
00448 );
00449
00450 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GEN_MAX, 0)
00451 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GEN_MAX, 1)
00452 #define P99_GEN_MAX(A, B) \
00453 P99_GEN_EXPR(maximum, ((A) >= (B)) ? (A) : (B), \
00454 P99_STD_REAL_EXTS \
00455 ) \
00456 ((A), (B))
00457
00458 P99_DECLARE_INLINE_EXPRESSIONS((minimum,
00459 (p00_a <= p00_b) ? p00_a : p00_b,
00460 p00_a, p00_b),
00461 P99_STD_REAL_EXTS
00462 );
00463
00464 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GEN_MIN, 0)
00465 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GEN_MIN, 1)
00466 #define P99_GEN_MIN(A, B) \
00467 P99_GEN_EXPR(minimum, ((A) <= (B)) ? (A) : (B), \
00468 P99_STD_REAL_EXTS \
00469 ) \
00470 ((A), (B))
00471
00472
00473 P99_DECLARE_INLINE_EXPRESSIONS((abs,
00474 (p00_a >= 0) ? p00_a : -p00_a,
00475 p00_a),
00476 P99_STD_SIGNED_EXTS, P99_STD_REAL_FLOATING_EXTS
00477 );
00478
00479 P99_DECLARE_INLINE_EXPRESSIONS((abs,
00480 p00_a,
00481 p00_a),
00482 P99_STD_UNSIGNED_EXTS
00483 );
00484
00485
00486 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GEN_ABS, 0)
00487 #define P99_GEN_ABS(A) P99_GEN_EXPR(abs, ((A) >= 0) ? (A) : -(A), P99_STD_REAL_EXTS)(A)
00488
00489 #define p00_gen_sind sin
00490 #define p00_gen_sinf sinf
00491 #define p00_gen_sinld sinl
00492 #define p00_gen_sindc csin
00493 #define p00_gen_sinfc csinf
00494 #define p00_gen_sinldc csinl
00495
00496 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_GEN_SIN, 0)
00497 #define P99_GEN_SIN(A) P99_GEN_EXPR(sin, (A), P99_STD_FLOATING_EXTS)(A)
00498
00499 inline int* p00_generic_test(int * p00_a) {
00500 double *p00_x;
00501 switch (P99_GEN_ABS(*p00_a % 3)) {
00502 case 0:
00503 return P99_GENERIC(&*p00_a,
00504 ,
00505 (int*, p00_a),
00506 (double*, p00_x+1),
00507 (float*, p00_x+2));
00508 #ifndef P99_CSIN_BUG
00509 case 1:
00510 return P99_GENERIC(&*p00_a,
00511 ,
00512 (double[7], P99_GEN_SIN(((p00_x+0)))),
00513 (int*, p00_a),
00514 (float*, p00_x+2));
00515 #endif
00516 default:
00517 return P99_GENERIC(&*p00_a,
00518 p00_x,
00519 (double*, p00_x+0),
00520 (float[7], p00_x+1),
00521 (int*, p00_a));
00522 }
00523 }
00524
00525 #else
00526
00623 #define P99_GENERIC(...)
00624
00644 #define P99_GENERIC_LIT(...)
00645
00677 #define P99_GENERIC_SIZE(UI, ...)
00678
00687 #define P99_GENERIC_SIZE_LIT(UI, ...)
00688
00698 #define P99_TYPED_TERN(COND, YES, NO)
00699
00706 #define P00_TYPE_CHOICE(YES, T, I) (T, YES)
00707
00715 #define P99_TYPE_CHOICE(EXP, YES, NO, ...)
00716
00723 #define P99_TYPE_UNSIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_UNSIGNED_TYPES)
00724 #define P99_TYPE_SIGNED(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_SIGNED_TYPES)
00725 #define P99_TYPE_REAL_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_FLOATING_TYPES)
00726 #define P99_TYPE_COMPLEX(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_COMPLEX_TYPES)
00727 #define P99_TYPE_FLOATING(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_FLOATING_TYPES)
00728 #define P99_TYPE_BASIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_BASIC_TYPES)
00729 #define P99_TYPE_CHARACTER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_CHARACTER_TYPES)
00730 #define P99_TYPE_INTEGER(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_INTEGER_TYPES)
00731 #define P99_TYPE_REAL(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_REAL_TYPES)
00732 #define P99_TYPE_ARITHMETIC(EXP) P99_TYPE_CHOICE((EXP), 1, 0, P99_STD_ARITHMETIC_TYPES)
00733
00751 #define P99_SIZE_CHOICE(UI, YES, NO, ...)
00752
00772 #define P99_SIZE_INDICATOR(UI, ...)
00773
00810 #define P99_DECLARE_INLINE_EXPRESSION(EXT, BASE, EXP, ...)
00811
00846 #define P99_DECLARE_INLINE_EXPRESSIONS(NEPL, ...)
00847
00848 extern void p00_invalid_function(void*, ...);
00849
00920 #define P99_GEN_EXPR(BASE, EXPR, ...)
00921
00922 #define P99_GEN_MAX(A, B) \
00923 P99_GEN_EXPR(maximum, ((A) >= (B)) ? (A) : (B), \
00924 P99_STD_REAL_EXTS \
00925 ) \
00926 ((A), (B))
00927
00928 #define P99_GEN_MIN(A, B) \
00929 P99_GEN_EXPR(minimum, ((A) <= (B)) ? (A) : (B), \
00930 P99_STD_REAL_EXTS \
00931 ) \
00932 ((A), (B))
00933
00934
00935 #define P99_GEN_ABS(A) P99_GEN_EXPR(abs, ((A) >= 0) ? (A) : -(A), P99_STD_REAL_EXTS)(A)
00936
00943 #define P99_GEN_SIN(A) P99_GEN_EXPR(sin, (A), P99_STD_FLOATING_EXTS)(A)
00944
00949 #endif
00950
00951 #define P00_OVALUES_(X, T, I) (T*, X[0])
00952 #define P00_OVALUES(X, ...) P99_FOR(X, P99_NARG(__VA_ARGS__), P00_SEQ, P00_OVALUES_, __VA_ARGS__)
00953 #define P00_OVALUE_(X, DEF, ...) P99_GENERIC(X, DEF, __VA_ARGS__)
00954
00955 #define P00_OVALUES1_(X, T, I) (T*, X)
00956 #define P00_OVALUES1(X, ...) P99_FOR(X, P99_NARG(__VA_ARGS__), P00_SEQ, P00_OVALUES1_, __VA_ARGS__)
00957 #define P00_OVALUE1_(X, ...) P99_GENERIC(&(X[0]), , P00_OVALUES1(X, __VA_ARGS__))
00958
00959 #define P00_AVALUES_(X, T, I) (T*, *(T(*)[1])X)
00960 #define P00_AVALUES(X, ...) P99_FOR(X, P99_NARG(__VA_ARGS__), P00_SEQ, P00_AVALUES_, __VA_ARGS__)
00961 #define P00_AVALUE_(X, DEF, ...) P99_GENERIC(X, DEF, __VA_ARGS__)
00962
00963
00964 #ifdef P00_DOXYGEN
00965
00981 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_OVALUE, 0)
00982 P00_DOCUMENT_TYPE_ARGUMENT(P99_OVALUE, 1)
00983 P00_DOCUMENT_TYPE_ARGUMENT(P99_OVALUE, 2)
00984 P00_DOCUMENT_TYPE_ARGUMENT(P99_OVALUE, 3)
00985 #define P99_OVALUE(X, ...)
00986
01002 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_AVALUE, 0)
01003 P00_DOCUMENT_TYPE_ARGUMENT(P99_AVALUE, 1)
01004 P00_DOCUMENT_TYPE_ARGUMENT(P99_AVALUE, 2)
01005 P00_DOCUMENT_TYPE_ARGUMENT(P99_AVALUE, 3)
01006 #define P99_AVALUE(X, ...)
01007
01024 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_OBJSIZE, 0)
01025 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJSIZE, 1)
01026 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJSIZE, 2)
01027 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJSIZE, 3)
01028 #define P99_OBJSIZE(X, ...)
01029
01046 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_OBJLEN, 0)
01047 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJLEN, 1)
01048 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJLEN, 2)
01049 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJLEN, 3)
01050 #define P99_OBJLEN(X, ...)
01051 #else
01052 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_OVALUE, 0)
01053 P00_DOCUMENT_TYPE_ARGUMENT(P99_OVALUE, 1)
01054 P00_DOCUMENT_TYPE_ARGUMENT(P99_OVALUE, 2)
01055 P00_DOCUMENT_TYPE_ARGUMENT(P99_OVALUE, 3)
01056 #define P99_OVALUE(X, ...) P00_OVALUE_((X), P00_OVALUE1_((X), __VA_ARGS__), P00_OVALUES((X), __VA_ARGS__))
01057
01058 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_AVALUE, 0)
01059 P00_DOCUMENT_TYPE_ARGUMENT(P99_AVALUE, 1)
01060 P00_DOCUMENT_TYPE_ARGUMENT(P99_AVALUE, 2)
01061 P00_DOCUMENT_TYPE_ARGUMENT(P99_AVALUE, 3)
01062 #define P99_AVALUE(X, ...) P00_AVALUE_((X), P00_OVALUE1_((X), __VA_ARGS__), P00_AVALUES((X), __VA_ARGS__))
01063
01064 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_OBJSIZE, 0)
01065 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJSIZE, 1)
01066 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJSIZE, 2)
01067 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJSIZE, 3)
01068 #define P99_OBJSIZE(X, ...) (sizeof P99_OVALUE(X, __VA_ARGS__))
01069
01070 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_OBJLEN, 0)
01071 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJLEN, 1)
01072 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJLEN, 2)
01073 P00_DOCUMENT_TYPE_ARGUMENT(P99_OBJLEN, 3)
01074 #define P99_OBJLEN(X, ...) (P99_OBJSIZE(X, __VA_ARGS__)/(sizeof (X)[0]))
01075 #endif
01076
01077 #define P00_SPRINT_DEFINE(T, ...) \
01078 p99_inline \
01079 char const* P99_PASTE2(p00_sprint_, T)(T p00_val, char*restrict p00_str, unsigned p00_form) { \
01080 enum { p00_len = P99_NARG(__VA_ARGS__), }; \
01081 static char const*const p00_format[p00_len] = { __VA_ARGS__ }; \
01082 char const*const p00_f = (p00_form < p00_len) \
01083 ? p00_format[p00_form] \
01084 : p00_format[0]; \
01085 sprintf(p00_str, p00_f, p00_val); \
01086 return p00_str; \
01087 } \
01088 P99_MACRO_END(P00_SPRINT_DEFINE, T)
01089
01090 P00_SPRINT_DEFINE(char, "%c");
01091 P00_SPRINT_DEFINE(schar, "%hhd");
01092 P00_SPRINT_DEFINE(uchar, "%hhu", "%#hhX", "%#hho");
01093 P00_SPRINT_DEFINE(short, "%hd");
01094 P00_SPRINT_DEFINE(ushort, "%hu", "%#hX", "%#ho");
01095 P00_SPRINT_DEFINE(int, "%d");
01096 P00_SPRINT_DEFINE(unsigned, "%u", "%#X", "%#o");
01097 P00_SPRINT_DEFINE(long, "%ld");
01098 P00_SPRINT_DEFINE(ulong, "%lu", "%#lX", "%#lo");
01099 P00_SPRINT_DEFINE(llong, "%lld");
01100 P00_SPRINT_DEFINE(ullong, "%llu", "%#llX", "%#llo");
01101 P00_SPRINT_DEFINE(float, "%g", "%a");
01102 P00_SPRINT_DEFINE(double, "%g", "%a");
01103 P00_SPRINT_DEFINE(ldouble, "%Lg", "%La");
01104
01105 P99_CONST_FUNCTION
01106 p99_inline
01107 char const* p00_sprint__Bool(_Bool p00_val, char*restrict p00_str, unsigned p00_form) {
01108 P99_UNUSED(p00_str);
01109 P99_UNUSED(p00_form);
01110 char const*const p00_format[] = {
01111 "false", "true",
01112 "0", "1",
01113 "f", "t",
01114 };
01115 register unsigned const p00_len = P99_ALEN(p00_format) / 2;
01116 if (p00_form >= p00_len) p00_form = 0;
01117 return p00_format[p00_form * 2 + p00_val];
01118 }
01119
01120 P99_CONST_FUNCTION
01121 p99_inline
01122 char const* p00_sprint_charp(char const* p00_val, char*restrict p00_str, unsigned p00_form) {
01123 P99_UNUSED(p00_str);
01124 P99_UNUSED(p00_form);
01125 return p00_val;
01126 }
01127
01128 p99_inline
01129 char const* p00_sprint_voidp(void * p00_val, char*restrict p00_str, unsigned p00_form) {
01130 P99_UNUSED(p00_form);
01131 sprintf(p00_str, "%p", p00_val);
01132 return p00_str;
01133 }
01134
01135 #ifndef __STDC_NO_COMPLEX__
01136 p99_inline
01137 char const* p00_sprint_cfloat(cfloat p00_val, char*restrict p00_str, unsigned p00_form) {
01138 char const*const p00_format[] = { "(%g, %g)", "(%a, %a)", };
01139 register unsigned const p00_len = P99_ALEN(p00_format);
01140 char const*const p00_f = (p00_form < p00_len)
01141 ? p00_format[p00_form]
01142 : p00_format[0];
01143 sprintf(p00_str, p00_f, creal(p00_val), cimag(p00_val));
01144 return p00_str;
01145 }
01146
01147 p99_inline
01148 char const* p00_sprint_cdouble(cdouble p00_val, char*restrict p00_str, unsigned p00_form) {
01149 char const*const p00_format[] = { "(%g, %g)", "(%a, %a)", };
01150 register unsigned const p00_len = P99_ALEN(p00_format);
01151 char const*const p00_f = (p00_form < p00_len)
01152 ? p00_format[p00_form]
01153 : p00_format[0];
01154 sprintf(p00_str, p00_f, creal(p00_val), cimag(p00_val));
01155 return p00_str;
01156 }
01157
01158 p99_inline
01159 char const* p00_sprint_cldouble(cldouble p00_val, char*restrict p00_str, unsigned p00_form) {
01160 char const*const p00_format[] = { "(%Lg, %Lg)", "(%La, %La)", };
01161 register unsigned const p00_len = P99_ALEN(p00_format);
01162 char const*const p00_f = (p00_form < p00_len)
01163 ? p00_format[p00_form]
01164 : p00_format[0];
01165 sprintf(p00_str, p00_f, creal(p00_val), cimag(p00_val));
01166 return p00_str;
01167 }
01168 #endif
01169
01170
01171 #ifdef p99x_uintmax
01172 #define UINT64_D19 UINT64_C(10000000000000000000)
01173 p99_inline
01174 void p00_sprint_p99x_uintmax_u_ite(p99x_uintmax p00_val, char*restrict p00_str) {
01175 uint64_t p00_ar[2*sizeof(p99x_uintmax)/sizeof(uint64_t)];
01176 size_t p00_pos = 0;
01177 for (; p00_val >= UINT64_D19; ++p00_pos) {
01178
01179
01180 p00_ar[p00_pos] = (uint64_t)(p00_val % UINT64_D19);
01181 p00_val /= UINT64_D19;
01182 }
01183 p00_str += sprintf(p00_str, "%" PRIu64, (uint64_t)p00_val);
01184 while (p00_pos) {
01185 --p00_pos;
01186 p00_str += sprintf(p00_str, "%019" PRIu64, p00_ar[p00_pos]);
01187 }
01188 }
01189 p99_inline
01190 char* p00_sprint_p99x_uintmax_u(p99x_uintmax p00_val, char*restrict p00_str) {
01191 p00_sprint_p99x_uintmax_u_ite(p00_val, p00_str);
01192 return p00_str;
01193 }
01194 #define UINT64_O21 (~(UINT64_C(1)<<63))
01195 p99_inline
01196 void p00_sprint_p99x_uintmax_o_ite(p99x_uintmax p00_val, char*restrict p00_str) {
01197 uint64_t p00_ar[3*sizeof(p99x_uintmax)/sizeof(uint64_t)];
01198 size_t p00_pos = 0;
01199 for (;;) {
01200
01201 p00_ar[p00_pos] = ((uint64_t)p00_val) & UINT64_O21;
01202 p00_val >>= 63;
01203 if (!p00_val) break;
01204 ++p00_pos;
01205 }
01206 p00_str += sprintf(p00_str, "%#" PRIo64, p00_ar[p00_pos]);
01207 while (p00_pos) {
01208 --p00_pos;
01209 p00_str += sprintf(p00_str, "%021" PRIo64, p00_ar[p00_pos]);
01210 }
01211 }
01212 p99_inline
01213 char* p00_sprint_p99x_uintmax_o(p99x_uintmax p00_val, char*restrict p00_str) {
01214 p00_sprint_p99x_uintmax_o_ite(p00_val, p00_str);
01215 return p00_str;
01216 }
01217 p99_inline
01218 void p00_sprint_p99x_uintmax_X_ite(p99x_uintmax p00_val, char*restrict p00_str) {
01219 uint64_t p00_ar[2*sizeof(p99x_uintmax)/sizeof(uint64_t)];
01220 size_t p00_pos = 0;
01221 for (;;) {
01222
01223 p00_ar[p00_pos] = (uint64_t)p00_val;
01224 p00_val >>= 64;
01225 if (!p00_val) break;
01226 ++p00_pos;
01227 }
01228 p00_str += sprintf(p00_str, "%#" PRIX64, p00_ar[p00_pos]);
01229 while (p00_pos) {
01230 --p00_pos;
01231 p00_str += sprintf(p00_str, "%016" PRIX64, p00_ar[p00_pos]);
01232 }
01233 }
01234 p99_inline
01235 char const* p00_sprint_p99x_uintmax_X(p99x_uintmax p00_val, char*restrict p00_str) {
01236 p00_sprint_p99x_uintmax_X_ite(p00_val, p00_str);
01237 return p00_str;
01238 }
01239
01240 p99_inline
01241 char const* p00_sprint_p99x_intmax(p99x_intmax p00_val, char*restrict p00_str, unsigned p00_form) {
01242 P99_UNUSED(p00_form);
01243 if (p00_val < 0) {
01244 p00_str[0] = '-';
01245 p00_sprint_p99x_uintmax_u(-p00_val, p00_str + 1);
01246 } else {
01247 p00_sprint_p99x_uintmax_u(p00_val, p00_str);
01248 }
01249 return p00_str;
01250 }
01251
01252 p99_inline
01253 char const* p00_sprint_p99x_uintmax(p99x_uintmax p00_val, char*restrict p00_str, unsigned p00_form) {
01254 switch (p00_form) {
01255 default: return p00_sprint_p99x_uintmax_u(p00_val, p00_str);
01256 case 1: return p00_sprint_p99x_uintmax_X(p00_val, p00_str);
01257 case 2: return p00_sprint_p99x_uintmax_o(p00_val, p00_str);
01258 }
01259 }
01260 #endif
01261
01262
01263
01264 #define P00_SPRINT(NAME, T, I) \
01265 (T, P99_PASTE2(p00_sprint_, T)), \
01266 (T const, P99_PASTE2(p00_sprint_, T)), \
01267 (T volatile, P99_PASTE2(p00_sprint_, T)), \
01268 (T const volatile, P99_PASTE2(p00_sprint_, T))
01269
01270
01271 #define P00_SPRINT_LIST_(...) \
01272 P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEQ, P00_SPRINT, __VA_ARGS__)
01273
01274 #define P00_SPRINT_LIST() P00_SPRINT_LIST_(P99_EXT_ARITHMETIC_TYPES)
01275
01276 #define P00_SPRINT_FORMAT_(X, A, ...) \
01277 P99_GENERIC((X), \
01278 p00_sprint_voidp, \
01279 (char*, p00_sprint_charp), \
01280 (char const*, p00_sprint_charp), \
01281 (char*const, p00_sprint_charp), \
01282 (char const*const, p00_sprint_charp), \
01283 (char*volatile, p00_sprint_charp), \
01284 (char const*volatile, p00_sprint_charp), \
01285 (char*const volatile, p00_sprint_charp), \
01286 (char const*const volatile, p00_sprint_charp), \
01287 (char*restrict, p00_sprint_charp), \
01288 (char const*restrict, p00_sprint_charp), \
01289 (char*const restrict, p00_sprint_charp), \
01290 (char const*const restrict, p00_sprint_charp), \
01291 (char*volatile restrict, p00_sprint_charp), \
01292 (char const*volatile restrict, p00_sprint_charp), \
01293 (char*const volatile restrict, p00_sprint_charp), \
01294 (char const*const volatile restrict, p00_sprint_charp), \
01295 __VA_ARGS__)((X), \
01296 \
01297 \
01298 \
01299 (char[(sizeof(X+0)*22+64)/8]){ 0 }, \
01300 (A))
01301
01302 #define P00_SPRINT_FORMAT(...) P00_SPRINT_FORMAT_(__VA_ARGS__)
01303
01331 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FORMAT, 0)
01332 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FORMAT, 2)
01333 #define P99_FORMAT(...) \
01334 P00_SPRINT_FORMAT \
01335 (P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
01336 (__VA_ARGS__, 0) \
01337 (__VA_ARGS__), \
01338 P00_SPRINT_LIST())
01339
01340 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FORMATS, 0)
01341 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FORMATS, 1)
01342 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FORMATS, 2)
01343 #define P99_FORMATS(...) P99_SEQ(P99_FORMAT, __VA_ARGS__)
01344 #define P00_PRINTF(...) printf(__VA_ARGS__)
01345
01346 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_PRINTF, 1)
01347 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_PRINTF, 2)
01348 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_PRINTF, 3)
01349 #define P99_PRINTF(FORMAT, ...) printf(FORMAT, P99_FORMATS(__VA_ARGS__))
01350
01351 #define P00_FPRINTF(...) fprintf(__VA_ARGS__)
01352 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FPRINTF, 2)
01353 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FPRINTF, 3)
01354 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FPRINTF, 4)
01355 #define P99_FPRINTF(F, FORMAT, ...) fprintf(F, FORMAT, P99_FORMATS(__VA_ARGS__))
01356
01357 #define P00_SPRINTF(...) sprintf(__VA_ARGS__)
01358 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SPRINTF, 2)
01359 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SPRINTF, 3)
01360 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SPRINTF, 4)
01361 #define P99_SPRINTF(S, FORMAT, ...) sprintf(S, FORMAT, P99_FORMATS(__VA_ARGS__))
01362
01363 #define P00_SNPRINTF(...) snprintf(__VA_ARGS__)
01364 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SNPRINTF, 3)
01365 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SNPRINTF, 4)
01366 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_SNPRINTF, 5)
01367 #define P99_SNPRINTF(S, N, FORMAT, ...) snprintf(S, N, FORMAT, P99_FORMATS(__VA_ARGS__))
01368
01369 #define P00_DEFINE_IN_RANGE(T) \
01370 P99_CONST_FUNCTION \
01371 p99_inline \
01372 bool P99_PASTE2(p00_in_range_, T)(T p00_r, T p00_s, T p00_len) { \
01373 return (p00_r >= p00_s) && ((p00_r - p00_s) < p00_len); \
01374 }
01375
01376 P99_CONST_FUNCTION
01377 p99_inline
01378 bool p00_in_range_voidp(void* p00_r_, void* p00_s_, size_t p00_len) {
01379 unsigned char* p00_r = p00_r_;
01380 unsigned char* p00_s = p00_s_;
01381 return (p00_r >= p00_s) && ((size_t)(p00_r - p00_s) < p00_len);
01382 }
01383
01384 P99_SER(P00_DEFINE_IN_RANGE, P99_EXT_REAL_TYPES)
01385
01386 #define P00_IN_RANGE_PART(NAME, T, I) \
01387 (T, P99_PASTE2(p00_in_range_, T)), \
01388 (T const, P99_PASTE2(p00_in_range_, T)), \
01389 (T volatile, P99_PASTE2(p00_in_range_, T)), \
01390 (T const volatile, P99_PASTE2(p00_in_range_, T))
01391
01392
01393 #define P00_IN_RANGE_LIST_(...) \
01394 P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEQ, P00_IN_RANGE_PART, __VA_ARGS__)
01395
01396 #define P00_IN_RANGE_LIST() P00_IN_RANGE_LIST_(P99_EXT_REAL_TYPES)
01397
01398 #define P00_IN_RANGE(R, S, L, ...) \
01399 P99_GENERIC((1 ? (R) : (S)), p00_in_range_voidp, __VA_ARGS__)((R), (S), (L))
01400
01411 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_IN_RANGE, 0)
01412 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_IN_RANGE, 1)
01413 #define P99_IN_RANGE(R, S, L) P00_IN_RANGE((R), (S), (L), P00_IN_RANGE_LIST())
01414
01415 #endif