Boost logo

Boost :

From: Emile Cormier (emilecormier_at_[hidden])
Date: 2006-03-15 21:56:33

Consider the following snippet:

template <uint8_t F, uint8_t L, class T, class R=T&, class I=T&>
class Bitfield
   BOOST_STATIC_ASSERT( F < 8*sizeof(T) );
   BOOST_STATIC_ASSERT( L < 8*sizeof(T) );

      FIRST = F, //!< Position of the first bit
      LAST = L, //!< Position of the last bit
      WIDTH = LAST - FIRST + 1, //!< Width in bits of the
      VAL_MASK = (1 << WIDTH) - 1, //!< Mask applied against
      assigned values
      FIELD_MASK = VAL_MASK << FIRST //!< Mask of the field's bit

What would be the most appropriate type for the F and L template
parameters? I had arbitrarily picked uint8_t because I felt that it
would big enough for a right-hand-side shift operand (at least until
they come up with processors supporting 512-bit registers). But since I
static-check the range of these compile-time constants, I don't see the
point in constraining them to uint8_t.

Is integral promotion performed on the right-hand-side operand of a
shift operator?

I'm thinking I should use (unsigned int) instead of (unsigned char), in
case Bitfield is later extended to support bit manipulations in
multi-word data.

P.S. I just spotted a problem that I forgot to fix in the latest draft I
just uploaded.

The problem is with:
VAL_MASK = (1 << WIDTH) - 1

With the arm-elf-gcc compiler, I get an error when WIDTH is 32. That
line needs to be replaced with:
VAL_MASK = ((1 << (WIDTH-1)) << 1) - 1

When WIDTH is 32, (1 << 31) << 1 == 0, so after the subtraction we get
VAL_MASK == -1, which is 0xffffffff when interpreted as unsigned. We
still get the desired result even though the second shift resulted in an

  Emile Cormier

Boost list run by bdawes at, gregod at, cpdaniel at, john at