mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-07 00:19:27 +00:00
AK: Add a 'HostIsLittleEndian' constant and use it instead of BYTE_ORDER
Previously we were using the preprocessor everywhere we needed this constant, so let's move away from that and use a constexpr constant.
This commit is contained in:
parent
b3a295a5bd
commit
94f5389934
35
AK/Endian.h
35
AK/Endian.h
|
@ -35,39 +35,40 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
inline constexpr static bool HostIsLittleEndian = true;
|
||||||
|
#else
|
||||||
|
inline constexpr static bool HostIsLittleEndian = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ALWAYS_INLINE constexpr T convert_between_host_and_little_endian(T value)
|
ALWAYS_INLINE constexpr T convert_between_host_and_little_endian(T value)
|
||||||
{
|
{
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
if constexpr (HostIsLittleEndian || sizeof(T) == 1)
|
||||||
return value;
|
return value;
|
||||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
else if constexpr (sizeof(T) == 8)
|
||||||
if constexpr (sizeof(T) == 8)
|
|
||||||
return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
|
return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
|
||||||
if constexpr (sizeof(T) == 4)
|
else if constexpr (sizeof(T) == 4)
|
||||||
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
|
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
|
||||||
if constexpr (sizeof(T) == 2)
|
else if constexpr (sizeof(T) == 2)
|
||||||
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
|
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
|
||||||
if constexpr (sizeof(T) == 1)
|
else
|
||||||
return value;
|
static_assert(DependentFalse<T>, "Cannot byte-swap values larger than 64-bits");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ALWAYS_INLINE constexpr T convert_between_host_and_big_endian(T value)
|
ALWAYS_INLINE constexpr T convert_between_host_and_big_endian(T value)
|
||||||
{
|
{
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
if constexpr (sizeof(T) == 1 || !HostIsLittleEndian)
|
||||||
if constexpr (sizeof(T) == 8)
|
return value;
|
||||||
|
else if constexpr (sizeof(T) == 8)
|
||||||
return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
|
return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
|
||||||
if constexpr (sizeof(T) == 4)
|
else if constexpr (sizeof(T) == 4)
|
||||||
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
|
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
|
||||||
if constexpr (sizeof(T) == 2)
|
else if constexpr (sizeof(T) == 2)
|
||||||
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
|
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
|
||||||
if constexpr (sizeof(T) == 1)
|
else
|
||||||
return value;
|
static_assert(DependentFalse<T>, "Cannot byte-swap values larger than 64-bits");
|
||||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
||||||
return value;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -176,10 +176,8 @@ static constexpr auto max_representable_power_of_ten_in_u64 = 19;
|
||||||
static_assert(1e19 <= static_cast<double>(NumericLimits<u64>::max()));
|
static_assert(1e19 <= static_cast<double>(NumericLimits<u64>::max()));
|
||||||
static_assert(1e20 >= static_cast<double>(NumericLimits<u64>::max()));
|
static_assert(1e20 >= static_cast<double>(NumericLimits<u64>::max()));
|
||||||
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
static_assert(HostIsLittleEndian, "Float parsing currently assumes little endian, this fact is only used in fast parsing of 8 digits at a time"
|
||||||
# error Float parsing currently assumes little endian, this fact is only used in fast parsing of 8 digits at a time \
|
"\nyou _should_ only need to change read eight_digits to make this big endian compatible.");
|
||||||
you _should_ only need to change read eight_digits to make this big endian compatible.
|
|
||||||
#endif
|
|
||||||
constexpr u64 read_eight_digits(char const* string)
|
constexpr u64 read_eight_digits(char const* string)
|
||||||
{
|
{
|
||||||
u64 val;
|
u64 val;
|
||||||
|
|
|
@ -225,7 +225,7 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(VM& vm, TypedArrayB
|
||||||
// 9. Let elementSize be TypedArrayElementSize(typedArray).
|
// 9. Let elementSize be TypedArrayElementSize(typedArray).
|
||||||
|
|
||||||
// 10. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
|
// 10. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
|
||||||
constexpr bool is_little_endian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
|
constexpr bool is_little_endian = AK::HostIsLittleEndian;
|
||||||
|
|
||||||
// 11. Let expectedBytes be NumericToRawBytes(elementType, expected, isLittleEndian).
|
// 11. Let expectedBytes be NumericToRawBytes(elementType, expected, isLittleEndian).
|
||||||
auto expected_bytes = MUST_OR_THROW_OOM(numeric_to_raw_bytes<T>(vm, expected, is_little_endian));
|
auto expected_bytes = MUST_OR_THROW_OOM(numeric_to_raw_bytes<T>(vm, expected, is_little_endian));
|
||||||
|
|
Loading…
Reference in a new issue