1 #ifndef ROSE_INTEGEROPS_H
2 #define ROSE_INTEGEROPS_H
6 #include <boost/static_assert.hpp>
7 #include <boost/optional.hpp>
9 namespace IntegerOpsPrivate {
15 static const size_t value = std::numeric_limits<T>::digits;
18 template <
typename T,
size_t Count,
bool TooBig>
struct SHL1Helper;
19 template <
typename T,
size_t Count>
21 static const T value = 0;
23 template <
typename T,
size_t Count>
25 static const T value = T(1) << Count;
35 namespace IntegerOps {
38 template <
typename T,
size_t n>
48 template <
typename T,
size_t n>
56 return shl1<T>(n) - 1;
62 inline T
genMask(
size_t lobit,
size_t hibit)
64 assert(hibit<8*
sizeof(T));
66 return genMask<T>(1+hibit-lobit) << lobit;
71 template <
size_t NBits,
typename T>
77 inline bool signBit2(T value,
size_t width=8*
sizeof(T)) {
78 assert(width>0 && width<=8*
sizeof(T));
79 T sign_mask = shl1<T>(width-1);
80 return 0 != (value & sign_mask);
87 template <
size_t FromBits,
size_t ToBits,
typename T>
93 inline T
signExtend2(T value,
size_t from_width,
size_t to_width) {
94 assert(from_width<=8*
sizeof(T));
95 assert(to_width<=8*
sizeof(T));
96 return value | (
signBit2(value, from_width) ? (genMask<T>(to_width) ^ genMask<T>(from_width)) : T(0));
102 template <
size_t NBits,
typename T>
107 template <
typename T>
108 inline T
shiftLeft2(T value,
size_t count,
size_t width=8*
sizeof(T)) {
109 assert(width>0 && width<=8*
sizeof(T));
110 return (value * shl1<T>(count)) & genMask<T>(width);
116 template <
size_t NBits,
typename T>
118 return (count >= NBits) ? T(0) : (value >> count);
121 template <
typename T>
123 assert(width>0 && width<=8*
sizeof(T));
124 return (count >= width) ? T(0) : (value >> count);
130 template <
size_t NBits,
typename T>
132 if (count >= NBits) {
135 return (shiftRightLogical<NBits>(value, count) |
140 template <
typename T>
142 if (count >= width) {
143 return signBit2(value, width) ? genMask<T>(width) : T(0);
146 (
signBit2(value, width) ? (genMask<T>(width) ^ genMask<T>(width-count)) : T(0)));
153 template <
size_t NBits,
typename T>
159 template <
typename T>
160 inline T
rotateLeft2(T value,
size_t count,
size_t width=8*
sizeof(T)) {
161 assert(width>0 && width<=8*
sizeof(T));
163 return ((value << count) | (value >> (width-count))) & genMask<T>(width);
169 template <
size_t NBits,
typename T>
175 template <
typename T>
176 inline T
rotateRight2(T value,
size_t count,
size_t width=8*
sizeof(T)) {
177 assert(width>0 && width<=8*
sizeof(T));
178 return ((value >> count) | (value << (width - count))) & genMask<T>(width);
183 template <
typename T>
186 assert(
sizeof(T) <=
sizeof(uint64_t));
187 if (0 != (value &
SHL1<T, 8*
sizeof(T)-1>::value))
189 uint64_t uval = value;
200 template <
typename T>
203 assert(
sizeof(T) <=
sizeof(uint64_t));
204 uint64_t uval = value;
205 bool low_bits_set =
false;
209 return retval + (low_bits_set ? 1 : 0);
219 template <
typename T>
223 while (n != 0 && n < a) {
234 template<
size_t lobit,
size_t hibit,
typename T>
236 assert(hibit<8*
sizeof(T));
237 assert(hibit>=lobit);
239 return shiftLeft<8*sizeof(T)>(value &
GenMask<T, 1+hibit-lobit>::value, lobit);
244 assert(hibit<8*
sizeof(T));
245 assert(hibit>=lobit);
246 assert(0==(value & ~genMask<T>(1+hibit-lobit)));
247 return shiftLeft2<T>(value & genMask<T>(1+hibit-lobit), lobit);
254 template<
size_t lobit,
size_t hibit,
typename T>
256 assert(hibit<8*
sizeof(T));
257 assert(hibit>=lobit);
261 inline T
extract2(
size_t lobit,
size_t hibit, T bits)
263 assert(hibit<8*
sizeof(T));
264 assert(hibit>=lobit);
265 return shiftRightLogical<8*sizeof(T)>(bits, lobit) & genMask<T>(1+hibit-lobit);
274 return 0 == (~m1 & m2);
282 for (
size_t i=0; i<8*
sizeof(T); ++i) {
283 if (0 != (val & shl1<T>(i)))
294 for (
size_t i=0; i<8*
sizeof(T); ++i) {
295 if (0 == (val & shl1<T>(i)))
306 for (
size_t bitno = 8*
sizeof(T); bitno>0; --bitno) {
307 if (0 != (val & shl1<T>(bitno-1)))
308 return boost::optional<size_t>(bitno-1);
311 return boost::optional<size_t>();
315 #endif // ROSE_INTEGEROPS_H