/*============================================================================= Copyright (c) 2011-2017 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_BIT_BIT_LENGTH_HPP #define SPROUT_BIT_BIT_LENGTH_HPP #include #include #include #include namespace sprout { namespace detail { SPROUT_STATIC_CONSTEXPR std::size_t bit_len_8_table[std::size_t(UCHAR_MAX) + 1] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; template struct bit_len { private: SPROUT_STATIC_CONSTEXPR std::size_t next_size = Size - 1; SPROUT_STATIC_CONSTEXPR std::size_t shift_bits = next_size * CHAR_BIT; private: template SPROUT_CONSTEXPR Integral impl(Integral x, unsigned char i) const { return bit_len_8_table[i] ? bit_len_8_table[i] + next_size * CHAR_BIT : sprout::detail::bit_len().template operator()(x) ; } public: template SPROUT_CONSTEXPR Integral operator()(Integral x) const { return impl(x, static_cast((x >> shift_bits) & UCHAR_MAX)); } }; template<> struct bit_len<1> { public: template SPROUT_CONSTEXPR Integral operator()(Integral x) const { return bit_len_8_table[static_cast(x & UCHAR_MAX)]; } }; } // namespace detail // // bit_length // template inline SPROUT_CONSTEXPR typename std::enable_if< std::is_integral::value, Integral >::type bit_length(Integral x) { return sprout::detail::bit_len().template operator()(x); } } // namespace sprout #endif // #ifndef SPROUT_BIT_BIT_LENGTH_HPP