00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CU_INT_H
00019 #define CU_INT_H
00020
00021 #include <cu/fwd.h>
00022 #include <cu/conf.h>
00023 #include <cu/debug.h>
00024 #include <stdint.h>
00025
00026 CU_BEGIN_DECLARATIONS
00027
00028
00029
00030 #if CUCONF_SIZEOF_INT == 4
00031 # define CUP_UINT_NAME(prefix, name) prefix##uint32_##name
00032 #elif CUCONF_SIZEOF_INT == 8
00033 # define CUP_UINT_NAME(prefix, name) prefix##uint64_##name
00034 #else
00035 # error Unexpected CUCONF_SIZEOF_INT
00036 #endif
00037
00038 #if CUCONF_SIZEOF_LONG == 4
00039 # define CUP_ULONG_NAME(prefix, name) prefix##uint32_##name
00040 #elif CUCONF_SIZEOF_LONG == 8
00041 # define CUP_ULONG_NAME(prefix, name) prefix##uint64_##name
00042 #else
00043 # error Unexpected CUCONF_SIZEOF_LONG
00044 #endif
00045
00046 #if CUCONF_SIZEOF_INTPTR_T == 4
00047 # define CUP_UINTPTR_NAME(prefix, name) prefix##uint32_##name
00048 #elif CUCONF_SIZEOF_INTPTR_T == 8
00049 # define CUP_UINTPTR_NAME(prefix, name) prefix##uint64_##name
00050 #else
00051 # error Unexpected CUCONF_SIZEOF_UINTPTR_T
00052 #endif
00053
00054 #if CU_WORD_SIZE == 4
00055 # define CUP_WORD_NAME(prefix, name) prefix##uint32_##name
00056 #elif CU_WORD_SIZE == 8
00057 # define CUP_WORD_NAME(prefix, name) prefix##uint64_##name
00058 #else
00059 # error Unexpected CU_WORD_SIZE
00060 #endif
00061
00062
00063 CU_SINLINE int cu_int_min(int x, int y)
00064 { return x < y? x : y; }
00065
00066
00067 CU_SINLINE int cu_int_max(int x, int y)
00068 { return x > y? x : y; }
00069
00070
00071 CU_SINLINE unsigned int cu_uint_min(unsigned int x, unsigned int y)
00072 { return x < y? x : y; }
00073
00074
00075 CU_SINLINE unsigned int cu_uint_max(unsigned int x, unsigned int y)
00076 { return x > y? x : y; }
00077
00078
00079 CU_SINLINE long cu_long_min(long x, long y)
00080 { return x < y? x : y; }
00081
00082
00083 CU_SINLINE long cu_long_max(long x, long y)
00084 { return x > y? x : y; }
00085
00086
00087 CU_SINLINE unsigned long cu_ulong_min(unsigned long x, unsigned long y)
00088 { return x < y? x : y; }
00089
00090
00091 CU_SINLINE unsigned long cu_ulong_max(unsigned long x, unsigned long y)
00092 { return x > y? x : y; }
00093
00094
00095 CU_SINLINE intptr_t cu_intptr_min(intptr_t x, intptr_t y)
00096 { return x < y? x : y; }
00097
00098
00099 CU_SINLINE intptr_t cu_intptr_max(intptr_t x, intptr_t y)
00100 { return x > y? x : y; }
00101
00102
00103 CU_SINLINE uintptr_t cu_uintptr_min(uintptr_t x, uintptr_t y)
00104 { return x < y? x : y; }
00105
00106
00107 CU_SINLINE uintptr_t cu_uintptr_max(uintptr_t x, uintptr_t y)
00108 { return x > y? x : y; }
00109
00110
00111
00112 CU_SINLINE int cu_int_abs(int x) { return x >= 0? x : -x; }
00113
00114
00115 CU_SINLINE long cu_long_abs(long x) { return x >= 0? x : -x; }
00116
00117
00118
00119
00120
00121
00122
00123 CU_SINLINE int cu_int_sgn(int x) { return x < 0? -1 : x > 0? 1 : 0; }
00124
00125
00126 CU_SINLINE int cu_long_sgn(int x) { return x < 0? -1 : x > 0? 1 : 0; }
00127
00128
00129
00130 CU_SINLINE int cu_int_cmp(int x, int y) { return x < y? -1 : x > y? 1 : 0; }
00131
00132
00133
00134 CU_SINLINE int cu_long_cmp(long x, long y) { return x < y? -1 : x > y? 1 : 0; }
00135
00136
00137
00138 CU_SINLINE unsigned int cu_uint_ceil_div(unsigned int x, unsigned int y)
00139 { return (x + y - 1)/y; }
00140
00141
00142 CU_SINLINE unsigned long cu_ulong_ceil_div(unsigned long x, unsigned long y)
00143 { return (x + y - 1)/y; }
00144
00145
00146 uint_fast8_t cu_uint8_dcover(uint_fast8_t x) CU_ATTR_PURE;
00147
00148
00149 uint_fast16_t cu_uint16_dcover(uint_fast16_t x) CU_ATTR_PURE;
00150
00151
00152 uint_fast32_t cu_uint32_dcover(uint_fast32_t x) CU_ATTR_PURE;
00153
00154
00155 uint_fast64_t cu_uint64_dcover(uint_fast64_t x) CU_ATTR_PURE;
00156
00157
00158 CU_SINLINE unsigned int cu_uint_dcover(unsigned int x)
00159 { return CUP_UINT_NAME(cu_,dcover)(x); }
00160
00161
00162 CU_SINLINE unsigned long cu_ulong_dcover(unsigned long x)
00163 { return CUP_ULONG_NAME(cu_,dcover)(x); }
00164
00165
00166 CU_SINLINE uintptr_t cu_uintptr_dcover(uintptr_t x)
00167 { return CUP_UINTPTR_NAME(cu_,dcover)(x); }
00168
00169
00170 CU_SINLINE unsigned int
00171 cu_uint_ucover(unsigned int x) { return x | ~(x - 1); }
00172
00173
00174 CU_SINLINE unsigned long
00175 cu_ulong_ucover(unsigned long x) { return x | ~(x - 1L); }
00176
00177
00178
00179 CU_SINLINE unsigned int
00180 cu_uint_lzeros(unsigned int x) { return ~x & (x - 1); }
00181
00182
00183 CU_SINLINE unsigned long
00184 cu_ulong_lzeros(unsigned long x) { return ~x & (x - 1L); }
00185
00186
00187 CU_SINLINE unsigned int
00188 cu_uint_uzeros(unsigned int x) { return ~cu_uint_dcover(x); }
00189
00190
00191 CU_SINLINE unsigned long
00192 cu_ulong_uzeros(unsigned long x) { return ~cu_ulong_dcover(x); }
00193
00194
00195
00196 CU_SINLINE uint_fast8_t cu_uint8_exp2_ceil_log2(uint_fast8_t x)
00197 { return cu_uint8_dcover(x - 1) + 1; }
00198
00199
00200 CU_SINLINE uint_fast16_t cu_uint16_exp2_ceil_log2(uint_fast16_t x)
00201 { return cu_uint16_dcover(x - 1) + 1; }
00202
00203
00204 CU_SINLINE uint_fast32_t cu_uint32_exp2_ceil_log2(uint_fast32_t x)
00205 { return cu_uint32_dcover(x - UINT32_C(1)) + UINT32_C(1); }
00206
00207
00208 CU_SINLINE uint_fast64_t cu_uint64_exp2_ceil_log2(uint_fast64_t x)
00209 { return cu_uint64_dcover(x - UINT64_C(1)) + UINT64_C(1); }
00210
00211
00212 CU_SINLINE unsigned int
00213 cu_uint_exp2_ceil_log2(unsigned int x)
00214 { return cu_uint_dcover(x - 1) + 1; }
00215
00216
00217 CU_SINLINE unsigned long
00218 cu_ulong_exp2_ceil_log2(unsigned long x)
00219 { return cu_ulong_dcover(x - 1L) + 1L; }
00220
00221
00222
00223 unsigned int cu_uint8_bit_count(uint_fast8_t x) CU_ATTR_PURE;
00224
00225
00226 unsigned int cu_uint16_bit_count(uint_fast16_t x) CU_ATTR_PURE;
00227
00228
00229 unsigned int cu_uint32_bit_count(uint_fast32_t x) CU_ATTR_PURE;
00230
00231
00232 unsigned int cu_uint64_bit_count(uint_fast64_t x) CU_ATTR_PURE;
00233
00234
00235 CU_SINLINE unsigned int cu_uint_bit_count(unsigned int x)
00236 { return CUP_UINT_NAME(cu_,bit_count)(x); }
00237
00238
00239 CU_SINLINE unsigned long cu_ulong_bit_count(unsigned long x)
00240 { return CUP_ULONG_NAME(cu_,bit_count)(x); }
00241
00242
00243
00244
00245 unsigned int cu_uint8_floor_log2(uint_fast8_t x) CU_ATTR_PURE;
00246
00247
00248 unsigned int cu_uint16_floor_log2(uint_fast16_t x) CU_ATTR_PURE;
00249
00250
00251 unsigned int cu_uint32_floor_log2(uint_fast32_t x) CU_ATTR_PURE;
00252
00253
00254 unsigned int cu_uint64_floor_log2(uint_fast64_t x) CU_ATTR_PURE;
00255
00256
00257 CU_SINLINE unsigned int cu_uint_floor_log2(unsigned int x)
00258 { return CUP_UINT_NAME(cu_,floor_log2)(x); }
00259
00260
00261 CU_SINLINE unsigned int cu_ulong_floor_log2(unsigned long x)
00262 { return CUP_ULONG_NAME(cu_,floor_log2)(x); }
00263
00264
00265 unsigned int cu_uint8_ceil_log2(uint_fast8_t x) CU_ATTR_PURE;
00266
00267
00268 unsigned int cu_uint16_ceil_log2(uint_fast16_t x) CU_ATTR_PURE;
00269
00270
00271 unsigned int cu_uint32_ceil_log2(uint_fast32_t x) CU_ATTR_PURE;
00272
00273
00274 unsigned int cu_uint64_ceil_log2(uint_fast64_t x) CU_ATTR_PURE;
00275
00276
00277 CU_SINLINE unsigned int cu_uint_ceil_log2(unsigned int x)
00278 { return CUP_UINT_NAME(cu_, ceil_log2)(x); }
00279
00280
00281 CU_SINLINE unsigned int cu_ulong_ceil_log2(unsigned long x)
00282 { return CUP_ULONG_NAME(cu_, ceil_log2)(x); }
00283
00284
00285 CU_SINLINE unsigned int
00286 cu_uint8_log2_lowbit(uint_fast8_t x)
00287 {
00288 cu_debug_assert(x);
00289 return cu_uint8_bit_count(~x & (x - 1));
00290 }
00291
00292 CU_SINLINE unsigned int
00293 cu_uint16_log2_lowbit(uint_fast16_t x)
00294 {
00295 cu_debug_assert(x);
00296 return cu_uint16_bit_count(~x & (x - 1));
00297 }
00298
00299 CU_SINLINE unsigned int
00300 cu_uint32_log2_lowbit(uint_fast32_t x)
00301 {
00302 cu_debug_assert(x);
00303 return cu_uint32_bit_count(~x & (x - 1));
00304 }
00305
00306 CU_SINLINE unsigned int
00307 cu_uint64_log2_lowbit(uint_fast64_t x)
00308 {
00309 cu_debug_assert(x);
00310 return cu_uint64_bit_count(~x & (x - 1));
00311 }
00312
00313
00314 CU_SINLINE unsigned int
00315 cu_uint_log2_lowbit(unsigned int x)
00316 { return CUP_UINT_NAME(cu_,log2_lowbit)(x); }
00317
00318
00319 CU_SINLINE unsigned int
00320 cu_ulong_log2_lowbit(unsigned long x)
00321 { return CUP_ULONG_NAME(cu_,log2_lowbit)(x); }
00322
00323
00324 CU_SINLINE unsigned int
00325 cu_uintptr_log2_lowbit(uintptr_t x)
00326 { return CUP_UINTPTR_NAME(cu_,log2_lowbit)(x); }
00327
00328
00329
00330
00331
00332 #ifdef CUCONF_WORDS_BIGENDIAN
00333
00334
00335 CU_SINLINE uint16_t cu_uint16_hton(uint16_t i) { return i; }
00336
00337
00338 CU_SINLINE uint32_t cu_uint32_hton(uint32_t i) { return i; }
00339
00340 #else
00341
00342 CU_SINLINE uint16_t cu_uint16_hton(uint16_t i)
00343 {
00344 return (i >> 8) | ((i & 0xff) << 8);
00345 }
00346 CU_SINLINE uint32_t cu_uint32_hton(uint32_t i)
00347 {
00348 return (i >> 24) | ((i & 0xff) << 24)
00349 | ((i & 0xff0000) >> 8) | ((i & 0xff00) << 8);
00350 }
00351
00352 #endif
00353 #define cu_uint16_ntoh cu_uint16_hton
00354 #define cu_uint32_ntoh cu_uint32_hton
00355
00356
00357 CU_END_DECLARATIONS
00358
00359 #endif