From fbc198e75d38f8d8fe2f964cd4be8055c8c5b6d6 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 20 Oct 2019 21:28:38 +0300 Subject: [PATCH] Add __int128 support to endian_reverse --- .../boost/endian/detail/endian_reverse.hpp | 14 +++- .../boost/endian/detail/integral_by_size.hpp | 10 +++ test/endian_reverse_test.cpp | 67 +++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/include/boost/endian/detail/endian_reverse.hpp b/include/boost/endian/detail/endian_reverse.hpp index 5761b2c..4fd71bb 100644 --- a/include/boost/endian/detail/endian_reverse.hpp +++ b/include/boost/endian/detail/endian_reverse.hpp @@ -62,7 +62,7 @@ inline uint16_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint16_t x ) BOOST_N #endif } -inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint32_t x) BOOST_NOEXCEPT +inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint32_t x ) BOOST_NOEXCEPT { #ifdef BOOST_ENDIAN_NO_INTRINSICS @@ -76,7 +76,7 @@ inline uint32_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint32_t x) BOOST_NOE #endif } -inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint64_t x) BOOST_NOEXCEPT +inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint64_t x ) BOOST_NOEXCEPT { #ifdef BOOST_ENDIAN_NO_INTRINSICS @@ -91,6 +91,16 @@ inline uint64_t BOOST_ENDIAN_CONSTEXPR endian_reverse_impl(uint64_t x) BOOST_NOE # endif } +#if defined(BOOST_HAS_INT128) + +inline uint128_type BOOST_ENDIAN_CONSTEXPR endian_reverse_impl( uint128_type x ) BOOST_NOEXCEPT +{ + return endian_reverse_impl( static_cast( x >> 64 ) ) | + static_cast( endian_reverse_impl( static_cast( x ) ) ) << 64; +} + +#endif + } // namespace detail // Requires: diff --git a/include/boost/endian/detail/integral_by_size.hpp b/include/boost/endian/detail/integral_by_size.hpp index b0fd885..d53ee17 100644 --- a/include/boost/endian/detail/integral_by_size.hpp +++ b/include/boost/endian/detail/integral_by_size.hpp @@ -7,6 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt #include +#include #include namespace boost @@ -40,6 +41,15 @@ template<> struct integral_by_size<8> typedef uint64_t type; }; +#if defined(BOOST_HAS_INT128) + +template<> struct integral_by_size<16> +{ + typedef uint128_type type; +}; + +#endif + } // namespace detail } // namespace endian } // namespace boost diff --git a/test/endian_reverse_test.cpp b/test/endian_reverse_test.cpp index 9dbba16..fa0f907 100644 --- a/test/endian_reverse_test.cpp +++ b/test/endian_reverse_test.cpp @@ -72,6 +72,24 @@ template T const test_value::w1; template T const test_value::v2; template T const test_value::w2; +#if defined(BOOST_HAS_INT128) + +template struct test_value +{ + static const T v1 = static_cast( 0x1F2E3D4C5B6A7988ull ) << 64 | static_cast( 0xF1E2D3C4B5A69780ull ); + static const T w1 = static_cast( 0x8097A6B5C4D3E2F1ull ) << 64 | static_cast( 0x88796A5B4C3D2E1Full ); + + static const T v2 = static_cast( 0xF1E2D3C4B5A69788ull ) << 64 | static_cast( 0x1F2E3D4C5B6A7980ull ); + static const T w2 = static_cast( 0x80796A5B4C3D2E1Full ) << 64 | static_cast( 0x8897A6B5C4D3E2F1ull ); +}; + +template T const test_value::v1; +template T const test_value::w1; +template T const test_value::v2; +template T const test_value::w2; + +#endif // #if defined(BOOST_HAS_INT128) + template void test() { using boost::endian::endian_reverse; @@ -114,6 +132,48 @@ template void test() } } +template void test_np() +{ + using boost::endian::endian_reverse; + using boost::endian::endian_reverse_inplace; + + { + T t1 = test_value::v1; + + T t2 = endian_reverse( t1 ); + BOOST_TEST( t2 == test_value::w1 ); + + T t3 = endian_reverse( t2 ); + BOOST_TEST( t3 == t1 ); + + T t4 = t1; + + endian_reverse_inplace( t4 ); + BOOST_TEST( t4 == test_value::w1 ); + + endian_reverse_inplace( t4 ); + BOOST_TEST( t4 == t1 ); + } + + { + T t1 = test_value::v2; + + T t2 = endian_reverse( t1 ); + BOOST_TEST( t2 == test_value::w2 ); + + T t3 = endian_reverse( t2 ); + BOOST_TEST( t3 == t1 ); + + T t4 = t1; + + endian_reverse_inplace( t4 ); + BOOST_TEST( t4 == test_value::w2 ); + + endian_reverse_inplace( t4 ); + BOOST_TEST( t4 == t1 ); + } +} + int main() { test(); @@ -152,5 +212,12 @@ int main() test(); #endif +#if defined(BOOST_HAS_INT128) + + test_np(); + test_np(); + +#endif + return boost::report_errors(); }