Skip to content

Commit

Permalink
Statically assert the unsigned integer requirements in bit.hpp. Fixes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
pdimov committed Sep 21, 2022
1 parent 2cc3e23 commit 66a742f
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions include/boost/core/bit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEP
template<class T>
BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return boost::core::detail::countl_impl( x );
}

Expand Down Expand Up @@ -169,6 +171,8 @@ inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
template<class T>
int countl_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::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) )
Expand All @@ -194,6 +198,8 @@ int countl_zero( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return boost::core::countl_zero( static_cast<T>( ~x ) );
}

Expand Down Expand Up @@ -234,6 +240,8 @@ BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEP
template<class T>
BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return boost::core::detail::countr_impl( x );
}

Expand Down Expand Up @@ -304,6 +312,8 @@ inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
template<class T>
int countr_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::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) )
Expand All @@ -329,6 +339,8 @@ int countr_zero( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return boost::core::countr_zero( static_cast<T>( ~x ) );
}

Expand Down Expand Up @@ -377,6 +389,8 @@ BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x
template<class T>
BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return boost::core::detail::popcount_impl( x );
}

Expand Down Expand Up @@ -408,6 +422,8 @@ BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCE
template<class T>
BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );

BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
Expand All @@ -427,13 +443,17 @@ BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

unsigned const mask = std::numeric_limits<T>::digits - 1;
return x << (s & mask) | x >> ((-s) & mask);
}

template<class T>
BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

unsigned const mask = std::numeric_limits<T>::digits - 1;
return x >> (s & mask) | x << ((-s) & mask);
}
Expand All @@ -443,6 +463,8 @@ BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return x != 0 && ( x & ( x - 1 ) ) == 0;
}

Expand All @@ -451,13 +473,17 @@ BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return static_cast<T>(
std::numeric_limits<T>::digits - boost::core::countl_zero( x ) );
}

template<class T>
BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

return x == 0? 0: T(1) << ( boost::core::bit_width( x ) - 1 );
}

Expand Down Expand Up @@ -510,6 +536,8 @@ BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x )
template<class T>
BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );

BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );

BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
Expand Down

2 comments on commit 66a742f

@Lastique
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not enable_if? This would potentially allow user's overloads for his own integer types.

@pdimov
Copy link
Member Author

@pdimov pdimov commented on 66a742f Sep 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard fail is what it currently does (on gcc/clang) and what it's currently documented to do.

enable_if is arguably more correct because the standard functions use it, but I prefer to wait until someone actually requests that feature.

Please sign in to comment.