From caef08988e5149ba397a6c956eaaec82f0acbc3f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 23 Mar 2017 10:53:13 -0400 Subject: [PATCH 1/3] BitField: Make mostly constexpr capable Makes the constructor and retrieval functions constexpr. --- Source/Core/Common/BitField.h | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/Source/Core/Common/BitField.h b/Source/Core/Common/BitField.h index 10312f1c38..35d294d220 100644 --- a/Source/Core/Common/BitField.h +++ b/Source/Core/Common/BitField.h @@ -121,7 +121,7 @@ private: public: // Force default constructor to be created // so that we can use this within unions - BitField() = default; + constexpr BitField() = default; // We explicitly delete the copy assignment operator here, because the // default copy assignment would copy the full storage value, rather than @@ -139,20 +139,8 @@ public: return *this; } - __forceinline T Value() const - { - if (std::numeric_limits::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(); } + constexpr T Value() const { return Value(std::is_signed()); } + constexpr operator T() const { return Value(); } private: // 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 @@ -161,10 +149,21 @@ private: typedef typename std::conditional::value, std::underlying_type, std::enable_if>::type::type StorageType; + constexpr T Value(std::true_type) const + { + using shift_amount = std::integral_constant; + return static_cast((storage << (shift_amount() - position)) >> shift_amount()); + } + + constexpr T Value(std::false_type) const + { + return static_cast((storage & GetMask()) >> position); + } + // Unsigned version of StorageType typedef typename std::make_unsigned::type StorageTypeU; - __forceinline StorageType GetMask() const + static constexpr StorageType GetMask() { return (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position; } From e43c495ce5a230fa81684899afc59b1c50da3cdb Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 23 Mar 2017 10:59:40 -0400 Subject: [PATCH 2/3] BitField: Convert typedefs to using aliases --- Source/Core/Common/BitField.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Core/Common/BitField.h b/Source/Core/Common/BitField.h index 35d294d220..4d6a269e90 100644 --- a/Source/Core/Common/BitField.h +++ b/Source/Core/Common/BitField.h @@ -146,8 +146,11 @@ private: // 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::type directly. - typedef typename std::conditional::value, std::underlying_type, - std::enable_if>::type::type StorageType; + using StorageType = typename std::conditional_t::value, std::underlying_type, + std::enable_if>::type; + + // Unsigned version of StorageType + using StorageTypeU = std::make_unsigned_t; constexpr T Value(std::true_type) const { @@ -160,9 +163,6 @@ private: return static_cast((storage & GetMask()) >> position); } - // Unsigned version of StorageType - typedef typename std::make_unsigned::type StorageTypeU; - static constexpr StorageType GetMask() { return (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position; From b711daee5ff18479b11657262a338f3c431d0ef0 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 23 Mar 2017 11:01:39 -0400 Subject: [PATCH 3/3] BitField: Get rid of a C-style cast This can simply be the max value of the unsigned type. --- Source/Core/Common/BitField.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/BitField.h b/Source/Core/Common/BitField.h index 4d6a269e90..85a595239c 100644 --- a/Source/Core/Common/BitField.h +++ b/Source/Core/Common/BitField.h @@ -165,7 +165,7 @@ private: static constexpr StorageType GetMask() { - return (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position; + return (std::numeric_limits::max() >> (8 * sizeof(T) - bits)) << position; } StorageType storage;