bit_util: Add SignExtend implementation with runtime bit_count argument

This commit is contained in:
MerryMage 2016-12-21 14:13:50 +00:00 committed by Merry
parent 02b2ab7581
commit b23b524b03

View file

@ -59,7 +59,7 @@ constexpr bool Bit(size_t bit_position, const T value) {
#pragma warning(pop) #pragma warning(pop)
#endif #endif
/// Sign-extends a value that has NBits bits to the full bitwidth of type T. /// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
template<size_t bit_count, typename T> template<size_t bit_count, typename T>
inline T SignExtend(const T value) { inline T SignExtend(const T value) {
static_assert(bit_count <= BitSize<T>(), "bit_count larger than bitsize of T"); static_assert(bit_count <= BitSize<T>(), "bit_count larger than bitsize of T");
@ -72,6 +72,19 @@ inline T SignExtend(const T value) {
return value; return value;
} }
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
template<typename T>
inline T SignExtend(const size_t bit_count, const T value) {
ASSERT_MSG(bit_count <= BitSize<T>(), "bit_count larger than bitsize of T");
const T mask = static_cast<T>(1ULL << bit_count) - 1;
const bool signbit = Bit<T>(bit_count - 1, value);
if (signbit) {
return value | ~mask;
}
return value;
}
template <typename Integral> template <typename Integral>
inline size_t BitCount(Integral value) { inline size_t BitCount(Integral value) {
return std::bitset<BitSize<Integral>()>(value).count(); return std::bitset<BitSize<Integral>()>(value).count();