Skip to content

Commit

Permalink
Fixed constexpr-ness of bx::bitCast.
Browse files Browse the repository at this point in the history
  • Loading branch information
bkaradzic committed Nov 15, 2024
1 parent 109637a commit cf3b711
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 101 deletions.
2 changes: 1 addition & 1 deletion include/bx/bx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename Ty, typename FromT>
constexpr Ty narrowCast(const FromT& _from, Location _location = Location::current() );
Ty narrowCast(const FromT& _from, Location _location = Location::current() );

/// Copy memory block.
///
Expand Down
15 changes: 9 additions & 6 deletions include/bx/inline/bx.inl
Original file line number Diff line number Diff line change
Expand Up @@ -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<FromT>()
, "bx::bitCast failed! FromT must be trivially copyable."
);
static_assert(isTriviallyCopyable<Ty>()
, "bx::bitCast failed! Ty must be trivially copyable."
);
static_assert(isTriviallyConstructible<Ty>()
, "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<typename Ty, typename FromT>
inline constexpr Ty narrowCast(const FromT& _from, Location _location)
inline Ty narrowCast(const FromT& _from, Location _location)
{
Ty to = static_cast<Ty>(_from);
BX_ASSERT_LOC(_location, static_cast<FromT>(to) == _from
Expand Down
18 changes: 6 additions & 12 deletions include/bx/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 //
Expand Down Expand Up @@ -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"
Expand Down
87 changes: 5 additions & 82 deletions tests/cast_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,89 +7,12 @@
#include <bx/bx.h>
#include <string.h>

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<uint64_t>(d64v);
const double result = bx::bitCast<double>(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<double>(u64v);
const uint64_t result = bx::bitCast<uint64_t>(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<uint64_t>(19880124.0) );
STATIC_REQUIRE(0x3fe9000000000000ull == bx::bitCast<uint64_t>(0.781250) );
STATIC_REQUIRE(19880124.0 == bx::bitCast<double>(0x4172f58bc0000000ull) );
STATIC_REQUIRE(0.781250 == bx::bitCast<double>(0x3fe9000000000000ull) );
}

TEST_CASE("Narrow cast", "[cast]")
Expand Down

0 comments on commit cf3b711

Please sign in to comment.