P99
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
p99_int.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  2013 Pierre-Nicolas Clauss                                  */
00007 /* (C) copyright  2012 William Morris                                         */
00008 /*                                                                            */
00009 /* This file is free software; it is part of the P99 project.                 */
00010 /* You can redistribute it and/or modify it under the terms of the QPL as     */
00011 /* given in the file LICENSE. It is distributed without any warranty;         */
00012 /* without even the implied warranty of merchantability or fitness for a      */
00013 /* particular purpose.                                                        */
00014 /*                                                                            */
00015 #ifndef     P99_INT_H_
00016 # define    P99_INT_H_
00017 
00036 #include "p99_c99.h"
00037 #include "p99_id.h"
00038 #include "p99_type.h"
00039 
00040 #if P99_COMPILER & (P99_COMPILER_GNU | P99_COMPILER_OPEN64)
00041 # if P99_GCC_VERSION >= 40200UL
00042 #   pragma GCC diagnostic ignored "-Wmissing-braces"
00043 # endif
00044 #endif
00045 
00056 #define P00_DOCUMENT_C2(WIDTH) 
00058 #ifdef UINT16_MAX
00059 P00_DOCUMENT_C2(16)
00060 #define P99X_UINT16_C2(H, L) ((((uint16_t)(uint8_t)H) << 8u) | (uint16_t)(uint8_t)L)
00061 #endif
00062 #ifdef INT16_MAX
00063 P00_DOCUMENT_C2(16)
00064 #define P99X_INT16_C2(H, L) ((((int16_t)(int8_t)H) << 8u) | (int16_t)(int8_t)L)
00065 #endif
00066 #ifdef UINT32_MAX
00067 P00_DOCUMENT_C2(32)
00068 #define P99X_UINT32_C2(H, L) ((((uint32_t)(uint16_t)H) << 16u) | (uint32_t)(uint16_t)L)
00069 #endif
00070 #ifdef INT32_MAX
00071 P00_DOCUMENT_C2(32)
00072 #define P99X_INT32_C2(H, L) ((((int32_t)(int16_t)H) << 16u) | (int32_t)(int16_t)L)
00073 #endif
00074 #ifdef UINT64_MAX
00075 P00_DOCUMENT_C2(64)
00076 #define P99X_UINT64_C2(H, L) ((((uint64_t)(uint32_t)H) << 32u) | (uint64_t)(uint32_t)L)
00077 #endif
00078 #ifdef INT64_MAX
00079 P00_DOCUMENT_C2(64)
00080 #define P99X_INT64_C2(H, L) ((((int64_t)(int32_t)H) << 32u) | (int64_t)(int32_t)L)
00081 #endif
00082 
00083 #ifdef p99x_uint128
00084 P00_DOCUMENT_C2(128)
00085 #define P99X_UINT128_C2(H, L) ((((p99x_uint128)H) << 64u) | (p99x_uint128)L)
00086 #define P99X_UINT128_0 P99X_UINT128_C2(0x0000000000000000, 0x0000000000000000)
00087 #define P99X_UINT128_MAX P99X_UINT128_C2(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF)
00088 #endif
00089 
00090 #ifdef p99x_int128
00091 P00_DOCUMENT_C2(128)
00092 #define P99X_INT128_C2(H, L) ((((p99x_int128)H) << 64u) | (p99x_int128)L)
00093 #define P99X_INT128_MAX P99X_INT128_C2(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF)
00094 #define P99X_INT128_MIN P99X_INT128_C2(0x8000000000000000, 0x0000000000000000)
00095 #endif
00096 
00109 #ifndef p99x_uint128
00110 typedef uintmax_t p99x_uintmax;
00111 #endif
00112 
00125 #ifndef p99x_int128
00126 typedef intmax_t p99x_intmax;
00127 #endif
00128 
00129 #ifdef P00_DOXYGEN
00130 
00141 typedef extendedInt p99x_uint128;
00142 
00154 typedef extendedInt p99x_int128;
00155 #endif
00156 
00157 #ifdef p99x_uintmax
00158 
00159 #define P99X__SIGN_PROMOTE(EXPR)                                                \
00160 ((p99x_uintmax)+P99_SIGN_PROMOTE(P99_UE_MAX(EXPR), (p99x_uintmax)+UINTMAX_MAX))
00161 
00162 #define P99X__SHIFT(EXPR)                                                       \
00163 ((P99_SIGN_PROMOTE(P99_UE_MAX(EXPR), UINTMAX_MAX) > (p99x_uintmax)+UINTMAX_MAX) \
00164  ? 64u                                                                          \
00165  : 0u)
00166 #endif
00167 
00168 #ifndef P99_HIGH2
00169 # if P99_UINTMAX_WIDTH == 64
00170 #  define P99_HIGH2(X)                                         \
00171 ((((X) & P00_B0) ? P00_S0 : 0u)                                \
00172  | (((X) & P00_B1) ? P00_S1 : 0u)                              \
00173  | (((X) & P00_B2) ? P00_S2 : 0u)                              \
00174  | (((X) & P00_B3) ? P00_S3 : 0u)                              \
00175  | (((X) & P00_B4) ? P00_S4 : 0u)                              \
00176  | (((X) & P00_B5) ? P00_S5 : 0u))
00177 # endif
00178 #endif
00179 #ifndef P99_HIGH2
00180 # if P99_UINTMAX_WIDTH <= 128
00181 #  define P99_HIGH2(X)                                         \
00182 ((((X) & P00_B0) ? P00_S0 : 0u)                                \
00183  | (((X) & P00_B1) ? P00_S1 : 0u)                              \
00184  | (((X) & P00_B2) ? P00_S2 : 0u)                              \
00185  | (((X) & P00_B3) ? P00_S3 : 0u)                              \
00186  | (((X) & P00_B4) ? P00_S4 : 0u)                              \
00187  | (((X) & P00_B5) ? P00_S5 : 0u)                              \
00188  | (((X) & P00_B6) ? P00_S6 : 0u))
00189 # endif
00190 #endif
00191 
00192 #ifndef P99X__SHIFT
00193 #define P99X__SHIFT(EXPR) 0
00194 #endif
00195 
00196 #ifndef P99X__SIGN_PROMOTE
00197 #define P99X__SIGN_PROMOTE(EXPR) 0
00198 #endif
00199 
00200 #define P99_HIGH2_1(X) ((X) == P99_UINTMAX_MAX ? P99_UINTMAX_WIDTH : (P99_HIGH2((X) + UINTMAX_C(1))))
00201 
00208 P00_DOCUMENT_TYPE_ARGUMENT(P99_TO_UNSIGNED, 0)
00209 P00_DOCUMENT_MACRO_ARGUMENT(P99_TO_UNSIGNED, 1)
00210 #define P99_TO_UNSIGNED(T, MACRO)                              \
00211 ((uintmax_t)                                                   \
00212  (sizeof(T) < sizeof(signed)                                   \
00213   ? (sizeof(T) == 1u                                           \
00214      ? MACRO(unsigned char)                                    \
00215      : MACRO(unsigned short))                                  \
00216   : (sizeof(T) < sizeof(unsigned long)                         \
00217      ? MACRO(unsigned)                                         \
00218      : (sizeof(T) < sizeof(unsigned long long)                 \
00219         ? MACRO(unsigned long)                                 \
00220         : MACRO(unsigned long long)))))
00221 
00235 #define P99_M1(T) ((T)-1)
00236 
00242 #define P99_M1U(T) (P99_ISSIGNED(T) ? P99_TO_UNSIGNED(T, P99_M1) : P99_C(uintmax_t, P99_M1(T)))
00243 
00244 #define P00_DOCUMENT_SIGNED(X) 
00245 #define P00_DOCUMENT_UNSIGNED(X) 
00278 #define P99_C(T, X) ((T)+(X))
00279 
00280 #define P00_DOCUMENT_CONSTANT(T) 
00282 /* Constants macros for the required typedefs */
00283 
00284 #if !defined(SIZE_C)
00285 P00_DOCUMENT_CONSTANT(size_t)
00286 # define SIZE_C(X) P99_C(size_t, X)
00287 #endif
00288 
00289 #if !defined(PTRDIFF_C)
00290 P00_DOCUMENT_CONSTANT(ptrdiff_t)
00291 # define PTRDIFF_C(X) P99_C(ptrdiff_t, X)
00292 #endif
00293 
00294 #if !defined(WCHAR_C)
00295 P00_DOCUMENT_CONSTANT(wchar_t)
00296 # define WCHAR_C(X) P99_C(wchar_t, X)
00297 #endif
00298 
00299 #if !defined(WINT_C)
00300 P00_DOCUMENT_CONSTANT(wint_t)
00301 # define WINT_C(X) P99_C(wint_t, X)
00302 #endif
00303 
00304 /* Constants macros for the optional typedefs */
00305 
00306 #if defined(SIG_ATOMIC_MAX) && !defined(SIG_ATOMIC_C)
00307 P00_DOCUMENT_CONSTANT(sig_atomic_t)
00308 # define SIG_ATOMIC_C(X) P99_C(sig_atomic_t, X)
00309 #endif
00310 
00311 #if defined(UINTPTR_MAX) && !defined(UINTPTR_C)
00312 P00_DOCUMENT_CONSTANT(uintptr_t)
00313 # define UINTPTR_C(X) P99_C(uintptr_t, X)
00314 #endif
00315 
00316 #if defined(UINTPTR_MAX) && !defined(INTPTR_C)
00317 P00_DOCUMENT_CONSTANT(intptr_t)
00318 # define INTPTR_C(X) P99_C(intptr_t, X)
00319 #endif
00320 
00321 
00322 
00323 
00324 P00_DOCUMENT_SIGNED(0)
00325 #define P99_0(T) P99_C(T, 0)
00326 
00327 P00_DOCUMENT_UNSIGNED(0)
00328 #define P99_0U(T) P99_TO_UNSIGNED(T, P99_0)
00329 
00330 P00_DOCUMENT_SIGNED(1)
00331 #define P99_1(T) P99_C(T, 1)
00332 
00333 P00_DOCUMENT_UNSIGNED(1)
00334 #define P99_1U(T)  P99_TO_UNSIGNED(T, P99_1)
00335 
00336 P00_DOCUMENT_SIGNED(2)
00337 #define P99_2(T) P99_C(T, 2)
00338 
00339 P00_DOCUMENT_UNSIGNED(2)
00340 #define P99_2U(T)  P99_TO_UNSIGNED(T, P99_2)
00341 
00342 P00_DOCUMENT_SIGNED(3)
00343 #define P99_3(T) P99_C(T, 3)
00344 
00345 P00_DOCUMENT_UNSIGNED(3)
00346 #define P99_3U(T)  P99_TO_UNSIGNED(T, P99_3)
00347 
00354 P00_DOCUMENT_TYPE_ARGUMENT(P99_UT_MAX, 0)
00355 #define P99_UT_MAX(T) (P99_M1U(T))
00356 
00368 #define P99_UT_MAX1(T) (P99_UT_MAX(T)/2u)
00369 
00381 #define P00_ST_MIN1(T) (-(T)P99_UT_MAX1(T))
00382 
00398 P00_DOCUMENT_TYPE_ARGUMENT(P99_ISSIGNED, 0)
00399 #define P99_ISSIGNED(T) (P99_M1(T) < P99_1(T))
00400 
00417 #define P99_SIGN_PROMOTE(A, B) (1 ? (A) : (B))
00418 
00419 
00420 #define P00_SEE_PROMOTE 
00422 #define P00_DOCUMENT_PROMOTE(X) 
00424 P00_DOCUMENT_PROMOTE(0)
00425 P00_SEE_PROMOTE
00426 #define P99_PROMOTE_0(EXPR) P99_SIGN_PROMOTE(0, (EXPR))
00427 
00428 P00_DOCUMENT_PROMOTE(1)
00429 P00_SEE_PROMOTE
00430 #define P99_PROMOTE_1(EXPR) P99_SIGN_PROMOTE(1, (EXPR))
00431 
00432 P00_DOCUMENT_PROMOTE(2)
00433 P00_SEE_PROMOTE
00434 #define P99_PROMOTE_2(EXPR) P99_SIGN_PROMOTE(2, (EXPR))
00435 
00436 P00_DOCUMENT_PROMOTE(3)
00437 P00_SEE_PROMOTE
00438 #define P99_PROMOTE_3(EXPR) P99_SIGN_PROMOTE(3, (EXPR))
00439 
00440 P00_DOCUMENT_PROMOTE(0U)
00441 P00_SEE_PROMOTE
00442 #define P99_PROMOTE_0U(EXPR) P99_SIGN_PROMOTE(0U, (EXPR))
00443 
00444 P00_DOCUMENT_PROMOTE(1u)
00445 P00_SEE_PROMOTE
00446 #define P99_PROMOTE_1U(EXPR) P99_SIGN_PROMOTE(1U, (EXPR))
00447 
00448 P00_DOCUMENT_PROMOTE(2u)
00449 P00_SEE_PROMOTE
00450 #define P99_PROMOTE_2U(EXPR) P99_SIGN_PROMOTE(2U, (EXPR))
00451 
00452 
00453 P00_DOCUMENT_PROMOTE(-1)
00454 P00_SEE_PROMOTE
00455 #define P99_PROMOTE_M1(EXPR) P99_SIGN_PROMOTE(-1, (EXPR))
00456 
00461 P00_SEE_PROMOTE
00462 #define P99_PROMOTE_M1U(EXPR) P99_SIGN_PROMOTE(P99_PROMOTE_M1(EXPR), P99_PROMOTE_0U(EXPR))
00463 
00470 P00_SEE_PROMOTE
00471 #define P99_UE_MAX(EXPR) (P99_PROMOTE_M1U(EXPR))
00472 
00484 P00_SEE_PROMOTE
00485 #define P99_UE_MAX1(EXPR) (P99_UE_MAX(EXPR)/P99_PROMOTE_2U(EXPR))
00486 
00487 
00488 #ifdef DOXYGEN
00489 
00503 P00_SEE_PROMOTE
00504 #define P99_EWIDTH(EXPR)
00505 
00509 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMAX, 0)
00510 #define P99_TMAX(T)
00511 
00515 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMIN, 0)
00516 #define P99_TMIN(T)
00517 
00518 #endif
00519 
00520 #ifdef p99x_uintmax
00521 #define P99_EWIDTH(EXPR)                                                                \
00522   (P99X__SHIFT(EXPR)                                                                    \
00523  ? (P99_HIGH2_1((uintmax_t)+(P99_UE_MAX(EXPR)>>P99X__SHIFT(EXPR))) + P99X__SHIFT(EXPR)) \
00524  : P99_HIGH2_1(P99_UE_MAX(EXPR))                                                        \
00525  )
00526 #else
00527 #define P99_EWIDTH(EXPR) P99_HIGH2_1(P99_UE_MAX(EXPR))
00528 #endif
00529 
00541 P00_SEE_PROMOTE
00542 #define P99_EPREC(EXPR) (P99_EWIDTH(EXPR) - P99_SIGNED(EXPR))
00543 
00558 P00_SEE_PROMOTE
00559 #define P99_EPADDING(EXPR) (sizeof(P99_PROMOTE_0(EXPR))*CHAR_BIT - P99_EWIDTH(EXPR))
00560 
00561 #define P99_SE_MAX(EXPR)                                       \
00562 ((((P99_PROMOTE_1(EXPR)                                        \
00563     << (P99_EWIDTH(EXPR) - 2U))                                \
00564    - P99_PROMOTE_1(EXPR))                                      \
00565   << 1U)                                                       \
00566  + P99_PROMOTE_1(EXPR))
00567 
00568 
00580 #define P00_SE_MIN1(EXPR) (-P99_SE_MAX(EXPR))
00581 
00597 P00_SEE_PROMOTE
00598 #define P99_SIGNED(EXPR) (P99_PROMOTE_M1(EXPR) < P99_PROMOTE_1(EXPR))
00599 
00600 
00601 P99_CONST_FUNCTION
00602 p99_inline
00603 uintmax_t p00_abs_signed(intmax_t p00_a) {
00604   uintmax_t p00_aa = p00_a;
00605   /* The minus is taken on the unsigned value, so it gives the
00606      correct result with -INTMAX_MAX, namely INTMAX_MAX, which might
00607      not be representable for two's complement representation. */
00608   return (p00_a < INTMAX_C(0)) ? -p00_aa : p00_a;
00609 }
00610 
00624 #define P99_ABS(EXPR) (P99_SIGNED(EXPR) ? p00_abs_signed(EXPR) : P99_C(uintmax_t, EXPR))
00625 
00626 #if defined(p99x_uintmax) && defined(p99x_intmax)
00627 P99_CONST_FUNCTION
00628 p99_inline
00629 p99x_uintmax p99x__abs_signed(p99x_intmax p00_a) {
00630   p99x_uintmax p00_aa = p00_a;
00631   /* The minus is taken on the unsigned value, so it gives the
00632      correct result with -INTMAX_MAX, namely INTMAX_MAX, which might
00633      not be representable for two's complement representation. */
00634   return (p00_a < (p99x_intmax)0) ? -p00_aa : p00_a;
00635 }
00636 #define P99X_ABS(EXPR) (P99_SIGNED(EXPR) ? p99x__abs_signed(EXPR) : (EXPR))
00637 #endif
00638 
00639 #ifndef P99X_ABS
00640 
00650 # define P99X_ABS P00_ABS
00651 #endif
00652 
00659 typedef enum {
00660   p99_signed_representation_invalid = 0,
00661   p99_signed_representation_magnitude = 1,
00662   p99_signed_representation_ones = 2,
00663   p99_signed_representation_twos = 3,
00664 } p99_signed_representation;
00665 
00674 P00_DOCUMENT_TYPE_ARGUMENT(P99_SIGNED_REPRESENTATION, 0)
00675 #define P99_SIGNED_REPRESENTATION(T) P99_C(p99_signed_representation, (P99_M1(T) & P99_3(T)))
00676 
00677 
00683 #define P99_2COMPLEMENT(T) (P99_SIGNED_REPRESENTATION(T) == p99_signed_representation_twos)
00684 
00685 #ifdef p99x_uintmax
00686 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMAX, 0)
00687 #define P99_TMAX(T)                                                     \
00688 ((T)                                                                    \
00689  (P99X__SHIFT((T)0)                                                     \
00690   ? (P99_ISSIGNED(T) ? P99X__SIGN_PROMOTE((T)-1)/2u : P99_UE_MAX((T)0)) \
00691   : (P99_ISSIGNED(T) ? P99_UT_MAX1(T) : P99_UT_MAX(T))))
00692 
00693 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMIN, 0)
00694 #define P99_TMIN(T)                                                                   \
00695 ((T)                                                                                  \
00696  (P99X__SHIFT((T)0)                                                                   \
00697   ? (P99_ISSIGNED(T) ? (-(P99X__SIGN_PROMOTE((T)-1)/2u)) - P99_2COMPLEMENT(T) : (T)0) \
00698   : (P99_ISSIGNED(T) ? (P00_ST_MIN1(T) - P99_2COMPLEMENT(T)) : P99_0(T))))
00699 #else
00700 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMAX, 0)
00701 #define P99_TMAX(T) P99_C(T, P99_ISSIGNED(T) ? P99_UT_MAX1(T) : P99_UT_MAX(T))
00702 P00_DOCUMENT_TYPE_ARGUMENT(P99_TMIN, 0)
00703 #define P99_TMIN(T) P99_C(T, P99_ISSIGNED(T) ? (P00_ST_MIN1(T) - P99_2COMPLEMENT(T)) : P99_0(T))
00704 #endif
00705 
00706 
00715 #define P99_E_REPRESENTATION(EXPR) ((p99_signed_representation)(P99_PROMOTE_M1(EXPR) & P99_PROMOTE_3(EXPR)))
00716 
00717 
00723 #define P99_E_2COMPLEMENT(EXPR)                                                        \
00724 P99_SIGN_PROMOTE(P99_E_REPRESENTATION(EXPR) == p99_signed_representation_twos, (EXPR))
00725 
00730 #define P99_EMAX(EXPR) (P99_SIGNED(EXPR) ? P99_SE_MAX(EXPR) : P99_PROMOTE_M1(EXPR))
00731 
00736 #define P99_EMIN(EXPR) (P99_SIGNED(EXPR) ? (P00_SE_MIN1(EXPR) - P99_E_2COMPLEMENT(EXPR)) : P99_PROMOTE_0(EXPR))
00737 
00748 #define P99_TPREC(T)                                           \
00749 (P99X__SHIFT((T)-1)                                            \
00750  ? P99_EPREC((T)-1)                                            \
00751  : P99_HIGH2_1(P99_TMAX(T)))
00752 
00765 #define P99_TWIDTH(T) (P99_TPREC(T) + P99_ISSIGNED(T))
00766 
00780 #define P99_TPADDING(T) ((sizeof(T)*CHAR_BIT) - P99_TWIDTH(T))
00781 
00782 #ifdef P00_DOXYGEN
00783 #define P00_DECLARE_OVERFLOW(SUFF)                                                                                                            \
00784                        \
00785  \
00786                                                        \
00787 p99_inline                                                                                                                                    \
00788 P99_BUILTIN_TYPE(SUFF,)                                                                                                                       \
00789 P99_PASTE2(p99_twos, SUFF)(P99_BUILTIN_TYPE(u, SUFF) p00_a);                                                                                  \
00790 p99_inline                                                                                                                                    \
00791 P99_BUILTIN_TYPE(SUFF,)                                                                                                                       \
00792 P99_PASTE2(p99_add, SUFF)(P99_BUILTIN_TYPE(SUFF,) p00_a, P99_BUILTIN_TYPE(SUFF,) p00_b, int* p00_err)
00793 #else
00794 #define P00_DECLARE_OVERFLOW(SUFF)                             \
00795   P00_DECLARE_TWOS(SUFF)                                       \
00796   P00_DECLARE_UNSIG(SUFF)                                      \
00797   P00_DECLARE_ADD0(SUFF)                                       \
00798   P00_DECLARE_ADD1(SUFF)                                       \
00799   P00_DECLARE_ADD2(SUFF)                                       \
00800   P00_DECLARE_ADD(SUFF)                                        \
00801   P00_DECLARE_SUB0(SUFF)                                       \
00802   P00_DECLARE_SUB1(SUFF)                                       \
00803   P00_DECLARE_SUB2(SUFF)                                       \
00804   P00_DECLARE_SUB(SUFF)                                        \
00805 P99_MACRO_END(p99_overflow_, SUFF)
00806 
00807 
00808 #define P00_DECLARE_TWOS(SUFF)                                                                        \
00809 P99_CONST_FUNCTION                                                                                    \
00810 p99_inline                                                                                            \
00811 P99_BUILTIN_TYPE(SUFF)                                                                                \
00812 P99_PASTE2(p99_twos, SUFF)(P99_BUILTIN_TYPE(u, SUFF) p00_a) {                                         \
00813   P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF);                                   \
00814   P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1);              \
00815   /* the unsigned max, as if it had just one value bit more */                                        \
00816   P99_BUILTIN_TYPE(u, SUFF) const utype_max = (P99_BUILTIN_TYPE(u, SUFF))((2 * type_max) + 1);        \
00817   return                                                                                              \
00818     /* for positive values there is nothing to do, this includes the                                  \
00819        case where the unsigned type has the same number of value bits                                 \
00820        as the signed type */                                                                          \
00821     (p00_a <= type_max)                                                                               \
00822     ? p00_a                                                                                           \
00823     /* Capture the special case where type_max1 is a trap                                             \
00824        representation for the signed type */                                                          \
00825     : (((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) && (p00_a == type_max1))                    \
00826        ? (P99_BUILTIN_TYPE(SUFF))(-0)                                                                 \
00827        /* otherwise compute the negative modulo utype_max + 1. for                                    \
00828           the case that the unsigned type is much wider than the                                      \
00829           signed type we mask the higher order bits away. */                                          \
00830        : (P99_BUILTIN_TYPE(SUFF))((-(P99_BUILTIN_TYPE(SUFF))(utype_max - (utype_max & p00_a))) - 1)); \
00831 }
00832 
00833 #define P00_DECLARE_UNSIG(SUFF)                                                                         \
00834 P99_CONST_FUNCTION                                                                                      \
00835 p99_inline                                                                                              \
00836 P99_BUILTIN_TYPE(u, SUFF)                                                                               \
00837 P99_PASTE2(p99_unsig, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a) {                                             \
00838   /* needed to avoid spurious compiler warnings */                                                      \
00839   register P99_BUILTIN_TYPE(SUFF) const type_null = 0;                                                  \
00840   register P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF);                            \
00841   register P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1);       \
00842   /* the unsigned max, as if it had just one value bit more */                                          \
00843   register P99_BUILTIN_TYPE(u, SUFF) const utype_max = (P99_BUILTIN_TYPE(u, SUFF))((2 * type_max) + 1); \
00844   return                                                                                                \
00845     p00_a >= type_null                                                                                  \
00846     ? p00_a                                                                                             \
00847     /* Capture the special case where -INTMAX_MIN can not represented                                   \
00848        in the signed type */                                                                            \
00849     : (((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) && (p00_a == P99_BUILTIN_MIN(SUFF)))          \
00850        ? type_max1                                                                                      \
00851        /* otherwise compute the negative modulo utype_max + 1. */                                       \
00852        : (P99_BUILTIN_TYPE(u, SUFF))((utype_max - (P99_BUILTIN_TYPE(u, SUFF))-p00_a) + 1));             \
00853 }
00854 
00855 #define P00_DECLARE_ADD0(SUFF)                                                               \
00856 P99_CONST_FUNCTION                                                                           \
00857 p99_inline                                                                                   \
00858 P99_BUILTIN_TYPE(u, SUFF)                                                                    \
00859 P99_PASTE2(p00_add0, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, P99_BUILTIN_TYPE(SUFF) p00_b) {     \
00860   register P99_BUILTIN_TYPE(u, SUFF) p00_ua = P99_PASTE2(p99_unsig, SUFF)(p00_a);            \
00861   register P99_BUILTIN_TYPE(u, SUFF) p00_ub = P99_PASTE2(p99_unsig, SUFF)(p00_b);            \
00862   register P99_BUILTIN_TYPE(u, SUFF) p00_res = (P99_BUILTIN_TYPE(u, SUFF))(p00_ua + p00_ub); \
00863   return p00_res;                                                                            \
00864 }
00865 
00866 #define P00_DECLARE_SUB0(SUFF)                                                               \
00867 P99_CONST_FUNCTION                                                                           \
00868 p99_inline                                                                                   \
00869 P99_BUILTIN_TYPE(u, SUFF)                                                                    \
00870 P99_PASTE2(p00_sub0, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a, P99_BUILTIN_TYPE(SUFF) p00_b) {     \
00871   register P99_BUILTIN_TYPE(u, SUFF) p00_ua = P99_PASTE2(p99_unsig, SUFF)(p00_a);            \
00872   register P99_BUILTIN_TYPE(u, SUFF) p00_ub = P99_PASTE2(p99_unsig, SUFF)(p00_b);            \
00873   register P99_BUILTIN_TYPE(u, SUFF) p00_res = (P99_BUILTIN_TYPE(u, SUFF))(p00_ua - p00_ub); \
00874   return p00_res;                                                                            \
00875 }
00876 
00877 #define P00_DECLARE_ADD2(SUFF)                                                                    \
00878 P99_CONST_FUNCTION                                                                                \
00879 p99_inline                                                                                        \
00880 P99_BUILTIN_TYPE(SUFF)                                                                            \
00881      P99_PASTE2(p00_add2, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a,                                     \
00882                                 P99_BUILTIN_TYPE(SUFF) p00_b,                                     \
00883                                 int p00_err[P99_ATLEAST 1]) {                                     \
00884   /* needed to avoid spurious compiler warnings */                                                \
00885   register P99_BUILTIN_TYPE(SUFF) const type_null = 0;                                            \
00886   register P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF);                      \
00887   register P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1); \
00888   register P99_BUILTIN_TYPE(u, SUFF) p00_uc                                                       \
00889     = P99_PASTE2(p00_add0, SUFF)(p00_a, p00_b);                                                   \
00890   register P99_BUILTIN_TYPE(SUFF) p00_c                                                           \
00891     = P99_PASTE2(p99_twos, SUFF)(p00_uc);                                                         \
00892   /* (x ^ y) < 0 iff x and y have different signs */                                              \
00893   if (P99_UNLIKELY(((p00_a ^ p00_b) >= type_null) && ((p00_b ^ p00_c) < type_null))               \
00894       /* capture the case of the trap value */                                                    \
00895       || ((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF))                                       \
00896           && (p00_uc == type_max1)))                                                              \
00897     p00_err[0] = ERANGE;                                                                          \
00898   return p00_c;                                                                                   \
00899 }
00900 
00901 #define P00_DECLARE_SUB2(SUFF)                                                                    \
00902 P99_CONST_FUNCTION                                                                                \
00903 p99_inline                                                                                        \
00904 P99_BUILTIN_TYPE(SUFF)                                                                            \
00905      P99_PASTE2(p00_sub2, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a,                                     \
00906                                 P99_BUILTIN_TYPE(SUFF) p00_b,                                     \
00907                                 int p00_err[P99_ATLEAST 1]) {                                     \
00908   /* needed to avoid spurious compiler warnings */                                                \
00909   register P99_BUILTIN_TYPE(SUFF) const type_null = 0;                                            \
00910   register P99_BUILTIN_TYPE(u, SUFF) const type_max = P99_BUILTIN_MAX(SUFF);                      \
00911   register P99_BUILTIN_TYPE(u, SUFF) const type_max1 = (P99_BUILTIN_TYPE(u, SUFF))(type_max + 1); \
00912   register P99_BUILTIN_TYPE(u, SUFF) p00_uc                                                       \
00913     = P99_PASTE2(p00_sub0, SUFF)(p00_a, p00_b);                                                   \
00914   register P99_BUILTIN_TYPE(SUFF) p00_c                                                           \
00915     = P99_PASTE2(p99_twos, SUFF)(p00_uc);                                                         \
00916   /* (x ^ y) < 0 iff x and y have different signs */                                              \
00917   if (P99_UNLIKELY(((p00_a ^ p00_b) < type_null) && ((p00_b ^ p00_c) >= type_null))               \
00918       /* capture the case of the trap value */                                                    \
00919       || ((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF))                                       \
00920           && (p00_uc == type_max1)))                                                              \
00921     p00_err[0] = ERANGE;                                                                          \
00922   return p00_c;                                                                                   \
00923 }
00924 
00925 #define P00_DECLARE_ADD1(SUFF)                                 \
00926 P99_CONST_FUNCTION                                             \
00927 p99_inline                                                     \
00928 P99_BUILTIN_TYPE(SUFF)                                         \
00929      P99_PASTE2(p00_add1, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a,  \
00930                                 P99_BUILTIN_TYPE(SUFF) p00_b,  \
00931                                 int p00_err[P99_ATLEAST 1]) {  \
00932   /* needed to avoid spurious compiler warnings */             \
00933   register P99_BUILTIN_TYPE(SUFF) const type_null = 0;         \
00934   register P99_BUILTIN_TYPE(SUFF) p00_ret;                     \
00935   if (p00_b >= type_null) {                                    \
00936     if (P99_LIKELY(P99_BUILTIN_MAX(SUFF) - p00_b >= p00_a)) {  \
00937       p00_ret = p00_a + p00_b;                                 \
00938     } else {                                                   \
00939       p00_ret = ((p00_b - P99_BUILTIN_MAX(SUFF)) + p00_a) - 1; \
00940       p00_err[0] = ERANGE;                                     \
00941     }                                                          \
00942   } else {                                                     \
00943     if (P99_LIKELY(P99_BUILTIN_MIN(SUFF) - p00_b <= p00_a)) {  \
00944       p00_ret = p00_a + p00_b;                                 \
00945     } else {                                                   \
00946       p00_ret = ((p00_b + P99_BUILTIN_MAX(SUFF)) + p00_a) + 1; \
00947       p00_err[0] = ERANGE;                                     \
00948     }                                                          \
00949   }                                                            \
00950   return p00_ret;                                              \
00951 }
00952 
00953 #define P00_DECLARE_SUB1(SUFF)                                 \
00954 P99_CONST_FUNCTION                                             \
00955 p99_inline                                                     \
00956 P99_BUILTIN_TYPE(SUFF)                                         \
00957      P99_PASTE2(p00_sub1, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a,  \
00958                                 P99_BUILTIN_TYPE(SUFF) p00_b,  \
00959                                 int p00_err[P99_ATLEAST 1]) {  \
00960   /* needed to avoid spurious compiler warnings */             \
00961   register P99_BUILTIN_TYPE(SUFF) const type_null = 0;         \
00962   register P99_BUILTIN_TYPE(SUFF) p00_ret;                     \
00963   if (p00_b <= type_null) {                                    \
00964     if (P99_LIKELY(P99_BUILTIN_MAX(SUFF) + p00_b >= p00_a)) {  \
00965       p00_ret = p00_a - p00_b;                                 \
00966     } else {                                                   \
00967       p00_ret = (p00_a - (p00_b + P99_BUILTIN_MAX(SUFF))) + 1; \
00968       p00_err[0] = ERANGE;                                     \
00969     }                                                          \
00970   } else {                                                     \
00971     if (P99_LIKELY(P99_BUILTIN_MIN(SUFF) + p00_b <= p00_a)) {  \
00972       p00_ret = p00_a - p00_b;                                 \
00973     } else {                                                   \
00974       p00_ret = (p00_a - (p00_b - P99_BUILTIN_MAX(SUFF))) - 1; \
00975       p00_err[0] = ERANGE;                                     \
00976     }                                                          \
00977   }                                                            \
00978   return p00_ret;                                              \
00979 }
00980 
00981 #define P00_DECLARE_ADD(SUFF)                                  \
00982 P99_CONST_FUNCTION                                             \
00983 p99_inline                                                     \
00984 P99_BUILTIN_TYPE(SUFF)                                         \
00985      P99_PASTE2(p99_add, 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_add2, SUFF)(p00_a, p00_b, p00_err)        \
00991     : P99_PASTE2(p00_add1, SUFF)(p00_a, p00_b, p00_err);       \
00992 }
00993 
00994 #define P00_DECLARE_SUB(SUFF)                                  \
00995 P99_CONST_FUNCTION                                             \
00996 p99_inline                                                     \
00997 P99_BUILTIN_TYPE(SUFF)                                         \
00998      P99_PASTE2(p99_sub, SUFF)(P99_BUILTIN_TYPE(SUFF) p00_a,   \
00999                                P99_BUILTIN_TYPE(SUFF) p00_b,   \
01000                                int p00_err[P99_ATLEAST 1]) {   \
01001   return                                                       \
01002     (P99_BUILTIN_MAX(SUFF) < P99_BUILTIN_MAX(u, SUFF))         \
01003     ? P99_PASTE2(p00_sub2, SUFF)(p00_a, p00_b, p00_err)        \
01004     : P99_PASTE2(p00_sub1, SUFF)(p00_a, p00_b, p00_err);       \
01005 }
01006 #endif
01007 
01008 P00_DECLARE_OVERFLOW(c);
01009 P00_DECLARE_OVERFLOW(hh);
01010 P00_DECLARE_OVERFLOW(h);
01011 P00_DECLARE_OVERFLOW();
01012 P00_DECLARE_OVERFLOW(l);
01013 P00_DECLARE_OVERFLOW(ll);
01014 
01035 #if P99_COMPILER & P99_COMPILER_CLANG
01036 # define P99_INIT                                                  \
01037 _Pragma("GCC diagnostic push")                                     \
01038 _Pragma("GCC diagnostic ignored \"-Wmissing-braces\"")             \
01039 _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \
01040   { 0 }                                                            \
01041 _Pragma("GCC diagnostic pop")
01042 #else
01043 # define P99_INIT { 0 }
01044 #endif
01045 
01046 #define P00_LVAL1(T) ((T)P99_INIT)
01047 #define P00_LVAL(T, ...) ((T){ __VA_ARGS__ })
01048 
01062 #define P99_LVAL(...) P99_IF_LE(P99_NARG(__VA_ARGS__),1)(P00_LVAL1(__VA_ARGS__))(P00_LVAL(__VA_ARGS__))
01063 
01064 #ifdef DOXYGEN
01065 
01096 # define P99_RVAL(T, VAL)
01097 #else
01098 # define P99_RVAL(...)                                         \
01099   P99_IF_EQ_1(P99_NARG(__VA_ARGS__))                           \
01100   (P00_RVAL1(__VA_ARGS__))                                     \
01101   (P00_RVAL2(__VA_ARGS__))
01102 #endif
01103 
01104 #define P00_RVAL1_(T) (((const struct { int p00_bla1; T p00_T1; }){ .p00_bla1 = 0 }).p00_T1)
01105 #define P00_RVAL2_(T) (((      struct { int p00_bla2; T p00_T2; }){ .p00_bla2 = 0 }).p00_T2)
01106 
01107 #define P00_RVAL2(T, ...) (P00_RVAL2_(T) = (__VA_ARGS__))
01108 #define P00_RVAL1(T) P00_RVAL2(T, P00_RVAL1_(T))
01109 
01129 #define P99_AVAL(T) P00_RVAL2_(T)
01130 
01131 
01132 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_CHOOSE5, 0)
01133 #define P99_CHOOSE5(xT, cc, cs, ci, cl, cll)                   \
01134 ((sizeof(xT) < sizeof(int))                                    \
01135  ? ((sizeof(xT) < sizeof(short))                               \
01136     ? cc                                                       \
01137     : cs)                                                      \
01138  : ((sizeof(xT) <= sizeof(long))                               \
01139     ? ((sizeof(xT) == sizeof(int))                             \
01140        ? ci                                                    \
01141        : cl)                                                   \
01142     : cll))
01143 
01144 
01145 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_PRI, 0)
01146 #define P99_PRI(xT, F, LEN)                                    \
01147 P99_CHOOSE5(xT,                                                \
01148             "%" #LEN "hh" #F,                                  \
01149             "%" #LEN "h" #F,                                   \
01150             "%" #LEN "" #F,                                    \
01151             "%" #LEN "l" #F,                                   \
01152             "%" #LEN "ll" #F)
01153 
01158 #define P00_J(X) (0 ? P99_0(uintmax_t) : (X))
01159 
01160 
01174 #define P99_HMASK(N,M) (P99_PASTE2(P00_MASK_, N)^P99_PASTE2(P00_MASK_, P99_MINUS(N, M)))
01175 
01219 #define P99_LOW2(X) ((X) & -(X))
01220 
01224 P99_CONST_FUNCTION
01225 p99_inline
01226 uintmax_t p99_low2(uintmax_t p00_x) { return P99_LOW2(p00_x); }
01227 
01234 #define P99_LOW2MASK1(X) ((X) ^ ((X) - 1))
01235 
01239 P99_CONST_FUNCTION
01240 p99_inline
01241 uintmax_t p99_low2mask1(uintmax_t p00_x) { return P99_LOW2MASK1(p00_x); }
01242 
01249 #define P99_LOW2MASK0(X) (~(X) & ((X) - 1))
01250 
01254 P99_CONST_FUNCTION
01255 p99_inline
01256 uintmax_t p99_low2mask0(uintmax_t p00_x) { return P99_LOW2MASK0(p00_x); }
01257 
01264 #define P99_MASK2LOW1(X) ((X) | -(X))
01265 
01269 P99_CONST_FUNCTION
01270 p99_inline
01271 uintmax_t p99_mask2low1(uintmax_t p00_x) { return P99_MASK2LOW1(p00_x); }
01272 
01279 #define P99_MASK2LOW0(X) ((X) ^ -(X))
01280 
01284 P99_CONST_FUNCTION
01285 p99_inline
01286 uintmax_t p99_mask2low0(uintmax_t p00_x) { return P99_MASK2LOW0(p00_x); }
01287 
01293 #define P99_LOW2CLEAR(X) ((X) & ((X) - 1))
01294 
01298 P99_CONST_FUNCTION
01299 p99_inline
01300 uintmax_t p99_low2clear(uintmax_t p00_x) { return P99_LOW2CLEAR(p00_x); }
01301 
01307 #define P99_LOW2FILL(X) ((X) | ((X) - 1))
01308 
01312 P99_CONST_FUNCTION
01313 p99_inline
01314 uintmax_t p99_low2fill(uintmax_t p00_x) { return P99_LOW2FILL(p00_x); }
01315 
01321 #define P99_LOW0SET(X) ((X) | ((X) + 1))
01322 
01326 P99_CONST_FUNCTION
01327 p99_inline
01328 uintmax_t p99_low0set(uintmax_t p00_x) { return P99_LOW0SET(p00_x); }
01329 
01336 #define P99_LOW2SHIFT(X) (P99_LIKELY(!!(X)) ? ((X) / ((X) & -(X))) : 0u)
01337 
01341 P99_CONST_FUNCTION
01342 p99_inline
01343 uintmax_t p99_low2shift(uintmax_t p00_x) { return P99_LOW2SHIFT(p00_x); }
01344 
01353 P99_CONST_FUNCTION
01354 p99_inline
01355 uintmax_t p99_next_popcount(uintmax_t p00_x) {
01356   uintmax_t p00_ret = 0;
01357   if (p00_x) {
01358     uintmax_t p00_b = P99_LOW2(p00_x);
01359     uintmax_t p00_t = p00_x + p00_b;
01360     uintmax_t p00_c = p00_x ^ p00_t;
01361     uintmax_t p00_m = (p00_c >> 2) / p00_b;
01362     p00_ret = p00_t | p00_m;
01363   }
01364   return p00_ret;
01365 }
01366 
01378 P99_DECLARE_UNION(p00_endian_2);
01380 P99_DECLARE_UNION(p00_endian_4);
01382 P99_DECLARE_UNION(p00_endian_8);
01384 P99_DECLARE_UNION(p00_endian_16);
01385 
01386 typedef uint16_t p00_uint_byte_2;
01387 typedef uint32_t p00_uint_byte_4;
01388 typedef uint64_t p00_uint_byte_8;
01389 
01390 union p00_endian_2 {
01391   uint8_t p00_c[2];
01392   uint16_t p00_i;
01393 };
01394 
01395 union p00_endian_4 {
01396   uint8_t p00_c[4];
01397   uint32_t p00_i;
01398 };
01399 
01400 union p00_endian_8 {
01401   uint8_t p00_c[8];
01402   uint64_t p00_i;
01403 };
01404 
01405 
01406 #ifdef UINT128_MAX
01407 typedef uint128_t p00_uint_byte_16;
01408 
01409 union p00_endian_16 {
01410   uint8_t p00_c[16];
01411   uint128_t p00_i;
01412 };
01413 #else
01414 # ifdef p99x_uint128
01415 typedef p99x_uint128 p00_uint_byte_16;
01416 
01417 union p00_endian_16 {
01418   uint8_t p00_c[16];
01419   p99x_uint128 p00_i;
01420 };
01421 # endif
01422 #endif
01423 
01424 
01425 #define P00_HTON0(N, X, I) [I] = (0xFF & ((X)>>((N - (I + 1))*CHAR_BIT)))
01426 #define P00_HTON(N, X) P99_FOR(N, N, P00_SEQ, P00_HTON0, P99_DUPL(N, X))
01427 #define P99_HTON_INITIALIZER(N, X) { .p00_c = { P00_HTON(N, X) } }
01428 
01434 #define P99_HTON(N, X) (((P99_PASTE2(p00_endian_, N) const)P99_HTON_INITIALIZER(N, X)).p00_i)
01435 
01442 P00_DOCUMENT_NUMBER_ARGUMENT(P99_HTONS, 0)
01443 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_HTONS, 1)
01444 #define P99_HTONS(X) P99_HTON(2, X)
01445 
01452 P00_DOCUMENT_NUMBER_ARGUMENT(P99_HTONL, 0)
01453 P00_DOCUMENT_PERMITTED_ARGUMENT(P99_HTONL, 1)
01454 #define P99_HTONL(X) P99_HTON(4, X)
01455 
01456 
01457 #define P00_NTOH0(N, X, I) (((P99_PASTE2(p00_uint_byte_, N))((X).p00_c[I]))<<((N - (I + 1))*CHAR_BIT))
01458 #define P00_NTOH(N, X, XX) P99_FOR(N, N, P00_BOR, P00_NTOH0, P99_DUPL(N, XX))
01459 #define P99_NTOH_INITIALIZER(N, X) { .p00_i = (X) }
01460 
01466 #define P99_NTOH(N, X) (P99_PASTE2(p00_uint_byte_, N) const)P00_NTOH(N, X, ((P99_PASTE2(p00_endian_, N) const)P99_NTOH_INITIALIZER(N, X)))
01467 
01474 P00_DOCUMENT_NUMBER_ARGUMENT(P99_NTOHS, 0)
01475 #define P99_NTOHS(X) P99_NTOH(2, X)
01476 
01483 P00_DOCUMENT_NUMBER_ARGUMENT(P99_NTOHL, 0)
01484 #define P99_NTOHL(X) P99_NTOH(4, X)
01485 
01486 
01487 
01497 #endif      /* !P99_INT_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines