mirror of
https://github.com/boostorg/core.git
synced 2025-05-09 23:03:54 +00:00
Add byteswap to bit.hpp
This commit is contained in:
parent
6b9f0cbf57
commit
b591214103
@ -792,6 +792,60 @@ typedef endian::type endian_type;
|
||||
|
||||
#undef BOOST_CORE_BIT_NATIVE_INITIALIZER
|
||||
|
||||
// byteswap
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_CONSTEXPR inline boost::uint8_t byteswap_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return (x << 8) | (x >> 8);
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::uint32_t step16 = x << 16 | x >> 16;
|
||||
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::uint64_t step32 = x << 32 | x >> 32;
|
||||
boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T> BOOST_CXX14_CONSTEXPR T byteswap( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer );
|
||||
|
||||
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) )
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint8_t>( x ) ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint16_t>( x ) ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint32_t>( x ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint64_t>( x ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
|
@ -296,6 +296,8 @@ run bit_popcount_test.cpp
|
||||
: : : $(pedantic-errors) ;
|
||||
run bit_endian_test.cpp
|
||||
: : : $(pedantic-errors) ;
|
||||
run bit_byteswap_test.cpp
|
||||
: : : $(pedantic-errors) ;
|
||||
|
||||
compile-fail bit_width_fail.cpp
|
||||
: <warnings>off ;
|
||||
@ -308,6 +310,7 @@ compile has_single_bit_test_cx.cpp ;
|
||||
compile bit_floor_test_cx.cpp ;
|
||||
compile bit_ceil_test_cx.cpp ;
|
||||
compile bit_popcount_test_cx.cpp ;
|
||||
compile bit_byteswap_test_cx.cpp ;
|
||||
|
||||
run type_name_test.cpp ;
|
||||
|
||||
|
26
test/bit_byteswap_test.cpp
Normal file
26
test/bit_byteswap_test.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Test for boost/core/bit.hpp (byteswap)
|
||||
//
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/bit.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::int8_t)0x01 ), 0x01 );
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint8_t)0xF1 ), 0xF1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::int16_t)0x0102 ), 0x0201 );
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint16_t)0xF1E2 ), 0xE2F1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::int32_t)0x01020304 ), 0x04030201 );
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint32_t)0xF1E2D3C4u ), 0xC4D3E2F1u );
|
||||
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::int64_t)0x0102030405060708ll ), 0x0807060504030201ll );
|
||||
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint64_t)0xF1E2D3C4B5A69788ull ), 0x8897A6B5C4D3E2F1ull );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
37
test/bit_byteswap_test_cx.cpp
Normal file
37
test/bit_byteswap_test_cx.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
// constexpr test for boost/core/bit.hpp (bit_width)
|
||||
//
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
|
||||
#elif defined(BOOST_MSVC) && BOOST_MSVC / 10 == 191
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC is " BOOST_STRINGIZE(BOOST_MSVC) )
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/core/bit.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::int8_t)0x01 ) == 0x01 );
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::uint8_t)0xF1 ) == 0xF1 );
|
||||
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::int16_t)0x0102 ) == 0x0201 );
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::uint16_t)0xF1E2 ) == 0xE2F1 );
|
||||
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::int32_t)0x01020304 ) == 0x04030201 );
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::uint32_t)0xF1E2D3C4u ) == 0xC4D3E2F1u );
|
||||
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::int64_t)0x0102030405060708ll ) == 0x0807060504030201ll );
|
||||
STATIC_ASSERT( boost::core::byteswap( (std::uint64_t)0xF1E2D3C4B5A69788ull ) == 0x8897A6B5C4D3E2F1ull );
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user