00001 #ifndef ROSE_INTEGEROPS_H
00002 #define ROSE_INTEGEROPS_H
00003
00004 #include <limits>
00005 #include <boost/static_assert.hpp>
00006
00007 namespace IntegerOpsPrivate {
00008
00009 template <typename T>
00010 struct NumBits {
00011 BOOST_STATIC_ASSERT (std::numeric_limits<T>::radix == 2);
00012 BOOST_STATIC_ASSERT (std::numeric_limits<T>::is_integer);
00013 static const size_t value = std::numeric_limits<T>::digits;
00014 };
00015
00016 template <typename T, size_t Count, bool TooBig> struct SHL1Helper;
00017 template <typename T, size_t Count>
00018 struct SHL1Helper<T, Count, true> {
00019 static const T value = 0;
00020 };
00021 template <typename T, size_t Count>
00022 struct SHL1Helper<T, Count, false> {
00023 static const T value = T(1) << Count;
00024 };
00025
00026 }
00027
00028 namespace IntegerOps {
00029
00030
00031 template <typename T, size_t Count>
00032 struct SHL1: public IntegerOpsPrivate::SHL1Helper<T, Count, (Count >= IntegerOpsPrivate::NumBits<T>::value)> {};
00033
00034
00035 template <typename T>
00036 inline T shl1(size_t count) {
00037 return (count >= IntegerOpsPrivate::NumBits<T>::value) ? T(0) : (T(1) << count);
00038 }
00039
00040
00041 template <typename T, size_t Count>
00042 struct GenMask {
00043 static const T value = SHL1<T, Count>::value - T(1);
00044 };
00045
00046 template <typename T>
00047 inline T genMask(size_t count) {
00048 return shl1<T>(count) - 1;
00049 }
00050
00051 template <size_t NBits, typename T>
00052 inline bool signBit(T value) {
00053 return (value & SHL1<T, NBits - 1>::value) != T(0);
00054 }
00055
00056 template <size_t FromBits, size_t ToBits, typename T>
00057 inline T signExtend(T value) {
00058 return value | (signBit<FromBits>(value) ? (GenMask<T, ToBits>::value ^ GenMask<T, FromBits>::value) : T(0));
00059 }
00060
00061 template <size_t NBits, typename T>
00062 inline T shiftLeft(T value, size_t count) {
00063 return (value * shl1<T>(count)) & GenMask<T, NBits>::value;
00064 }
00065
00066 template <size_t NBits, typename T>
00067 inline T shiftRightLogical(T value, size_t count) {
00068 return (count >= NBits) ? T(0) : (value >> count);
00069 }
00070
00071 template <size_t NBits, typename T>
00072 inline T shiftRightArithmetic(T value, size_t count) {
00073 if (count >= NBits) {
00074 return signBit<NBits>(value) ? GenMask<T, NBits>::value : T(0);
00075 } else {
00076 return shiftRightLogical<NBits>(value, count) |
00077 (signBit<NBits>(value) ? (GenMask<T, NBits>::value ^ genMask<T>(NBits - count)) : T(0));
00078 }
00079 }
00080
00081 template <size_t NBits, typename T>
00082 inline T rotateLeft(T value, size_t count) {
00083 count %= NBits;
00084 return ((value << count) | (value >> (NBits - count))) & GenMask<T, NBits>::value;
00085 }
00086
00087 template <size_t NBits, typename T>
00088 inline T rotateRight(T value, size_t count) {
00089 count %= NBits;
00090 return ((value >> count) | (value << (NBits - count))) & GenMask<T, NBits>::value;
00091 }
00092
00093 template <typename T>
00094 inline T log2(T a) {
00095 T n = T(1);
00096 T i = 0;
00097 while (n != 0 && n < a) {n <<= 1; ++i;}
00098 return i;
00099 }
00100
00101 }
00102
00103 #endif // ROSE_INTEGEROPS_H