00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef P99_INT_H_
00014 # define P99_INT_H_
00015
00034 #include "p99_c99.h"
00035 #include "p99_id.h"
00036 #include "p99_type.h"
00037
00038 #if P99_COMPILER & (P99_COMPILER_CLANG | P99_COMPILER_GNU | P99_COMPILER_OPEN64)
00039 # if P99_GCC_VERSION >= 40200UL
00040 # pragma GCC diagnostic ignored "-Wmissing-braces"
00041 # endif
00042 #endif
00043
00054 #define P00_DOCUMENT_C2(WIDTH)
00056 #ifdef UINT16_MAX
00057 P00_DOCUMENT_C2(16)
00058 #define P99X_UINT16_C2(H, L) ((((uint16_t)(uint8_t)H) << 8u) | (uint16_t)(uint8_t)L)
00059 #endif
00060 #ifdef INT16_MAX
00061 P00_DOCUMENT_C2(16)
00062 #define P99X_INT16_C2(H, L) ((((int16_t)(int8_t)H) << 8u) | (int16_t)(int8_t)L)
00063 #endif
00064 #ifdef UINT32_MAX
00065 P00_DOCUMENT_C2(32)
00066 #define P99X_UINT32_C2(H, L) ((((uint32_t)(uint16_t)H) << 16u) | (uint32_t)(uint16_t)L)
00067 #endif
00068 #ifdef INT32_MAX
00069 P00_DOCUMENT_C2(32)
00070 #define P99X_INT32_C2(H, L) ((((int32_t)(int16_t)H) << 16u) | (int32_t)(int16_t)L)
00071 #endif
00072 #ifdef UINT64_MAX
00073 P00_DOCUMENT_C2(64)
00074 #define P99X_UINT64_C2(H, L) ((((uint64_t)(uint32_t)H) << 32u) | (uint64_t)(uint32_t)L)
00075 #endif
00076 #ifdef INT64_MAX
00077 P00_DOCUMENT_C2(64)
00078 #define P99X_INT64_C2(H, L) ((((int64_t)(int32_t)H) << 32u) | (int64_t)(int32_t)L)
00079 #endif
00080
00081 #ifdef p99x_uint128
00082 P00_DOCUMENT_C2(128)
00083 #define P99X_UINT128_C2(H, L) ((((p99x_uint128)H) << 64u) | (p99x_uint128)L)
00084 #define P99X_UINT128_0 P99X_UINT128_C2(0x0000000000000000, 0x0000000000000000)
00085 #define P99X_UINT128_MAX P99X_UINT128_C2(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF)
00086 #endif
00087
00088 #ifdef p99x_int128
00089 P00_DOCUMENT_C2(128)
00090 #define P99X_INT128_C2(H, L) ((((p99x_int128)H) << 64u) | (p99x_int128)L)
00091 #define P99X_INT128_MAX P99X_INT128_C2(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF)
00092 #define P99X_INT128_MIN P99X_INT128_C2(0x8000000000000000, 0x0000000000000000)
00093 #endif
00094
00107 #ifndef p99x_uint128
00108 typedef uintmax_t p99x_uintmax;
00109 #endif
00110
00123 #ifndef p99x_int128
00124 typedef intmax_t p99x_intmax;
00125 #endif
00126
00127 #ifdef P00_DOXYGEN
00128
00139 typedef extendedInt p99x_uint128;
00140
00152 typedef extendedInt p99x_int128;
00153 #endif
00154
00155 #ifdef p99x_uintmax
00156
00157 #define P99X__SIGN_PROMOTE(EXPR) \
00158 ((p99x_uintmax)P99_SIGN_PROMOTE(P99_UE_MAX(EXPR), (p99x_uintmax)UINTMAX_MAX))
00159
00160 #define P99X__SHIFT(EXPR) \
00161 ((P99_SIGN_PROMOTE(P99_UE_MAX(EXPR), UINTMAX_MAX) > (p99x_uintmax)UINTMAX_MAX) \
00162 ? 64u \
00163 : 0u)
00164 #endif
00165
00166 #ifndef P99_HIGH2
00167 # if P99_UINTMAX_WIDTH == 64
00168 # define P99_HIGH2(X) \
00169 ((((X) & P00_B0) ? P00_S0 : 0u) \
00170 | (((X) & P00_B1) ? P00_S1 : 0u) \
00171 | (((X) & P00_B2) ? P00_S2 : 0u) \
00172 | (((X) & P00_B3) ? P00_S3 : 0u) \
00173 | (((X) & P00_B4) ? P00_S4 : 0u) \
00174 | (((X) & P00_B5) ? P00_S5 : 0u))
00175 # endif
00176 #endif
00177 #ifndef P99_HIGH2
00178 # if P99_UINTMAX_WIDTH <= 128
00179 # define P99_HIGH2(X) \
00180 ((((X) & P00_B0) ? P00_S0 : 0u) \
00181 | (((X) & P00_B1) ? P00_S1 : 0u) \
00182 | (((X) & P00_B2) ? P00_S2 : 0u) \
00183 | (((X) & P00_B3) ? P00_S3 : 0u) \
00184 | (((X) & P00_B4) ? P00_S4 : 0u) \
00185 | (((X) & P00_B5) ? P00_S5 : 0u) \
00186 | (((X) & P00_B6) ? P00_S6 : 0u))
00187 # endif
00188 #endif
00189
00190 #ifndef P99X__SHIFT
00191 #define P99X__SHIFT(EXPR) 0
00192 #endif
00193
00194 #ifndef P99X__SIGN_PROMOTE
00195 #define P99X__SIGN_PROMOTE(EXPR) 0
00196 #endif
00197
00198 #define P99_HIGH2_1(X) ((X) == P99_UINTMAX_MAX ? P99_UINTMAX_WIDTH : (P99_HIGH2((X) + UINTMAX_C(1))))
00199
00206 P00_DOCUMENT_TYPE_ARGUMENT(P99_TO_UNSIGNED, 0)
00207 P00_DOCUMENT_MACRO_ARGUMENT(P99_TO_UNSIGNED, 1)
00208 #define P99_TO_UNSIGNED(T, MACRO) \
00209 ((uintmax_t) \
00210 (sizeof(T) < sizeof(signed) \
00211 ? (sizeof(T) == 1u \
00212 ? MACRO(unsigned char) \
00213 : MACRO(unsigned short)) \
00214 : (sizeof(T) < sizeof(unsigned long) \
00215 ? MACRO(unsigned) \
00216 : (sizeof(T) < sizeof(unsigned long long) \
00217 ? MACRO(unsigned long) \
00218 : MACRO(unsigned long long)))))
00219
00233 #define P99_M1(T) ((T)-1)
00234
00240 #define P99_M1U(T) (P99_ISSIGNED(T) ? P99_TO_UNSIGNED(T, P99_M1) : P99_M1(T))
00241
00242 #define P00_DOCUMENT_SIGNED(X)
00243 #define P00_DOCUMENT_UNSIGNED(X)
00277 #define P99_C(T, X) ((T)+(X))
00278
00279 #define P00_DOCUMENT_CONSTANT(T)
00281
00282
00283 #if !defined(SIZE_C)
00284 P00_DOCUMENT_CONSTANT(size_t)
00285 # define SIZE_C(X) P99_C(size_t, X)
00286 #endif
00287
00288 #if !defined(PTRDIFF_C)
00289 P00_DOCUMENT_CONSTANT(ptrdiff_t)
00290 # define PTRDIFF_C(X) P99_C(ptrdiff_t, X)
00291 #endif
00292
00293 #if !defined(WCHAR_C)
00294 P00_DOCUMENT_CONSTANT(wchar_t)
00295 # define WCHAR_C(X) P99_C(wchar_t, X)
00296 #endif
00297
00298 #if !defined(WINT_C)
00299 P00_DOCUMENT_CONSTANT(wint_t)
00300 # define WINT_C(X) P99_C(wint_t, X)
00301 #endif
00302
00303
00304
00305 #if defined(SIG_ATOMIC_MAX) && !defined(SIG_ATOMIC_C)
00306 P00_DOCUMENT_CONSTANT(sig_atomic_t)
00307 # define SIG_ATOMIC_C(X) P99_C(sig_atomic_t, X)
00308 #endif
00309
00310 #if defined(UINTPTR_MAX) && !defined(UINTPTR_C)
00311 P00_DOCUMENT_CONSTANT(uintptr_t)
00312 # define UINTPTR_C(X) P99_C(uintptr_t, X)
00313 #endif
00314
00315 #if defined(UINTPTR_MAX) && !defined(INTPTR_C)
00316 P00_DOCUMENT_CONSTANT(intptr_t)
00317 # define INTPTR_C(X) P99_C(intptr_t, X)
00318 #endif
00319
00320
00321
00322
00323 P00_DOCUMENT_SIGNED(0)
00324 #define P99_0(T) P99_C(T, 0)
00325
00326 P00_DOCUMENT_UNSIGNED(0)
00327 #define P99_0U(T) P99_TO_UNSIGNED(T, P99_0)
00328
00329 P00_DOCUMENT_SIGNED(1)
00330 #define P99_1(T) P99_C(T, 1)
00331
00332 P00_DOCUMENT_UNSIGNED(1)
00333 #define P99_1U(T) P99_TO_UNSIGNED(T, P99_1)
00334
00335 P00_DOCUMENT_SIGNED(2)
00336 #define P99_2(T) P99_C(T, 2)
00337
00338 P00_DOCUMENT_UNSIGNED(2)
00339 #define P99_2U(T) P99_TO_UNSIGNED(T, P99_2)
00340
00341 P00_DOCUMENT_SIGNED(3)
00342 #define P99_3(T) P99_C(T, 3)
00343
00344 P00_DOCUMENT_UNSIGNED(3)
00345 #define P99_3U(T) P99_TO_UNSIGNED(T, P99_3)
00346
00353 P00_DOCUMENT_TYPE_ARGUMENT(P99_UT_MAX, 0)
00354 #define P99_UT_MAX(T) (P99_M1U(T))
00355
00367 #define P99_UT_MAX1(T) (P99_UT_MAX(T)/2u)
00368
00380 #define P00_ST_MIN1(T) (-(T)P99_UT_MAX1(T))
00381
00397 P00_DOCUMENT_TYPE_ARGUMENT(P99_ISSIGNED, 0)
00398 #define P99_ISSIGNED(T) (P99_M1(T) < P99_0(T))
00399
00416 #define P99_SIGN_PROMOTE(A, B) (1 ? (A) : (B))
00417
00418
00419 #define P00_SEE_PROMOTE
00421 #define P00_DOCUMENT_PROMOTE(X)
00423 P00_DOCUMENT_PROMOTE(0)
00424 P00_SEE_PROMOTE
00425 #define P99_PROMOTE_0(EXPR) P99_SIGN_PROMOTE(0, (EXPR))
00426
00427 P00_DOCUMENT_PROMOTE(1)
00428 P00_SEE_PROMOTE
00429 #define P99_PROMOTE_1(EXPR) P99_SIGN_PROMOTE(1, (EXPR))
00430
00431 P00_DOCUMENT_PROMOTE(2)
00432 P00_SEE_PROMOTE
00433 #define P99_PROMOTE_2(EXPR) P99_SIGN_PROMOTE(2, (EXPR))
00434
00435 P00_DOCUMENT_PROMOTE(3)
00436 P00_SEE_PROMOTE
00437 #define P99_PROMOTE_3(EXPR) P99_SIGN_PROMOTE(3, (EXPR))
00438
00439 P00_DOCUMENT_PROMOTE(0U)
00440 P00_SEE_PROMOTE
00441 #define P99_PROMOTE_0U(EXPR) P99_SIGN_PROMOTE(0U, (EXPR))
00442
00443 P00_DOCUMENT_PROMOTE(1u)
00444 P00_SEE_PROMOTE
00445 #define P99_PROMOTE_1U(EXPR) P99_SIGN_PROMOTE(1U, (EXPR))
00446
00447 P00_DOCUMENT_PROMOTE(2u)
00448 P00_SEE_PROMOTE
00449 #define P99_PROMOTE_2U(EXPR) P99_SIGN_PROMOTE(2U, (EXPR))
00450
00451
00452 P00_DOCUMENT_PROMOTE(-1)
00453 P00_SEE_PROMOTE
00454 #define P99_PROMOTE_M1(EXPR) P99_SIGN_PROMOTE(-1, (EXPR))
00455
00460 P00_SEE_PROMOTE
00461 #define P99_PROMOTE_M1U(EXPR) P99_SIGN_PROMOTE(P99_PROMOTE_M1(EXPR), P99_PROMOTE_0U(EXPR))
00462
00469 P00_SEE_PROMOTE
00470 #define P99_UE_MAX(EXPR) (P99_PROMOTE_M1U(EXPR))
00471
00483 P00_SEE_PROMOTE
00484 #define P99_UE_MAX1(EXPR) (P99_UE_MAX(EXPR)/P99_PROMOTE_2U(EXPR))
00485
00486
00487 #ifdef DOXYGEN
00488
00502 P00_SEE_PROMOTE
00503 #define P99_EWIDTH(EXPR)
00504
00508 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMAX, 0)
00509 #define P99_TMAX(T)
00510
00514 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMIN, 0)
00515 #define P99_TMIN(T)
00516
00517 #endif
00518
00519 #ifdef p99x_uintmax
00520 #define P99_EWIDTH(EXPR) \
00521 (P99X__SHIFT(EXPR) \
00522 ? (P99_HIGH2_1((uintmax_t)(P99_UE_MAX(EXPR)>>P99X__SHIFT(EXPR))) + P99X__SHIFT(EXPR)) \
00523 : P99_HIGH2_1(P99_UE_MAX(EXPR)) \
00524 )
00525 #else
00526 #define P99_EWIDTH(EXPR) P99_HIGH2_1(P99_UE_MAX(EXPR))
00527 #endif
00528
00540 P00_SEE_PROMOTE
00541 #define P99_EPREC(EXPR) (P99_EWIDTH(EXPR) - P99_SIGNED(EXPR))
00542
00557 P00_SEE_PROMOTE
00558 #define P99_EPADDING(EXPR) (sizeof(P99_PROMOTE_0(EXPR))*CHAR_BIT - P99_EWIDTH(EXPR))
00559
00560 #define P99_SE_MAX(EXPR) \
00561 ((((P99_PROMOTE_1(EXPR) \
00562 << (P99_EWIDTH(EXPR) - 2U)) \
00563 - P99_PROMOTE_1(EXPR)) \
00564 << 1U) \
00565 + P99_PROMOTE_1(EXPR))
00566
00567
00579 #define P00_SE_MIN1(EXPR) (-P99_SE_MAX(EXPR))
00580
00596 P00_SEE_PROMOTE
00597 #define P99_SIGNED(EXPR) (P99_PROMOTE_M1(EXPR) < P99_PROMOTE_0(EXPR))
00598
00599
00600 p99_inline
00601 uintmax_t p00_abs_signed(intmax_t p00_a) {
00602 uintmax_t p00_aa = p00_a;
00603
00604
00605
00606 return (p00_a < INTMAX_C(0)) ? -p00_aa : p00_a;
00607 }
00608
00622 #define P99_ABS(EXPR) (P99_SIGNED(EXPR) ? p00_abs_signed(EXPR) : (EXPR))
00623
00624 #if defined(p99x_uintmax) && defined(p99x_intmax)
00625 p99_inline
00626 p99x_uintmax p99x__abs_signed(p99x_intmax p00_a) {
00627 p99x_uintmax p00_aa = p00_a;
00628
00629
00630
00631 return (p00_a < (p99x_intmax)0) ? -p00_aa : p00_a;
00632 }
00633 #define P99X_ABS(EXPR) (P99_SIGNED(EXPR) ? p99x__abs_signed(EXPR) : (EXPR))
00634 #endif
00635
00636 #ifndef P99X_ABS
00637
00647 # define P99X_ABS P00_ABS
00648 #endif
00649
00656 typedef enum {
00657 p99_signed_representation_invalid = 0,
00658 p99_signed_representation_magnitude = 1,
00659 p99_signed_representation_ones = 2,
00660 p99_signed_representation_twos = 3,
00661 } p99_signed_representation;
00662
00671 P00_DOCUMENT_TYPE_ARGUMENT(P99_SIGNED_REPRESENTATION, 0)
00672 #define P99_SIGNED_REPRESENTATION(T) ((p99_signed_representation)(P99_M1(T) & P99_3(T)))
00673
00674
00680 #define P99_2COMPLEMENT(T) ((T)(P99_SIGNED_REPRESENTATION(T) == p99_signed_representation_twos))
00681
00682 #ifdef p99x_uintmax
00683 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMAX, 0)
00684 #define P99_TMAX(T) \
00685 ((T) \
00686 (P99X__SHIFT((T)0) \
00687 ? (P99_ISSIGNED(T) ? P99X__SIGN_PROMOTE((T)-1)/2u : P99_UE_MAX((T)0)) \
00688 : (P99_ISSIGNED(T) ? P99_UT_MAX1(T) : P99_UT_MAX(T))))
00689
00690 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMIN, 0)
00691 #define P99_TMIN(T) \
00692 ((T) \
00693 (P99X__SHIFT((T)0) \
00694 ? (P99_ISSIGNED(T) ? (-(P99X__SIGN_PROMOTE((T)-1)/2u)) - P99_2COMPLEMENT(T) : (T)0) \
00695 : (P99_ISSIGNED(T) ? (P00_ST_MIN1(T) - P99_2COMPLEMENT(T)) : P99_0(T))))
00696 #else
00697 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMAX, 0)
00698 #define P99_TMAX(T) (P99_ISSIGNED(T) ? P99_UT_MAX1(T) : P99_UT_MAX(T))
00699 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMIN, 0)
00700 #define P99_TMIN(T) (P99_ISSIGNED(T) ? (P00_ST_MIN1(T) - P99_2COMPLEMENT(T)) : P99_0(T))
00701 #endif
00702
00703
00712 #define P99_E_REPRESENTATION(EXPR) ((p99_signed_representation)(P99_PROMOTE_M1(EXPR) & P99_PROMOTE_3(EXPR)))
00713
00714
00720 #define P99_E_2COMPLEMENT(EXPR) \
00721 P99_SIGN_PROMOTE(P99_E_REPRESENTATION(EXPR) == p99_signed_representation_twos, (EXPR))
00722
00727 #define P99_EMAX(EXPR) (P99_SIGNED(EXPR) ? P99_SE_MAX(EXPR) : P99_PROMOTE_M1(EXPR))
00728
00733 #define P99_EMIN(EXPR) (P99_SIGNED(EXPR) ? (P00_SE_MIN1(EXPR) - P99_E_2COMPLEMENT(EXPR)) : P99_PROMOTE_0(EXPR))
00734
00745 #define P99_TPREC(T) \
00746 (P99X__SHIFT((T)-1) \
00747 ? P99_EPREC((T)-1) \
00748 : P99_HIGH2_1(P99_TMAX(T)))
00749
00762 #define P99_TWIDTH(T) (P99_TPREC(T) + P99_ISSIGNED(T))
00763
00777 #define P99_TPADDING(T) ((sizeof(T)*CHAR_BIT) - P99_TWIDTH(T))
00778
00779 #ifdef P00_DOXYGEN
00780 #define P00_DECLARE_OVERFLOW(SUFF) \
00781 \
00782 \
00783 \
00784 p99_inline \
00785 P99_BUILTIN_TYPE(SUFF,) \
00786 P99_PASTE2(p99_twos, SUFF)(P99_BUILTIN_TYPE(u, SUFF) p00_a); \
00787 p99_inline \
00788 P99_BUILTIN_TYPE(SUFF,) \
00789 P99_PASTE2(p99_add, SUFF)(P99_BUILTIN_TYPE(SUFF,) p00_a, P99_BUILTIN_TYPE(SUFF,) p00_b, int* p00_err)
00790 #else
00791 #define P00_DECLARE_OVERFLOW(SUFF) \
00792 P00_DECLARE_TWOS(SUFF) \
00793 P00_DECLARE_UNSIG(SUFF) \
00794 P00_DECLARE_ADD0(SUFF) \
00795 P00_DECLARE_ADD1(SUFF) \
00796 P00_DECLARE_ADD2(SUFF) \
00797 P00_DECLARE_ADD(SUFF) \
00798 P00_DECLARE_SUB0(SUFF) \
00799 P00_DECLARE_SUB1(SUFF) \
00800 P00_DECLARE_SUB2(SUFF) \
00801 P00_DECLARE_SUB(SUFF) \
00802 P99_MACRO_END(p99_overflow_, SUFF)
00803
00804
00805 #define P00_DECLARE_TWOS(SUFF) \
00806 p99_inline \
00807 P99_BUILTIN_TYPE(SUFF) \
00808 P99_PASTE2(p99_twos, SUFF)(P99_BUILTIN_TYPE(u, SUFF) p00_a) { \
00809 P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF); \
00810 P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1); \
00811 \
00812 P99_BUILTIN_TYPE(u, SUFF) const utype_max = (P99_BUILTIN_TYPE(u, SUFF))((2 * type_max) + 1); \
00813 return \
00814
00815
00816 \
00817 (p00_a <= type_max) \
00818 ? p00_a \
00819
00820 \
00821 : (((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) && (p00_a == type_max1)) \
00822 ? (P99_BUILTIN_TYPE(SUFF))(-0) \
00823
00824
00825 \
00826 : (P99_BUILTIN_TYPE(SUFF))((-(P99_BUILTIN_TYPE(SUFF))(utype_max - (utype_max & p00_a))) - 1)); \
00827 }
00828
00829 #define P00_DECLARE_UNSIG(SUFF) \
00830 p99_inline \
00831 P99_BUILTIN_TYPE(u, SUFF) \
00832 P99_PASTE2(p99_unsig, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a) { \
00833 \
00834 register P99_BUILTIN_TYPE(SUFF) const type_null = 0; \
00835 register P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF); \
00836 register P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1); \
00837 \
00838 register P99_BUILTIN_TYPE(u, SUFF) const utype_max = (P99_BUILTIN_TYPE(u, SUFF))((2 * type_max) + 1); \
00839 return \
00840 p00_a >= type_null \
00841 ? p00_a \
00842
00843 \
00844 : (((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) && (p00_a == P99_BUILTIN_MIN(SUFF))) \
00845 ? type_max1 \
00846 \
00847 : (P99_BUILTIN_TYPE(u, SUFF))((utype_max - (P99_BUILTIN_TYPE(u, SUFF))-p00_a) + 1)); \
00848 }
00849
00850 #define P00_DECLARE_ADD0(SUFF) \
00851 p99_inline \
00852 P99_BUILTIN_TYPE(u, SUFF) \
00853 P99_PASTE2(p00_add0, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, P99_BUILTIN_TYPE(SUFF) p00_b) { \
00854 register P99_BUILTIN_TYPE(u, SUFF) p00_ua = P99_PASTE2(p99_unsig, SUFF)(p00_a); \
00855 register P99_BUILTIN_TYPE(u, SUFF) p00_ub = P99_PASTE2(p99_unsig, SUFF)(p00_b); \
00856 register P99_BUILTIN_TYPE(u, SUFF) p00_res = (P99_BUILTIN_TYPE(u, SUFF))(p00_ua + p00_ub); \
00857 return p00_res; \
00858 }
00859
00860 #define P00_DECLARE_SUB0(SUFF) \
00861 p99_inline \
00862 P99_BUILTIN_TYPE(u, SUFF) \
00863 P99_PASTE2(p00_sub0, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, P99_BUILTIN_TYPE(SUFF) p00_b) { \
00864 register P99_BUILTIN_TYPE(u, SUFF) p00_ua = P99_PASTE2(p99_unsig, SUFF)(p00_a); \
00865 register P99_BUILTIN_TYPE(u, SUFF) p00_ub = P99_PASTE2(p99_unsig, SUFF)(p00_b); \
00866 register P99_BUILTIN_TYPE(u, SUFF) p00_res = (P99_BUILTIN_TYPE(u, SUFF))(p00_ua - p00_ub); \
00867 return p00_res; \
00868 }
00869
00870 #define P00_DECLARE_ADD2(SUFF) \
00871 p99_inline \
00872 P99_BUILTIN_TYPE(SUFF) \
00873 P99_PASTE2(p00_add2, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, \
00874 P99_BUILTIN_TYPE(SUFF) p00_b, \
00875 int p00_err[P99_ATLEAST 1]) { \
00876 \
00877 register P99_BUILTIN_TYPE(SUFF) const type_null = 0; \
00878 register P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF); \
00879 register P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1); \
00880 register P99_BUILTIN_TYPE(u, SUFF) p00_uc \
00881 = P99_PASTE2(p00_add0, SUFF)(p00_a, p00_b); \
00882 register P99_BUILTIN_TYPE(SUFF) p00_c \
00883 = P99_PASTE2(p99_twos, SUFF)(p00_uc); \
00884 \
00885 if (P99_UNLIKELY(((p00_a ^ p00_b) >= type_null) && ((p00_b ^ p00_c) < type_null)) \
00886 \
00887 || ((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) \
00888 && (p00_uc == type_max1))) \
00889 p00_err[0] = ERANGE; \
00890 return p00_c; \
00891 }
00892
00893 #define P00_DECLARE_SUB2(SUFF) \
00894 p99_inline \
00895 P99_BUILTIN_TYPE(SUFF) \
00896 P99_PASTE2(p00_sub2, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, \
00897 P99_BUILTIN_TYPE(SUFF) p00_b, \
00898 int p00_err[P99_ATLEAST 1]) { \
00899 \
00900 register P99_BUILTIN_TYPE(SUFF) const type_null = 0; \
00901 register P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF); \
00902 register P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1); \
00903 register P99_BUILTIN_TYPE(u, SUFF) p00_uc \
00904 = P99_PASTE2(p00_sub0, SUFF)(p00_a, p00_b); \
00905 register P99_BUILTIN_TYPE(SUFF) p00_c \
00906 = P99_PASTE2(p99_twos, SUFF)(p00_uc); \
00907 \
00908 if (P99_UNLIKELY(((p00_a ^ p00_b) < type_null) && ((p00_b ^ p00_c) >= type_null)) \
00909 \
00910 || ((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) \
00911 && (p00_uc == type_max1))) \
00912 p00_err[0] = ERANGE; \
00913 return p00_c; \
00914 }
00915
00916 #define P00_DECLARE_ADD1(SUFF) \
00917 p99_inline \
00918 P99_BUILTIN_TYPE(SUFF) \
00919 P99_PASTE2(p00_add1, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, \
00920 P99_BUILTIN_TYPE(SUFF) p00_b, \
00921 int p00_err[P99_ATLEAST 1]) { \
00922 \
00923 register P99_BUILTIN_TYPE(SUFF) const type_null = 0; \
00924 register P99_BUILTIN_TYPE(SUFF) p00_ret; \
00925 if (p00_b >= type_null) { \
00926 if (P99_LIKELY(P99_BUILTIN_MAX(SUFF) - p00_b >= p00_a)) { \
00927 p00_ret = p00_a + p00_b; \
00928 } else { \
00929 p00_ret = ((p00_b - P99_BUILTIN_MAX(SUFF)) + p00_a) - 1; \
00930 p00_err[0] = ERANGE; \
00931 } \
00932 } else { \
00933 if (P99_LIKELY(P99_BUILTIN_MIN(SUFF) - p00_b <= p00_a)) { \
00934 p00_ret = p00_a + p00_b; \
00935 } else { \
00936 p00_ret = ((p00_b + P99_BUILTIN_MAX(SUFF)) + p00_a) + 1; \
00937 p00_err[0] = ERANGE; \
00938 } \
00939 } \
00940 return p00_ret; \
00941 }
00942
00943 #define P00_DECLARE_SUB1(SUFF) \
00944 p99_inline \
00945 P99_BUILTIN_TYPE(SUFF) \
00946 P99_PASTE2(p00_sub1, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, \
00947 P99_BUILTIN_TYPE(SUFF) p00_b, \
00948 int p00_err[P99_ATLEAST 1]) { \
00949 \
00950 register P99_BUILTIN_TYPE(SUFF) const type_null = 0; \
00951 register P99_BUILTIN_TYPE(SUFF) p00_ret; \
00952 if (p00_b <= type_null) { \
00953 if (P99_LIKELY(P99_BUILTIN_MAX(SUFF) + p00_b >= p00_a)) { \
00954 p00_ret = p00_a - p00_b; \
00955 } else { \
00956 p00_ret = (p00_a - (p00_b + P99_BUILTIN_MAX(SUFF))) + 1; \
00957 p00_err[0] = ERANGE; \
00958 } \
00959 } else { \
00960 if (P99_LIKELY(P99_BUILTIN_MIN(SUFF) + p00_b <= p00_a)) { \
00961 p00_ret = p00_a - p00_b; \
00962 } else { \
00963 p00_ret = (p00_a - (p00_b - P99_BUILTIN_MAX(SUFF))) - 1; \
00964 p00_err[0] = ERANGE; \
00965 } \
00966 } \
00967 return p00_ret; \
00968 }
00969
00970 #define P00_DECLARE_ADD(SUFF) \
00971 p99_inline \
00972 P99_BUILTIN_TYPE(SUFF) \
00973 P99_PASTE2(p99_add, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, \
00974 P99_BUILTIN_TYPE(SUFF) p00_b, \
00975 int p00_err[P99_ATLEAST 1]) { \
00976 return \
00977 (P99_BUILTIN_MAX(SUFF) < P99_BUILTIN_MAX(u, SUFF)) \
00978 ? P99_PASTE2(p00_add2, SUFF)(p00_a, p00_b, p00_err) \
00979 : P99_PASTE2(p00_add1, SUFF)(p00_a, p00_b, p00_err); \
00980 }
00981
00982 #define P00_DECLARE_SUB(SUFF) \
00983 p99_inline \
00984 P99_BUILTIN_TYPE(SUFF) \
00985 P99_PASTE2(p99_sub, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, \
00986 P99_BUILTIN_TYPE(SUFF) p00_b, \
00987 int p00_err[P99_ATLEAST 1]) { \
00988 return \
00989 (P99_BUILTIN_MAX(SUFF) < P99_BUILTIN_MAX(u, SUFF)) \
00990 ? P99_PASTE2(p00_sub2, SUFF)(p00_a, p00_b, p00_err) \
00991 : P99_PASTE2(p00_sub1, SUFF)(p00_a, p00_b, p00_err); \
00992 }
00993 #endif
00994
00995 P00_DECLARE_OVERFLOW(c);
00996 P00_DECLARE_OVERFLOW(hh);
00997 P00_DECLARE_OVERFLOW(h);
00998 P00_DECLARE_OVERFLOW();
00999 P00_DECLARE_OVERFLOW(l);
01000 P00_DECLARE_OVERFLOW(ll);
01001
01022 #define P99_INIT { 0 }
01023
01024 #define P00_LVAL(T, ...) ((T){ __VA_ARGS__ })
01025
01039 #define P99_LVAL(...) P99_IF_LE(P99_NARG(__VA_ARGS__),1)(P00_LVAL(__VA_ARGS__, 0))(P00_LVAL(__VA_ARGS__))
01040
01041 #ifdef DOXYGEN
01042
01073 # define P99_RVAL(T, VAL)
01074 #else
01075 # define P99_RVAL(...) \
01076 P99_IF_EQ_1(P99_NARG(__VA_ARGS__)) \
01077 (P00_RVAL1(__VA_ARGS__)) \
01078 (P00_RVAL2(__VA_ARGS__))
01079 #endif
01080
01081 #define P00_RVAL1_(T) (((const struct { int p00_bla1; T p00_T1; }){ .p00_bla1 = 0 }).p00_T1)
01082 #define P00_RVAL2_(T) ((( struct { int p00_bla2; T p00_T2; }){ .p00_bla2 = 0 }).p00_T2)
01083
01084 #define P00_RVAL2(T, ...) (P00_RVAL2_(T) = (__VA_ARGS__))
01085 #define P00_RVAL1(T) P00_RVAL2(T, P00_RVAL1_(T))
01086
01106 #define P99_AVAL(T) P00_RVAL2_(T)
01107
01108
01109 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_CHOOSE5, 0)
01110 #define P99_CHOOSE5(xT, cc, cs, ci, cl, cll) \
01111 ((sizeof(xT) < sizeof(int)) \
01112 ? ((sizeof(xT) < sizeof(short)) \
01113 ? cc \
01114 : cs) \
01115 : ((sizeof(xT) <= sizeof(long)) \
01116 ? ((sizeof(xT) == sizeof(int)) \
01117 ? ci \
01118 : cl) \
01119 : cll))
01120
01121
01122 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_PRI, 0)
01123 #define P99_PRI(xT, F, LEN) \
01124 P99_CHOOSE5(xT, \
01125 "%" #LEN "hh" #F, \
01126 "%" #LEN "h" #F, \
01127 "%" #LEN "" #F, \
01128 "%" #LEN "l" #F, \
01129 "%" #LEN "ll" #F)
01130
01135 #define P00_J(X) (0 ? P99_0(uintmax_t) : (X))
01136
01137
01151 #define P99_HMASK(N,M) (P99_PASTE2(P00_MASK_, N)^P99_PASTE2(P00_MASK_, P99_MINUS(N, M)))
01152
01196 #define P99_LOW2(X) ((X) & -(X))
01197
01201 p99_inline
01202 uintmax_t p99_low2(uintmax_t p00_x) { return P99_LOW2(p00_x); }
01203
01210 #define P99_LOW2MASK1(X) ((X) ^ ((X) - 1))
01211
01215 p99_inline
01216 uintmax_t p99_low2mask1(uintmax_t p00_x) { return P99_LOW2MASK1(p00_x); }
01217
01224 #define P99_LOW2MASK0(X) (~(X) & ((X) - 1))
01225
01229 p99_inline
01230 uintmax_t p99_low2mask0(uintmax_t p00_x) { return P99_LOW2MASK0(p00_x); }
01231
01238 #define P99_MASK2LOW1(X) ((X) | -(X))
01239
01243 p99_inline
01244 uintmax_t p99_mask2low1(uintmax_t p00_x) { return P99_MASK2LOW1(p00_x); }
01245
01252 #define P99_MASK2LOW0(X) ((X) ^ -(X))
01253
01257 p99_inline
01258 uintmax_t p99_mask2low0(uintmax_t p00_x) { return P99_MASK2LOW0(p00_x); }
01259
01265 #define P99_LOW2CLEAR(X) ((X) & ((X) - 1))
01266
01270 p99_inline
01271 uintmax_t p99_low2clear(uintmax_t p00_x) { return P99_LOW2CLEAR(p00_x); }
01272
01278 #define P99_LOW2FILL(X) ((X) | ((X) - 1))
01279
01283 p99_inline
01284 uintmax_t p99_low2fill(uintmax_t p00_x) { return P99_LOW2FILL(p00_x); }
01285
01291 #define P99_LOW0SET(X) ((X) | ((X) + 1))
01292
01296 p99_inline
01297 uintmax_t p99_low0set(uintmax_t p00_x) { return P99_LOW0SET(p00_x); }
01298
01305 #define P99_LOW2SHIFT(X) (P99_LIKELY(!!(X)) ? ((X) / ((X) & -(X))) : 0u)
01306
01310 p99_inline
01311 uintmax_t p99_low2shift(uintmax_t p00_x) { return P99_LOW2SHIFT(p00_x); }
01312
01321 p99_inline
01322 uintmax_t p99_next_popcount(uintmax_t p00_x) {
01323 uintmax_t p00_ret = 0;
01324 if (p00_x) {
01325 uintmax_t p00_b = P99_LOW2(p00_x);
01326 uintmax_t p00_t = p00_x + p00_b;
01327 uintmax_t p00_c = p00_x ^ p00_t;
01328 uintmax_t p00_m = (p00_c >> 2) / p00_b;
01329 p00_ret = p00_t | p00_m;
01330 }
01331 return p00_ret;
01332 }
01333
01345 P99_DECLARE_UNION(p99_endian_2);
01347 P99_DECLARE_UNION(p99_endian_4);
01349 P99_DECLARE_UNION(p99_endian_8);
01351 P99_DECLARE_UNION(p99_endian_16);
01352
01353 typedef uint16_t p00_uint_byte_2;
01354 typedef uint32_t p00_uint_byte_4;
01355 typedef uint64_t p00_uint_byte_8;
01356
01357 union p99_endian_2 {
01358 uint8_t p00_c[2];
01359 uint16_t p00_i;
01360 };
01361
01362 union p99_endian_4 {
01363 uint8_t p00_c[4];
01364 uint32_t p00_i;
01365 };
01366
01367 union p99_endian_8 {
01368 uint8_t p00_c[8];
01369 uint64_t p00_i;
01370 };
01371
01372
01373 #ifdef UINT128_MAX
01374 typedef uint128_t p00_uint_byte_16;
01375
01376 union p99_endian_16 {
01377 uint8_t p00_c[16];
01378 uint128_t p00_i;
01379 };
01380 #else
01381 # ifdef p99x_uint128
01382 typedef p99x_uint128 p00_uint_byte_16;
01383
01384 union p99_endian_16 {
01385 uint8_t p00_c[16];
01386 p99x_uint128 p00_i;
01387 };
01388 # endif
01389 #endif
01390
01391
01392 #define P00_HTON0(N, X, I) [I] = (0xFF & ((X)>>((N - (I + 1))*CHAR_BIT)))
01393 #define P00_HTON(N, X) P99_FOR(N, N, P00_SEQ, P00_HTON0, P99_DUPL(N, X))
01394 #define P99_HTON_INITIALIZER(N, X) { .p00_c = { P00_HTON(N, X) } }
01395
01401 #define P99_HTON(N, X) (((P99_PASTE2(p99_endian_, N) const)P99_HTON_INITIALIZER(N, X)).p00_i)
01402
01409 P00_DOCUMENT_NUMBER_ARGUMENT(P99_HTONS, 0)
01410 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_HTONS, 1)
01411 #define P99_HTONS(X) P99_HTON(2, X)
01412
01419 P00_DOCUMENT_NUMBER_ARGUMENT(P99_HTONL, 0)
01420 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_HTONL, 1)
01421 #define P99_HTONL(X) P99_HTON(4, X)
01422
01423
01424 #define P00_NTOH0(N, X, I) (((P99_PASTE2(p00_uint_byte_, N))((X).p00_c[I]))<<((N - (I + 1))*CHAR_BIT))
01425 #define P00_NTOH(N, X, XX) P99_FOR(N, N, P00_BOR, P00_NTOH0, P99_DUPL(N, XX))
01426 #define P99_NTOH_INITIALIZER(N, X) { .p00_i = (X) }
01427
01433 #define P99_NTOH(N, X) (P99_PASTE2(p00_uint_byte_, N) const)P00_NTOH(N, X, ((P99_PASTE2(p99_endian_, N) const)P99_NTOH_INITIALIZER(N, X)))
01434
01441 P00_DOCUMENT_NUMBER_ARGUMENT(P99_NTOHS, 0)
01442 #define P99_NTOHS(X) P99_NTOH(2, X)
01443
01450 P00_DOCUMENT_NUMBER_ARGUMENT(P99_NTOHL, 0)
01451 #define P99_NTOHL(X) P99_NTOH(4, X)
01452
01453
01454
01464 #endif