diff --git a/include/bx/bx.h b/include/bx/bx.h index 8da9816..1ca44ec 100644 --- a/include/bx/bx.h +++ b/include/bx/bx.h @@ -223,7 +223,7 @@ namespace bx /// Performs `static_cast` of value `_from`, and in debug build runtime verifies/asserts /// that the value didn't change. template - constexpr Ty narrowCast(const FromT& _from, Location _location = Location::current() ); + Ty narrowCast(const FromT& _from, Location _location = Location::current() ); /// Copy memory block. /// diff --git a/include/bx/inline/bx.inl b/include/bx/inline/bx.inl index 9745e1a..ef0933c 100644 --- a/include/bx/inline/bx.inl +++ b/include/bx/inline/bx.inl @@ -153,18 +153,21 @@ namespace bx static_assert(sizeof(Ty) == sizeof(FromT) , "bx::bitCast failed! Ty and FromT must be the same size." ); + static_assert(isTriviallyCopyable() + , "bx::bitCast failed! FromT must be trivially copyable." + ); + static_assert(isTriviallyCopyable() + , "bx::bitCast failed! Ty must be trivially copyable." + ); static_assert(isTriviallyConstructible() - , "bx::bitCast failed! Destination target must be trivially constructible." + , "bx::bitCast failed! Ty must be trivially constructible." ); - Ty to; - memCopy(&to, &_from, sizeof(Ty) ); - - return to; + return __builtin_bit_cast(Ty, _from); } template - inline constexpr Ty narrowCast(const FromT& _from, Location _location) + inline Ty narrowCast(const FromT& _from, Location _location) { Ty to = static_cast(_from); BX_ASSERT_LOC(_location, static_cast(to) == _from diff --git a/include/bx/platform.h b/include/bx/platform.h index abbd1c0..4560d7a 100644 --- a/include/bx/platform.h +++ b/include/bx/platform.h @@ -342,18 +342,6 @@ # define BX_COMPILER_NAME "MSVC 17.0" # elif BX_COMPILER_MSVC >= 1920 // Visual Studio 2019 # define BX_COMPILER_NAME "MSVC 16.0" -# elif BX_COMPILER_MSVC >= 1910 // Visual Studio 2017 -# define BX_COMPILER_NAME "MSVC 15.0" -# elif BX_COMPILER_MSVC >= 1900 // Visual Studio 2015 -# define BX_COMPILER_NAME "MSVC 14.0" -# elif BX_COMPILER_MSVC >= 1800 // Visual Studio 2013 -# define BX_COMPILER_NAME "MSVC 12.0" -# elif BX_COMPILER_MSVC >= 1700 // Visual Studio 2012 -# define BX_COMPILER_NAME "MSVC 11.0" -# elif BX_COMPILER_MSVC >= 1600 // Visual Studio 2010 -# define BX_COMPILER_NAME "MSVC 10.0" -# elif BX_COMPILER_MSVC >= 1500 // Visual Studio 2008 -# define BX_COMPILER_NAME "MSVC 9.0" # else # define BX_COMPILER_NAME "MSVC" # endif // @@ -481,6 +469,12 @@ static_assert(!BX_COMPILER_GCC || BX_COMPILER_GCC >= 80400, "\n\n" "\tMinimum supported GCC version is 8.4 (March 4, 2020).\n" "\t\n"); +// https://learn.microsoft.com/en-us/visualstudio/releases/2019/history +static_assert(!BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1927, "\n\n" + "\t** IMPORTANT! **\n\n" + "\tMinimum supported MSVC 19.27 / Visual Studio 2019 version 16.7 (August 5, 2020).\n" + "\t\n"); + static_assert(!BX_CPU_ENDIAN_BIG, "\n\n" "\t** IMPORTANT! **\n\n" "\tThe code was not tested for big endian, and big endian CPU is considered unsupported.\n" diff --git a/tests/cast_test.cpp b/tests/cast_test.cpp index abe3470..b4163cf 100644 --- a/tests/cast_test.cpp +++ b/tests/cast_test.cpp @@ -7,89 +7,12 @@ #include #include -namespace bx +TEST_CASE("Bit cast", "[cast]") { - extern void memCopyRef(void* _dst, const void* _src, size_t _numBytes); -} - -TEST_CASE("Bit cast round trip test using double to uint64_t", "[cast]") -{ - constexpr double d64v = 19880124.0; - REQUIRE(sizeof(double) == sizeof(uint64_t) ); - - SECTION("bx::bitCast") - { - const uint64_t u64v = bx::bitCast(d64v); - const double result = bx::bitCast(u64v); - REQUIRE(result == d64v); - } - - SECTION("bx::memCopy") - { - uint64_t u64v = 0; - double result = 0; - bx::memCopy(&u64v, &d64v, sizeof(uint64_t) ); - bx::memCopy(&result, &u64v, sizeof(double) ); - REQUIRE(result == d64v); - } - - SECTION("bx::memCopyRef") - { - uint64_t u64v = 0; - double result = 0; - bx::memCopyRef(&u64v, &d64v, sizeof(uint64_t) ); - bx::memCopyRef(&result, &u64v, sizeof(double) ); - REQUIRE(result == d64v); - } - - SECTION("::memcpy") - { - uint64_t u64v = 0; - double result = 0; - ::memcpy(&u64v, &d64v, sizeof(uint64_t) ); - ::memcpy(&result, &u64v, sizeof(double) ); - REQUIRE(result == d64v); - } -} - -TEST_CASE("Bit cast round trip test using uint64_t to double", "[cast]") -{ - constexpr uint64_t u64v = 0x3fe9000000000000ull; - REQUIRE(sizeof(uint64_t) == sizeof(double) ); - - SECTION("bx::bitCast") - { - const double d64v = bx::bitCast(u64v); - const uint64_t result = bx::bitCast(d64v); - REQUIRE(result == u64v); - } - - SECTION("bx::memCopy") - { - double d64v = 0; - uint64_t result = 0; - bx::memCopy(&d64v, &u64v, sizeof(double) ); - bx::memCopy(&result, &d64v, sizeof(uint64_t) ); - REQUIRE(result == u64v); - } - - SECTION("bx::memCopyRef") - { - double d64v = 0; - uint64_t result = 0; - bx::memCopyRef(&d64v, &u64v, sizeof(double) ); - bx::memCopyRef(&result, &d64v, sizeof(uint64_t) ); - REQUIRE(result == u64v); - } - - SECTION("::memcpy") - { - double d64v = 0; - uint64_t result = 0; - ::memcpy(&d64v, &u64v, sizeof(double) ); - ::memcpy(&result, &d64v, sizeof(uint64_t) ); - REQUIRE(result == u64v); - } + STATIC_REQUIRE(0x4172f58bc0000000ull == bx::bitCast(19880124.0) ); + STATIC_REQUIRE(0x3fe9000000000000ull == bx::bitCast(0.781250) ); + STATIC_REQUIRE(19880124.0 == bx::bitCast(0x4172f58bc0000000ull) ); + STATIC_REQUIRE(0.781250 == bx::bitCast(0x3fe9000000000000ull) ); } TEST_CASE("Narrow cast", "[cast]")