1 | /* |
1 | /* |
2 | * libecb |
2 | * libecb |
3 | * |
3 | * |
4 | * Copyright (©) 2009-2011 Marc Alexander Lehmann |
4 | * Copyright (©) 2009-2011 Marc Alexander Lehmann |
|
|
5 | * Copyright (©) 2011 Emanuele Giaquinta |
5 | * All rights reserved. |
6 | * All rights reserved. |
6 | * |
7 | * |
7 | * Redistribution and use in source and binary forms, with or without modifica- |
8 | * Redistribution and use in source and binary forms, with or without modifica- |
8 | * tion, are permitted provided that the following conditions are met: |
9 | * tion, are permitted provided that the following conditions are met: |
9 | * |
10 | * |
… | |
… | |
26 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
28 | */ |
28 | |
29 | |
29 | #ifndef ECB_H |
30 | #ifndef ECB_H |
30 | #define ECB_H |
31 | #define ECB_H |
|
|
32 | |
|
|
33 | #include <inttypes.h> |
31 | |
34 | |
32 | #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) |
35 | #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) |
33 | |
36 | |
34 | #ifndef __cplusplus |
37 | #ifndef __cplusplus |
35 | # if __STDC_VERSION__ >= 199901L |
38 | # if __STDC_VERSION__ >= 199901L |
… | |
… | |
79 | #endif |
82 | #endif |
80 | |
83 | |
81 | /* put into ifs if you are very sure that the expression */ |
84 | /* put into ifs if you are very sure that the expression */ |
82 | /* is mostly true or mosty false. note that these return */ |
85 | /* is mostly true or mosty false. note that these return */ |
83 | /* booleans, not the expression. */ |
86 | /* booleans, not the expression. */ |
84 | #define ecb_expect_false(expr) ecb_expect ((expr) ? 1 : 0, 0) |
87 | #define ecb_unlikely(expr) ecb_expect ((expr) ? 1 : 0, 0) |
85 | #define ecb_expect_true(expr) ecb_expect ((expr) ? 1 : 0, 1) |
88 | #define ecb_likely(expr) ecb_expect ((expr) ? 1 : 0, 1) |
86 | |
89 | |
87 | /* try to tell the compiler that some condition is definitely true */ |
90 | /* try to tell the compiler that some condition is definitely true */ |
88 | #define ecb_assume(cond) do { if (!(cond)) unreachable (); } while (0) |
91 | #define ecb_assume(cond) do { if (!(cond)) unreachable (); } while (0) |
89 | |
92 | |
90 | /* count trailing zero bits and count # of one bits */ |
93 | /* count trailing zero bits and count # of one bits */ |
91 | #if ECB_GCC_VERSION(3,4) |
94 | #if ECB_GCC_VERSION(3,4) |
92 | ECB_HEADER_INLINE int ecb_ctz32 (unsigned int x) { return __builtin_ctz (x); } |
95 | ECB_HEADER_INLINE int ecb_ctz32 (uint32_t x) { return __builtin_ctz (x); } |
93 | ECB_HEADER_INLINE int ecb_popcount32 (unsigned int x) { return __builtin_popcount (x); } |
96 | ECB_HEADER_INLINE int ecb_popcount32 (uint32_t x) { return __builtin_popcount (x); } |
94 | #else |
97 | #else |
95 | ECB_HEADER_INLINE |
98 | ECB_HEADER_INLINE |
96 | ecb_ctz32 (unsigned int x) ecb_const |
99 | ecb_ctz32 (uint32_t x) ecb_const |
97 | { |
100 | { |
98 | int r = 0; |
101 | int r = 0; |
99 | |
102 | |
100 | x &= -x; /* this isolates the lowest bit */ |
103 | x &= -x; /* this isolates the lowest bit */ |
101 | |
104 | |
… | |
… | |
107 | |
110 | |
108 | return r; |
111 | return r; |
109 | } |
112 | } |
110 | |
113 | |
111 | ECB_HEADER_INLINE |
114 | ECB_HEADER_INLINE |
112 | ecb_popcount32 (unsigned int x) ecb_const |
115 | ecb_popcount32 (uint32_t x) ecb_const |
113 | { |
116 | { |
114 | x -= (x >> 1) & 0x55555555; |
117 | x -= (x >> 1) & 0x55555555; |
115 | x = ((x >> 2) & 0x33333333) + (x & 0x33333333); |
118 | x = ((x >> 2) & 0x33333333) + (x & 0x33333333); |
116 | x = ((x >> 4) + x) & 0x0f0f0f0f; |
119 | x = ((x >> 4) + x) & 0x0f0f0f0f; |
117 | x *= 0x01010101; |
120 | x *= 0x01010101; |
… | |
… | |
128 | } |
131 | } |
129 | |
132 | |
130 | ECB_HEADER_INLINE ecb_bool ecb_big_endian () ecb_const { return ecb_byteorder_helper () == 0x11; }; |
133 | ECB_HEADER_INLINE ecb_bool ecb_big_endian () ecb_const { return ecb_byteorder_helper () == 0x11; }; |
131 | ECB_HEADER_INLINE ecb_bool ecb_little_endian () ecb_const { return ecb_byteorder_helper () == 0x44; }; |
134 | ECB_HEADER_INLINE ecb_bool ecb_little_endian () ecb_const { return ecb_byteorder_helper () == 0x44; }; |
132 | |
135 | |
|
|
136 | #if ecb_cplusplus_does_not_suck |
|
|
137 | // does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) |
|
|
138 | template<typename T, int N> |
|
|
139 | static inline int array_length (const T (&arr)[N]) |
|
|
140 | { |
|
|
141 | return N; |
|
|
142 | } |
|
|
143 | #else |
|
|
144 | #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) |
133 | #endif |
145 | #endif |
134 | |
146 | |
|
|
147 | ECB_INLINE uint32_t |
|
|
148 | ecb_rotate32_right (uint32_t c, unsigned int count = 1) |
|
|
149 | { |
|
|
150 | return (c << (32 - count)) | (c >> count); |
|
|
151 | } |
|
|
152 | |
|
|
153 | ECB_INLINE uint32_t |
|
|
154 | ecb_rotate32_left (uint32_t c, unsigned int count = 1) |
|
|
155 | { |
|
|
156 | return (c >> (32 - count)) | (c << count); |
|
|
157 | } |
|
|
158 | |
|
|
159 | #endif |
|
|
160 | |