@ -117,21 +117,21 @@ private:
// We don't delete it because we want BitField to be trivially copyable.
constexpr BitField & operator = ( const BitField & ) = default ;
// Storage Type is T for non-enum types and the underlying type of T if
// Underlying Type 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
// former case to workaround compile errors which arise when using
// std::underlying_type<T>::type directly.
using Storage Type = typename std : : conditional_t < std : : is_enum < T > : : value , std : : underlying_type < T > ,
std : : enable_if < true , T > > : : type ;
using Underlying Type = typename std : : conditional_t < std : : is_enum _v < T > , std : : underlying_type < T > ,
std : : enable_if < true , T > > : : type ;
// Unsigned version of StorageType
using StorageType U = std : : make_unsigned_t < Storage Type> ;
// We store the value as the unsigned type to avoid undefined behaviour on value shifting
using StorageType = std : : make_unsigned_t < Underlying Type> ;
public :
/// Constants to allow limited introspection of fields if needed
static constexpr std : : size_t position = Position ;
static constexpr std : : size_t bits = Bits ;
static constexpr StorageType mask = ( ( ( StorageType U ) ~ 0 ) > > ( 8 * sizeof ( T ) - bits ) ) < < position ;
static constexpr StorageType mask = ( ( ( StorageType ) ~ 0 ) > > ( 8 * sizeof ( T ) - bits ) ) < < position ;
/**
* Formats a value by masking and shifting it according to the field parameters . A value
@ -148,11 +148,12 @@ public:
* union in a constexpr context .
*/
static constexpr FORCE_INLINE T ExtractValue ( const StorageType & storage ) {
if ( std : : numeric_limits < T> : : is_signed ) {
if constexpr ( std : : numeric_limits < Underlying Type > : : is_signed ) {
std : : size_t shift = 8 * sizeof ( T ) - bits ;
return ( T ) ( ( storage < < ( shift - position ) ) > > shift ) ;
return static_cast < T > ( static_cast < UnderlyingType > ( storage < < ( shift - position ) ) > >
shift ) ;
} else {
return ( T ) ( ( storage & mask ) > > position ) ;
return static_cast < T > ( ( storage & mask ) > > position ) ;
}
}