From 66a742f41e4d197eb8e2aef4aef64c275e9700f0 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 21 Sep 2022 19:07:33 +0300 Subject: [PATCH] Statically assert the unsigned integer requirements in bit.hpp. Fixes #129. --- include/boost/core/bit.hpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/boost/core/bit.hpp b/include/boost/core/bit.hpp index ddd435b..69e1763 100644 --- a/include/boost/core/bit.hpp +++ b/include/boost/core/bit.hpp @@ -92,6 +92,8 @@ BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEP template BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return boost::core::detail::countl_impl( x ); } @@ -169,6 +171,8 @@ inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT template int countl_zero( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) @@ -194,6 +198,8 @@ int countl_zero( T x ) BOOST_NOEXCEPT template BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return boost::core::countl_zero( static_cast( ~x ) ); } @@ -234,6 +240,8 @@ BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEP template BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return boost::core::detail::countr_impl( x ); } @@ -304,6 +312,8 @@ inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT template int countr_zero( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) @@ -329,6 +339,8 @@ int countr_zero( T x ) BOOST_NOEXCEPT template BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return boost::core::countr_zero( static_cast( ~x ) ); } @@ -377,6 +389,8 @@ BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x template BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return boost::core::detail::popcount_impl( x ); } @@ -408,6 +422,8 @@ BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCE template BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) ) @@ -427,6 +443,8 @@ BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT template BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + unsigned const mask = std::numeric_limits::digits - 1; return x << (s & mask) | x >> ((-s) & mask); } @@ -434,6 +452,8 @@ BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT template BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + unsigned const mask = std::numeric_limits::digits - 1; return x >> (s & mask) | x << ((-s) & mask); } @@ -443,6 +463,8 @@ BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT template BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return x != 0 && ( x & ( x - 1 ) ) == 0; } @@ -451,6 +473,8 @@ BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT template BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return static_cast( std::numeric_limits::digits - boost::core::countl_zero( x ) ); } @@ -458,6 +482,8 @@ BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT template BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + return x == 0? 0: T(1) << ( boost::core::bit_width( x ) - 1 ); } @@ -510,6 +536,8 @@ BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x ) template BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )