byteswap.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #ifndef BOOST_HASH2_DETAIL_BYTESWAP_HPP_INCLUDED
  2. #define BOOST_HASH2_DETAIL_BYTESWAP_HPP_INCLUDED
  3. // Copyright 2025 Christian Mazakas
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // https://www.boost.org/LICENSE_1_0.txt
  6. #include <boost/hash2/detail/is_constant_evaluated.hpp>
  7. #include <boost/config.hpp>
  8. #include <cstdint>
  9. #if defined(_MSC_VER)
  10. #include <intrin.h>
  11. #endif
  12. namespace boost
  13. {
  14. namespace hash2
  15. {
  16. namespace detail
  17. {
  18. BOOST_CXX14_CONSTEXPR inline std::uint32_t byteswap_impl( std::uint32_t x ) noexcept
  19. {
  20. std::uint32_t step16 = x << 16 | x >> 16;
  21. return ( ( step16 << 8 ) & 0xff00ff00 ) | ( ( step16 >> 8 ) & 0x00ff00ff );
  22. }
  23. BOOST_CXX14_CONSTEXPR inline std::uint64_t byteswap_impl( std::uint64_t x ) noexcept
  24. {
  25. std::uint64_t step32 = x << 32 | x >> 32;
  26. std::uint64_t step16 = ( step32 & 0x0000ffff0000ffffull ) << 16 | ( step32 & 0xffff0000ffff0000ull ) >> 16;
  27. return ( step16 & 0x00ff00ff00ff00ffull ) << 8 | ( step16 & 0xff00ff00ff00ff00ull ) >> 8;
  28. }
  29. BOOST_CXX14_CONSTEXPR inline std::uint32_t byteswap( std::uint32_t x ) noexcept
  30. {
  31. #if defined(__GNUC__) || defined(__clang__)
  32. return __builtin_bswap32( x );
  33. #elif defined(_MSC_VER)
  34. if( !detail::is_constant_evaluated() )
  35. {
  36. return _byteswap_ulong( x );
  37. }
  38. else
  39. {
  40. return byteswap_impl( x );
  41. }
  42. #else
  43. return byteswap_impl( x );
  44. #endif
  45. }
  46. BOOST_CXX14_CONSTEXPR inline std::uint64_t byteswap( std::uint64_t x ) noexcept
  47. {
  48. #if defined(__GNUC__) || defined(__clang__)
  49. return __builtin_bswap64( x );
  50. #elif defined(_MSC_VER)
  51. if( !detail::is_constant_evaluated() )
  52. {
  53. return _byteswap_uint64( x );
  54. }
  55. else
  56. {
  57. return byteswap_impl( x );
  58. }
  59. #else
  60. return byteswap_impl( x );
  61. #endif
  62. }
  63. } // namespace detail
  64. } // namespace hash2
  65. } // namespace boost
  66. #endif // #ifndef BOOST_HASH2_DETAIL_BYTESWAP_HPP_INCLUDED