diff --git a/sprout/bit/clrsb.hpp b/sprout/bit/clrsb.hpp index fea2f41e..17799a4b 100644 --- a/sprout/bit/clrsb.hpp +++ b/sprout/bit/clrsb.hpp @@ -30,7 +30,7 @@ namespace sprout { # endif template inline SPROUT_CONSTEXPR int - clrsb(Integral x) { + clrsb(Integral x) SPROUT_NOEXCEPT { return sprout::clz(~x); } } // namespace detail @@ -42,7 +42,7 @@ namespace sprout { std::is_integral::value, int >::type - clrsb(Integral x) { + clrsb(Integral x) SPROUT_NOEXCEPT { return sprout::detail::clrsb(x); } } // namespace sprout diff --git a/sprout/bit/clz.hpp b/sprout/bit/clz.hpp index c2f5a3f0..376c72c9 100644 --- a/sprout/bit/clz.hpp +++ b/sprout/bit/clz.hpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include namespace sprout { namespace detail { @@ -28,32 +31,68 @@ namespace sprout { return __builtin_clzll(x); } # endif - template - inline SPROUT_CONSTEXPR int - clz_non0_impl(Integral x, Integral m = Integral(1) << (CHAR_BIT * sizeof(Integral) - 1)) { - return m == 0 || x & m ? 0 - : 1 + sprout::detail::clz_non0_impl(x, static_cast(m >> 1)) - ; + template + inline SPROUT_CONSTEXPR typename std::enable_if< + (N == 1), + sprout::pair + >::type + clz_bytes(sprout::pair const& xn) SPROUT_NOEXCEPT { + return xn; + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + (N > 1), + sprout::pair + >::type + clz_bytes(sprout::pair const& xn) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::clz_bytes( + sprout::shlr(xn.first, (sizeof(Integral) - N / 2) * CHAR_BIT) ? xn + : type(sprout::shll(xn.first, N / 2 * CHAR_BIT), xn.second + N / 2 * CHAR_BIT) + ); } template - inline SPROUT_CONSTEXPR typename std::enable_if< - std::is_unsigned::value, - int - >::type - clz_non0(Integral x) { - return sprout::detail::clz_non0_impl(static_cast(x)); - } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - std::is_signed::value, - int - >::type - clz_non0(Integral x) { - return sprout::detail::clz_non0(static_cast::type>(x)); + inline SPROUT_CONSTEXPR sprout::pair + clz_bytes(sprout::pair const& xn) SPROUT_NOEXCEPT { + return sprout::detail::clz_bytes(xn); } template inline SPROUT_CONSTEXPR int - clz(Integral x) { + clz_bits1(sprout::pair const& xn) SPROUT_NOEXCEPT { + return xn.second - sprout::shlr(xn.first, sizeof(Integral) * CHAR_BIT - 1); + } + template + inline SPROUT_CONSTEXPR int + clz_bits2(sprout::pair const& xn) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::clz_bits1( + sprout::shlr(xn.first, sizeof(Integral) * CHAR_BIT - 2) ? xn + : type(sprout::shll(xn.first, 2), xn.second + 2) + ); + } + template + inline SPROUT_CONSTEXPR int + clz_bits4(sprout::pair const& xn) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::clz_bits2( + sprout::shlr(xn.first, sizeof(Integral) * CHAR_BIT - 4) ? xn + : type(sprout::shll(xn.first, 4), xn.second + 4) + ); + } + template + inline SPROUT_CONSTEXPR int + clz_bits(sprout::pair const& xn) SPROUT_NOEXCEPT { + return sprout::detail::clz_bits4(xn); + } + template + inline SPROUT_CONSTEXPR int + clz_non0(Integral x) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::clz_bits(sprout::detail::clz_bytes(type(x, 1))); + } + template + inline SPROUT_CONSTEXPR int + clz(Integral x) SPROUT_NOEXCEPT { return x == 0 ? static_cast(sizeof(x) * CHAR_BIT) : sprout::detail::clz_non0(x) ; @@ -67,7 +106,7 @@ namespace sprout { std::is_integral::value, int >::type - clz(Integral x) { + clz(Integral x) SPROUT_NOEXCEPT { return sprout::detail::clz(x); } } // namespace sprout diff --git a/sprout/bit/ctz.hpp b/sprout/bit/ctz.hpp index faa8db1f..b4b000c0 100644 --- a/sprout/bit/ctz.hpp +++ b/sprout/bit/ctz.hpp @@ -11,6 +11,10 @@ #include #include #include +#include +#include +#include +#include namespace sprout { namespace detail { @@ -28,27 +32,70 @@ namespace sprout { return __builtin_ctzll(x); } # endif - template + template inline SPROUT_CONSTEXPR typename std::enable_if< - std::is_unsigned::value, - int + (N == 1), + sprout::pair >::type - ctz_non0(Integral x) { - return x & 1 ? 0 - : 1 + sprout::detail::ctz_non0(static_cast(x >> 1)) - ; + ctz_bytes(sprout::pair const& xn) SPROUT_NOEXCEPT { + return xn; + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + (N > 1), + sprout::pair + >::type + ctz_bytes(sprout::pair const& xn) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::ctz_bytes( + (xn.first & static_cast(sprout::numeric_limits::least>::max())) ? xn + : type(sprout::shlr(xn.first, N / 2 * CHAR_BIT), xn.second + N / 2 * CHAR_BIT) + ); } template - inline SPROUT_CONSTEXPR typename std::enable_if< - std::is_signed::value, - int - >::type - ctz_non0(Integral x) { - return sprout::detail::ctz_non0(static_cast::type>(x)); + inline SPROUT_CONSTEXPR sprout::pair + ctz_bytes(sprout::pair const& xn) SPROUT_NOEXCEPT { + return sprout::detail::ctz_bytes(xn); } template inline SPROUT_CONSTEXPR int - ctz(Integral x) { + ctz_bits1(sprout::pair const& xn) SPROUT_NOEXCEPT { + return (xn.first & Integral(0x1ul)) ? xn.second + : xn.second + 1 + ; + } + template + inline SPROUT_CONSTEXPR int + ctz_bits2(sprout::pair const& xn) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::ctz_bits1( + (xn.first & Integral(0x3ul)) ? xn + : type(sprout::shlr(xn.first, 2), xn.second + 2) + ); + } + template + inline SPROUT_CONSTEXPR int + ctz_bits4(sprout::pair const& xn) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::ctz_bits2( + (xn.first & Integral(0xful)) ? xn + : type(sprout::shlr(xn.first, 4), xn.second + 4) + ); + } + template + inline SPROUT_CONSTEXPR int + ctz_bits(sprout::pair const& xn) SPROUT_NOEXCEPT { + return sprout::detail::ctz_bits4(xn); + } + template + inline SPROUT_CONSTEXPR int + ctz_non0(Integral x) SPROUT_NOEXCEPT { + typedef sprout::pair type; + return sprout::detail::ctz_bits(sprout::detail::ctz_bytes(type(x, 0))); + } + template + inline SPROUT_CONSTEXPR int + ctz(Integral x) SPROUT_NOEXCEPT { return x == 0 ? static_cast(sizeof(x) * CHAR_BIT) : sprout::detail::ctz_non0(x) ; @@ -62,7 +109,7 @@ namespace sprout { std::is_integral::value, int >::type - ctz(Integral x) { + ctz(Integral x) SPROUT_NOEXCEPT { return sprout::detail::ctz(x); } } // namespace sprout