1#ifndef ROSE_INTEGEROPS_H 
    2#define ROSE_INTEGEROPS_H 
    6#include <boost/static_assert.hpp> 
    7#include <boost/optional.hpp> 
    9namespace IntegerOpsPrivate {
 
   13        BOOST_STATIC_ASSERT (std::numeric_limits<T>::radix == 2);
 
   14        BOOST_STATIC_ASSERT (std::numeric_limits<T>::is_integer);
 
   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;
 
 
   38template <
typename T, 
size_t n>
 
   48template <
typename T, 
size_t n>
 
   56    return shl1<T>(n) - 1;
 
 
   62inline T 
genMask(
size_t lobit, 
size_t hibit)
 
   64    assert(hibit<8*
sizeof(T));
 
   66    return genMask<T>(1+hibit-lobit) << lobit;
 
 
   71template <
size_t NBits, 
typename T>
 
   77inline 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);
 
 
   87template <
size_t FromBits, 
size_t ToBits, 
typename T>
 
   93inline 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));
 
 
  102template <
size_t NBits, 
typename T>
 
  108inline 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);
 
 
  116template <
size_t NBits, 
typename T>
 
  118    return (count >= NBits) ? T(0) : (value >> count);
 
 
  123    assert(width>0 && width<=8*
sizeof(T));
 
  124    return (count >= width) ? T(0) : (value >> count);
 
 
  130template <
size_t NBits, 
typename T>
 
  132    if (count >= NBits) {
 
  135        return (shiftRightLogical<NBits>(value, count) |
 
 
  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)));
 
 
  153template <
size_t NBits, 
typename T>
 
  160inline 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);
 
 
  169template <
size_t NBits, 
typename T>
 
  176inline 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);
 
 
  186    assert(
sizeof(T) <= 
sizeof(uint64_t));
 
  187    if (0 != (value & 
SHL1<T, 8*
sizeof(T)-1>::value))
 
  189    uint64_t uval = value;
 
 
  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);
 
 
  223    while (n != 0 && n < a) {
 
  234template<
size_t lobit, 
size_t hibit, 
typename T>
 
  236    assert(hibit<8*
sizeof(T));
 
  237    assert(hibit>=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);
 
 
  254template<
size_t lobit, 
size_t hibit, 
typename T>
 
  256    assert(hibit<8*
sizeof(T));
 
  257    assert(hibit>=lobit);
 
  258    return shiftRightLogical<8*sizeof(T)>(bits, lobit) & 
GenMask<T, 1+hibit-lobit>::value;
 
 
  261inline 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>();
 
 
 
Bit-wise operations on integers.
 
T shiftRightArithmetic(T value, size_t count)
Shifts bits of value right by count bits with sign extension.
 
T extract(T bits)
Extract bits from a value.
 
T rotateLeft(T value, size_t count)
Rotate the bits of the value left by count bits.
 
T shiftRightLogical(T value, size_t count)
Shifts bits of value right by count bits without sign extension.
 
bool signBit(T value)
Returns true if the sign bit is set, false if clear.
 
T signExtend2(T value, size_t from_width, size_t to_width)
Sign extend value.
 
T shift_to(T value)
Create a shifted value.
 
bool signBit2(T value, size_t width=8 *sizeof(T))
Returns true if the sign bit is set, false if clear.
 
size_t countClear(T val)
Counts how many bits are clear (zero).
 
T rotateRight2(T value, size_t count, size_t width=8 *sizeof(T))
Rotate bits of the value right by count bits.
 
T rotateRight(T value, size_t count)
Rotate bits of the value right by count bits.
 
T signExtend(T value)
Sign extend value.
 
boost::optional< size_t > msb_set(T val)
Optionally returns the zero-origin position of the most significant set bit.
 
T shift_to2(size_t lobit, size_t hibit, T value)
Create a shifted value.
 
bool bitmask_subset(T m1, T m2)
Determines if one bitmask is a subset of another.
 
T rotateLeft2(T value, size_t count, size_t width=8 *sizeof(T))
Rotate the bits of the value left by count bits.
 
T extract2(size_t lobit, size_t hibit, T bits)
Extract bits from a value.
 
bool isPowerOfTwo(T value)
Returns true if the value is a power of two.
 
T log2max(T value)
Returns the base-2 logorithm of value.
 
T genMask(size_t n)
Bitmask with bits 0 through N-1 set.
 
size_t countSet(T val)
Counts how many bits are set (one).
 
T shiftLeft(T value, size_t count)
Shifts bits of value left by count bits.
 
T shiftLeft2(T value, size_t count, size_t width=8 *sizeof(T))
Shifts bits of value left by count bits.
 
T shiftRightArithmetic2(T value, size_t count, size_t width=8 *sizeof(T))
Shifts bits of value right by count bits with sign extension.
 
T shl1(size_t n)
Bitmask with bit n set.
 
T shiftRightLogical2(T value, size_t count, size_t width=8 *sizeof(T))
Shifts bits of value right by count bits without sign extension.
 
Bit mask constant with bits 0 through n-1 set.
 
Bitmask constant with bit n set.