This is an automated email from the ASF dual-hosted git repository.
panxiaolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new dccc25983b8 [Chore](compile) use std::endian to replace BYTE_ORDER
(#52425)
dccc25983b8 is described below
commit dccc25983b8d3fcabc748dd6c8eb718d593e8420
Author: Pxl <[email protected]>
AuthorDate: Mon Jun 30 10:16:17 2025 +0800
[Chore](compile) use std::endian to replace BYTE_ORDER (#52425)
use std::endian to replace BYTE_ORDER
---
be/src/gutil/endian.h | 257 +++++---------------
be/src/olap/key_coder.h | 41 +---
be/src/olap/tablet_meta_manager.cpp | 11 +-
be/src/olap/uint24.h | 4 +-
be/src/util/bit_util.h | 266 ---------------------
be/src/util/byte_stream_split.cpp | 38 +--
be/src/util/coding.h | 49 +---
be/src/util/hash_util.hpp | 30 ++-
be/src/vec/common/format_ip.h | 6 +-
.../exec/format/parquet/parquet_column_convert.h | 4 +-
be/src/vec/exec/format/parquet/parquet_pred_cmp.h | 3 +-
be/src/vec/functions/function_string.h | 44 ++--
be/test/util/bit_util_test.cpp | 22 +-
13 files changed, 161 insertions(+), 614 deletions(-)
diff --git a/be/src/gutil/endian.h b/be/src/gutil/endian.h
index 33430eec0db..b59e8503356 100644
--- a/be/src/gutil/endian.h
+++ b/be/src/gutil/endian.h
@@ -32,6 +32,7 @@
#include <assert.h>
+#include "olap/uint24.h"
#include "vec/core/wide_integer.h"
// Portable handling of unaligned loads, stores, and copies.
@@ -160,138 +161,68 @@ inline uint32_t bswap_24(uint32_t x) {
return ((x & 0x0000ffULL) << 16) | ((x & 0x00ff00ULL)) | ((x &
0xff0000ULL) >> 16);
}
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-
-// Definitions for ntohl etc. that don't require us to include
-// netinet/in.h. We wrap bswap_32 and bswap_16 in functions rather
-// than just #defining them because in debug mode, gcc doesn't
-// correctly handle the (rather involved) definitions of bswap_32.
-// gcc guarantees that inline functions are as fast as macros, so
-// this isn't a performance hit.
-inline uint16_t ghtons(uint16_t x) {
- return bswap_16(x);
-}
-inline uint32_t ghtonl(uint32_t x) {
- return bswap_32(x);
-}
-inline uint64_t ghtonll(uint64_t x) {
- return gbswap_64(x);
+template <typename T>
+T byte_swap(T x) {
+ if constexpr (sizeof(T) == sizeof(wide::Int256)) {
+ return gbswap_256(x);
+ } else if constexpr (sizeof(T) == sizeof(__int128)) {
+ return gbswap_128(x);
+ } else if constexpr (sizeof(T) == sizeof(int64_t)) {
+ return bswap_64(x);
+ } else if constexpr (sizeof(T) == sizeof(int32_t)) {
+ return bswap_32(x);
+ } else if constexpr (sizeof(T) == sizeof(doris::uint24_t)) {
+ return bswap_24(x);
+ } else if constexpr (sizeof(T) == sizeof(int16_t)) {
+ return bswap_16(x);
+ } else {
+ static_assert(sizeof(T) == 1, "Unsupported type size for byte_swap");
+ return x; // No byte swap needed for unsupported types
+ }
}
-#else
-
-// These definitions are simpler on big-endian machines
-// These are functions instead of macros to avoid self-assignment warnings
-// on calls such as "i = ghtnol(i);". This also provides type checking.
-inline uint16_t ghtons(uint16_t x) {
- return x;
-}
-inline uint32_t ghtonl(uint32_t x) {
- return x;
-}
-inline uint64_t ghtonll(uint64_t x) {
- return x;
+template <std::endian target, typename T>
+T to_endian(T value) {
+ if constexpr (std::endian::native == target) {
+ return value; // No swap needed
+ } else {
+ static_assert(std::endian::native == std::endian::big ||
+ std::endian::native == std::endian::little,
+ "Unsupported endianness");
+ return byte_swap(value);
+ }
}
-#endif // bytesex
-
-// ntoh* and hton* are the same thing for any size and bytesex,
-// since the function is an involution, i.e., its own inverse.
-#if !defined(__APPLE__)
-// This one is safe to take as it's an extension
-#define htonll(x) ghtonll(x)
-#define ntohll(x) htonll(x)
-#endif
-
// Utilities to convert numbers between the current hosts's native byte
// order and little-endian byte order
//
// Load/Store methods are alignment safe
class LittleEndian {
public:
- // Conversion functions.
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-
- static uint16_t FromHost16(uint16_t x) { return x; }
- static uint16_t ToHost16(uint16_t x) { return x; }
-
- static uint32_t FromHost32(uint32_t x) { return x; }
- static uint32_t ToHost32(uint32_t x) { return x; }
-
- static uint64_t FromHost64(uint64_t x) { return x; }
- static uint64_t ToHost64(uint64_t x) { return x; }
-
- static unsigned __int128 FromHost128(unsigned __int128 x) { return x; }
- static unsigned __int128 ToHost128(unsigned __int128 x) { return x; }
-
- static wide::UInt256 FromHost256(wide::UInt256 x) { return x; }
- static wide::UInt256 ToHost256(wide::UInt256 x) { return x; }
-
- static bool IsLittleEndian() { return true; }
-
-#else
-
- static uint16_t FromHost16(uint16_t x) { return bswap_16(x); }
- static uint16_t ToHost16(uint16_t x) { return bswap_16(x); }
-
- static uint32_t FromHost32(uint32_t x) { return bswap_32(x); }
- static uint32_t ToHost32(uint32_t x) { return bswap_32(x); }
-
- static uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
- static uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
-
- static unsigned __int128 FromHost128(unsigned __int128 x) { return
gbswap_128(x); }
- static unsigned __int128 ToHost128(unsigned __int128 x) { return
gbswap_128(x); }
+ // Functions to do unaligned loads and stores in little-endian order.
+ static uint16_t Load16(const void* p) {
+ return to_endian<std::endian::little>(UNALIGNED_LOAD16(p));
+ }
- static wide::UInt256 FromHost256(wide::UInt256 x) { return gbswap_256(x); }
- static wide::UInt256 ToHost256(wide::UInt256 x) { return gbswap_256(x); }
+ static void Store16(void* p, uint16_t v) {
+ UNALIGNED_STORE16(p, to_endian<std::endian::little>(v));
+ }
- static bool IsLittleEndian() { return false; }
+ static uint32_t Load32(const void* p) {
+ return to_endian<std::endian::little>(UNALIGNED_LOAD32(p));
+ }
-#endif /* ENDIAN */
+ static void Store32(void* p, uint32_t v) {
+ UNALIGNED_STORE32(p, to_endian<std::endian::little>(v));
+ }
- // Functions to do unaligned loads and stores in little-endian order.
- static uint16_t Load16(const void* p) { return
ToHost16(UNALIGNED_LOAD16(p)); }
-
- static void Store16(void* p, uint16_t v) { UNALIGNED_STORE16(p,
FromHost16(v)); }
-
- static uint32_t Load32(const void* p) { return
ToHost32(UNALIGNED_LOAD32(p)); }
-
- static void Store32(void* p, uint32_t v) { UNALIGNED_STORE32(p,
FromHost32(v)); }
-
- static uint64_t Load64(const void* p) { return
ToHost64(UNALIGNED_LOAD64(p)); }
-
- // Build a uint64_t from 1-8 bytes.
- // 8 * len least significant bits are loaded from the memory with
- // LittleEndian order. The 64 - 8 * len most significant bits are
- // set all to 0.
- // In latex-friendly words, this function returns:
- // $\sum_{i=0}^{len-1} p[i] 256^{i}$, where p[i] is unsigned.
- //
- // This function is equivalent with:
- // uint64_t val = 0;
- // memcpy(&val, p, len);
- // return ToHost64(val);
- // TODO(user): write a small benchmark and benchmark the speed
- // of a memcpy based approach.
- //
- // For speed reasons this function does not work for len == 0.
- // The caller needs to guarantee that 1 <= len <= 8.
- static uint64_t Load64VariableLength(const void* const p, int len) {
- assert(len >= 1 && len <= 8);
- const char* const buf = static_cast<const char*>(p);
- uint64_t val = 0;
- --len;
- do {
- val = (val << 8) | buf[len];
- // (--len >= 0) is about 10 % faster than (len--) in some
benchmarks.
- } while (--len >= 0);
- // No ToHost64(...) needed. The bytes are accessed in little-endian
manner
- // on every architecture.
- return val;
+ static uint64_t Load64(const void* p) {
+ return to_endian<std::endian::little>(UNALIGNED_LOAD64(p));
}
- static void Store64(void* p, uint64_t v) { UNALIGNED_STORE64(p,
FromHost64(v)); }
+ static void Store64(void* p, uint64_t v) {
+ UNALIGNED_STORE64(p, to_endian<std::endian::little>(v));
+ }
};
// Utilities to convert numbers between the current hosts's native byte
@@ -300,88 +231,30 @@ public:
// Load/Store methods are alignment safe
class BigEndian {
public:
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-
- static uint16_t FromHost16(uint16_t x) { return bswap_16(x); }
- static uint16_t ToHost16(uint16_t x) { return bswap_16(x); }
-
- static uint32_t FromHost24(uint32_t x) { return bswap_24(x); }
- static uint32_t ToHost24(uint32_t x) { return bswap_24(x); }
-
- static uint32_t FromHost32(uint32_t x) { return bswap_32(x); }
- static uint32_t ToHost32(uint32_t x) { return bswap_32(x); }
-
- static uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
- static uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
-
- static unsigned __int128 FromHost128(unsigned __int128 x) { return
gbswap_128(x); }
- static unsigned __int128 ToHost128(unsigned __int128 x) { return
gbswap_128(x); }
-
- static wide::UInt256 FromHost256(wide::UInt256 x) { return gbswap_256(x); }
- static wide::UInt256 ToHost256(wide::UInt256 x) { return gbswap_256(x); }
-
- static bool IsLittleEndian() { return true; }
-
-#else
-
- static uint16_t FromHost16(uint16_t x) { return x; }
- static uint16_t ToHost16(uint16_t x) { return x; }
-
- static uint32_t FromHost24(uint32_t x) { return x; }
- static uint32_t ToHost24(uint32_t x) { return x; }
-
- static uint32_t FromHost32(uint32_t x) { return x; }
- static uint32_t ToHost32(uint32_t x) { return x; }
+ // Functions to do unaligned loads and stores in little-endian order.
+ static uint16_t Load16(const void* p) {
+ return to_endian<std::endian::big>(UNALIGNED_LOAD16(p));
+ }
- static uint64_t FromHost64(uint64_t x) { return x; }
- static uint64_t ToHost64(uint64_t x) { return x; }
+ static void Store16(void* p, uint16_t v) {
+ UNALIGNED_STORE16(p, to_endian<std::endian::big>(v));
+ }
- static wide::UInt256 FromHost256(wide::UInt256 x) { return x; }
- static wide::UInt256 ToHost256(wide::UInt256 x) { return x; }
+ static uint32_t Load32(const void* p) {
+ return to_endian<std::endian::big>(UNALIGNED_LOAD32(p));
+ }
- static bool IsLittleEndian() { return false; }
+ static void Store32(void* p, uint32_t v) {
+ UNALIGNED_STORE32(p, to_endian<std::endian::big>(v));
+ }
-#endif /* ENDIAN */
- // Functions to do unaligned loads and stores in little-endian order.
- static uint16_t Load16(const void* p) { return
ToHost16(UNALIGNED_LOAD16(p)); }
-
- static void Store16(void* p, uint16_t v) { UNALIGNED_STORE16(p,
FromHost16(v)); }
-
- static uint32_t Load32(const void* p) { return
ToHost32(UNALIGNED_LOAD32(p)); }
-
- static void Store32(void* p, uint32_t v) { UNALIGNED_STORE32(p,
FromHost32(v)); }
-
- static uint64_t Load64(const void* p) { return
ToHost64(UNALIGNED_LOAD64(p)); }
-
- // Build a uint64_t from 1-8 bytes.
- // 8 * len least significant bits are loaded from the memory with
- // BigEndian order. The 64 - 8 * len most significant bits are
- // set all to 0.
- // In latex-friendly words, this function returns:
- // $\sum_{i=0}^{len-1} p[i] 256^{i}$, where p[i] is unsigned.
- //
- // This function is equivalent with:
- // uint64_t val = 0;
- // memcpy(&val, p, len);
- // return ToHost64(val);
- // TODO(user): write a small benchmark and benchmark the speed
- // of a memcpy based approach.
- //
- // For speed reasons this function does not work for len == 0.
- // The caller needs to guarantee that 1 <= len <= 8.
- static uint64_t Load64VariableLength(const void* const p, int len) {
- assert(len >= 1 && len <= 8);
- uint64_t val = Load64(p);
- uint64_t mask = 0;
- --len;
- do {
- mask = (mask << 8) | 0xff;
- // (--len >= 0) is about 10 % faster than (len--) in some
benchmarks.
- } while (--len >= 0);
- return val & mask;
+ static uint64_t Load64(const void* p) {
+ return to_endian<std::endian::big>(UNALIGNED_LOAD64(p));
}
- static void Store64(void* p, uint64_t v) { UNALIGNED_STORE64(p,
FromHost64(v)); }
+ static void Store64(void* p, uint64_t v) {
+ UNALIGNED_STORE64(p, to_endian<std::endian::big>(v));
+ }
}; // BigEndian
// Network byte order is big-endian
diff --git a/be/src/olap/key_coder.h b/be/src/olap/key_coder.h
index c53d7a6ee47..8f4d110e518 100644
--- a/be/src/olap/key_coder.h
+++ b/be/src/olap/key_coder.h
@@ -89,31 +89,6 @@ public:
using CppType = typename CppTypeTraits<field_type>::CppType;
using UnsignedCppType = typename
CppTypeTraits<field_type>::UnsignedCppType;
-private:
- // Swap value's endian from/to big endian
- static UnsignedCppType swap_big_endian(UnsignedCppType val) {
- if constexpr (field_type == FieldType::OLAP_FIELD_TYPE_DECIMAL256) {
- return BigEndian::FromHost256(val);
- } else {
- switch (sizeof(UnsignedCppType)) {
- case 1:
- return val;
- case 2:
- return BigEndian::FromHost16(val);
- case 4:
- return BigEndian::FromHost32(val);
- case 8:
- return BigEndian::FromHost64(val);
- case 16:
- return BigEndian::FromHost128(val);
- default:
- throw Exception(Status::FatalError("Invalid type to big
endian, type={}, size={}",
- int(field_type),
sizeof(UnsignedCppType)));
- }
- }
- }
-
-public:
static void full_encode_ascending(const void* value, std::string* buf) {
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, value, sizeof(unsigned_val));
@@ -123,7 +98,7 @@ public:
(static_cast<UnsignedCppType>(1) <<
(sizeof(UnsignedCppType) * CHAR_BIT - 1));
}
// make it bigendian
- unsigned_val = swap_big_endian(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
buf->append((char*)&unsigned_val, sizeof(unsigned_val));
}
@@ -141,7 +116,7 @@ public:
}
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
- unsigned_val = swap_big_endian(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
if (std::is_signed<CppType>::value) {
unsigned_val ^=
(static_cast<UnsignedCppType>(1) <<
(sizeof(UnsignedCppType) * CHAR_BIT - 1));
@@ -164,7 +139,7 @@ public:
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, value, sizeof(unsigned_val));
// make it bigendian
- unsigned_val = BigEndian::FromHost24(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
buf->append((char*)&unsigned_val, sizeof(unsigned_val));
}
@@ -179,7 +154,7 @@ public:
}
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
- unsigned_val = BigEndian::FromHost24(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
encoded_key->remove_prefix(sizeof(UnsignedCppType));
return Status::OK();
@@ -198,7 +173,7 @@ public:
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, value, sizeof(unsigned_val));
// make it bigendian
- unsigned_val = BigEndian::FromHost32(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
buf->append((char*)&unsigned_val, sizeof(unsigned_val));
}
@@ -214,7 +189,7 @@ public:
}
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
- unsigned_val = BigEndian::FromHost32(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
encoded_key->remove_prefix(sizeof(UnsignedCppType));
return Status::OK();
@@ -233,7 +208,7 @@ public:
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, value, sizeof(unsigned_val));
// make it bigendian
- unsigned_val = BigEndian::FromHost64(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
buf->append((char*)&unsigned_val, sizeof(unsigned_val));
}
@@ -249,7 +224,7 @@ public:
}
UnsignedCppType unsigned_val;
memcpy(&unsigned_val, encoded_key->data, sizeof(UnsignedCppType));
- unsigned_val = BigEndian::FromHost64(unsigned_val);
+ unsigned_val = to_endian<std::endian::big>(unsigned_val);
memcpy(cell_ptr, &unsigned_val, sizeof(UnsignedCppType));
encoded_key->remove_prefix(sizeof(UnsignedCppType));
return Status::OK();
diff --git a/be/src/olap/tablet_meta_manager.cpp
b/be/src/olap/tablet_meta_manager.cpp
index 7c08d785620..62c7a2d8ea6 100644
--- a/be/src/olap/tablet_meta_manager.cpp
+++ b/be/src/olap/tablet_meta_manager.cpp
@@ -24,7 +24,6 @@
#include <boost/algorithm/string/trim.hpp>
#include <fstream>
-#include <memory>
#include <string>
#include <vector>
@@ -213,8 +212,8 @@ std::string
TabletMetaManager::encode_delete_bitmap_key(TTabletId tablet_id, int
std::string key;
key.reserve(20);
key.append(DELETE_BITMAP);
- put_fixed64_le(&key, BigEndian::FromHost64(tablet_id));
- put_fixed64_le(&key, BigEndian::FromHost64(version));
+ put_fixed64_le(&key, to_endian<std::endian::big>(tablet_id));
+ put_fixed64_le(&key, to_endian<std::endian::big>(version));
return key;
}
@@ -222,15 +221,15 @@ std::string
TabletMetaManager::encode_delete_bitmap_key(TTabletId tablet_id) {
std::string key;
key.reserve(12);
key.append(DELETE_BITMAP);
- put_fixed64_le(&key, BigEndian::FromHost64(tablet_id));
+ put_fixed64_le(&key, to_endian<std::endian::big>(tablet_id));
return key;
}
void TabletMetaManager::decode_delete_bitmap_key(std::string_view enc_key,
TTabletId* tablet_id,
int64_t* version) {
DCHECK_EQ(enc_key.size(), 20);
- *tablet_id = BigEndian::ToHost64(UNALIGNED_LOAD64(enc_key.data() + 4));
- *version = BigEndian::ToHost64(UNALIGNED_LOAD64(enc_key.data() + 12));
+ *tablet_id = to_endian<std::endian::big>(UNALIGNED_LOAD64(enc_key.data() +
4));
+ *version = to_endian<std::endian::big>(UNALIGNED_LOAD64(enc_key.data() +
12));
}
Status TabletMetaManager::save_delete_bitmap(DataDir* store, TTabletId
tablet_id,
diff --git a/be/src/olap/uint24.h b/be/src/olap/uint24.h
index 88d90407336..e04ccae8c52 100644
--- a/be/src/olap/uint24.h
+++ b/be/src/olap/uint24.h
@@ -22,8 +22,6 @@
#include <iostream>
#include <string>
-#include "olap/olap_common.h"
-
namespace doris {
// 24bit int type, used to store date type in storage
@@ -44,7 +42,7 @@ public:
return *this;
}
- uint24_t& operator=(const uint128_t& value) {
+ uint24_t& operator=(const unsigned __int128& value) {
data[0] = static_cast<uint8_t>(value);
data[1] = static_cast<uint8_t>(value >> 8);
data[2] = static_cast<uint8_t>(value >> 16);
diff --git a/be/src/util/bit_util.h b/be/src/util/bit_util.h
index 99056aed01c..466d9904fe6 100644
--- a/be/src/util/bit_util.h
+++ b/be/src/util/bit_util.h
@@ -146,100 +146,12 @@ public:
return result;
}
- // Swaps the byte order (i.e. endianess)
- static inline int64_t byte_swap(int64_t value) { return
__builtin_bswap64(value); }
- static inline uint64_t byte_swap(uint64_t value) {
- return static_cast<uint64_t>(__builtin_bswap64(value));
- }
- static inline int32_t byte_swap(int32_t value) { return
__builtin_bswap32(value); }
- static inline uint32_t byte_swap(uint32_t value) {
- return static_cast<uint32_t>(__builtin_bswap32(value));
- }
- static inline int16_t byte_swap(int16_t value) {
- return (((value >> 8) & 0xff) | ((value & 0xff) << 8));
- }
- static inline uint16_t byte_swap(uint16_t value) {
- return static_cast<uint16_t>(byte_swap(static_cast<int16_t>(value)));
- }
-
- // Write the swapped bytes into dst. len must be 1, 2, 4 or 8.
- static inline void byte_swap(void* dst, void* src, int len) {
- switch (len) {
- case 1:
- *reinterpret_cast<int8_t*>(dst) = *reinterpret_cast<int8_t*>(src);
- break;
-
- case 2:
- *reinterpret_cast<int16_t*>(dst) =
byte_swap(*reinterpret_cast<int16_t*>(src));
- break;
-
- case 4:
- *reinterpret_cast<int32_t*>(dst) =
byte_swap(*reinterpret_cast<int32_t*>(src));
- break;
-
- case 8:
- *reinterpret_cast<int64_t*>(dst) =
byte_swap(*reinterpret_cast<int64_t*>(src));
- break;
-
- default:
- DCHECK(false);
- }
- }
-
// Returns the rounded up to 64 multiple. Used for conversions of bits to
i64.
static inline uint32_t round_up_numi64(uint32_t bits) { return (bits + 63)
>> 6; }
// Returns the rounded up to 32 multiple. Used for conversions of bits to
i32.
constexpr static inline uint32_t round_up_numi32(uint32_t bits) { return
(bits + 31) >> 5; }
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- // Converts to big endian format (if not already in big endian).
- static inline int64_t big_endian(int64_t value) { return byte_swap(value);
}
- static inline uint64_t big_endian(uint64_t value) { return
byte_swap(value); }
- static inline int32_t big_endian(int32_t value) { return byte_swap(value);
}
- static inline uint32_t big_endian(uint32_t value) { return
byte_swap(value); }
- static inline int16_t big_endian(int16_t value) { return byte_swap(value);
}
- static inline uint16_t big_endian(uint16_t value) { return
byte_swap(value); }
-#else
- static inline int64_t big_endian(int64_t val) { return val; }
- static inline uint64_t big_endian(uint64_t val) { return val; }
- static inline int32_t big_endian(int32_t val) { return val; }
- static inline uint32_t big_endian(uint32_t val) { return val; }
- static inline int16_t big_endian(int16_t val) { return val; }
- static inline uint16_t big_endian(uint16_t val) { return val; }
-#endif
-
- template <typename T>
- static T big_endian_to_host(T value) {
- if constexpr (std::is_same_v<T, wide::Int256>) {
- return BigEndian::ToHost256(value);
- } else if constexpr (std::is_same_v<T, wide::UInt256>) {
- return BigEndian::ToHost256(value);
- } else if constexpr (std::is_same_v<T, __int128>) {
- return BigEndian::ToHost128(value);
- } else if constexpr (std::is_same_v<T, unsigned __int128>) {
- return BigEndian::ToHost128(value);
- } else if constexpr (std::is_same_v<T, int64_t>) {
- return BigEndian::ToHost64(value);
- } else if constexpr (std::is_same_v<T, uint64_t>) {
- return BigEndian::ToHost64(value);
- } else if constexpr (std::is_same_v<T, int32_t>) {
- return BigEndian::ToHost32(value);
- } else if constexpr (std::is_same_v<T, uint32_t>) {
- return BigEndian::ToHost32(value);
- } else if constexpr (std::is_same_v<T, int16_t>) {
- return BigEndian::ToHost16(value);
- } else if constexpr (std::is_same_v<T, uint16_t>) {
- return BigEndian::ToHost16(value);
- } else if constexpr (std::is_same_v<T, int8_t>) {
- return value;
- } else if constexpr (std::is_same_v<T, uint8_t>) {
- return value;
- } else {
- throw Exception(Status::FatalError("__builtin_unreachable"));
- }
- }
-
/// Returns the smallest power of two that contains v. If v is a power of
two, v is
/// returned. Taken from
/// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
@@ -301,74 +213,6 @@ public:
/// Returns the rounded up number of bytes that fit the number of bits.
constexpr static inline uint32_t RoundUpNumBytes(uint32_t bits) { return
(bits + 7) >> 3; }
- /// Non hw accelerated pop count.
- /// TODO: we don't use this in any perf sensitive code paths currently.
There
- /// might be a much faster way to implement this.
- static inline int PopcountNoHw(uint64_t x) {
- int count = 0;
- for (; x != 0; ++count) x &= x - 1;
- return count;
- }
-
- /// Returns the number of set bits in x
- static inline int Popcount(uint64_t x) {
- //if (LIKELY(CpuInfo::is_supported(CpuInfo::POPCNT))) {
- // return POPCNT_popcnt_u64(x);
- //} else {
- return PopcountNoHw(x);
- // }
- }
-
- // Compute correct population count for various-width signed integers
- template <typename T>
- static inline int PopcountSigned(T v) {
- // Converting to same-width unsigned then extending preserves the bit
pattern.
- return BitUtil::Popcount(static_cast<typename
std::make_unsigned<T>::type>(v));
- }
-
- /// Logical right shift for signed integer types
- /// This is needed because the C >> operator does arithmetic right shift
- /// Negative shift amounts lead to undefined behavior
- template <typename T>
- constexpr static T ShiftRightLogical(T v, int shift) {
- // Conversion to unsigned ensures most significant bits always filled
with 0's
- return static_cast<typename std::make_unsigned<T>::type>(v) >> shift;
- }
-
- /// Get an specific bit of a numeric type
- template <typename T>
- static inline int8_t GetBit(T v, int bitpos) {
- T masked = v & (static_cast<T>(0x1) << bitpos);
- return static_cast<int8_t>(ShiftRightLogical(masked, bitpos));
- }
-
- /// Set a specific bit to 1
- /// Behavior when bitpos is negative is undefined
- template <typename T>
- constexpr static T SetBit(T v, int bitpos) {
- return v | (static_cast<T>(0x1) << bitpos);
- }
-
- /// Set a specific bit to 0
- /// Behavior when bitpos is negative is undefined
- template <typename T>
- constexpr static T UnsetBit(T v, int bitpos) {
- return v & ~(static_cast<T>(0x1) << bitpos);
- }
-
- /// Returns 'value' rounded up to the nearest multiple of 'factor' when
factor is
- /// a power of two
- static inline int64_t RoundUpToPowerOf2(int64_t value, int64_t factor) {
- DCHECK((factor > 0) && ((factor & (factor - 1)) == 0));
- return (value + (factor - 1)) & ~(factor - 1);
- }
-
- // speed up function compute for SIMD
- static inline size_t RoundUpToPowerOf2Int32(size_t value, size_t factor) {
- DCHECK((factor > 0) && ((factor & (factor - 1)) == 0));
- return (value + (factor - 1)) & ~(factor - 1);
- }
-
template <typename T>
static inline T RoundDownToPowerOf2(T value, T factor) {
static_assert(std::is_integral<T>::value, "T must be an integral
type");
@@ -406,116 +250,6 @@ public:
}
return v >> num_bits;
}
-
- static void ByteSwapScalar(void* dest, const void* source, int len) {
- uint8_t* dst = reinterpret_cast<uint8_t*>(dest);
- const uint8_t* src = reinterpret_cast<const uint8_t*>(source);
- switch (len) {
- case 1:
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src);
- return;
- case 2:
- *reinterpret_cast<uint16_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint16_t*>(src));
- return;
- case 3:
- *reinterpret_cast<uint16_t*>(dst + 1) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint16_t*>(src));
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src + 2);
- return;
- case 4:
- *reinterpret_cast<uint32_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint32_t*>(src));
- return;
- case 5:
- *reinterpret_cast<uint32_t*>(dst + 1) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint32_t*>(src));
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src + 4);
- return;
- case 6:
- *reinterpret_cast<uint32_t*>(dst + 2) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint32_t*>(src));
- *reinterpret_cast<uint16_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const uint16_t*>(src
+ 4));
- return;
- case 7:
- *reinterpret_cast<uint32_t*>(dst + 3) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint32_t*>(src));
- *reinterpret_cast<uint16_t*>(dst + 1) =
- BitUtil::byte_swap(*reinterpret_cast<const uint16_t*>(src
+ 4));
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src + 6);
- return;
- case 8:
- *reinterpret_cast<uint64_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- return;
- case 9:
- *reinterpret_cast<uint64_t*>(dst + 1) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src + 8);
- return;
- case 10:
- *reinterpret_cast<uint64_t*>(dst + 2) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint16_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const uint16_t*>(src
+ 8));
- return;
- case 11:
- *reinterpret_cast<uint64_t*>(dst + 3) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint16_t*>(dst + 1) =
- BitUtil::byte_swap(*reinterpret_cast<const uint16_t*>(src
+ 8));
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src + 10);
- return;
- case 12:
- *reinterpret_cast<uint64_t*>(dst + 4) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint32_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const uint32_t*>(src
+ 8));
- return;
- case 13:
- *reinterpret_cast<uint64_t*>(dst + 5) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint32_t*>(dst + 1) =
- BitUtil::byte_swap(*reinterpret_cast<const uint32_t*>(src
+ 8));
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src + 12);
- return;
- case 14:
- *reinterpret_cast<uint64_t*>(dst + 6) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint32_t*>(dst + 2) =
- BitUtil::byte_swap(*reinterpret_cast<const uint32_t*>(src
+ 8));
- *reinterpret_cast<uint16_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const uint16_t*>(src
+ 12));
- return;
- case 15:
- *reinterpret_cast<uint64_t*>(dst + 7) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint32_t*>(dst + 3) =
- BitUtil::byte_swap(*reinterpret_cast<const uint32_t*>(src
+ 8));
- *reinterpret_cast<uint16_t*>(dst + 1) =
- BitUtil::byte_swap(*reinterpret_cast<const uint16_t*>(src
+ 12));
- *reinterpret_cast<uint8_t*>(dst) = *reinterpret_cast<const
uint8_t*>(src + 14);
- return;
- case 16:
- *reinterpret_cast<uint64_t*>(dst + 8) =
- BitUtil::byte_swap(*reinterpret_cast<const
uint64_t*>(src));
- *reinterpret_cast<uint64_t*>(dst) =
- BitUtil::byte_swap(*reinterpret_cast<const uint64_t*>(src
+ 8));
- return;
- default:
- // Revert to slow loop-based swap.
- ByteSwapScalarLoop(source, len, dest);
- return;
- }
- }
-
- static void ByteSwapScalarLoop(const void* src, int len, void* dst) {
- //TODO: improve the performance of following code further using BSWAP
intrinsic
- uint8_t* d = reinterpret_cast<uint8_t*>(dst);
- const uint8_t* s = reinterpret_cast<const uint8_t*>(src);
- for (int i = 0; i < len; ++i) d[i] = s[len - i - 1];
- }
};
} // namespace doris
diff --git a/be/src/util/byte_stream_split.cpp
b/be/src/util/byte_stream_split.cpp
index 94d112f6dab..6ba84ff6ba7 100644
--- a/be/src/util/byte_stream_split.cpp
+++ b/be/src/util/byte_stream_split.cpp
@@ -38,25 +38,25 @@ inline void do_merge_streams(const uint8_t** src_streams,
int width, int64_t nva
for (int i = 0; i < kBlockSize; i += 8) {
uint64_t v;
std::memcpy(&v, src + i, sizeof(v));
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- dest[stream + i * width] = static_cast<uint8_t>(v);
- dest[stream + (i + 1) * width] = static_cast<uint8_t>(v >> 8);
- dest[stream + (i + 2) * width] = static_cast<uint8_t>(v >> 16);
- dest[stream + (i + 3) * width] = static_cast<uint8_t>(v >> 24);
- dest[stream + (i + 4) * width] = static_cast<uint8_t>(v >> 32);
- dest[stream + (i + 5) * width] = static_cast<uint8_t>(v >> 40);
- dest[stream + (i + 6) * width] = static_cast<uint8_t>(v >> 48);
- dest[stream + (i + 7) * width] = static_cast<uint8_t>(v >> 56);
-#else
- dest[stream + i * width] = static_cast<uint8_t>(v >> 56);
- dest[stream + (i + 1) * width] = static_cast<uint8_t>(v >> 48);
- dest[stream + (i + 2) * width] = static_cast<uint8_t>(v >> 40);
- dest[stream + (i + 3) * width] = static_cast<uint8_t>(v >> 32);
- dest[stream + (i + 4) * width] = static_cast<uint8_t>(v >> 24);
- dest[stream + (i + 5) * width] = static_cast<uint8_t>(v >> 16);
- dest[stream + (i + 6) * width] = static_cast<uint8_t>(v >> 8);
- dest[stream + (i + 7) * width] = static_cast<uint8_t>(v);
-#endif
+ if constexpr (std::endian::native == std::endian::little) {
+ dest[stream + i * width] = static_cast<uint8_t>(v);
+ dest[stream + (i + 1) * width] = static_cast<uint8_t>(v >>
8);
+ dest[stream + (i + 2) * width] = static_cast<uint8_t>(v >>
16);
+ dest[stream + (i + 3) * width] = static_cast<uint8_t>(v >>
24);
+ dest[stream + (i + 4) * width] = static_cast<uint8_t>(v >>
32);
+ dest[stream + (i + 5) * width] = static_cast<uint8_t>(v >>
40);
+ dest[stream + (i + 6) * width] = static_cast<uint8_t>(v >>
48);
+ dest[stream + (i + 7) * width] = static_cast<uint8_t>(v >>
56);
+ } else if constexpr (std::endian::native == std::endian::big) {
+ dest[stream + i * width] = static_cast<uint8_t>(v >> 56);
+ dest[stream + (i + 1) * width] = static_cast<uint8_t>(v >>
48);
+ dest[stream + (i + 2) * width] = static_cast<uint8_t>(v >>
40);
+ dest[stream + (i + 3) * width] = static_cast<uint8_t>(v >>
32);
+ dest[stream + (i + 4) * width] = static_cast<uint8_t>(v >>
24);
+ dest[stream + (i + 5) * width] = static_cast<uint8_t>(v >>
16);
+ dest[stream + (i + 6) * width] = static_cast<uint8_t>(v >>
8);
+ dest[stream + (i + 7) * width] = static_cast<uint8_t>(v);
+ }
}
src_streams[stream] += kBlockSize;
}
diff --git a/be/src/util/coding.h b/be/src/util/coding.h
index 3368174f5bf..67ae763dc95 100644
--- a/be/src/util/coding.h
+++ b/be/src/util/coding.h
@@ -8,6 +8,7 @@
#pragma once
+#include <bit>
#ifndef __APPLE__
#include <endian.h>
#endif
@@ -28,39 +29,23 @@ inline void encode_fixed8(uint8_t* buf, uint8_t val) {
}
inline void encode_fixed16_le(uint8_t* buf, uint16_t val) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ val = to_endian<std::endian::little>(val);
memcpy(buf, &val, sizeof(val));
-#else
- uint16_t res = bswap_16(val);
- memcpy(buf, &res, sizeof(res));
-#endif
}
inline void encode_fixed32_le(uint8_t* buf, uint32_t val) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ val = to_endian<std::endian::little>(val);
memcpy(buf, &val, sizeof(val));
-#else
- uint32_t res = bswap_32(val);
- memcpy(buf, &res, sizeof(res));
-#endif
}
inline void encode_fixed64_le(uint8_t* buf, uint64_t val) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ val = to_endian<std::endian::little>(val);
memcpy(buf, &val, sizeof(val));
-#else
- uint64_t res = gbswap_64(val);
- memcpy(buf, &res, sizeof(res));
-#endif
}
inline void encode_fixed128_le(uint8_t* buf, uint128_t val) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ val = to_endian<std::endian::little>(val);
memcpy(buf, &val, sizeof(val));
-#else
- uint128_t res = gbswap_128(val);
- memcpy(buf, &res, sizeof(res));
-#endif
}
inline uint8_t decode_fixed8(const uint8_t* buf) {
@@ -70,41 +55,25 @@ inline uint8_t decode_fixed8(const uint8_t* buf) {
inline uint16_t decode_fixed16_le(const uint8_t* buf) {
uint16_t res;
memcpy(&res, buf, sizeof(res));
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- return res;
-#else
- return bswap_16(res);
-#endif
+ return to_endian<std::endian::little>(res);
}
inline uint32_t decode_fixed32_le(const uint8_t* buf) {
uint32_t res;
memcpy(&res, buf, sizeof(res));
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- return res;
-#else
- return bswap_32(res);
-#endif
+ return to_endian<std::endian::little>(res);
}
inline uint64_t decode_fixed64_le(const uint8_t* buf) {
uint64_t res;
memcpy(&res, buf, sizeof(res));
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- return res;
-#else
- return gbswap_64(res);
-#endif
+ return to_endian<std::endian::little>(res);
}
inline uint128_t decode_fixed128_le(const uint8_t* buf) {
uint128_t res;
memcpy(&res, buf, sizeof(res));
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- return res;
-#else
- return gbswap_128(res);
-#endif
+ return to_endian<std::endian::little>(res);
}
template <typename T>
diff --git a/be/src/util/hash_util.hpp b/be/src/util/hash_util.hpp
index fbf10b75ae0..39901e22200 100644
--- a/be/src/util/hash_util.hpp
+++ b/be/src/util/hash_util.hpp
@@ -24,9 +24,11 @@
#include <xxh3.h>
#include <zlib.h>
+#include <bit>
#include <functional>
#include "common/compiler_util.h" // IWYU pragma: keep
+#include "gutil/endian.h"
#include "gutil/hash/city.h"
#include "runtime/define_primitive_type.h"
#include "util/cpu_info.h"
@@ -228,18 +230,22 @@ public:
while (data != end) {
uint64_t k;
-#if (BYTE_ORDER == BIG_ENDIAN)
- k = (uint64_t)data[0];
- k |= (uint64_t)data[1] << 8;
- k |= (uint64_t)data[2] << 16;
- k |= (uint64_t)data[3] << 24;
- k |= (uint64_t)data[4] << 32;
- k |= (uint64_t)data[5] << 40;
- k |= (uint64_t)data[6] << 48;
- k |= (uint64_t)data[7] << 56;
-#else
- k = *((uint64_t*)data);
-#endif
+ if constexpr (std::endian::native == std::endian::big) {
+ k = (uint64_t)data[0];
+ k |= (uint64_t)data[1] << 8;
+ k |= (uint64_t)data[2] << 16;
+ k |= (uint64_t)data[3] << 24;
+ k |= (uint64_t)data[4] << 32;
+ k |= (uint64_t)data[5] << 40;
+ k |= (uint64_t)data[6] << 48;
+ k |= (uint64_t)data[7] << 56;
+ } else if constexpr (std::endian::native == std::endian::little) {
+ k = *((uint64_t*)data);
+ } else {
+ static_assert(std::endian::native == std::endian::big ||
+ std::endian::native ==
std::endian::little,
+ "Unsupported endianness");
+ }
k *= m;
k ^= k >> r;
diff --git a/be/src/vec/common/format_ip.h b/be/src/vec/common/format_ip.h
index 6b7a9221ae7..c06de536632 100644
--- a/be/src/vec/common/format_ip.h
+++ b/be/src/vec/common/format_ip.h
@@ -303,9 +303,9 @@ inline void format_ipv6(unsigned char* src, char*& dst,
uint8_t zeroed_tail_byte
uint8_t ipv4_buffer[IPV4_BINARY_LENGTH] = {0};
memcpy(ipv4_buffer, src + 12, IPV4_BINARY_LENGTH);
// Due to historical reasons format_ipv4() takes ipv4 in BE
format, but inside ipv6 we store it in LE-format.
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- std::reverse(std::begin(ipv4_buffer), std::end(ipv4_buffer));
-#endif
+ if constexpr (std::endian::native == std::endian::little) {
+ std::reverse(std::begin(ipv4_buffer), std::end(ipv4_buffer));
+ }
format_ipv4(ipv4_buffer, dst,
std::min(zeroed_tail_bytes_count,
static_cast<uint8_t>(IPV4_BINARY_LENGTH)),
"0");
diff --git a/be/src/vec/exec/format/parquet/parquet_column_convert.h
b/be/src/vec/exec/format/parquet/parquet_column_convert.h
index 3715588fd70..e2a6afe3bd9 100644
--- a/be/src/vec/exec/format/parquet/parquet_column_convert.h
+++ b/be/src/vec/exec/format/parquet/parquet_column_convert.h
@@ -425,7 +425,7 @@ public:
ValueCopyType value = 0;
memcpy(reinterpret_cast<char*>(&value), buf + offset,
sizeof(value));
offset += fixed_type_length;
- value = BitUtil::big_endian_to_host(value);
+ value = to_endian<std::endian::big>(value);
value = value >> ((sizeof(value) - fixed_type_length) * 8);
auto& v = reinterpret_cast<DecimalType&>(data[start_idx + i]);
v = (DecimalType)value;
@@ -460,7 +460,7 @@ class StringToDecimal : public PhysicalToLogicalConverter {
ValueCopyType value = 0;
if (len > 0) {
memcpy(reinterpret_cast<char*>(&value), buf + offset[i - 1],
len);
- value = BitUtil::big_endian_to_host(value);
+ value = to_endian<std::endian::big>(value);
value = value >> ((sizeof(value) - len) * 8);
}
auto& v = reinterpret_cast<DecimalType&>(data[start_idx + i]);
diff --git a/be/src/vec/exec/format/parquet/parquet_pred_cmp.h
b/be/src/vec/exec/format/parquet/parquet_pred_cmp.h
index c340592336d..bac6aa0b63e 100644
--- a/be/src/vec/exec/format/parquet/parquet_pred_cmp.h
+++ b/be/src/vec/exec/format/parquet/parquet_pred_cmp.h
@@ -21,7 +21,6 @@
#include <cstring>
#include <vector>
-#include "cctz/civil_time.h"
#include "cctz/time_zone.h"
#include "exec/olap_common.h"
#include "gutil/endian.h"
@@ -81,7 +80,7 @@ private:
Int128 value = buf_start[0] & 0x80 ? -1 : 0;
memcpy(reinterpret_cast<char*>(&value) + sizeof(Int128) -
encoded_data.size(), buf_start,
encoded_data.size());
- value = BigEndian::ToHost128(value);
+ value = to_endian<std::endian::big>(value);
if (dest_scale > scale) {
value *=
DecimalScaleParams::get_scale_factor<DecimalPrimitiveType>(dest_scale - scale);
} else if (dest_scale < scale) {
diff --git a/be/src/vec/functions/function_string.h
b/be/src/vec/functions/function_string.h
index ad065525023..a0908f4da67 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -4328,29 +4328,33 @@ private:
return;
}
const char* bytes = (const char*)(num);
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- int k = 3;
- for (; k >= 0; --k) {
- if (bytes[k]) {
- break;
+ if constexpr (std::endian::native == std::endian::little) {
+ int k = 3;
+ for (; k >= 0; --k) {
+ if (bytes[k]) {
+ break;
+ }
}
- }
- offsets[line_num] = offsets[line_num - 1] + k + 1;
- for (; k >= 0; --k) {
- chars.push_back(bytes[k] ? bytes[k] : '\0');
- }
-#else
- int k = 0;
- for (; k < 4; ++k) {
- if (bytes[k]) {
- break;
+ offsets[line_num] = offsets[line_num - 1] + k + 1;
+ for (; k >= 0; --k) {
+ chars.push_back(bytes[k] ? bytes[k] : '\0');
}
+ } else if constexpr (std::endian::native == std::endian::big) {
+ int k = 0;
+ for (; k < 4; ++k) {
+ if (bytes[k]) {
+ break;
+ }
+ }
+ offsets[line_num] = offsets[line_num - 1] + 4 - k;
+ for (; k < 4; ++k) {
+ chars.push_back(bytes[k] ? bytes[k] : '\0');
+ }
+ } else {
+ static_assert(std::endian::native == std::endian::big ||
+ std::endian::native == std::endian::little,
+ "Unsupported endianness");
}
- offsets[line_num] = offsets[line_num - 1] + 4 - k;
- for (; k < 4; ++k) {
- chars.push_back(bytes[k] ? bytes[k] : '\0');
- }
-#endif
}
};
diff --git a/be/test/util/bit_util_test.cpp b/be/test/util/bit_util_test.cpp
index fd3bee01432..3dacf1ac867 100644
--- a/be/test/util/bit_util_test.cpp
+++ b/be/test/util/bit_util_test.cpp
@@ -20,6 +20,7 @@
#include <gtest/gtest-message.h>
#include <gtest/gtest-test-part.h>
+#include <bit>
#include <boost/utility/binary.hpp>
#include "gtest/gtest_pred_impl.h"
@@ -36,17 +37,6 @@ TEST(BitUtil, Ceil) {
EXPECT_EQ(BitUtil::ceil(9, 8), 2);
}
-TEST(BitUtil, Popcount) {
- EXPECT_EQ(BitUtil::popcount(BOOST_BINARY(0 1 0 1 0 1 0 1)), 4);
- EXPECT_EQ(BitUtil::popcount_no_hw(BOOST_BINARY(0 1 0 1 0 1 0 1)), 4);
- EXPECT_EQ(BitUtil::popcount(BOOST_BINARY(1 1 1 1 0 1 0 1)), 6);
- EXPECT_EQ(BitUtil::popcount_no_hw(BOOST_BINARY(1 1 1 1 0 1 0 1)), 6);
- EXPECT_EQ(BitUtil::popcount(BOOST_BINARY(1 1 1 1 1 1 1 1)), 8);
- EXPECT_EQ(BitUtil::popcount_no_hw(BOOST_BINARY(1 1 1 1 1 1 1 1)), 8);
- EXPECT_EQ(BitUtil::popcount(0), 0);
- EXPECT_EQ(BitUtil::popcount_no_hw(0), 0);
-}
-
TEST(BitUtil, BigEndianToHost) {
uint16_t v16 = 0x1234;
uint32_t v32 = 0x12345678;
@@ -55,12 +45,12 @@ TEST(BitUtil, BigEndianToHost) {
wide::UInt256 v256 =
wide::UInt256(0x123456789abcdef0) << 192 |
wide::UInt256(0x123456789abcdef0) << 128 |
wide::UInt256(0x123456789abcdef0) << 64 |
wide::UInt256(0x123456789abcdef0);
- EXPECT_EQ(BitUtil::big_endian_to_host(v16), 0x3412);
- EXPECT_EQ(BitUtil::big_endian_to_host(v32), 0x78563412);
- EXPECT_EQ(BitUtil::big_endian_to_host(v64), 0xf0debc9a78563412);
- EXPECT_EQ(BitUtil::big_endian_to_host(v128),
+ EXPECT_EQ(to_endian<std::endian::big>(v16), 0x3412);
+ EXPECT_EQ(to_endian<std::endian::big>(v32), 0x78563412);
+ EXPECT_EQ(to_endian<std::endian::big>(v64), 0xf0debc9a78563412);
+ EXPECT_EQ(to_endian<std::endian::big>(v128),
((__int128)0xf0debc9a78563412LL << 64) | 0xf0debc9a78563412LL);
- EXPECT_EQ(BitUtil::big_endian_to_host(v256),
+ EXPECT_EQ(to_endian<std::endian::big>(v256),
wide::UInt256(0xf0debc9a78563412) << 192 |
wide::UInt256(0xf0debc9a78563412) << 128 |
wide::UInt256(0xf0debc9a78563412) << 64 |
wide::UInt256(0xf0debc9a78563412));
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]