Merge pull request #5139 from lioncash/bitfield
BitField: Minor cleanup
This commit is contained in:
commit
2c531889b2
|
@ -121,7 +121,7 @@ private:
|
||||||
public:
|
public:
|
||||||
// Force default constructor to be created
|
// Force default constructor to be created
|
||||||
// so that we can use this within unions
|
// so that we can use this within unions
|
||||||
BitField() = default;
|
constexpr BitField() = default;
|
||||||
|
|
||||||
// We explicitly delete the copy assignment operator here, because the
|
// We explicitly delete the copy assignment operator here, because the
|
||||||
// default copy assignment would copy the full storage value, rather than
|
// default copy assignment would copy the full storage value, rather than
|
||||||
|
@ -139,34 +139,33 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline T Value() const
|
constexpr T Value() const { return Value(std::is_signed<T>()); }
|
||||||
{
|
constexpr operator T() const { return Value(); }
|
||||||
if (std::numeric_limits<T>::is_signed)
|
|
||||||
{
|
|
||||||
std::size_t shift = 8 * sizeof(T) - bits;
|
|
||||||
return (T)((storage << (shift - position)) >> shift);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (T)((storage & GetMask()) >> position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline operator T() const { return Value(); }
|
|
||||||
private:
|
private:
|
||||||
// StorageType is T for non-enum types and the underlying type of T if
|
// StorageType is T for non-enum types and the underlying type of T if
|
||||||
// T is an enumeration. Note that T is wrapped within an enable_if in the
|
// T is an enumeration. Note that T is wrapped within an enable_if in the
|
||||||
// former case to workaround compile errors which arise when using
|
// former case to workaround compile errors which arise when using
|
||||||
// std::underlying_type<T>::type directly.
|
// std::underlying_type<T>::type directly.
|
||||||
typedef typename std::conditional<std::is_enum<T>::value, std::underlying_type<T>,
|
using StorageType = typename std::conditional_t<std::is_enum<T>::value, std::underlying_type<T>,
|
||||||
std::enable_if<true, T>>::type::type StorageType;
|
std::enable_if<true, T>>::type;
|
||||||
|
|
||||||
// Unsigned version of StorageType
|
// Unsigned version of StorageType
|
||||||
typedef typename std::make_unsigned<StorageType>::type StorageTypeU;
|
using StorageTypeU = std::make_unsigned_t<StorageType>;
|
||||||
|
|
||||||
__forceinline StorageType GetMask() const
|
constexpr T Value(std::true_type) const
|
||||||
{
|
{
|
||||||
return (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position;
|
using shift_amount = std::integral_constant<size_t, 8 * sizeof(T) - bits>;
|
||||||
|
return static_cast<T>((storage << (shift_amount() - position)) >> shift_amount());
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr T Value(std::false_type) const
|
||||||
|
{
|
||||||
|
return static_cast<T>((storage & GetMask()) >> position);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr StorageType GetMask()
|
||||||
|
{
|
||||||
|
return (std::numeric_limits<StorageTypeU>::max() >> (8 * sizeof(T) - bits)) << position;
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageType storage;
|
StorageType storage;
|
||||||
|
|
Loading…
Reference in New Issue