23 # define P99_CHOICE_H_
33 #define P00_CASE_RETURN(NAME, X, I) case I: return X
35 #define P99_CASE_RETURN(...) P99_FOR(,P99_NARG(__VA_ARGS__), P00_SEP, P00_CASE_RETURN, __VA_ARGS__)
37 #define P99_CHOICE_FUNCTION(TYPE, NAME, DEFAULT, ...) \
44 TYPE NAME(size_t p00_x) { \
46 P99_CASE_RETURN(__VA_ARGS__); \
47 default: return DEFAULT; \
50 P99_MACRO_END(_choice_function_, NAME)
54 2, 3, 5, 7, 11, 13, 17, 19, 23, 31, 37, 41, 43, 47,
55 53, 57, 59, 61, 67, 71);
58 #define P00_UNIQUE_BIT_MULT_3 0x1DU
59 #define P00_UNIQUE_BIT_MULT_4 0xD2FU
60 #define P00_UNIQUE_BIT_MULT_5 0x077CB531U
61 #define P00_UNIQUE_BIT_MULT_6 0X022FDD63CC95386DU
63 #define P00_UNIQUE_BIT_MULT(BITS) P99_PASTE2(P00_UNIQUE_BIT_MULT_, BITS)
65 #define P00_UNIQUE_BIT_HASH(X, BITS, WIDTH) \
66 ((((X) * P00_UNIQUE_BIT_MULT(BITS)) >> (WIDTH - BITS)) \
67 & P99_PASTE3(UINT, WIDTH, _MAX))
69 #define P00_UNIQUE_BIT_(BIT, BITS, WIDTH) \
70 P00_UNIQUE_BIT_HASH(P99_PASTE3(UINT, WIDTH, _C)(1) << BIT, BITS, WIDTH)
73 #define P00_UNIQUE_BIT_RETURN(NAME, X, I) case P00_UNIQUE_BIT_(I, X, NAME): return I
78 #define P00_UNIQUE_BIT_FUNCTION(TYPE, NAME, DEFAULT, BITS, WIDTH) \
80 TYPE P99_PASTE2(NAME, BITS)(size_t p00_x)
82 #define P00_UNIQUE_BIT_FUNCTION(TYPE, NAME, DEFAULT, BITS, WIDTH) \
85 TYPE P99_PASTE2(NAME, BITS)(P99_PASTE3(uint, WIDTH, _t) p00_x) { \
87 P99_FOR(WIDTH, WIDTH, P00_SEP, P00_UNIQUE_BIT_RETURN, P99_DUPL(WIDTH, BITS)); \
88 default: return DEFAULT; \
91 P99_MACRO_END(_unique_bit)
94 P00_UNIQUE_BIT_FUNCTION(
unsigned, p00_unique_bit_hash_, -1, 3, 8);
95 P00_UNIQUE_BIT_FUNCTION(
unsigned, p00_unique_bit_hash_, -1, 4, 16);
96 P00_UNIQUE_BIT_FUNCTION(
unsigned, p00_unique_bit_hash_, -1, 5, 32);
97 P00_UNIQUE_BIT_FUNCTION(
unsigned, p00_unique_bit_hash_, -1, 6, 64);
105 #define P00_UNIQUE_BIT(BITS, WIDTH) \
111 unsigned P99_PASTE2(p99_unique_bit_, WIDTH)(P99_PASTE3(uint, WIDTH, _t) p00_x) { \
115 P99_PASTE2(p00_unique_bit_hash_, BITS) \
116 (P00_UNIQUE_BIT_HASH(p00_x, BITS, WIDTH)); \
123 unsigned P99_PASTE2(p99_unique_bit_checked_, WIDTH)(P99_PASTE3(uint, WIDTH, _t) p00_x) { \
124 unsigned p00_ret = P99_PASTE2(p99_unique_bit_, WIDTH)(p00_x); \
125 return ((P99_PASTE3(UINT, WIDTH, _C)(1) << p00_ret) == p00_x) ? p00_ret : -1; \
127 P99_MACRO_END(_unique_bit)
129 P00_UNIQUE_BIT(3, 8);
130 P00_UNIQUE_BIT(4, 16);
131 P00_UNIQUE_BIT(5, 32);
132 P00_UNIQUE_BIT(6, 64);