
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) ); BOOST_STATIC_ASSERT( F <= L ); enum { FIRST = F, //!< Position of the first bit LAST = L, //!< Position of the last bit WIDTH = LAST - FIRST + 1, //!< Width in bits of the Bitfield VAL_MASK = (1 << WIDTH) - 1, //!< Mask applied against assigned values FIELD_MASK = VAL_MASK << FIRST //!< Mask of the field's bit positions }; }; 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 "overflow". -- Emile Cormier emilecormier@mailcan.com