#ifndef NONSTD_INTEGRAL_H #define NONSTD_INTEGRAL_H /* The size of data objects. * * This is a numerical quantity, not a bit pattern. Thus it fits into the * signed integer category. This notion conflicts with the definition of * size_t. We provide a signed counterpart, with wrappers for sizeof() and * offsetof() that do bounds checking and convert the result. * * My conjecture is that size_t was chosen to be unsigned to wring the most out * of each available bit on e.g. segmented 16-bit memory architectures. */ // ssize_t comes from special header built by configure script #include "internal/ssize.h" #define size2ssize(n) ((n) > (size_t)SSIZE_MAX ? -1 : (ssize_t)(n)) #define ssize2size(n) ((n) < 0 ? 0U : (size_t)(n)) #define ssizeof(x) size2ssize(sizeof(x)) #define soffsetof(t, m) size2ssize(offsetof((t), (m))) #include #include #include /* Integer bit patterns * * Purpose: bitwise operations and modular arithmetic. * * 6.2.5 * * A computation involving unsigned operands can never overflow, because a * result that cannot be represented by the resulting unsigned integer type * is reduced modulo the number that is one greater than the largest value * that can be represented by the resulting type. * * Each type "bN" is guaranteed to hold at least N bits. * * However, the types must be at least the size of int, or else they will be * silently converted to signed int in any expression, and lose the unsigned * guarantees. * * 6.3.1.1 * * If an int can represent all values of the original type, the value is * converted to an int; otherwise it is converted to an unsigned int. */ typedef unsigned int b16; typedef unsigned long b32; typedef unsigned long long b64; #define B16_MAX UINT_MAX #define B32_MAX ULONG_MAX #define B64_MAX ULLONG_MAX #define B16_C(n) (n ## U) #define B32_C(n) (n ## UL) #define B64_C(n) (n ## ULL) #define PRIdB16 "%u" #define PRIdB32 "%lu" #define PRIdB64 "%llu" /* Regular (signed) integers * * Purpose: normal arithmetical operations and measurement, without modular * arithmetic expectations. * * Care is required with these types to avoid overflow, which is undefined * behavior. * * Each type "iN" is guaranteed to hold at least N bits, but may be wider if * that would be faster for the processor. The "_trim" variety attempts to save * space for e.g. big arrays. */ typedef int i8; typedef signed char i8_trim; typedef int i16; typedef short i16_trim; typedef long i32; typedef int_least32_t i32_trim; typedef long long i64; typedef int_least64_t i64_trim; #define I8_MIN INT_MIN #define I8_MAX INT_MAX #define I8_TRIM_MIN SCHAR_MIN #define I8_TRIM_MAX SCHAR_MAX #define I16_MIN INT_MIN #define I16_MAX INT_MAX #define I16_TRIM_MIN SHRT_MIN #define I16_TRIM_MAX SHRT_MAX #define I32_MIN LONG_MIN #define I32_MAX LONG_MAX #define I32_TRIM_MIN INT_LEAST32_MIN #define I32_TRIM_MAX INT_LEAST32_MAX #define I64_MIN LLONG_MIN #define I64_MAX LLONG_MAX #define I64_TRIM_MIN INT_LEAST64_MIN #define I64_TRIM_MAX INT_LEAST64_MAX #define I8_C(n) (n) #define I16_C(n) (n) #define I32_C(n) (n ## L) #define I64_C(n) (n ## LL) #define PRIdI8 "%d" #define PRIdI8_TRIM "%hh" #define PRIdI16 "%d" #define PRIdI16_TRIM "%h" #define PRIdI32 "%ld" #define PRIdI32_TRIM PRIdLEAST32 #define PRIdI64 "%lld" #define PRIdI64_TRIM PRIdLEAST64 /* Character types ********************************************************/ /* Character type 1: Smallest units of addressible storage. * * Purpose: load and store the raw aliased bytes of a C object. it's a rare * situation, used inside functions like memcpy or fwrite. Also, due to signed * integer promotion, this type shouldn't be used in arithmetic operations. * * 6.2.6.1 * * Values stored in unsigned bit-fields *and objects of type unsigned char* * shall be represented using a pure binary notation. * * Values stored in non-bit-field objects of any other object type consist of n * x CHAR_BIT bits, where n is the size of an object of that type, in bytes. * The value may be copied into an object of type unsigned char [n] (e.g., by * memcpy); the resulting set of bytes is called the object representation of * the value. * * 6.2.6.2 * * For unsigned integer types *other than unsigned char,* the bits of the * object representation shall be divided into two groups: value bits and * padding bits (there need not be any of the latter). */ typedef unsigned char raw_byte; /* Character type 2: Codepoints in a character encoding. * * The tasks of human language processing are too broad for a base language * library, and the rules change as languages and locales do. Use a proper * library for this, such as ICU, and its provided data types. * * - Note: pointers to native C string literals should be char*, as the * signedness of char is implementation-defined. */ // No extra definitions for codepoints /* Character type 3: Small integers. * * Already covered with i8 and i8_trim. */ // No extra definitions for small integers #endif