From 753060f232745ea2a3fa197a176c3a8675699053 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 25 Jan 2021 14:41:17 -0800 Subject: Basic math: reworked ExtractBit and renamed to ExtractLSB; added tests --- Common/interface/BasicMath.hpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'Common/interface') diff --git a/Common/interface/BasicMath.hpp b/Common/interface/BasicMath.hpp index 78e9beaf..5f37c164 100644 --- a/Common/interface/BasicMath.hpp +++ b/Common/interface/BasicMath.hpp @@ -2189,18 +2189,24 @@ inline Uint32 BitInterleave16(Uint16 _x, Uint16 _y) return x | (y << 1u); } +/// Returns the least-signficant bit and clears it in the input argument template -inline T ExtractBit(T& bits) +typename std::enable_if::value, T>::type ExtractLSB(T& bits) { - static_assert(std::is_enum::value || std::is_integral::value, "T must be enum or integer type"); + if (bits == T{0}) + return 0; - using U = std::conditional_t<(sizeof(T) > sizeof(Uint32)), Uint64, Uint32>; - VERIFY_EXPR(static_cast(bits) > 0); + const T bit = bits & ~(bits - T{1}); + bits &= ~bit; - const U result = static_cast(bits) & ~(static_cast(bits) - U{1}); - bits = static_cast(static_cast(bits) & ~result); + return bit; +} - return static_cast(result); +/// Returns the enum value representing the least-signficant bit and clears it in the input argument +template +typename std::enable_if::value, T>::type ExtractLSB(T& bits) +{ + return static_cast(ExtractLSB(reinterpret_cast::type&>(bits))); } } // namespace Diligent -- cgit v1.2.3