diff --git a/include/boost/core/bit.hpp b/include/boost/core/bit.hpp index 68a39be..a6147e4 100644 --- a/include/boost/core/bit.hpp +++ b/include/boost/core/bit.hpp @@ -43,6 +43,16 @@ # define BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL #endif +#if defined(__has_builtin) +# if __has_builtin(__builtin_bit_cast) +# define BOOST_CORE_HAS_BUILTIN_BIT_CAST +# endif +#endif + +#if defined(BOOST_MSVC) && BOOST_MSVC >= 1926 +# define BOOST_CORE_HAS_BUILTIN_BIT_CAST +#endif + namespace boost { namespace core @@ -50,6 +60,16 @@ namespace core // bit_cast +#if defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST) + +template +BOOST_CONSTEXPR To bit_cast( From const & from ) BOOST_NOEXCEPT +{ + return __builtin_bit_cast( To, from ); +} + +#else + template To bit_cast( From const & from ) BOOST_NOEXCEPT { @@ -60,6 +80,8 @@ To bit_cast( From const & from ) BOOST_NOEXCEPT return to; } +#endif + // countl #if defined(__GNUC__) || defined(__clang__) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 73818ef..5f79241 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -304,6 +304,7 @@ run bit_byteswap_test.cpp compile-fail bit_width_fail.cpp : off ; +compile bit_cast_test_cx.cpp ; compile bit_rotate_test_cx.cpp ; compile bit_countr_test_cx.cpp ; compile bit_countl_test_cx.cpp ; diff --git a/test/bit_cast_test_cx.cpp b/test/bit_cast_test_cx.cpp new file mode 100644 index 0000000..33a2b74 --- /dev/null +++ b/test/bit_cast_test_cx.cpp @@ -0,0 +1,24 @@ +// constexpr test for boost/core/bit.hpp (bit_cast) +// +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_NO_CXX11_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined" ) + +#else + +#include +#include + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +STATIC_ASSERT( boost::core::bit_cast( 1.0f ) == 0x3F800000u ); +STATIC_ASSERT( boost::core::bit_cast( 1.0 ) == 0x3FF0000000000000ull ); + +#endif