hecl/FourCC: Eliminate undefined behavior within FourCC interface

Type punning like this isn't actually well-defined behavior. Only
casting to char/unsigned char is well defined. This presents a problem
when using FourCC instances in constexpr contexts, given constexpr
contexts are forbidden from having undefined behavior in them.

Because of that, any attempt to use the const char* constructor within a
constexpr context would always result in a compilation error.
This commit is contained in:
Lioncash 2019-08-15 05:34:59 -04:00
parent 0f74cce2ca
commit 06c436b68d
1 changed files with 5 additions and 3 deletions

View File

@ -26,7 +26,7 @@ public:
constexpr FourCC() noexcept = default; constexpr FourCC() noexcept = default;
constexpr FourCC(const FourCC& other) noexcept = default; constexpr FourCC(const FourCC& other) noexcept = default;
constexpr FourCC(FourCC&& other) noexcept = default; constexpr FourCC(FourCC&& other) noexcept = default;
constexpr FourCC(const char* name) noexcept : num(*(uint32_t*)name) {} constexpr FourCC(const char* name) noexcept : fcc{name[0], name[1], name[2], name[3]} {}
constexpr FourCC(uint32_t n) noexcept : num(n) {} constexpr FourCC(uint32_t n) noexcept : num(n) {}
constexpr FourCC& operator=(const FourCC&) noexcept = default; constexpr FourCC& operator=(const FourCC&) noexcept = default;
@ -34,8 +34,10 @@ public:
bool operator==(const FourCC& other) const { return num == other.num; } bool operator==(const FourCC& other) const { return num == other.num; }
bool operator!=(const FourCC& other) const { return num != other.num; } bool operator!=(const FourCC& other) const { return num != other.num; }
bool operator==(const char* other) const { return num == *(uint32_t*)other; } bool operator==(const char* other) const {
bool operator!=(const char* other) const { return num != *(uint32_t*)other; } return std::memcmp(fcc, other, sizeof(fcc)) == 0;
}
bool operator!=(const char* other) const { return !operator==(other); }
bool operator==(int32_t other) const { return num == uint32_t(other); } bool operator==(int32_t other) const { return num == uint32_t(other); }
bool operator!=(int32_t other) const { return num != uint32_t(other); } bool operator!=(int32_t other) const { return num != uint32_t(other); }
bool operator==(uint32_t other) const { return num == other; } bool operator==(uint32_t other) const { return num == other; }