acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
number.h
1#pragma once
2
3
4//#include <limits.h>
5
6
7/* Definition of minimum-width integer types
8*
9* ::u8 -> ::u32 integer type, at least 8 bits, equivalent to uchar
10* ::u16 -> ::u32 integer type, at least 16 bits
11* ::u32 -> ::u32 integer type, at least 32 bits
12*
13* s8, s16, s32 -> signed counterparts of ::u8, ::u16, ::u32
14*
15* Always use macro's T8(), T16() or T32() to obtain exact-width results,
16* i.e., to specify the i32_size of the result of each expression.
17*/
18
19/*typedef ::i8 s8;
20typedef uchar uch;
21
22#if UINT_MAX >= 4294967295UL
23
24typedef ::i16 s16;
25typedef ::i32 s32;
26typedef ::u16 ush;
27typedef ::u32 ::u32;
28
29#define ONE32 0xffffffffU
30
31#else
32
33typedef ::i32 s16;
34typedef signed long s32;
35typedef ::u32 ::u16;
36typedef ::u32 long ::u32;
37
38#define ONE32 0xffffffffUL
39
40#endif*/
41
42#if UINT_MAX >= 4294967295UL
43
44#define ALLONES32 0xffffffffU
45
46#else
47
48#define ALLONES32 0xffffffffUL
49
50#endif
51
52#define ALLONES8 0xffU
53#define ALLONES16 0xffffU
54
55#define CLIP8(x) ((x) & ALLONES8)
56#define CLIP16(x) ((x) & ALLONES16)
57#define CLIP32(x) ((x) & ALLONES32)
58
59#ifdef _MSC_VER
60//typedef ::u64 ::u64;
61//typedef ::i64 s64;
62#define ULL(v) (v##ui64)
63#define ALLONES64 ULL(0xffffffffffffffff)
64#else /* !_MSC_VER */
65//typedef ::u32 ::i64 ::u64;
66//typedef signed ::i64 s64;
67#define ULL(v) (v##ULL)
68#define ALLONES64 ULL(0xffffffffffffffff)
69#endif /* ?_MSC_VER */
70#define CLIP64(x) ((x) & ONE64)
71#define ROTR64(v, n) (((v) >> (n)) | CLIP64((v) << (64 - (n))))
72/*
73* Note: the test is used to detect native 64-bit architectures;
74* if the ::u32 long is strictly greater than 32-bit, it is
75* assumed to be at least 64-bit. This will not work correctly
76* on (old) 36-bit architectures (PDP-11 for instance).
77*
78* On non-64-bit architectures, "::i64" is used.
79*/
80
81/*
82* U8TO32_BIG(c) returns the 32-bit value stored in big-endian convention
83* in the uchar array pointed to by c.
84*/
85#define U8TO32_BIG(c) (((::u32)CLIP8(*(c)) << 24) | ((::u32)CLIP8(*((c) + 1)) << 16) | ((::u32)CLIP8(*((c) + 2)) << 8) | ((::u32)CLIP8(*((c) + 3))))
86
87/*
88* U8TO32_LITTLE(c) returns the 32-bit value stored in little-endian convention
89* in the uchar array pointed to by c.
90*/
91#define U8TO32_LITTLE(c) (((::u32)CLIP8(*(c))) | ((::u32)CLIP8(*((c) + 1)) << 8) | (::u32)CLIP8(*((c) + 2)) << 16) | ((::u32)CLIP8(*((c) + 3)) << 24))
92
93/*
94* U8TO32_BIG(c, v) stores the 32-bit-value v in big-endian convention
95* into the uchar array pointed to by c.
96*/
97#define U32TO8_BIG(c, v) do { ::u32 x = (v); ::u8 *d = (c); d[0] = CLIP8(x >> 24); d[1] = CLIP8(x >> 16); d[2] = CLIP8(x >> 8); d[3] = CLIP8(x); } while (0)
98
99/*
100* U8TO32_LITTLE(c, v) stores the 32-bit-value v in little-endian convention
101* into the uchar array pointed to by c.
102*/
103#define U32TO8_LITTLE(c, v) do { ::u32 x = (v); ::u8 *d = (c); d[0] = CLIP8(x); d[1] = CLIP8(x >> 8); d[2] = CLIP8(x >> 16); d[3] = CLIP8(x >> 24); } while (0)
104
105/*
106* ROTL32(v, n) returns the value of the 32-bit ::u32 value v after
107* a rotation of n bits to the left. It might be replaced by the appropriate
108* architecture-specific macro.
109*
110* It evaluates v and n twice.
111*
112* The compiler might emit a warning if n is the constant 0. The result
113* is undefined if n is greater than 31.
114*/
115#define ROTL32(v, n) (CLIP32((v) << (n)) | ((v) >> (32 - (n))))