sizeof(value_type));
}
+template <typename value_type>
+using make_unsigned_t = typename std::make_unsigned<value_type>::type;
+
/// Read a value of a particular endianness from memory, for a location
/// that starts at the given bit offset within the first byte.
template <typename value_type, endianness endian, std::size_t alignment>
val[1] = byte_swap<value_type, endian>(val[1]);
// Shift bits from the lower value into place.
- unsigned lowerVal = val[0] >> startBit;
+ make_unsigned_t<value_type> lowerVal = val[0] >> startBit;
// Mask off upper bits after right shift in case of signed type.
- unsigned numBitsFirstVal = (sizeof(value_type) * 8) - startBit;
- lowerVal &= (1 << numBitsFirstVal) - 1;
+ make_unsigned_t<value_type> numBitsFirstVal =
+ (sizeof(value_type) * 8) - startBit;
+ lowerVal &= ((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1;
// Get the bits from the upper value.
- unsigned upperVal = val[1] & ((1 << startBit) - 1);
+ make_unsigned_t<value_type> upperVal =
+ val[1] & (((make_unsigned_t<value_type>)1 << startBit) - 1);
// Shift them in to place.
upperVal <<= numBitsFirstVal;
// Mask off any existing bits in the upper part of the lower value that
// we want to replace.
- val[0] &= (1 << startBit) - 1;
- unsigned numBitsFirstVal = (sizeof(value_type) * 8) - startBit;
- unsigned lowerVal = value;
+ val[0] &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
+ make_unsigned_t<value_type> numBitsFirstVal =
+ (sizeof(value_type) * 8) - startBit;
+ make_unsigned_t<value_type> lowerVal = value;
if (startBit > 0) {
// Mask off the upper bits in the new value that are not going to go into
// the lower value. This avoids a left shift of a negative value, which
// is undefined behavior.
- lowerVal &= ((1 << numBitsFirstVal) - 1);
+ lowerVal &= (((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1);
// Now shift the new bits into place
lowerVal <<= startBit;
}
// Mask off any existing bits in the lower part of the upper value that
// we want to replace.
- val[1] &= ~((1 << startBit) - 1);
+ val[1] &= ~(((make_unsigned_t<value_type>)1 << startBit) - 1);
// Next shift the bits that go into the upper value into position.
- unsigned upperVal = value >> numBitsFirstVal;
+ make_unsigned_t<value_type> upperVal = value >> numBitsFirstVal;
// Mask off upper bits after right shift in case of signed type.
- upperVal &= (1 << startBit) - 1;
+ upperVal &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
val[1] |= upperVal;
// Finally, rewrite values.