Skip to content

Commit cffc99f

Browse files
committed
fix review
1 parent 98984a6 commit cffc99f

File tree

2 files changed

+27
-57
lines changed

2 files changed

+27
-57
lines changed

src/iceberg/util/endian.h

Lines changed: 24 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121

2222
#include <bit>
2323
#include <concepts>
24+
#include <cstdint>
2425

2526
/// \file iceberg/util/endian.h
2627
/// \brief Endianness conversion utilities
2728

2829
namespace iceberg {
2930

30-
/// \brief Concept for values that can be written in little-endian format.
31+
/// \brief Concept for values that can be converted to/from another endian format.
3132
template <typename T>
3233
concept EndianConvertible = std::is_arithmetic_v<T> && !std::same_as<T, bool>;
3334

@@ -37,20 +38,7 @@ constexpr T ToLittleEndian(T value) {
3738
if constexpr (std::endian::native == std::endian::little || sizeof(T) <= 1) {
3839
return value;
3940
} else {
40-
if constexpr (std::is_integral_v<T>) {
41-
return std::byteswap(value);
42-
} else if constexpr (std::is_floating_point_v<T>) {
43-
// For floats, use the bit_cast -> byteswap -> bit_cast pattern.
44-
if constexpr (sizeof(T) == sizeof(uint32_t)) {
45-
uint32_t int_representation = std::bit_cast<uint32_t>(value);
46-
int_representation = std::byteswap(int_representation);
47-
return std::bit_cast<T>(int_representation);
48-
} else if constexpr (sizeof(T) == sizeof(uint64_t)) {
49-
uint64_t int_representation = std::bit_cast<uint64_t>(value);
50-
int_representation = std::byteswap(int_representation);
51-
return std::bit_cast<T>(int_representation);
52-
}
53-
}
41+
return ByteSwap(value);
5442
}
5543
}
5644

@@ -60,20 +48,7 @@ constexpr T FromLittleEndian(T value) {
6048
if constexpr (std::endian::native == std::endian::little || sizeof(T) <= 1) {
6149
return value;
6250
} else {
63-
if constexpr (std::is_integral_v<T>) {
64-
return std::byteswap(value);
65-
} else if constexpr (std::is_floating_point_v<T>) {
66-
// For floats, use the bit_cast -> byteswap -> bit_cast pattern.
67-
if constexpr (sizeof(T) == sizeof(uint32_t)) {
68-
uint32_t int_representation = std::bit_cast<uint32_t>(value);
69-
int_representation = std::byteswap(int_representation);
70-
return std::bit_cast<T>(int_representation);
71-
} else if constexpr (sizeof(T) == sizeof(uint64_t)) {
72-
uint64_t int_representation = std::bit_cast<uint64_t>(value);
73-
int_representation = std::byteswap(int_representation);
74-
return std::bit_cast<T>(int_representation);
75-
}
76-
}
51+
return ByteSwap(value);
7752
}
7853
}
7954

@@ -83,19 +58,7 @@ constexpr T ToBigEndian(T value) {
8358
if constexpr (std::endian::native == std::endian::big || sizeof(T) <= 1) {
8459
return value;
8560
} else {
86-
if constexpr (std::is_integral_v<T>) {
87-
return std::byteswap(value);
88-
} else if constexpr (std::is_floating_point_v<T>) {
89-
if constexpr (sizeof(T) == sizeof(uint32_t)) {
90-
uint32_t int_representation = std::bit_cast<uint32_t>(value);
91-
int_representation = std::byteswap(int_representation);
92-
return std::bit_cast<T>(int_representation);
93-
} else if constexpr (sizeof(T) == sizeof(uint64_t)) {
94-
uint64_t int_representation = std::bit_cast<uint64_t>(value);
95-
int_representation = std::byteswap(int_representation);
96-
return std::bit_cast<T>(int_representation);
97-
}
98-
}
61+
return ByteSwap(value);
9962
}
10063
}
10164

@@ -105,18 +68,25 @@ constexpr T FromBigEndian(T value) {
10568
if constexpr (std::endian::native == std::endian::big || sizeof(T) <= 1) {
10669
return value;
10770
} else {
108-
if constexpr (std::is_integral_v<T>) {
109-
return std::byteswap(value);
110-
} else if constexpr (std::is_floating_point_v<T>) {
111-
if constexpr (sizeof(T) == sizeof(uint32_t)) {
112-
uint32_t int_representation = std::bit_cast<uint32_t>(value);
113-
int_representation = std::byteswap(int_representation);
114-
return std::bit_cast<T>(int_representation);
115-
} else if constexpr (sizeof(T) == sizeof(uint64_t)) {
116-
uint64_t int_representation = std::bit_cast<uint64_t>(value);
117-
int_representation = std::byteswap(int_representation);
118-
return std::bit_cast<T>(int_representation);
119-
}
71+
return ByteSwap(value);
72+
}
73+
}
74+
75+
/// \brief Byte-swap a value. For floating-point types, only support 32-bit and 64-bit
76+
/// floats.
77+
template <EndianConvertible T>
78+
constexpr T ByteSwap(T value) {
79+
if constexpr (sizeof(T) <= 1) {
80+
return value;
81+
} else if constexpr (std::is_integral_v<T>) {
82+
return std::byteswap(value);
83+
} else if constexpr (std::is_floating_point_v<T>) {
84+
if constexpr (sizeof(T) == sizeof(uint32_t)) {
85+
return std::bit_cast<T>(std::byteswap(std::bit_cast<uint32_t>(value)));
86+
} else if constexpr (sizeof(T) == sizeof(uint64_t)) {
87+
return std::bit_cast<T>(std::byteswap(std::bit_cast<uint64_t>(value)));
88+
} else {
89+
static_assert(false, "Unsupported floating-point size for endian conversion.");
12090
}
12191
}
12292
}

test/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ add_iceberg_test(json_serde_test
8686

8787
add_iceberg_test(util_test
8888
SOURCES
89-
formatter_test.cc
9089
config_test.cc
91-
visit_type_test.cc
90+
endian_test.cc
91+
formatter_test.cc
9292
string_utils_test.cc
93-
endian_test.cc)
93+
visit_type_test.cc)
9494

9595
if(ICEBERG_BUILD_BUNDLE)
9696
add_iceberg_test(avro_test

0 commit comments

Comments
 (0)