static constexpr UnderlyingType zero = UnderlyingType(0);
static constexpr UnderlyingType one = UnderlyingType(1);
+ using UnsignedType = typename std::make_unsigned<UnderlyingType>::type;
static constexpr UnderlyingType ones(size_t count) {
- return count < bitsPerBlock ? (one << count) - 1 : ~zero;
+ return (count < bitsPerBlock)
+ ? static_cast<UnderlyingType>((UnsignedType{1} << count) - 1)
+ : ~zero;
}
};
UnderlyingType value) {
DCHECK_LE(count, sizeof(UnderlyingType) * 8);
size_t cut = bitsPerBlock - count;
- DCHECK_EQ(value, value << cut >> cut);
+ if (cut != 8 * sizeof(UnderlyingType)) {
+ using U = typename std::make_unsigned<UnderlyingType>::type;
+ DCHECK_EQ(value, UnderlyingType(U(value) << cut) >> cut);
+ }
size_t idx = blockIndex(bitStart);
size_t offset = bitOffset(bitStart);
if (std::is_signed<UnderlyingType>::value) {
template <class T, class Traits>
inline auto Bits<T, Traits>::get(const T* p, size_t bitStart, size_t count)
-> UnderlyingType {
+ if (count == 0) {
+ return UnderlyingType{};
+ }
+
DCHECK_LE(count, sizeof(UnderlyingType) * 8);
size_t idx = blockIndex(bitStart);
size_t offset = bitOffset(bitStart);