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 of parts copied from previous work and as explicitly stated below, */
00004 /* the author and copyright holder for this work is                          */
00005 /* (C) copyright  2010-2012 Jens Gustedt, INRIA, France                      */
00006 /*                                                                           */
00007 /* This file is free software; it is part of the P99 project.                */
00008 /* You can redistribute it and/or modify it under the terms of the QPL as    */
00009 /* given in the file LICENSE. It is distributed without any warranty;        */
00010 /* without even the implied warranty of merchantability or fitness for a     */
00011 /* particular purpose.                                                       */
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 /* Constants macros for the required typedefs */
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 /* Constants macros for the optional typedefs */
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   /* The minus is taken on the unsigned value, so it gives the
00604      correct result with -INTMAX_MAX, namely INTMAX_MAX, which might
00605      not be representable for two's complement representation. */
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   /* The minus is taken on the unsigned value, so it gives the
00629      correct result with -INTMAX_MAX, namely INTMAX_MAX, which might
00630      not be representable for two's complement representation. */
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   /* the unsigned max, as if it had just one value bit more */                                        \
00812   P99_BUILTIN_TYPE(u, SUFF) const utype_max = (P99_BUILTIN_TYPE(u, SUFF))((2 * type_max) + 1);        \
00813   return                                                                                              \
00814     /* for positive values there is nothing to do, this includes the                                  \
00815        case where the unsigned type has the same number of value bits                                 \
00816        as the signed type */                                                                          \
00817     (p00_a <= type_max)                                                                               \
00818     ? p00_a                                                                                           \
00819     /* Capture the special case where type_max1 is a trap                                             \
00820        representation for the signed type */                                                          \
00821     : (((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) && (p00_a == type_max1))                    \
00822        ? (P99_BUILTIN_TYPE(SUFF))(-0)                                                                 \
00823        /* otherwise compute the negative modulo utype_max + 1. for                                    \
00824           the case that the unsigned type is much wider than the                                      \
00825           signed type we mask the higher order bits away. */                                          \
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   /* needed to avoid spurious compiler warnings */                                                      \
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   /* the unsigned max, as if it had just one value bit more */                                          \
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     /* Capture the special case where -INTMAX_MIN can not represented                                   \
00843        in the signed type */                                                                            \
00844     : (((P99_BUILTIN_MIN(SUFF) == -P99_BUILTIN_MAX(SUFF)) && (p00_a == P99_BUILTIN_MIN(SUFF)))          \
00845        ? type_max1                                                                                      \
00846        /* otherwise compute the negative modulo utype_max + 1. */                                       \
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   /* needed to avoid spurious compiler warnings */                                                \
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   /* (x ^ y) < 0 iff x and y have different signs */                                              \
00885   if (P99_UNLIKELY(((p00_a ^ p00_b) >= type_null) && ((p00_b ^ p00_c) < type_null))               \
00886       /* capture the case of the trap value */                                                    \
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   /* needed to avoid spurious compiler warnings */                                                \
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   /* (x ^ y) < 0 iff x and y have different signs */                                              \
00908   if (P99_UNLIKELY(((p00_a ^ p00_b) < type_null) && ((p00_b ^ p00_c) >= type_null))               \
00909       /* capture the case of the trap value */                                                    \
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   /* needed to avoid spurious compiler warnings */             \
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   /* needed to avoid spurious compiler warnings */             \
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      /* !P99_INT_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines