1/* Copyright 2026 uint (and contributors)
2
3Permission to use, copy, modify, and distribute this software for any
4purpose with or without fee is hereby granted, provided that the above
5copyright notice and this permission notice appear in all copies.
6
7THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15/* Guidance:
16 If you want to use the shorthand type names (eg u8 instead of ule_u8), you
17 must define ULE_SHORT_TYPE_NAMES before including this header.
18
19 If you want to define your own pointer types, you must define ULE_UPTR_TYPE
20 and ULE_IPTR_TYPE before including this header. */
21
22#ifndef ULETYPES_H
23#define ULETYPES_H
24
25#include <limits.h>
26#include <stddef.h>
27
28#if CHAR_BIT != 8
29 #error "libule: 8-bit bytes are required"
30#endif
31
32/* 8-bit */
33typedef unsigned char ule_u8;
34typedef signed char ule_i8;
35
36/* 16-bit */
37#if USHRT_MAX == 0xFFFFU
38 typedef unsigned short ule_u16;
39 typedef signed short ule_i16;
40 #define ULE_I16_MAX ((ule_i16)SHRT_MAX)
41 #define ULE_I16_MIN ((ule_i16)SHRT_MIN)
42#elif UINT_MAX == 0xFFFFU
43 typedef unsigned int ule_u16;
44 typedef signed int ule_i16;
45 #define ULE_I16_MAX ((ule_i16)INT_MAX)
46 #define ULE_I16_MIN ((ule_i16)INT_MIN)
47#else
48 #error "libule: no 16-bit integer type"
49#endif
50
51/* 32-bit */
52#if UINT_MAX == 0xFFFFFFFFUL
53 typedef unsigned int ule_u32;
54 typedef signed int ule_i32;
55 #define ULE_I32_MAX ((ule_i32)INT_MAX)
56 #define ULE_I32_MIN ((ule_i32)INT_MIN)
57#elif ULONG_MAX == 0xFFFFFFFFUL
58 typedef unsigned long ule_u32;
59 typedef signed long ule_i32;
60 #define ULE_I32_MAX ((ule_i32)LONG_MAX)
61 #define ULE_I32_MIN ((ule_i32)LONG_MIN)
62#elif USHRT_MAX == 0xFFFFFFFFUL
63 typedef unsigned short ule_u32;
64 typedef signed short ule_i32;
65 #define ULE_I32_MAX ((ule_i32)SHRT_MAX)
66 #define ULE_I32_MIN ((ule_i32)SHRT_MIN)
67#else
68 #error "libule: no 32-bit integer type"
69#endif
70
71/* 64-bit */
72#if ULONG_MAX > 0xFFFFFFFFUL
73 typedef unsigned long ule_u64;
74 typedef signed long ule_i64;
75 #define ULE_I64_MAX ((ule_i64)LONG_MAX)
76 #define ULE_I64_MIN ((ule_i64)LONG_MIN)
77 #define ULE_HAS_64 1
78#elif defined(_WIN64)
79 typedef size_t ule_u64;
80 typedef ptrdiff_t ule_i64;
81 #define ULE_HAS_64 1
82 #define ULE_I64_TWOS_COMPLEMENT 1
83#endif
84
85typedef char ule_check_u8[(sizeof(ule_u8) * CHAR_BIT == 8) ? 1 : -1];
86typedef char ule_check_i8[(sizeof(ule_i8) * CHAR_BIT == 8) ? 1 : -1];
87typedef char ule_check_u16[(sizeof(ule_u16) * CHAR_BIT == 16) ? 1 : -1];
88typedef char ule_check_i16[(sizeof(ule_i16) * CHAR_BIT == 16) ? 1 : -1];
89typedef char ule_check_u32[(sizeof(ule_u32) * CHAR_BIT == 32) ? 1 : -1];
90typedef char ule_check_i32[(sizeof(ule_i32) * CHAR_BIT == 32) ? 1 : -1];
91
92#ifdef ULE_HAS_64
93 typedef char ule_check_u64[(sizeof(ule_u64) * CHAR_BIT == 64) ? 1 : -1];
94 typedef char ule_check_i64[(sizeof(ule_i64) * CHAR_BIT == 64) ? 1 : -1];
95#endif /* ULE_HAS_64 */
96
97/* Pointer Length Sizes */
98#if defined(ULE_UPTR_TYPE) != defined(ULE_IPTR_TYPE)
99 #error "libule: define both ULE_UPTR_TYPE and ULE_IPTR_TYPE"
100#endif
101
102#if defined(ULE_UPTR_TYPE)
103 typedef ULE_UPTR_TYPE ule_uptr;
104 typedef ULE_IPTR_TYPE ule_iptr;
105
106#elif defined(_WIN64) || defined(_WIN32) || \
107 defined(__LP64__) || defined(_LP64) || \
108 defined(__ILP32__) || defined(_ILP32)
109 typedef size_t ule_uptr;
110 typedef ptrdiff_t ule_iptr;
111
112#else
113 #error "libule: define ULE_UPTR_TYPE and ULE_IPTR_TYPE for this target"
114#endif
115
116typedef char ule_check_uptr[(sizeof(ule_uptr) == sizeof(void*)) ? 1 : -1];
117typedef char ule_check_iptr[(sizeof(ule_iptr) == sizeof(void*)) ? 1 : -1];
118
119/* Limits */
120#define ULE_U8_MAX ((ule_u8)0xFFU)
121#define ULE_I8_MAX ((ule_i8)SCHAR_MAX)
122#define ULE_I8_MIN ((ule_i8)SCHAR_MIN)
123
124#define ULE_U16_MAX ((ule_u16)0xFFFFU)
125#define ULE_U32_MAX ((ule_u32)0xFFFFFFFFUL)
126
127#ifdef ULE_HAS_64
128 #define ULE_U64_MAX ((ule_u64)-1)
129
130 #ifdef ULE_I64_TWOS_COMPLEMENT
131 #define ULE_I64_MAX ((ule_i64)(ULE_U64_MAX >> 1))
132 #define ULE_I64_MIN ((ule_i64)(-ULE_I64_MAX - 1))
133 #endif /* ULE_I64_TWOS_COMPLEMENT */
134#endif /* ULE_HAS_64 */
135
136/* Size types */
137typedef size_t ule_usize;
138typedef ptrdiff_t ule_isize;
139
140/* (Optional) Short names */
141#ifdef ULE_SHORT_TYPE_NAMES
142 typedef ule_u8 u8;
143 typedef ule_i8 i8;
144 typedef ule_u16 u16;
145 typedef ule_i16 i16;
146 typedef ule_u32 u32;
147 typedef ule_i32 i32;
148
149 #ifdef ULE_HAS_64
150 typedef ule_u64 u64;
151 typedef ule_i64 i64;
152 #endif /* ULE_HAS_64 */
153
154 typedef ule_uptr uptr;
155 typedef ule_iptr iptr;
156 typedef ule_usize usize;
157 typedef ule_isize isize;
158#endif /* ULE_SHORT_TYPE_NAMES */
159
160#endif /* ULETYPES_H */
161