integerOps.h

Go to the documentation of this file.
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 // 1 << x, handling the case where x is >= the number of bits in T
00031 template <typename T, size_t Count>
00032 struct SHL1: public IntegerOpsPrivate::SHL1Helper<T, Count, (Count >= IntegerOpsPrivate::NumBits<T>::value)> {};
00033 
00034 // 1 << x, handling the case where x is >= the number of bits in T
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 // Set rightmost (from LSB) count bits of result, clear others
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 } // namespace IntegerOps
00102 
00103 #endif // ROSE_INTEGEROPS_H

Generated on Tue Jan 31 05:31:37 2012 for ROSE by  doxygen 1.4.7