summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2019-10-02 14:19:43 +0000
committerevergreen <evergreen@mongodb.com>2019-10-02 14:19:43 +0000
commit3175a30264d26b31309e9a4abfb69d9f14136702 (patch)
tree8864b8f41072071eb4603323cdbf1c76ba54a618
parentdadd0a797c334219b5980e7ac2dc9e38288bdc38 (diff)
downloadmongo-3175a30264d26b31309e9a4abfb69d9f14136702.tar.gz
SERVER-43175 platform/endian.h refresh
This is a very low-level bare metal header, and should ideally #include only std headers. - Remove Decimal128 dependency from endian.h. Decimal128 doesn't need endian conversions, and makes endian.h transitively include several higher-level mongo specifics. Current conversions are underspecified and mathematically incorrect or at least ambiguous. They swap the order within each of the low64 and high64 fields, but don't swap them with each other. This is behavior needed only by one spot in db/pipeline/value.cpp to deserialize NumberDecimal, so we can just inline the behavior there and remove it from endian.h. - Remove MONGO_CONFIG_BYTE_ORDER from config.h. The running compiler holds the ultimate truth on what the target endianness is (available via _BYTE_ORDER_). We should not read it from a config header. The names exported into C++ code for the endian possibilities can be changed to line up with those in C++20's std::endian {big,little,native} enum. This eliminates the Scons<=>C++ bridge protocol of "1234" and "4321" magic numbers. Scons will talk to the compiler, not directly to the code. - Use enum expressions (including if constexpr) rather than #if for branching on endianness. This makes bit-rot of unexecuted paths less likely, and is just cleaner C++. - Remove bswap_slow variants. All supported compilers have builtin bswap operations. Can reduce to a simple MSVC vs GCC branching. All compilers have a builtin, so remove the bswap_slow" implementation. - Don't need all the push_macro / pop_macro stuff, or really any macros at all. Just rely on inline C++ functions. These optimize to the same thing. - Don't need ByteOrderConverter or IntegralTypeMap traits either. Simpler metaprogramming based only on sizeof will work fine. All in all we can remove about 400 lines of old code here and shave some low-level edges off of the dependency graph. - benchmark
-rw-r--r--SConstruct5
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/config.h.in3
-rw-r--r--src/mongo/db/exec/document_value/value.cpp7
-rw-r--r--src/mongo/db/geo/hash.cpp59
-rw-r--r--src/mongo/platform/SConscript12
-rw-r--r--src/mongo/platform/decimal128.cpp12
-rw-r--r--src/mongo/platform/endian.h567
-rw-r--r--src/mongo/platform/endian_bm.cpp83
-rw-r--r--src/mongo/platform/endian_test.cpp364
10 files changed, 382 insertions, 731 deletions
diff --git a/SConstruct b/SConstruct
index 5ad509cbe80..91a3afebc85 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1124,11 +1124,6 @@ endian = get_option( "endian" )
if endian == "auto":
endian = sys.byteorder
-if endian == "little":
- env.SetConfigHeaderDefine("MONGO_CONFIG_BYTE_ORDER", "1234")
-elif endian == "big":
- env.SetConfigHeaderDefine("MONGO_CONFIG_BYTE_ORDER", "4321")
-
# These preprocessor macros came from
# http://nadeausoftware.com/articles/2012/02/c_c_tip_how_detect_processor_type_using_compiler_predefined_macros
#
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 93ca72b1504..a84ee8bf016 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -272,7 +272,6 @@ if env.TargetOSIs('windows'):
config_header_substs = (
('@mongo_config_altivec_vec_vbpermq_output_index@', 'MONGO_CONFIG_ALTIVEC_VEC_VBPERMQ_OUTPUT_INDEX'),
- ('@mongo_config_byte_order@', 'MONGO_CONFIG_BYTE_ORDER'),
('@mongo_config_debug_build@', 'MONGO_CONFIG_DEBUG_BUILD'),
('@mongo_config_have_ssl_set_ecdh_auto@', 'MONGO_CONFIG_HAVE_SSL_SET_ECDH_AUTO'),
('@mongo_config_have_ssl_ec_key_new@', 'MONGO_CONFIG_HAVE_SSL_EC_KEY_NEW'),
diff --git a/src/mongo/config.h.in b/src/mongo/config.h.in
index 74307db5de5..c7a9e1f5fd9 100644
--- a/src/mongo/config.h.in
+++ b/src/mongo/config.h.in
@@ -38,9 +38,6 @@
// Define altivec vec_vbpermq output index
@mongo_config_altivec_vec_vbpermq_output_index@
-// Define to target byte order (1234 vs 4321)
-@mongo_config_byte_order@
-
// Define if building a debug build
@mongo_config_debug_build@
diff --git a/src/mongo/db/exec/document_value/value.cpp b/src/mongo/db/exec/document_value/value.cpp
index e1835c64e45..f0d9f684222 100644
--- a/src/mongo/db/exec/document_value/value.cpp
+++ b/src/mongo/db/exec/document_value/value.cpp
@@ -1314,8 +1314,11 @@ Value Value::deserializeForSorter(BufReader& buf, const SorterDeserializeSetting
return Value(buf.read<LittleEndian<long long>>().value);
case NumberDouble:
return Value(buf.read<LittleEndian<double>>().value);
- case NumberDecimal:
- return Value(Decimal128(buf.read<LittleEndian<Decimal128::Value>>().value));
+ case NumberDecimal: {
+ auto lo = buf.read<LittleEndian<std::uint64_t>>().value;
+ auto hi = buf.read<LittleEndian<std::uint64_t>>().value;
+ return Value(Decimal128{Decimal128::Value{lo, hi}});
+ }
case Bool:
return Value(bool(buf.read<char>()));
case Date:
diff --git a/src/mongo/db/geo/hash.cpp b/src/mongo/db/geo/hash.cpp
index 6d870ece872..41c6801bf63 100644
--- a/src/mongo/db/geo/hash.cpp
+++ b/src/mongo/db/geo/hash.cpp
@@ -41,6 +41,8 @@ namespace mongo {
using std::stringstream;
+static constexpr bool kNativeLittle = (endian::Order::kNative == endian::Order::kLittle);
+
std::ostream& operator<<(std::ostream& s, const GeoHash& h) {
return s << h.toString();
}
@@ -237,12 +239,7 @@ void GeoHash::unhash_fast(unsigned* x, unsigned* y) const {
// 0x55 in binary is "01010101",
// it's an odd bitmask that we use to turn off all the even bits
unsigned t = (unsigned)(c[i]) & 0x55;
- int leftShift;
-#if MONGO_CONFIG_BYTE_ORDER == MONGO_LITTLE_ENDIAN
- leftShift = 4 * i;
-#else
- leftShift = 28 - (4 * i);
-#endif
+ const int leftShift = 4 * (kNativeLittle ? i : (7 - i));
*y |= geoBitSets.hashedToNormal[t] << leftShift;
t = ((unsigned)(c[i]) >> 1) & 0x55;
@@ -262,11 +259,11 @@ void GeoHash::unhash_slow(unsigned* x, unsigned* y) const {
}
void GeoHash::unhash(unsigned* x, unsigned* y) const {
-#if MONGO_CONFIG_BYTE_ORDER == MONGO_LITTLE_ENDIAN
- unhash_fast(x, y);
-#else
- unhash_slow(x, y);
-#endif
+ if constexpr (kNativeLittle) {
+ unhash_fast(x, y);
+ } else {
+ unhash_slow(x, y);
+ }
}
/** Is the 'bit'-th most significant bit set? (NOT the least significant) */
@@ -485,31 +482,31 @@ void GeoHash::clearUnusedBits() {
static void appendHashToBuilder(long long hash, BSONObjBuilder* builder, const char* fieldName) {
char buf[8];
-#if MONGO_CONFIG_BYTE_ORDER == MONGO_LITTLE_ENDIAN
- // Reverse the order of bytes when copying between BinData and GeoHash.
- // GeoHashes are meant to be compared from MSB to LSB, where the first 2 MSB indicate the
- // quadrant.
- // In BinData, the GeoHash of a 2D index is compared from LSB to MSB, so the bytes should be
- // reversed on little-endian systems
- copyAndReverse(buf, (char*)&hash);
-#else
- std::memcpy(buf, reinterpret_cast<char*>(&hash), 8);
-#endif
+ if constexpr (kNativeLittle) {
+ // Reverse the order of bytes when copying between BinData and GeoHash.
+ // GeoHashes are meant to be compared from MSB to LSB, where the first 2 MSB indicate the
+ // quadrant.
+ // In BinData, the GeoHash of a 2D index is compared from LSB to MSB, so the bytes should be
+ // reversed on little-endian systems
+ copyAndReverse(buf, (char*)&hash);
+ } else {
+ std::memcpy(buf, reinterpret_cast<char*>(&hash), 8);
+ }
builder->appendBinData(fieldName, 8, bdtCustom, buf);
}
static void appendHashToKeyString(long long hash, KeyString::Builder* ks) {
char buf[8];
-#if MONGO_CONFIG_BYTE_ORDER == MONGO_LITTLE_ENDIAN
- // Reverse the order of bytes when copying between BinData and GeoHash.
- // GeoHashes are meant to be compared from MSB to LSB, where the first 2 MSB indicate the
- // quadrant.
- // In BinData, the GeoHash of a 2D index is compared from LSB to MSB, so the bytes should be
- // reversed on little-endian systems
- copyAndReverse(buf, (char*)&hash);
-#else
- std::memcpy(buf, reinterpret_cast<char*>(&hash), 8);
-#endif
+ if constexpr (kNativeLittle) {
+ // Reverse the order of bytes when copying between BinData and GeoHash.
+ // GeoHashes are meant to be compared from MSB to LSB, where the first 2 MSB indicate the
+ // quadrant.
+ // In BinData, the GeoHash of a 2D index is compared from LSB to MSB, so the bytes should be
+ // reversed on little-endian systems
+ copyAndReverse(buf, (char*)&hash);
+ } else {
+ std::memcpy(buf, reinterpret_cast<char*>(&hash), 8);
+ }
ks->appendBinData(BSONBinData(buf, 8, bdtCustom));
}
diff --git a/src/mongo/platform/SConscript b/src/mongo/platform/SConscript
index 2a6c8a4f0bc..7038fd84f46 100644
--- a/src/mongo/platform/SConscript
+++ b/src/mongo/platform/SConscript
@@ -18,4 +18,14 @@ env.CppUnitTest(
'decimal128_bson_test.cpp',
'overflow_arithmetic_test.cpp'
],
-) \ No newline at end of file
+)
+
+env.Benchmark(
+ target='endian_bm',
+ source=[
+ 'endian_bm.cpp',
+ ],
+ LIBDEPS=[
+ ],
+)
+
diff --git a/src/mongo/platform/decimal128.cpp b/src/mongo/platform/decimal128.cpp
index ebe0447b7cf..3d0e06f42d5 100644
--- a/src/mongo/platform/decimal128.cpp
+++ b/src/mongo/platform/decimal128.cpp
@@ -49,6 +49,7 @@
#include "mongo/base/static_assert.h"
#include "mongo/base/string_data.h"
#include "mongo/config.h"
+#include "mongo/platform/endian.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/str.h"
@@ -166,14 +167,11 @@ size_t validateInputString(mongo::StringData input, std::uint32_t* signalingFlag
namespace mongo {
namespace {
+
// Determine system's endian ordering in order to construct decimal 128 values directly
-#if MONGO_CONFIG_BYTE_ORDER == 1234
-const int kHigh64 = 1;
-const int kLow64 = 0;
-#else
-const int kHigh64 = 0;
-const int kLow64 = 1;
-#endif
+constexpr bool kNativeLittle = (endian::Order::kNative == endian::Order::kLittle);
+const int kLow64 = kNativeLittle ? 0 : 1;
+const int kHigh64 = kNativeLittle ? 1 : 0;
// The Intel library uses long long for BID_UINT128s parts, which on some
// systems is longer than a uint64_t. We need to cast down, although there
diff --git a/src/mongo/platform/endian.h b/src/mongo/platform/endian.h
index 4d367baf89b..5a36f783ce0 100644
--- a/src/mongo/platform/endian.h
+++ b/src/mongo/platform/endian.h
@@ -31,509 +31,112 @@
#include <climits>
#include <cstdint>
+#include <cstdlib>
#include <cstring>
#include <type_traits>
-
-#include "mongo/base/static_assert.h"
-#include "mongo/config.h"
-#include "mongo/platform/decimal128.h"
-
-#pragma push_macro("MONGO_UINT16_SWAB")
-#pragma push_macro("MONGO_UINT32_SWAB")
-#pragma push_macro("MONGO_UINT64_SWAB")
-#pragma push_macro("htobe16")
-#pragma push_macro("htobe32")
-#pragma push_macro("htobe64")
-#pragma push_macro("htole16")
-#pragma push_macro("htole32")
-#pragma push_macro("htole64")
-#pragma push_macro("be16toh")
-#pragma push_macro("be32toh")
-#pragma push_macro("be64toh")
-#pragma push_macro("le16toh")
-#pragma push_macro("le32toh")
-#pragma push_macro("le64toh")
-
-#undef MONGO_UINT16_SWAB
-#undef MONGO_UINT32_SWAB
-#undef MONGO_UINT64_SWAB
-#undef htobe16
-#undef htobe32
-#undef htobe64
-#undef htole16
-#undef htole32
-#undef htole64
-#undef be16toh
-#undef be32toh
-#undef be64toh
-#undef le16toh
-#undef le32toh
-#undef le64toh
-
-#define MONGO_LITTLE_ENDIAN 1234
-#define MONGO_BIG_ENDIAN 4321
-
-#if defined(_MSC_VER)
-#include <cstdlib>
-#define MONGO_UINT16_SWAB(v) _byteswap_ushort(v)
-#define MONGO_UINT32_SWAB(v) _byteswap_ulong(v)
-#define MONGO_UINT64_SWAB(v) _byteswap_uint64(v)
-#elif defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) && \
- (__clang_major__ >= 3) && (__clang_minor__ >= 1)
-#if __has_builtin(__builtin_bswap16)
-#define MONGO_UINT16_SWAB(v) __builtin_bswap16(v)
-#endif
-#if __has_builtin(__builtin_bswap32)
-#define MONGO_UINT32_SWAB(v) __builtin_bswap32(v)
-#endif
-#if __has_builtin(__builtin_bswap64)
-#define MONGO_UINT64_SWAB(v) __builtin_bswap64(v)
-#endif
-#elif defined(__GNUC__) && (__GNUC__ >= 4)
-#if __GNUC__ >= 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 3
-#define MONGO_UINT32_SWAB(v) __builtin_bswap32(v)
-#define MONGO_UINT64_SWAB(v) __builtin_bswap64(v)
-#endif
-#if __GNUC__ >= 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 8
-#define MONGO_UINT16_SWAB(v) __builtin_bswap16(v)
-#endif
-#elif defined(__sun)
-#include <sys/byteorder.h>
-#define MONGO_UINT16_SWAB(v) BSWAP_16(v)
-#define MONGO_UINT32_SWAB(v) BSWAP_32(v)
-#define MONGO_UINT64_SWAB(v) BSWAP_64(v)
-#endif
-
-#ifndef MONGO_UINT16_SWAB
-#define MONGO_UINT16_SWAB(v) endian::bswap_slow16(v)
-#endif
-
-#ifndef MONGO_UINT32_SWAB
-#define MONGO_UINT32_SWAB(v) endian::bswap_slow32(v)
-#endif
-
-#ifndef MONGO_UINT64_SWAB
-#define MONGO_UINT64_SWAB(v) endian::bswap_slow64(v)
-#endif
-
-#if MONGO_CONFIG_BYTE_ORDER == MONGO_LITTLE_ENDIAN
-#define htobe16(v) MONGO_UINT16_SWAB(v)
-#define htobe32(v) MONGO_UINT32_SWAB(v)
-#define htobe64(v) MONGO_UINT64_SWAB(v)
-#define htole16(v) (v)
-#define htole32(v) (v)
-#define htole64(v) (v)
-#define be16toh(v) MONGO_UINT16_SWAB(v)
-#define be32toh(v) MONGO_UINT32_SWAB(v)
-#define be64toh(v) MONGO_UINT64_SWAB(v)
-#define le16toh(v) (v)
-#define le32toh(v) (v)
-#define le64toh(v) (v)
-#elif MONGO_CONFIG_BYTE_ORDER == MONGO_BIG_ENDIAN
-#define htobe16(v) (v)
-#define htobe32(v) (v)
-#define htobe64(v) (v)
-#define htole16(v) MONGO_UINT16_SWAB(v)
-#define htole32(v) MONGO_UINT32_SWAB(v)
-#define htole64(v) MONGO_UINT64_SWAB(v)
-#define be16toh(v) (v)
-#define be32toh(v) (v)
-#define be64toh(v) (v)
-#define le16toh(v) MONGO_UINT16_SWAB(v)
-#define le32toh(v) MONGO_UINT32_SWAB(v)
-#define le64toh(v) MONGO_UINT64_SWAB(v)
+#include <utility>
+
+namespace mongo::endian {
+
+/** Like `std::endian`. https://en.cppreference.com/w/cpp/types/endian */
+enum class Order {
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+ kLittle,
+ kBig,
+ kNative = kLittle,
+#elif defined(__GNUC__)
+ kLittle = __ORDER_LITTLE_ENDIAN__,
+ kBig = __ORDER_BIG_ENDIAN__,
+ kNative = __BYTE_ORDER__,
#else
-#error \
- "The endianness of target architecture is unknown. " \
- "Please define MONGO_CONFIG_BYTE_ORDER"
-#endif
+#error "Unsupported compiler or architecture"
+#endif // compiler check
+};
-namespace mongo {
-namespace endian {
+namespace detail {
-static inline uint16_t bswap_slow16(uint16_t v) {
- return ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8);
+inline std::uint8_t bswap(std::uint8_t v) {
+ return v;
}
-
-static inline uint32_t bswap_slow32(uint32_t v) {
- return ((v & 0x000000FFUL) << 24) | ((v & 0x0000FF00UL) << 8) | ((v & 0x00FF0000UL) >> 8) |
- ((v & 0xFF000000UL) >> 24);
+#if defined(_MSC_VER)
+inline std::uint16_t bswap(std::uint16_t v) {
+ return _byteswap_ushort(v);
+}
+inline std::uint32_t bswap(std::uint32_t v) {
+ return _byteswap_ulong(v);
+}
+inline std::uint64_t bswap(std::uint64_t v) {
+ return _byteswap_uint64(v);
}
+#else // non-MSVC
+inline std::uint16_t bswap(std::uint16_t v) {
+ return __builtin_bswap16(v);
+}
+inline std::uint32_t bswap(std::uint32_t v) {
+ return __builtin_bswap32(v);
+}
+inline std::uint64_t bswap(std::uint64_t v) {
+ return __builtin_bswap64(v);
+}
+#endif // non-MSVC
-static inline uint64_t bswap_slow64(uint64_t v) {
- return ((v & 0x00000000000000FFULL) << 56) | ((v & 0x000000000000FF00ULL) << 40) |
- ((v & 0x0000000000FF0000ULL) << 24) | ((v & 0x00000000FF000000ULL) << 8) |
- ((v & 0x000000FF00000000ULL) >> 8) | ((v & 0x0000FF0000000000ULL) >> 24) |
- ((v & 0x00FF000000000000ULL) >> 40) | ((v & 0xFF00000000000000ULL) >> 56);
+/**
+ * Same requirements as `std::bit_cast`. `From` is only being trivially copied, but `To` is
+ * being trivially constructed, which is a stronger operation.
+ * https://en.cppreference.com/w/cpp/numeric/bit_cast
+ */
+template <typename To,
+ typename From,
+ std::enable_if_t<sizeof(To) == sizeof(From) && //
+ std::is_trivially_copyable_v<From> && //
+ std::is_trivial_v<To>, //
+ int> = 0>
+To bitCast(From t) {
+ To u;
+ std::memcpy(&u, &t, sizeof(t));
+ return u;
}
template <typename T>
-struct ByteOrderConverter;
-
-template <>
-struct ByteOrderConverter<uint8_t> {
- typedef uint8_t T;
-
- inline static T nativeToBig(T t) {
- return t;
- }
-
- inline static T bigToNative(T t) {
- return t;
- }
-
- inline static T nativeToLittle(T t) {
- return t;
- }
-
- inline static T littleToNative(T t) {
- return t;
- }
-};
-
-template <>
-struct ByteOrderConverter<uint16_t> {
- typedef uint16_t T;
-
- inline static T nativeToBig(T t) {
- return htobe16(t);
- }
-
- inline static T bigToNative(T t) {
- return be16toh(t);
- }
-
- inline static T nativeToLittle(T t) {
- return htole16(t);
- }
+using RequireArithmetic = std::enable_if_t<std::is_arithmetic_v<T>, int>;
- inline static T littleToNative(T t) {
- return le16toh(t);
- }
-};
-
-template <>
-struct ByteOrderConverter<uint32_t> {
- typedef uint32_t T;
-
- inline static T nativeToBig(T t) {
- return htobe32(t);
- }
-
- inline static T bigToNative(T t) {
- return be32toh(t);
- }
-
- inline static T nativeToLittle(T t) {
- return htole32(t);
- }
-
- inline static T littleToNative(T t) {
- return le32toh(t);
- }
-};
-
-template <>
-struct ByteOrderConverter<uint64_t> {
- typedef uint64_t T;
-
- inline static T nativeToBig(T t) {
- return htobe64(t);
- }
-
- inline static T bigToNative(T t) {
- return be64toh(t);
- }
-
- inline static T nativeToLittle(T t) {
- return htole64(t);
- }
-
- inline static T littleToNative(T t) {
- return le64toh(t);
- }
-};
+} // namespace detail
-template <>
-struct ByteOrderConverter<int8_t> {
- typedef int8_t T;
-
- inline static T nativeToBig(T t) {
- return t;
- }
-
- inline static T bigToNative(T t) {
+template <Order From, Order To, typename T>
+T convertByteOrder(T t) {
+ if constexpr (From == To) {
return t;
+ } else {
+ static constexpr std::size_t bits = CHAR_BIT * sizeof(T);
+ // clang-format off
+ using BitInt = std::conditional_t<bits == 8, std::uint8_t,
+ std::conditional_t<bits == 16, std::uint16_t,
+ std::conditional_t<bits == 32, std::uint32_t,
+ std::conditional_t<bits == 64, std::uint64_t,
+ void>>>>;
+ // clang-format on
+ return detail::bitCast<T>(detail::bswap(detail::bitCast<BitInt>(t)));
}
-
- inline static T nativeToLittle(T t) {
- return t;
- }
-
- inline static T littleToNative(T t) {
- return t;
- }
-};
-
-template <>
-struct ByteOrderConverter<int16_t> {
- typedef int16_t T;
-
- inline static T nativeToBig(T t) {
- return htobe16(static_cast<uint16_t>(t));
- }
-
- inline static T bigToNative(T t) {
- return be16toh(static_cast<uint16_t>(t));
- }
-
- inline static T nativeToLittle(T t) {
- return htole16(static_cast<uint16_t>(t));
- }
-
- inline static T littleToNative(T t) {
- return le16toh(static_cast<uint16_t>(t));
- }
-};
-
-template <>
-struct ByteOrderConverter<int32_t> {
- typedef int32_t T;
-
- inline static T nativeToBig(T t) {
- return htobe32(static_cast<uint32_t>(t));
- }
-
- inline static T bigToNative(T t) {
- return be32toh(static_cast<uint32_t>(t));
- }
-
- inline static T nativeToLittle(T t) {
- return htole32(static_cast<uint32_t>(t));
- }
-
- inline static T littleToNative(T t) {
- return le32toh(static_cast<uint32_t>(t));
- }
-};
-
-template <>
-struct ByteOrderConverter<int64_t> {
- typedef int64_t T;
-
- inline static T nativeToBig(T t) {
- return htobe64(static_cast<uint64_t>(t));
- }
-
- inline static T bigToNative(T t) {
- return be64toh(static_cast<uint64_t>(t));
- }
-
- inline static T nativeToLittle(T t) {
- return htole64(static_cast<uint64_t>(t));
- }
-
- inline static T littleToNative(T t) {
- return le64toh(static_cast<uint64_t>(t));
- }
-};
-
-template <>
-struct ByteOrderConverter<float> {
- typedef float T;
-
- inline static T nativeToBig(T t) {
- MONGO_STATIC_ASSERT(sizeof(T) == sizeof(uint32_t));
-
- uint32_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = htobe32(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-
- inline static T bigToNative(T t) {
- uint32_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = be32toh(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-
- inline static T nativeToLittle(T t) {
- uint32_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = htole32(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-
- inline static T littleToNative(T t) {
- uint32_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = le32toh(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-};
-
-template <>
-struct ByteOrderConverter<double> {
- typedef double T;
-
- inline static T nativeToBig(T t) {
- MONGO_STATIC_ASSERT(sizeof(T) == sizeof(uint64_t));
-
- uint64_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = htobe64(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-
- inline static T bigToNative(T t) {
- uint64_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = be64toh(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-
- inline static T nativeToLittle(T t) {
- uint64_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = htole64(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-
- inline static T littleToNative(T t) {
- uint64_t temp;
- std::memcpy(&temp, &t, sizeof(t));
- temp = le64toh(temp);
- std::memcpy(&t, &temp, sizeof(t));
- return t;
- }
-};
-
-template <>
-struct ByteOrderConverter<Decimal128::Value> {
- typedef Decimal128::Value T;
-
- inline static T nativeToBig(T t) {
- t.low64 = ByteOrderConverter<uint64_t>::nativeToBig(t.low64);
- t.high64 = ByteOrderConverter<uint64_t>::nativeToBig(t.high64);
- return t;
- }
-
- inline static T bigToNative(T t) {
- t.low64 = ByteOrderConverter<uint64_t>::bigToNative(t.low64);
- t.high64 = ByteOrderConverter<uint64_t>::bigToNative(t.high64);
- return t;
- }
-
- inline static T nativeToLittle(T t) {
- t.low64 = ByteOrderConverter<uint64_t>::nativeToLittle(t.low64);
- t.high64 = ByteOrderConverter<uint64_t>::nativeToLittle(t.high64);
- return t;
- }
-
- inline static T littleToNative(T t) {
- t.low64 = ByteOrderConverter<uint64_t>::littleToNative(t.low64);
- t.high64 = ByteOrderConverter<uint64_t>::littleToNative(t.high64);
- return t;
- }
-};
-
-// Use a typemape to normalize non-fixed-width integral types to the associated fixed width
-// types.
-
-template <typename T>
-struct IntegralTypeMap {
- typedef T type;
-};
-
-template <>
-struct IntegralTypeMap<signed char> {
- MONGO_STATIC_ASSERT(CHAR_BIT == 8);
- typedef int8_t type;
-};
-
-template <>
-struct IntegralTypeMap<unsigned char> {
- MONGO_STATIC_ASSERT(CHAR_BIT == 8);
- typedef uint8_t type;
-};
-
-template <>
-struct IntegralTypeMap<char> {
- MONGO_STATIC_ASSERT(CHAR_BIT == 8);
- typedef std::conditional<std::is_signed<char>::value, int8_t, uint8_t>::type type;
-};
-
-template <>
-struct IntegralTypeMap<long long> {
- MONGO_STATIC_ASSERT(sizeof(long long) == sizeof(int64_t));
- typedef int64_t type;
-};
-
-template <>
-struct IntegralTypeMap<unsigned long long> {
- MONGO_STATIC_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t));
- typedef uint64_t type;
-};
-
-template <typename T>
-inline T nativeToBig(T t) {
- return ByteOrderConverter<typename IntegralTypeMap<T>::type>::nativeToBig(t);
}
-template <typename T>
-inline T bigToNative(T t) {
- return ByteOrderConverter<typename IntegralTypeMap<T>::type>::bigToNative(t);
+template <typename T, detail::RequireArithmetic<T> = 0>
+T nativeToBig(T t) {
+ return convertByteOrder<Order::kNative, Order::kBig>(t);
}
-template <typename T>
-inline T nativeToLittle(T t) {
- return ByteOrderConverter<typename IntegralTypeMap<T>::type>::nativeToLittle(t);
+template <typename T, detail::RequireArithmetic<T> = 0>
+T nativeToLittle(T t) {
+ return convertByteOrder<Order::kNative, Order::kLittle>(t);
}
-template <typename T>
-inline T littleToNative(T t) {
- return ByteOrderConverter<typename IntegralTypeMap<T>::type>::littleToNative(t);
+template <typename T, detail::RequireArithmetic<T> = 0>
+T bigToNative(T t) {
+ return convertByteOrder<Order::kBig, Order::kNative>(t);
}
-} // namespace endian
-} // namespace mongo
-
-#undef MONGO_UINT16_SWAB
-#undef MONGO_UINT32_SWAB
-#undef MONGO_UINT64_SWAB
-#undef htobe16
-#undef htobe32
-#undef htobe64
-#undef htole16
-#undef htole32
-#undef htole64
-#undef be16toh
-#undef be32toh
-#undef be64toh
-#undef le16toh
-#undef le32toh
-#undef le64toh
+template <typename T, detail::RequireArithmetic<T> = 0>
+T littleToNative(T t) {
+ return convertByteOrder<Order::kLittle, Order::kNative>(t);
+}
-#pragma pop_macro("MONGO_UINT16_SWAB")
-#pragma pop_macro("MONGO_UINT32_SWAB")
-#pragma pop_macro("MONGO_UINT64_SWAB")
-#pragma pop_macro("htobe16")
-#pragma pop_macro("htobe32")
-#pragma pop_macro("htobe64")
-#pragma pop_macro("htole16")
-#pragma pop_macro("htole32")
-#pragma pop_macro("htole64")
-#pragma pop_macro("be16toh")
-#pragma pop_macro("be32toh")
-#pragma pop_macro("be64toh")
-#pragma pop_macro("le16toh")
-#pragma pop_macro("le32toh")
-#pragma pop_macro("le64toh")
+} // namespace mongo::endian
diff --git a/src/mongo/platform/endian_bm.cpp b/src/mongo/platform/endian_bm.cpp
new file mode 100644
index 00000000000..e38ad01e670
--- /dev/null
+++ b/src/mongo/platform/endian_bm.cpp
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2019-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+
+#include "mongo/platform/basic.h"
+
+#include <array>
+#include <cstdint>
+#include <limits>
+#include <numeric>
+#include <random>
+#include <string>
+#include <vector>
+
+#include <benchmark/benchmark.h>
+
+#include "mongo/base/string_data.h"
+#include "mongo/platform/endian.h"
+
+namespace mongo {
+namespace {
+
+template <typename T>
+void BM_NativeToBig(benchmark::State& state) {
+ std::uint64_t items = 0;
+ std::vector<T> in(1000);
+ std::iota(in.begin(), in.end(), 0);
+ for (auto _ : state) {
+ for (auto& i : in)
+ benchmark::DoNotOptimize(endian::nativeToBig(i));
+ items += in.size();
+ }
+ state.SetItemsProcessed(items);
+}
+
+template <typename T>
+void BM_NativeToLittle(benchmark::State& state) {
+ std::uint64_t items = 0;
+ std::vector<T> in(1000);
+ std::iota(in.begin(), in.end(), 0);
+ for (auto _ : state) {
+ for (auto& i : in)
+ benchmark::DoNotOptimize(endian::nativeToLittle(i));
+ items += in.size();
+ }
+ state.SetItemsProcessed(items);
+}
+
+BENCHMARK_TEMPLATE(BM_NativeToBig, uint16_t);
+BENCHMARK_TEMPLATE(BM_NativeToBig, uint32_t);
+BENCHMARK_TEMPLATE(BM_NativeToBig, uint64_t);
+BENCHMARK_TEMPLATE(BM_NativeToLittle, uint16_t);
+BENCHMARK_TEMPLATE(BM_NativeToLittle, uint32_t);
+BENCHMARK_TEMPLATE(BM_NativeToLittle, uint64_t);
+
+} // namespace
+} // namespace mongo
diff --git a/src/mongo/platform/endian_test.cpp b/src/mongo/platform/endian_test.cpp
index aaf6f61838b..c26eab902cb 100644
--- a/src/mongo/platform/endian_test.cpp
+++ b/src/mongo/platform/endian_test.cpp
@@ -34,45 +34,10 @@
#include "mongo/config.h"
#include "mongo/unittest/unittest.h"
-namespace mongo {
+namespace mongo::endian {
+namespace {
-using namespace endian;
-
-TEST(EndianTest, TestSlow16) {
- uint8_t le_buf[] = {0x01, 0x02};
- uint8_t be_buf[] = {0x02, 0x01};
- uint16_t le;
- uint16_t be;
- std::memcpy(&le, le_buf, sizeof(le));
- std::memcpy(&be, be_buf, sizeof(be));
-
- ASSERT_EQUALS(be, endian::bswap_slow16(le));
- ASSERT_EQUALS(le, endian::bswap_slow16(be));
-}
-
-TEST(EndianTest, TestSlow32) {
- uint8_t le_buf[] = {0x01, 0x02, 0x03, 0x04};
- uint8_t be_buf[] = {0x04, 0x03, 0x02, 0x01};
- uint32_t le;
- uint32_t be;
- std::memcpy(&le, le_buf, sizeof(le));
- std::memcpy(&be, be_buf, sizeof(be));
-
- ASSERT_EQUALS(be, endian::bswap_slow32(le));
- ASSERT_EQUALS(le, endian::bswap_slow32(be));
-}
-
-TEST(EndianTest, TestSlow64) {
- uint8_t le_buf[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
- uint8_t be_buf[] = {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
- uint64_t le;
- uint64_t be;
- std::memcpy(&le, le_buf, sizeof(le));
- std::memcpy(&be, be_buf, sizeof(be));
-
- ASSERT_EQUALS(be, endian::bswap_slow64(le));
- ASSERT_EQUALS(le, endian::bswap_slow64(be));
-}
+const bool kNativeLittle = (endian::Order::kNative == endian::Order::kLittle);
TEST(EndianTest, NativeToBig_uint16_t) {
uint8_t le_buf[] = {0x01, 0x02};
@@ -82,11 +47,11 @@ TEST(EndianTest, NativeToBig_uint16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToBig_uint32_t) {
@@ -97,11 +62,11 @@ TEST(EndianTest, NativeToBig_uint32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToBig_uint64_t) {
@@ -112,11 +77,11 @@ TEST(EndianTest, NativeToBig_uint64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToBig_int16_t) {
@@ -127,11 +92,11 @@ TEST(EndianTest, NativeToBig_int16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToBig_int32_t) {
@@ -142,11 +107,11 @@ TEST(EndianTest, NativeToBig_int32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToBig_int64_t) {
@@ -157,11 +122,11 @@ TEST(EndianTest, NativeToBig_int64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToBig_float) {
@@ -172,11 +137,11 @@ TEST(EndianTest, NativeToBig_float) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToBig_double) {
@@ -187,11 +152,11 @@ TEST(EndianTest, NativeToBig_double) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(be, nativeToBig(le));
-#else
- ASSERT_EQUALS(be, nativeToBig(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(be, nativeToBig(le));
+ } else {
+ ASSERT_EQUALS(be, nativeToBig(be));
+ }
}
TEST(EndianTest, NativeToLittle_uint16_t) {
@@ -202,11 +167,11 @@ TEST(EndianTest, NativeToLittle_uint16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, NativeToLittle_uint32_t) {
@@ -217,11 +182,11 @@ TEST(EndianTest, NativeToLittle_uint32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, NativeToLittle_uint64_t) {
@@ -232,11 +197,11 @@ TEST(EndianTest, NativeToLittle_uint64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, NativeToLittle_int16_t) {
@@ -247,11 +212,11 @@ TEST(EndianTest, NativeToLittle_int16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, NativeToLittle_int32_t) {
@@ -262,11 +227,11 @@ TEST(EndianTest, NativeToLittle_int32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, NativeToLittle_int64_t) {
@@ -277,11 +242,11 @@ TEST(EndianTest, NativeToLittle_int64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, NativeToLittle_float) {
@@ -292,11 +257,11 @@ TEST(EndianTest, NativeToLittle_float) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, NativeToLittle_double) {
@@ -307,11 +272,11 @@ TEST(EndianTest, NativeToLittle_double) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, nativeToLittle(le));
-#else
- ASSERT_EQUALS(le, nativeToLittle(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, nativeToLittle(le));
+ } else {
+ ASSERT_EQUALS(le, nativeToLittle(be));
+ }
}
TEST(EndianTest, LittleToNative_uint16_t) {
@@ -322,11 +287,11 @@ TEST(EndianTest, LittleToNative_uint16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, LittleToNative_uint32_t) {
@@ -337,11 +302,11 @@ TEST(EndianTest, LittleToNative_uint32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, LittleToNative_uint64_t) {
@@ -352,11 +317,11 @@ TEST(EndianTest, LittleToNative_uint64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, LittleToNative_int16_t) {
@@ -367,11 +332,11 @@ TEST(EndianTest, LittleToNative_int16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, LittleToNative_int32_t) {
@@ -382,11 +347,11 @@ TEST(EndianTest, LittleToNative_int32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, LittleToNative_int64_t) {
@@ -397,11 +362,11 @@ TEST(EndianTest, LittleToNative_int64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, LittleToNative_float) {
@@ -412,11 +377,11 @@ TEST(EndianTest, LittleToNative_float) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, LittleToNative_double) {
@@ -427,11 +392,11 @@ TEST(EndianTest, LittleToNative_double) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, littleToNative(le));
-#else
- ASSERT_EQUALS(be, littleToNative(le));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, littleToNative(le));
+ } else {
+ ASSERT_EQUALS(be, littleToNative(le));
+ }
}
TEST(EndianTest, BigToNative_uint16_t) {
@@ -442,11 +407,11 @@ TEST(EndianTest, BigToNative_uint16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
TEST(EndianTest, BigToNative_uint32_t) {
@@ -457,11 +422,11 @@ TEST(EndianTest, BigToNative_uint32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
TEST(EndianTest, BigToNative_uint64_t) {
@@ -472,11 +437,11 @@ TEST(EndianTest, BigToNative_uint64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
TEST(EndianTest, BigToNative_int16_t) {
@@ -487,11 +452,11 @@ TEST(EndianTest, BigToNative_int16_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
TEST(EndianTest, BigToNative_int32_t) {
@@ -502,11 +467,11 @@ TEST(EndianTest, BigToNative_int32_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
TEST(EndianTest, BigToNative_int64_t) {
@@ -517,11 +482,11 @@ TEST(EndianTest, BigToNative_int64_t) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
TEST(EndianTest, BigToNative_float) {
@@ -532,11 +497,11 @@ TEST(EndianTest, BigToNative_float) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
TEST(EndianTest, BigToNative_double) {
@@ -547,11 +512,12 @@ TEST(EndianTest, BigToNative_double) {
std::memcpy(&le, le_buf, sizeof(le));
std::memcpy(&be, be_buf, sizeof(be));
-#if MONGO_CONFIG_BYTE_ORDER == 1234
- ASSERT_EQUALS(le, bigToNative(be));
-#else
- ASSERT_EQUALS(be, bigToNative(be));
-#endif
+ if (kNativeLittle) {
+ ASSERT_EQUALS(le, bigToNative(be));
+ } else {
+ ASSERT_EQUALS(be, bigToNative(be));
+ }
}
-} // namespace mongo
+} // namespace
+} // namespace mongo::endian