]> begriffs open source - libnonstd/blob - integral.h
initial
[libnonstd] / integral.h
1 #ifndef LIBNONSTD_INTEGRAL_H
2 #define LIBNONSTD_INTEGRAL_H
3
4 #include <limits.h>
5 #include <stddef.h>
6 #include <stdint.h>
7
8 /* C object representation type
9  *
10  * Use: access and manipulate the raw bytes of a C object.
11  *
12  * 6.2.6.1
13  *
14  * Values stored in unsigned bit-fields *and objects of type unsigned char*
15  * shall be represented using a pure binary notation.
16  *
17  * Values stored in non-bit-field objects of any other object type consist of n
18  * x CHAR_BIT bits, where n is the size of an object of that type, in bytes.
19  * The value may be copied into an object of type unsigned char [n] (e.g., by
20  * memcpy); the resulting set of bytes is called the object representation of
21  * the value.
22  *
23  * 6.2.6.2
24  *
25  * For unsigned integer types *other than unsigned char,* the bits of the
26  * object representation shall be divided into two groups: value bits and
27  * padding bits (there need not be any of the latter).
28  */
29
30 typedef unsigned char byte;
31
32 /* Integer bit patterns
33  *
34  * Usage: bitwise operations and modular arithmetic, with exact bit widths.
35  *
36  * 6.2.5
37  *
38  * A computation involving unsigned operands can never overflow, because a
39  * result that cannot be represented by the resulting unsigned integer type is
40  * reduced modulo the number that is one greater than the largest value that
41  * can be represented by the resulting type.
42  */
43
44 typedef uint8_t       b8;
45 typedef uint16_t      b16;
46 typedef uint32_t      b32;
47 typedef uint64_t      b64;
48
49 /* General-purpose (signed) integers
50  *
51  * Usage: normal arithmetical operations and measurement, without modular
52  * arithmetic expectations.
53  *
54  * Care is required with these types to avoid overflow, which is undefined
55  * behavior.
56  *
57  * Each type "iN" is guaranteed to hold at least N bits, but may be wider if
58  * that would be faster for the processor. The "_trim" variety attempts to save
59  * space for e.g. big arrays.
60  */
61
62 typedef int_fast8_t   i8;
63 typedef int_least8_t  i8_trim;
64
65 typedef int_fast16_t  i16;      // int
66 typedef int_least16_t i16_trim; // short
67
68 typedef int_fast32_t  i32;      // long
69 typedef int_least32_t i32_trim;
70
71 typedef int_fast64_t  i64;      // long long
72 typedef int_least64_t i64_trim;
73
74 /* The size of data objects.
75  *
76  * This is a numerical quantity, not a bit pattern. Thus it fits into the
77  * signed integer category. This notion conflicts with the definition of
78  * size_t. We provide a signed counterpart, and wrappers for sizeof() and
79  * offsetof() that do bounds checking and conver the result.
80  *
81  * My conjecture is that size_t was chosen to be unsigned to wring the most out
82  * of each available bit on e.g. segmented 16-bit memory architectures. A 64K
83  * object size limit was bad enough, and a 32K limit would be intolerable.
84  */
85
86 #ifdef HAVE_SSIZE_T
87         // get ssize_t from POSIX
88         #include <sys/types.h>
89 #else
90         // make our best approximation
91         typedef ptrdiff_t ssize_t;
92         #define SSIZE_MAX PTRDIFF_MAX
93 #endif
94
95 #define ssizeof(x) \
96         (sizeof(x) <= (size_t)SSIZE_MAX ? (ssize_t)sizeof(x) : -1)
97
98 #define soffsetof(t, m) \
99         (offsetof((t), (m)) <= (size_t)SSIZE_MAX ? offsetof((t), (m)) : -1)
100
101 /* Character types -- no extras provided. They are either out of scope for a
102  * base library, or are redundant with the types above. Here are the three uses
103  * of char:
104  *
105  * 1. Codepoints in a character encoding. The tasks of human language
106  *    processing are too broad for a base language library, and the rules
107  *    change as languages and locales do. Use a proper library for this, such
108  *    as ICU, and its provided data types.
109  *    
110  *    - Storage and transmission of UTF-8 can use b8.
111  *
112  *    - Pointers to native C string literals should be char*, as the signedness
113  *      of char is implementation-defined.
114  *
115  * 2. Smallest units of addressible storage. We covered this case already with
116  *    the byte type.
117  *
118  * 3. Small integers. Already covered with b8, i8, and i8_trim.
119  */
120
121 // Character typedefs intentionally left blank
122
123 #endif